-
Notifications
You must be signed in to change notification settings - Fork 139
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
feat: issue optional warning using '==' for wrapper types #2188
base: master
Are you sure you want to change the base?
Conversation
7ee8ffe
to
cfade8f
Compare
4d8d0c7
to
b8f1cae
Compare
@dashorst : thanks for the contribution. Please undo merge commit and rebase your fix commit on top of the latest master. We disallow merge commits for regular PR's to keep the history linear. |
@stephan-herrmann : any objections to the proposed warning & any chance you could review this PR? |
b8f1cae
to
014ee74
Compare
Simply rebase of the one feature commit on top of current master. This should make iloveeclipse happy, and serve as a baseline during the review -- please no further rebase or merge for the time being. Thanks. |
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.
Thanks for the PR which indeed pushes a lot of the correct buttons already!
Please have a look at my detailed remarks.
Once this is merged, we will also need a matching change to provide configuration of the new option in the compiler preferences UI (JDT/UI). Will you be available to provide a PR also for that part? (need to wait until the new constant in JavaCore is available).
When making further changes please keep them as separate commits, to allow me to inspect the incremental progress during review, thanks.
org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java
Outdated
Show resolved
Hide resolved
...lipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
Outdated
Show resolved
Hide resolved
...ipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/batch/messages.properties
Outdated
Show resolved
Hide resolved
...e.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
Outdated
Show resolved
Hide resolved
...se.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties
Outdated
Show resolved
Hide resolved
...t.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
Outdated
Show resolved
Hide resolved
...t.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
Outdated
Show resolved
Hide resolved
...t.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
Outdated
Show resolved
Hide resolved
One more thing: when the new option remains unset, we don't see any problems. I suggest to set the default to 'info', so that users will be informed about the new analysis, without it getting in their way, e.g., when their build is configured to fail on warnings etc. WDYT? Once we have the UI for this option, the problem hover will have affordance to directly go into the configuration UI for this particular irritant, which is a good way to ask the user if they want this analysis. If ecj keeps silent, they don't have this option :) |
When comparing wrapper types or Strings using '==' this is done by reference instead of value. Usually this is in error (e.g. Long only caches values between -127 and +127). By flagging this as an optional warning or even error (configurable) these cases can be easily weeded out. Fixes eclipse-jdt#2176
I very much appreciate the feedback @stephan-herrmann Will look into it. |
What is this push? Actually, 014ee74 was "more up-to-date" than this newer push. Please note that every force push disrupts the incremental review process. That's why I asked:
and:
|
I did it because @iloveeclipse asked for it (merges are not accepted) I didn't see your push. My sincere apologies. |
- rename ComparingWrapper to UnlikelyEqualExpressionArgumentType - move IProblem constant value to 1202 - add `SuppressWarnings("unlikely-arg-type") support - move test to `ProgrammingProblemsTest` - add test cases - add documentation
@stephan-herrmann Many thanks for your comments and feedback. I've done my best to incorporate your review and have updated the PR. |
I've set it to info.
Great and sounds logical |
...e.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
Outdated
Show resolved
Hide resolved
e.g. detecting Number == Long, and Number == Serializable comparisons.
These two answers seem to contradict each other, one token, or the three introduced by IDEA? So let's do a quick vote with only two alternatives for the tokens used with
Please have your say! :) For the CLI option I could warm for In the Errors/Warnings UI we could make it a two step configuration:
Internal names can then follow these decisions in a round-about manner. |
I like "dubious reference comparison" wording and I assume a simple "reference-comparison" for SuppressWarnings should be enough. Usually there aren't that many various dubious comparisons in same code. |
+1 |
Looks like I forgot to save when I tried to call out that we seem to have this consensus (yea 😄 ):
@dashorst do you want to update your change accordingly? I hope these will be small changes only. Please also revisit the warning message, if it speaks the same language as the above. |
- rename all unlikely to dubious - add suppression for this warning 'reference-comparison' - rename compiler option to dubiousReferenceComparison
I have updated the PR with the new 'requirements'. The build fails with the newly introduced warning. Before I add suppression to all those locations, I'd like to get feedback if the current state is correct. |
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 getting very close!
@dashorst please don't let the number of fresh review comments intimidate you.
Those are only minor issues that should not require further discussion, right?
Everything else looks great to me.
...s.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractBatchCompilerTest.java
Outdated
Show resolved
Hide resolved
...e.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
Outdated
Show resolved
Hide resolved
((leftType.isBoxedPrimitiveType() && rightType.isBoxedPrimitiveType()) || | ||
(!leftType.isPrimitiveType() && (rightType.isBoxedPrimitiveType() || rightTypeIsNumber)) || | ||
((leftType.isBoxedPrimitiveType() || leftTypeIsNumber) && !rightType.isPrimitiveType()) || | ||
(leftType.id == rightType.id && (leftType.id == TypeIds.T_JavaLangString || leftTypeIsNumber)))) |
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.
Here || leftTypeIsNumber
seems unnecessary: the case Number
== Number
is already covered above. Remove it and test method a8()
still triggers the error.
The same even holds for (leftType.isBoxedPrimitiveType() && rightType.isBoxedPrimitiveType()) ||
Detecting "boxed primitive or Number vs. anything non-primitive" covers all wrapper comparisons, doesn't it? 😄
...ipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/batch/messages.properties
Outdated
Show resolved
Hide resolved
...ipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
Outdated
Show resolved
Hide resolved
@@ -87,7 +87,10 @@ public class IrritantSet { | |||
.set( | |||
CompilerOptions.UnlikelyEqualsArgumentType | |||
| CompilerOptions.SuppressWarningsNotAnalysed | |||
| CompilerOptions.AnnotatedTypeArgumentToUnannotated); | |||
| CompilerOptions.AnnotatedTypeArgumentToUnannotated) | |||
// group-3 warnings enabled by default |
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.
warnings -> infos
@@ -2367,6 +2380,7 @@ public String toString() { | |||
buf.append("\n\t- unlikely argument type for collection methods: ").append(getSeverityString(UnlikelyCollectionMethodArgumentType)); //$NON-NLS-1$ | |||
buf.append("\n\t- unlikely argument type for collection methods, strict check against expected type: ").append(this.reportUnlikelyCollectionMethodArgumentTypeStrict ? ENABLED : DISABLED); //$NON-NLS-1$ | |||
buf.append("\n\t- unlikely argument types for equals(): ").append(getSeverityString(UnlikelyEqualsArgumentType)); //$NON-NLS-1$ | |||
buf.append("\n\t- dubious operand type for equal expression: ").append(getSeverityString(DubiousReferenceComparison)); //$NON-NLS-1$ |
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.
equal expression -> reference comparison
I really don't mind. I know I'm not very well versed in this code base, so I rely on your expertise on how I should implement things. I'll take a look soon and implement the necessary changes. Thank you so much for your time and energy. |
- modified compiler CLI option - implemented tests for CLI option
Thanks for your updates. We'll miss the 2024-06 release, given that M3 is completed. I'll set 2024-09 M1 as the milestone when it becomes available. This gives us a little time to discuss the final step: UI for the new option. @dashorst do feel prepared to propose such change in jdt.ui as well? I'd suggest looking at recent changes in ProblemSeveritiesConfigurationBlock as your starting point. |
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.
@dashorst the master branch has been re-opened, and this PR really is on the finish line.
I marked final polish items, but there's one more surprise: the jenkins build (already applying the modified compiler) signals dubious reference comparison also for various array types. What's going on there?
* Compiler option ID: Reporting an equal comparison with dubious reference types, i.e. wrapper types (Integer, Long) for primitives (int, resp. long) and Strings. | ||
* <p> | ||
* When enabled, the compiler will issue an error or a warning if a comparison | ||
* is involving wrapper type (or String) operands (e.g <code>'1234L == 5678L'</code>).</p> |
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.
where is the wrapper in the example?
* <dt>Possible values:</dt><dd><code>{ "error", "warning", "info", "ignore" }</code></dd> | ||
* <dt>Default:</dt><dd><code>"info"</code></dd> | ||
* </dl> | ||
* @since 3.38 |
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.
When all code changes are done, we'll have to bump up bundles to 3.39.0 (currently 3.38.100) and mention that version in @since
tags.
I can take care of that in the end.
new String[] {operator, new String(leftType.shortReadableName()), new String(rightType.shortReadableName())}, | ||
new String[] {operator, new String(leftType.readableName()), new String(rightType.readableName())}, |
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.
ups, these lines should be swapped. This way the default rendering of the problem will use short names, which is friendlier to the eye :)
Frankly, I don't know off-hand where the long version will be used, but let's just play by that convention.
I resolved merge conflicts. |
@dashorst a friendly reminder .. |
Unfortunately I have lost 60% of vision in my right eye: murky eye juice scrambles my vision such that letters become unreadable. This issue strains my eyes during the work day, limiting what I can do during the evenings (which is my volunteer time). While I have the will to continue pushing this further, I can't guarantee any progress in the short term. I would not mind if anyone else picks this up, but I can also imagine this being stalled for a while. |
Oh no! I'm very sorry.
It would be a pity if all that effort would go stale. I'll keep it on my radar and will try to take it to completion, unless you beat me to it, but don't feel urged to further stress your eyes. |
What it does
When comparing wrapper types or Strings using '==' this is done by reference instead of value. Usually this is in error (e.g. Long only caches values between -127 and +127). By flagging this as an optional warning or even error (configurable) these cases can be easily weeded out.
Fixes #2176
How to test
Use offending code comparing two Long references or two Strings using '==', and set the optional problem to a level like information, warning or error. The compiler should flag the offending line with the message
Comparing primitive wrapper types or Strings using '=='
Author checklist