Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions nullaway/src/main/java/com/uber/nullaway/NullAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,15 @@ public Description matchNewClass(NewClassTree tree, VisitorState state) {
if (methodSymbol == null) {
throw new RuntimeException("not expecting unresolved method here");
}
ExpressionTree enclosingExpression = tree.getEnclosingExpression();
if (enclosingExpression != null) {
// technically this is not a dereference; there is a requireNonNull() call in the
// bytecode. but it's close enough for error reporting
state.reportMatch(matchDereference(enclosingExpression, tree, state));
}
List<? extends ExpressionTree> actualParams = tree.getArguments();
if (tree.getClassBody() != null && actualParams.size() > 0) {
// passing parameters to constructor of anonymous class
if (tree.getClassBody() != null) {
// invoking constructor of anonymous class
// this constructor just invokes the constructor of the superclass, and
// in the AST does not have the parameter nullability annotations from the superclass.
// so, treat as if the superclass constructor is being invoked directly
Expand Down Expand Up @@ -1861,18 +1867,7 @@ private Description handleInvocation(
Symbol.MethodSymbol methodSymbol,
List<? extends ExpressionTree> actualParams) {
List<VarSymbol> formalParams = methodSymbol.getParameters();

boolean varArgsMethod = methodSymbol.isVarArgs();
if (formalParams.size() != actualParams.size()
&& !varArgsMethod
&& !methodSymbol.isStatic()
&& methodSymbol.isConstructor()
&& methodSymbol.enclClass().isInner()) {
// In special cases like one in issue #366
// formal params and actual params do not match while using JDK11+
// we bail out in this particular case
return Description.NO_MATCH;
}

// always do unboxing checks, whether or not the invoked method is annotated
for (int i = 0; i < formalParams.size() && i < actualParams.size(); i++) {
Expand Down
20 changes: 20 additions & 0 deletions nullaway/src/test/java/com/uber/nullaway/CoreTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -1134,4 +1134,24 @@ public void synchronizedInUnannotatedLambda() {
"}")
.doTest();
}

@Test
public void enclosingExpressionForNewClassTree() {
defaultCompilationHelper
.addSourceLines(
"Outer.java",
"package com.uber;",
"import org.jspecify.annotations.Nullable;",
"class Outer {",
" class Inner {}",
" static Inner testNegative(Outer outer) {",
" return outer.new Inner() {};",
" }",
" static Inner testPositive(@Nullable Outer outer) {",
" // BUG: Diagnostic contains: dereferenced expression outer is @Nullable",
" return outer.new Inner() {};",
" }",
"}")
.doTest();
}
}