-
Notifications
You must be signed in to change notification settings - Fork 46
Run NullAway in JSpecify mode #1608
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
Run NullAway in JSpecify mode #1608
Conversation
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
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.
Added some context. CC @msridhar. Let me know if for any/all of the flagged issues I should file a GitHub issue over at NullAway; happy to do so!
MethodInvocationTree inputTree = (MethodInvocationTree) ASTHelpers.getReceiver(tree); | ||
MethodInvocationTree inputTree = | ||
(MethodInvocationTree) | ||
requireNonNull( | ||
ASTHelpers.getReceiver(tree), "Instance method invocation must have receiver"); |
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.
All the places in which I had to add requireNonNull
are genuinely cases where we can't reasonably expect NullAway to infer the non-nullness invariant. 👍
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 is cool but I'm not sure why it's not detected outside JSpecify mode 🤔 Is there anything related to generics here?
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 you want I can file an issue for this one as well, though since it's not a bug as far as this project is concerned: also happy to leave 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 think I figured this one out; it's probably uber/NullAway#1144.
error-prone-contrib/pom.xml
Outdated
<!-- XXX: Drop this dependency declaration once NullAway in JSpecify | ||
mode no longer requires it when building with JDK 23+. --> | ||
<dependency> | ||
<groupId>com.google.code.findbugs</groupId> | ||
<artifactId>jsr305</artifactId> | ||
<scope>provided</scope> | ||
</dependency> |
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.
Without this version declaration builds with JDK 23+ fail with:
[WARNING] Cannot find annotation method 'when()' in type 'javax.annotation.Nonnull': class file for javax.annotation.Nonnull not found
[WARNING] /home/sschroevers/workspace/picnic/error-prone-support/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java: unknown enum constant javax.annotation.meta.When.MAYBE
reason: class file for javax.annotation.meta.When not found
(This causes a failure because we build with -Werror
.)
It's rather ironic that enabling JSpecify mode forces one to add a "competing" dependency to the classpath. 🙃
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.
Hrm, this is a weird one! Particularly that it's tied to JSpecify mode, I have no idea what's going on. Can you file an issue for this one?
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.
Sure! I'll first try to narrow down which aspect of ReactorRules
triggers the issue.
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.
Alright, filed uber/NullAway#1171.
// XXX: Drop the warning suppression annotation once NullAway in JSpecify mode understands that | ||
// the method references do not have a nullable return type. | ||
@BeforeTemplate | ||
@SuppressWarnings("NullAway") |
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.
As the type parameters aren't @Nullable
, I would expect NullAway to understand that Table.Cell::getRowKey
and do not return null
. But without the suppression we get:
[WARNING] /home/sschroevers/workspace/picnic/error-prone-support/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ImmutableTableRules.java:[64,23] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
(see http://t.uber.com/nullaway )
[WARNING] /home/sschroevers/workspace/picnic/error-prone-support/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ImmutableTableRules.java:[64,46] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
(see http://t.uber.com/nullaway )
[WARNING] /home/sschroevers/workspace/picnic/error-prone-support/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ImmutableTableRules.java:[64,72] [NullAway] referenced method returns @Nullable, but functional interface method java.util.function.Function.apply(T) returns @NonNull
(see http://t.uber.com/nullaway )
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 one could be a combination of uber/NullAway#1075 and uber/NullAway#1128. I'm hoping that uber/NullAway#1128 will fix it. Could you somehow like this from uber/NullAway#1128 so we can test if a fix for that issue fixes this one?
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.
// XXX: Drop the warning suppression annotation once NullAway in JSpecify mode understands that | ||
// `Mono<Void>` is a subtype of `Mono<@Nullable Void>`. | ||
@BeforeTemplate | ||
@SuppressWarnings("NullAway") | ||
Mono<@Nullable Void> before(Mono<T> mono) { |
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.
There are many similar expressions. NullAway can be appeased by simply replacing Mono<@Nullable Void>
with Mono<Void>
, but then VoidMissingNullable complains.
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 file an issue on this one. We have hacks for @Nullable Void
but we should disable them in JSpecify mode.
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.
Check! I filed uber/NullAway#1172.
3accab7
to
7eb979d
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
7eb979d
to
95c0a22
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
2 similar comments
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
4330736
to
60d9f56
Compare
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
I rebased the branch onto #1616 and added a commit. Two notes:
Thanks for all the help @msridhar! 🙏 |
Yeah this is the main reason we cut 0.12.6 🙂 uber/NullAway#1176 led to the same crash |
(Pitest correctly complains about a lack of coverage in |
9369cd3
to
248ac4b
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.
LGTM 👍
(Pitest correctly complains about a lack of coverage in AnnotationAttributeMatcher. That relates to this comment. Something we should fix, but I consider it out of scope for this PR. Up to @rickie and @mohamedsamehsalah to more carefully review the change in that particular class 😉.)
Refactored logic looks sound to me ✌️
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.
Changes LGTM! Nice work ✨
60d9f56
to
6ef1c6e
Compare
|
Mutation testing report by Pitest. Review any surviving mutants by inspecting the line comments under Files changed. |
This reverts commit c14e128.
This PR was accidentally merged into #1616. There it was amended to include the following changes: diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java
index 58384d2c..955d3753 100644
--- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java
+++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java
@@ -515,8 +515,13 @@ final class ReactorRules {
mono.switchIfEmpty(Mono.empty()), mono.flux().next(), mono.flux().singleOrEmpty());
}
+ // XXX: Consider filing a SonarCloud issue for the S2637 false positive.
@BeforeTemplate
- @SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
+ @SuppressWarnings({
+ "java:S2637" /* False positive: result is never `null`. */,
+ "java:S4968" /* Result may be `Mono<Void>`. */,
+ "key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
+ })
Mono<? extends @Nullable Void> before2(Mono<@Nullable Void> mono) {
return Refaster.anyOf(mono.ignoreElement(), mono.then());
}
@@ -970,8 +975,13 @@ final class ReactorRules {
return flux.ignoreElements().then();
}
+ // XXX: Consider filing a SonarCloud issue for the S2637 false positive.
@BeforeTemplate
- @SuppressWarnings("java:S4968" /* Result may be `Mono<Void>`. */)
+ @SuppressWarnings({
+ "java:S2637" /* False positive: result is never `null`. */,
+ "java:S4968" /* Result may be `Mono<Void>`. */,
+ "key-to-resolve-AnnotationUseStyle-and-TrailingComment-check-conflict"
+ })
Mono<? extends @Nullable Void> before2(Flux<@Nullable Void> flux) {
return flux.ignoreElements();
} |
This is a draft PR on top of #1598, to demonstrate the benefits and gotchas of running NullAway in JSpecify mode.
Suggested commit message.