Bug 472663 - [null][1.8] Wrong warning for method reference
Change-Id: Ib3e72958228daa6b857e65cfa61d044084e0deed
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index 99d085f..ae6e3d7 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -8336,4 +8336,63 @@
options,
"");
}
+public void testBug472663() {
+ runConformTestWithLibs(
+ new String[] {
+ "test/Callee.java",
+ "package test;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Callee {\n" +
+ " public static String staticOtherClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "\n" +
+ " public String instanceOtherClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+ // and now consume Callee.class:
+ runConformTestWithLibs(
+ new String[] {
+ "test/Caller.java",
+ "package test;\n" +
+ "\n" +
+ "import java.util.function.Function;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "\n" +
+ "@NonNullByDefault\n" +
+ "public class Caller {\n" +
+ " public void foo(final Callee callee) {\n" +
+ " Function<String, String> function;\n" +
+ "\n" +
+ " // assignments with warnings (wrong):\n" +
+ " function = Callee::staticOtherClass;\n" +
+ " function = callee::instanceOtherClass;\n" +
+ "\n" +
+ " // assignments with no warnings (ok):\n" +
+ " function = foo -> Callee.staticOtherClass(foo);\n" +
+ " function = foo -> callee.instanceOtherClass(foo);\n" +
+ " function = Caller::staticSameClass;\n" +
+ " function = this::instanceSameClass;\n" +
+ " }\n" +
+ "\n" +
+ " public static String staticSameClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "\n" +
+ " public String instanceSameClass(String foo) {\n" +
+ " return foo;\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index ad77677..845d662 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -66,6 +66,7 @@
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.ImplicitNullAnnotationVerifier;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
@@ -741,8 +742,14 @@
}
protected void checkNullAnnotations(BlockScope scope) {
- if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+ CompilerOptions compilerOptions = scope.compilerOptions();
+ if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
if (this.expectedType == null || !NullAnnotationMatching.hasContradictions(this.expectedType)) { // otherwise assume it has been reported and we can do nothing here
+ if ((this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
+ // not interested in reporting problems against this.binding:
+ new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
+ .checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+ }
// TODO: simplify by using this.freeParameters?
int len;
int expectedlen = this.binding.parameters.length;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
index aafe24b..9fa7cbf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
@@ -116,14 +116,14 @@
@Override
public ITypeAnnotationWalker toMethodParameter(short index) {
- // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier
+ // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier (triggered per invocation via MessageSend.resolveType() et al)
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toMethodParameter(index);
}
@Override
public ITypeAnnotationWalker toMethodReturn() {
- // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier
+ // don't set nextIsDefaultLocation, because signature-level nullness is handled by ImplicitNullAnnotationVerifier (triggered per invocation via MessageSend.resolveType() et al)
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toMethodReturn();
}