Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTill Brychcy2016-01-06 22:45:12 +0000
committerStephan Herrmann2016-02-04 16:39:47 +0000
commite2fc6e7db19ada9b01733b33b99936b7344de6b1 (patch)
tree885011c15d8b078326439854ee9117602ea62df3
parent1ee0a57ecfec949453b568bf91501e7d2b2dd1d1 (diff)
downloadeclipse.jdt.core-e2fc6e7db19ada9b01733b33b99936b7344de6b1.tar.gz
eclipse.jdt.core-e2fc6e7db19ada9b01733b33b99936b7344de6b1.tar.xz
eclipse.jdt.core-e2fc6e7db19ada9b01733b33b99936b7344de6b1.zip
Bug 485302 - [1.8][null]Missing warnings when using Wildcards with null
annotations Change-Id: I556568631a2e6fe1f505b92047e78e7fd844a5fb Signed-off-by: Till Brychcy <register.eclipse@brychcy.de>
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java88
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java4
2 files changed, 86 insertions, 6 deletions
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 e320e5cb95..e139e57a04 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
@@ -7761,22 +7761,27 @@ public void testBug448709() {
},
compilerOptions,
"----------\n" +
- "1. WARNING in Test.java (at line 39)\n" +
+ "1. WARNING in Test.java (at line 21)\n" +
+ " final U result = mapper.apply(source);\n" +
+ " ^^^^^^\n" +
+ "Null type safety (type annotations): The expression of type \'T\' needs unchecked conversion to conform to \'@NonNull capture#of ? super T\'\n" +
+ "----------\n" +
+ "2. WARNING in Test.java (at line 39)\n" +
" map(optNullableString, testMethodRef);\n" +
" ^^^^^^^^^^^^^\n" +
"Contradictory null annotations: method was inferred as \'@NonNull Optional<@NonNull Integer> map(@NonNull Optional<@Nullable String>, Function<@NonNull ? super @Nullable String,? extends @NonNull Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" +
"----------\n" +
- "2. WARNING in Test.java (at line 41)\n" +
+ "3. WARNING in Test.java (at line 41)\n" +
" map(optNullableString, Test::testMethod); // Error: Null type mismatch at parameter 1: required \'@NonNull String\' but provided \'@Nullable String\' via method descriptor Function<String,Integer>.apply(String)\n" +
" ^^^^^^^^^^^^^^^^\n" +
"Contradictory null annotations: method was inferred as \'@NonNull Optional<@NonNull Integer> map(@NonNull Optional<@Nullable String>, Function<@NonNull ? super @Nullable String,? extends @NonNull Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" +
"----------\n" +
- "3. WARNING in Test.java (at line 43)\n" +
+ "4. WARNING in Test.java (at line 43)\n" +
" map(optNullableString, (s) -> Test.testMethod(s));\n" +
" ^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
"Contradictory null annotations: method was inferred as \'@NonNull Optional<@NonNull Integer> map(@NonNull Optional<@Nullable String>, Function<@NonNull ? super @Nullable String,? extends @NonNull Integer>)\', but only one of \'@NonNull\' and \'@Nullable\' can be effective at any location\n" +
"----------\n" +
- "4. WARNING in Test.java (at line 43)\n" +
+ "5. WARNING in Test.java (at line 43)\n" +
" map(optNullableString, (s) -> Test.testMethod(s));\n" +
" ^\n" +
"Null type mismatch (type annotations): required \'@NonNull String\' but this expression has type \'@Nullable String\'\n" +
@@ -7785,6 +7790,28 @@ public void testBug448709() {
"1->2\n" +
"1->2");
}
+public void testBug448709b() {
+ runConformTestWithLibs(
+ new String[] {
+ "Test.java",
+ "import java.util.*;\n" +
+ "import java.util.function.*;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public class Test {\n" +
+ "\n" +
+ " public static final <T,U> void map(final @NonNull Optional<T> optional, final Function<@NonNull ? super T,? extends U> mapper) {\n" +
+ " final T source = optional.get();\n" +
+ " if (source != null) {\n" +
+ " final U result = mapper.apply(source);\n" +
+ " System.out.println(source+\"->\"+result);\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ getCompilerOptions(),
+ "");
+}
public void testBug459967_Array_constructor() {
runConformTestWithLibs(
new String[] {
@@ -10369,5 +10396,58 @@ public void testBug485030() {
" }\n" +
"}\n"
}, getCompilerOptions(), "");
+}
+public void testBug485302() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "WildCardNullable.java",
+ "package test;\n" +
+ "\n" +
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public class WildCardNullable {\n" +
+ " static class A<T> {\n" +
+ " @Nullable\n" +
+ " T returnNull() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "\n" +
+ " void acceptNonNullT(@NonNull T t) {\n" +
+ " }\n" +
+ "\n" +
+ " void acceptNonNullObject(@NonNull Object x) {\n" +
+ " }\n" +
+ " }\n" +
+ "\n" +
+ " static @NonNull Number g(A<? extends @NonNull Number> a) {\n" +
+ " return a.returnNull(); // error 1 expected\n" +
+ " }\n" +
+ "\n" +
+ " public static final <T> void map(final A<@NonNull ? super T> a, T t) {\n" +
+ " a.acceptNonNullT(t); // warning 2 expected\n" +
+ " a.acceptNonNullObject(t); // warning 3 expected\n" +
+ " }\n" +
+ "}\n" +
+ ""
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in WildCardNullable.java (at line 21)\n" +
+ " return a.returnNull(); // error 1 expected\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Null type mismatch (type annotations): required \'@NonNull Number\' but this expression has type \'@Nullable capture#of ? extends Number\'\n" +
+ "----------\n" +
+ "2. WARNING in WildCardNullable.java (at line 25)\n" +
+ " a.acceptNonNullT(t); // warning 2 expected\n" +
+ " ^\n" +
+ "Null type safety (type annotations): The expression of type \'T\' needs unchecked conversion to conform to \'@NonNull capture#of ? super T\'\n" +
+ "----------\n" +
+ "3. WARNING in WildCardNullable.java (at line 26)\n" +
+ " a.acceptNonNullObject(t); // warning 3 expected\n" +
+ " ^\n" +
+ "Null type safety (type annotations): The expression of type \'T\' needs unchecked conversion to conform to \'@NonNull Object\'\n" +
+ "----------\n"
+ );
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index 748dcd34af..48beb77ec1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -313,14 +313,14 @@ public class NullAnnotationMatching {
// when providing exactly the lower bound of the required type we're definitely fine:
TypeBinding lowerBound = ((CaptureBinding)requiredType).lowerBound;
if (lowerBound != null && areSameTypes(lowerBound, providedType, providedSubstitute))
- return true;
+ return (requiredType.tagBits & TagBits.AnnotationNullMASK) == (providedType.tagBits & TagBits.AnnotationNullMASK);
} else if (requiredType.kind() == Binding.TYPE_PARAMETER && requiredType == providedSubstitute) { //$IDENTITY-COMPARISON$
return true;
} else if (providedType instanceof CaptureBinding) {
// when requiring exactly the upper bound of the provided type we're fine, too:
TypeBinding upperBound = ((CaptureBinding)providedType).upperBound();
if (upperBound != null && areSameTypes(requiredType, upperBound, providedSubstitute))
- return true;
+ return (requiredType.tagBits & TagBits.AnnotationNullMASK) == (providedType.tagBits & TagBits.AnnotationNullMASK);
}
return false;
}

Back to the top