Skip to content
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

Properly check generic method overriding in explicitly-typed anonymous classes #808

Merged
merged 94 commits into from
Sep 29, 2023

Conversation

msridhar
Copy link
Collaborator

This completes a task lingering from #755, which did not handle overriding in anonymous classes. This case is slightly tricky as javac does not preserve annotations on type arguments in the types it computes for anonymous classes. To fix, we pass a Symbol where we were passing a Type in a couple places, as then we can call Symbol.isAnonymous() to check for an anonymous type. In such a case, we try to get the type from the enclosing NewClassTree of the overriding method. Note that this PR still does not handle anonymous classes that use the diamond operator; we add a test to show the gaps.

@msridhar msridhar added the jspecify Related to support for jspecify standard (see jspecify.dev) label Aug 18, 2023
@msridhar msridhar requested a review from lazaroclapp August 18, 2023 14:32
Copy link
Collaborator

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry it took so long. One initial pass here. Overall, it looks good.

" public @Nullable String apply(String s) { return null; }",
" };",
" FnClass<String, @Nullable String> fn4 = new FnClass<String, @Nullable String>() {",
" public @Nullable String apply(String s) { return null; }",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are both true positive cases on the parameter and both true negatives on the return value? Seems like it might test more combinations to do one each?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (newClassTree == null) {
throw new RuntimeException(
"method should be inside a NewClassTree " + state.getSourceForNode(path.getLeaf()));
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a check that the NewClassTree is for the same type as symbol['s supertype]? Or can that be safely assumed to never break?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test case for when the class name is given as something other than a simple name? new Foo.Builder<@Nullable String>() { ... } or even new Foo<@Nullable String>.Builder() {...}?

Copy link
Collaborator Author

@msridhar msridhar Sep 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a check that the NewClassTree is for the same type as symbol['s supertype]? Or can that be safely assumed to never break?

I added a check in af6ca1f; can't hurt :-)

Can we add a test case for when the class name is given as something other than a simple name? new Foo.Builder<@Nullable String>() { ... } or even new Foo<@Nullable String>.Builder() {...}?

I added some tests in 16eb9c2 but one of them is failing (see overrideAnonymousNestedClass()) 😐 I propose I fix that issue in a follow-up; does that sound ok?

@codecov
Copy link

codecov bot commented Sep 1, 2023

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (7d8cd4a) 86.79% compared to head (26085c4) 86.75%.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #808      +/-   ##
============================================
- Coverage     86.79%   86.75%   -0.05%     
- Complexity     1870     1876       +6     
============================================
  Files            74       74              
  Lines          6178     6197      +19     
  Branches       1202     1206       +4     
============================================
+ Hits           5362     5376      +14     
- Misses          405      408       +3     
- Partials        411      413       +2     
Files Coverage Δ
...away/src/main/java/com/uber/nullaway/NullAway.java 89.68% <100.00%> (ø)
...rc/main/java/com/uber/nullaway/GenericsChecks.java 89.65% <86.36%> (-0.32%) ⬇️

... and 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@msridhar
Copy link
Collaborator Author

@lazaroclapp I finally got around to addressing your feedback here; sorry for the long delay.

Copy link
Collaborator

@lazaroclapp lazaroclapp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See minor comment above, but otherwise SGTM!

.doTest();
}

@Ignore("Need to add support for this case")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create and link an issue!

@msridhar msridhar enabled auto-merge (squash) September 29, 2023 04:47
@msridhar msridhar merged commit b64d1c1 into uber:master Sep 29, 2023
8 of 9 checks passed
@msridhar msridhar deleted the override-anonymous-class-checking branch September 29, 2023 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
jspecify Related to support for jspecify standard (see jspecify.dev)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants