New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #12542: new TreeWalker property to skip exceptions #14779
base: master
Are you sure you want to change the base?
Conversation
6b3557a
to
800073f
Compare
src/main/resources/com/puppycrawl/tools/checkstyle/messages.properties
Outdated
Show resolved
Hide resolved
I think the 2 failing CIs are related to 2 new suppressions of non-compilable files. These new suppressions do not exist on the master branch, so these two non-compilable files will still fail the CI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
item:
ci command https://app.circleci.com/pipelines/github/checkstyle/checkstyle/25089/workflows/538c9779-440e-4a6e-a9eb-1361989b4ead/jobs/570860?invite=true#step-103-2 , you can try to run it on your local. recheck what is missing at https://github.com/checkstyle/contribution/blob/a2f8b1575c42b9156fdcedabbb528296eb32e09a/checkstyle-tester/projects-to-test-on.properties#L7 please send PR to that repo. |
@romani PR is created here checkstyle/contribution#852. |
Merged, CIs are restarted |
800073f
to
55f4771
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last:
55f4771
to
be6cfce
Compare
be6cfce
to
b95374d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last:
b95374d
to
c6a72a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok to merge.
Thanks a lot!
Sorry for didn't catch that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any regression provided to ensure this is working.
We need 2 reports. One with default treewalker (expecting no changes), another with new property turned on (show exceptions removed).
getFilteredViolations(file.getAbsolutePath(), contents, rootAST); | ||
addViolations(filteredViolations); | ||
catch (CheckstyleException ex) { | ||
if (!skipFileOnJavaParseException) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This catch spans almost the entire method and has the possibility to catch more than just parsing exceptions. There is no check that we are catching parse exceptions. We could be catching much more.
This should be trimmed back to ensure it only catches parse exceptions.
There is issue #12803 to allow us to have more methods that throw checkstyle exceptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rnveach I agree, this is definitely not the best way to suppress expections. However, I was trying to only enclose final DetailAST rootAST = JavaParser.parse(contents);
with try-catch. But, in that case, I need to use a return
to block the following procedure, which will cause our CI to complain, since it is not allowed to have a return in a void method. Do you agree to suppress it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not agree to suppress yet. There should ways around this that follow our style rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can also add a local variable flag. When an exception occurs set the flag to true, and we guard the following procedure with this flag. If this flag is true, then we do not proceed the following procedure. What about this? I felt like this is somehow over-engineering and it is not very elegant, so that's why I didn't use this at the first try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, we should catch only parse exceptions, not CheckstyleException.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to target with try catch only
catch (IllegalStateException ex) { |
So try catch should wrap only final DetailAST rootAST = JavaParser.parse(contents);
and we can catch CheckstyleException in this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, work around by using a skip
flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romani @rnveach This workaround using a skip
flag seems bring us more problems and potential suppressions with nullness.
checkstyle/src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java
Lines 169 to 198 in e84dc9c
try { | |
rootAST = JavaParser.parse(contents); | |
} | |
catch (CheckstyleException ex) { | |
if (skipFileOnJavaParseException) { | |
skip = true; | |
} | |
else { | |
throw ex; | |
} | |
} | |
if (!skip) { | |
if (!ordinaryChecks.isEmpty()) { | |
walk(rootAST, contents, AstState.ORDINARY); | |
} | |
if (!commentChecks.isEmpty()) { | |
final DetailAST astWithComments = JavaParser.appendHiddenCommentNodes(rootAST); | |
walk(astWithComments, contents, AstState.WITH_COMMENTS); | |
} | |
if (filters.isEmpty()) { | |
addViolations(violations); | |
} | |
else { | |
final SortedSet<Violation> filteredViolations = | |
getFilteredViolations(file.getAbsolutePath(), contents, rootAST); | |
addViolations(filteredViolations); | |
} | |
violations.clear(); | |
} |
New surviving error(s) found:
<checkerFrameworkError unstable="false">
<fileName>src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java</fileName>
<specifier>argument</specifier>
<message>incompatible argument for parameter ast of TreeWalker.walk.</message>
<lineContent>walk(rootAST, contents, AstState.ORDINARY);</lineContent>
<details>
found : @Initialized @Nullable DetailAST
required: @Initialized @NonNull DetailAST
</details>
</checkerFrameworkError>
<checkerFrameworkError unstable="false">
<fileName>src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java</fileName>
<specifier>argument</specifier>
<message>incompatible argument for parameter root of JavaParser.appendHiddenCommentNodes.</message>
<lineContent>final DetailAST astWithComments = JavaParser.appendHiddenCommentNodes(rootAST);</lineContent>
<details>
found : @Initialized @Nullable DetailAST
required: @Initialized @NonNull DetailAST
</details>
</checkerFrameworkError>
<checkerFrameworkError unstable="false">
<fileName>src/main/java/com/puppycrawl/tools/checkstyle/TreeWalker.java</fileName>
<specifier>argument</specifier>
<message>incompatible argument for parameter rootAST of TreeWalker.getFilteredViolations.</message>
<lineContent>getFilteredViolations(file.getAbsolutePath(), contents, rootAST);</lineContent>
<details>
found : @Initialized @Nullable DetailAST
required: @Initialized @NonNull DetailAST
</details>
</checkerFrameworkError>
I felt like this structure of code is too complicated. This is the core code of the project, it would be hard for later maintainers if we do more workarounds In this case, do you prefer to still work on this workaround (add a dummy initial value for rooAST instead of null), or prefer to suppress a single return statement, or there are any better solutions. Please share your thoughts. I am out of ideas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be hard for later maintainers
If we want to have better code, please do this actively, right now this issue stuck in not done state, and users still having unfortunate decisions to disable checkstyle because it doesn't support modern language features.
You will not avoid catch of exception, so Checker will be not happy, and you will do just playing with creation of method that hide such exceptions handling, but conceptually all will stay the same.
If we start new method creation, you will stick in review more. My suggestion is pass review quicker, get feature out to users, and work in separate PR in beautiful code as much as we need, no rush. You can create new PR, right now and collaborate on ideal form of code.
There is no problem with mutation of variable, we do this in a lot of places, one day we will improve, but existence of this doesn't block users to receive bug fixes and new features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion is pass review quicker, get feature out to users, and work in separate PR in beautiful code as much as we need, no rush.
Thanks for your advice. I will aim to finish this PR right now by suppressing the checker shown above. :)
catch (CheckstyleException ex) { | ||
if (!skipFileOnJavaParseException) { | ||
throw ex; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romani We are not going to display anything when exception occurs? We are going to completely hide that this happened? Even with haltOnException
, we display a message to the user to notify this happened.
https://github.com/checkstyle/checkstyle/blob/86195e06404df68905c90232f71a1c88491f9ad8/src/main/java/com/puppycrawl/tools/checkstyle/Checker.java#L349C61-L365
This seems very risk to completely ignore it.
I am for displaying a violation which can be suppressed, similar to halt on exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not going to display anything when exception occurs? We are going to completely hide that this happened?
If user explicitly configure to skip, we do skip swallow and no noise warning or any other messages. User should use it with caution.
I am for displaying a violation which can be suppressed, similar to halt on exception.
The whole idea of this property is to no extra violations and suppressions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am for displaying a violation which can be suppressed, similar to halt on exception.
Yep, same here. Otherwise, how can we easily determine what is being skipped? This is poor design from both a user and testability standpoint.
Imagine you use this property. You expect some violations in a file with newer syntax, but none appear. You want to know if the file is actually being checked or if the check is broken. How can you do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If user use this option, he is completely ok to skip checkstyle on some classes. Some Users value new syntax features more than checkstyle validation, it is normal, we should allow this.
It is same as all plugins have skip
options, to allow keep plugin plugin still in build but let users decide when to activate it to fail a build or ignore it when they want this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If user use this option, he is completely ok to skip checkstyle on some classes.
I’m not debating this; it is the essence of this feature. My question is how can a user know what is being skipped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Lmh-java we want to emulate the haltOnException
property. It is not clear to me why checker should care. Parsing exception happens, we catch it and log the message. Is this behavior not possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to #14779 (comment), do we move these two new properties to Checker instead of TreeWalker?
This is my mistake, these should live in TreeWalker for sure, thanks for calling this out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this behavior not possible?
I think this is possible. let me try. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
javaParseExceptionSeverity
to match what we catch/skip, as there is javadoc parsing.
<property name="skipFileOnJavaParseException" value="true"/>
<property name="javaParseExceptionSeverity" value="warning"/>
and I am ok to move parsing to and wrapping with catch to separate methods to return Optional<DetailsAST>
to make if (root.ifPresent()) {
. Whatever modern code style to unblock this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great idea. Thanks for your advice. I didn't think about Optional
before. I will use that instead.
@romani In addition, is this something to enable for google/sun styles? What about our default regression configurations? |
@rnveach I was also thinking about this the other day. I think we can copy the original 2 check config files an make another 2 with this property on. I.e., we have 4 built-in config: 1. Sun 2. Google 3. Sun No Exception 4. Google No Exception. My reason is: there are users who want to use the original check with exceptions, and for other group of user, in their cases, they might want to ignore the exceptions. About our default regressions: |
I am against duplicating the configs. There is more work that goes into ensuring how they are built and we don't need the headache of maintaining 2 copies. |
No, we are not going to promote this property, user should use it only if they really want it, and they understand side effects.
I do not think we need this flag in our configs. We should clearly see exception in report. |
GitHub, generate report |
GitHub, generate report |
GitHub, generate report |
5beaa32
to
2166145
Compare
I would expect no TreeWalker checks to run on files that we are skipping. I see that we are now passing a null AST to checks; I am not sure about what side effects this could possibly have. If we want to explore a bit, we could use the same config that we use in our no-exception openjdk executions (without the file filters) to see what other checks are effected. We will need to add a test reproducing the issue seen in the regression report. @Lmh-java please help us to understand what we need to do to avoid passing a null AST to TreeWalker checks. |
GitHub, generate report |
GitHub, generate report |
This is a mistake. I introduced Passing @Override
public void finishTree(DetailAST ast) {
if (ast == null) {
log(DEFAULT_LINE_NUMBER, MSG_KEY_NO_CODE);
}
} so it will be logged. Edit: based on observation locally, I think |
99701c6
to
07b5542
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Items
...le/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerSkipParsingExceptionConfig.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Item:
try { | ||
execute(config, files); | ||
assertWithMessage("Exception is expected").fail(); | ||
} | ||
catch (CheckstyleException exception) { | ||
assertWithMessage("Error message is unexpected") | ||
.that(exception.getMessage()) | ||
.contains("Exception was thrown while processing "); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use
checkstyle/src/test/java/com/puppycrawl/tools/checkstyle/internal/utils/TestUtil.java
Line 393 in bfb3e5f
public static <T extends Throwable> T getExpectedThrowable(Class<T> expectedType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
07b5542
to
f15fbed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok to merge
GitHub, generate report |
@Lmh-java , please update config to make severity as IGNORE and generate one more report |
@Lmh-java , please extend tests to kill mutation https://github.com/checkstyle/checkstyle/actions/runs/9040829453/job/24845471896?pr=14779#step:7:24 You can reproduce it on your local by |
f15fbed
to
5885b6d
Compare
GitHub, generate report |
Done, waiting for the report |
Done |
Last update, please add this Checker stuff to suppression https://github.com/checkstyle/checkstyle/actions/runs/9052825433/job/24870931959?pr=14779#step:6:1707 |
5885b6d
to
ac0129b
Compare
Issue #12542
Diff Regression config: https://gist.githubusercontent.com/Lmh-java/3a5a8c875c81c4d71a5d19da3541fe2e/raw/8c46739f01519889daf23af48af3ce119c16a155/treewalker-base-config.xml
Diff Regression patch config: https://gist.githubusercontent.com/Lmh-java/6a86d78094428f7bf6aa01580cb5d0b7/raw/0e89015ce2c11c91698db7aaf0bdd05491992f1f/treewalker-patch-config.xml
Diff Regression projects: https://gist.githubusercontent.com/Lmh-java/53136c15cf1a376e3addeb00be0685a5/raw/40d234556e0371dc514df3b34e502de4f55993a6/treewalker-projects.properties