Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2014-07-20 10:31:10 +0000
committerStephan Herrmann2014-07-22 14:28:00 +0000
commit61133b8c5e6da454f7cea747a5c83744e4b067c9 (patch)
treebb4298042628868e2ba4c0ddade0fd867a5014c2
parent41321e271ce9d99e44edf867f5f75e8abc4a221f (diff)
downloadeclipse.jdt.core-61133b8c5e6da454f7cea747a5c83744e4b067c9.tar.gz
eclipse.jdt.core-61133b8c5e6da454f7cea747a5c83744e4b067c9.tar.xz
eclipse.jdt.core-61133b8c5e6da454f7cea747a5c83744e4b067c9.zip
Bug 438469 - [null] How-to use null type annotations with generic
methods from interfaces in some library you only have as binary JAR? Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java8
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java3
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java18
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java141
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java51
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties4
8 files changed, 194 insertions, 47 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index adbacef955..0e9ba73570 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -12636,7 +12636,7 @@ public void test313_warn_options() {
"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" +
+ "The return type is incompatible with \'@NonNull Object\' returned from X.foo(Object, Object) (mismatching null constraints)\n" +
"----------\n" +
"2. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
@@ -12685,7 +12685,7 @@ public void test314_warn_options() {
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" +
+ "The return type is incompatible with \'@NonNull Object\' returned from X.foo(Object, Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
@@ -13677,7 +13677,7 @@ public void testBug375366c() throws IOException {
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" +
+ "The return type is incompatible with \'@NonNull Object\' returned from X.foo(Object, Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
@@ -13731,7 +13731,7 @@ public void testBug375366d() throws IOException {
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" +
+ "The return type is incompatible with \'@NonNull Object\' returned from X.foo(Object, Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
" @Nullable Object foo(Object o, Object o2) { return null; }\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index 1a8ca337a0..3b345165ce 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -34,6 +34,7 @@
* Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported
* Bug 430150 - [1.8][null] stricter checking against type variables
* Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
+ * Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
* Jesper S Moller - Contributions for
* bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
* bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -572,6 +573,7 @@ public void test011_problem_categories() {
expectedProblemAttributes.put("IllegalModifierForVariable", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("IllegalModifiersForElidedType", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("IllegalModifiers", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+ expectedProblemAttributes.put("IllegalParameterNullityRedefinition", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
@@ -1394,6 +1396,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("IllegalModifierForVariable", SKIP);
expectedProblemAttributes.put("IllegalModifiersForElidedType", SKIP);
expectedProblemAttributes.put("IllegalModifiers", SKIP);
+ expectedProblemAttributes.put("IllegalParameterNullityRedefinition", SKIP);
expectedProblemAttributes.put("IllegalPrimitiveOrArrayTypeForEnclosingInstance", SKIP);
expectedProblemAttributes.put("IllegalQualifiedEnumConstantLabel", SKIP);
expectedProblemAttributes.put("IllegalQualifiedParameterizedTypeAllocation", SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index b6df382281..ad645688e4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -941,7 +941,7 @@ public void test_parameter_specification_inheritance_005() {
"1. ERROR in X.java (at line 4)\n" +
" @Nullable Object getObject() { return null; }\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from Lib.getObject()\n" +
+ "The return type is incompatible with '@NonNull Object' returned from Lib.getObject() (mismatching null constraints)\n" +
"----------\n");
}
@@ -993,7 +993,7 @@ public void test_parameter_specification_inheritance_007() {
"1. ERROR in X.java (at line 3)\n" +
" Object getObject() { return null; }\n" +
" ^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from Lib.getObject()\n" +
+ "The return type is incompatible with '@NonNull Object' returned from Lib.getObject() (mismatching null constraints)\n" +
"----------\n");
}
//a method body violates the @NonNull return specification (repeated from super)
@@ -1230,7 +1230,7 @@ public void test_parameter_specification_inheritance_013() {
"1. ERROR in p1\\Y.java (at line 5)\n" +
" public @Nullable String getString(String s1, @NonNull String s2, @NonNull String s3) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from IY.getString(String, String, String)\n" +
+ "The return type is incompatible with '@NonNull String' returned from IY.getString(String, String, String) (mismatching null constraints)\n" +
// no problem regarding s1: widening @NonNull to unannotated
"----------\n" +
"2. ERROR in p1\\Y.java (at line 5)\n" +
@@ -2249,7 +2249,7 @@ public void test_illegal_annotation_007() {
"2. ERROR in p\\Test.java (at line 9)\n" +
" @org public Object foo() {\n" +
" ^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from TestInt.foo()\n" +
+ "The return type is incompatible with '@NonNull Object' returned from TestInt.foo() (mismatching null constraints)\n" +
"----------\n");
}
@@ -2306,7 +2306,7 @@ public void test_default_nullness_002() {
"1. ERROR in Y.java (at line 5)\n" +
" @Nullable Object getObject(Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from X.getObject(Object) (mismatching null constraints)\n" +
"----------\n" +
// additional error:
"2. ERROR in Y.java (at line 5)\n" +
@@ -2350,7 +2350,7 @@ public void test_default_nullness_003() {
"1. ERROR in p2\\Y.java (at line 5)\n" +
" protected @Nullable Object getObject(@Nullable Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from X.getObject(Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in p2\\Y.java (at line 6)\n" +
" bar(o);\n" +
@@ -2402,7 +2402,7 @@ public void test_default_nullness_003a() {
"1. ERROR in p2\\Y.java (at line 5)\n" +
" protected @Nullable Object getObject(@Nullable Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from X.getObject(Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in p2\\Y.java (at line 6)\n" +
" bar(o);\n" +
@@ -2465,7 +2465,7 @@ public void test_default_nullness_003b() {
"1. ERROR in p2\\Y.java (at line 5)\n" +
" protected @Nullable Object getObject(@Nullable Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from X.getObject(Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in p2\\Y.java (at line 6)\n" +
" bar(o);\n" +
@@ -2522,7 +2522,7 @@ public void test_default_nullness_003c() {
"1. ERROR in p2\\Y.java (at line 5)\n" +
" protected @Nullable Object getObject(@Nullable Object o) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from X.getObject(Object)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from X.getObject(Object) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in p2\\Y.java (at line 6)\n" +
" bar(o);\n" +
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 c98c41dba0..840a577fb4 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
@@ -312,7 +312,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
"1. ERROR in B.java (at line 5)\n" +
" public @Nullable Object foo(@NonNull String l) {\n" +
" ^^^^^^^^^^^^^^^^\n" +
- "The return type is incompatible with the @NonNull return from A<Object>.I<String>.foo(String)\n" +
+ "The return type is incompatible with '@NonNull Object' returned from A<Object>.I<String>.foo(String) (mismatching null constraints)\n" +
"----------\n" +
"2. ERROR in B.java (at line 5)\n" +
" public @Nullable Object foo(@NonNull String l) {\n" +
@@ -2911,20 +2911,20 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
},
options,
"----------\n" +
- "1. ERROR in X.java (at line 12)\n" +
- " class Z extends X {\n" +
- " ^\n" +
- "The method foo1(List<@NonNull X>) from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "1. ERROR in X.java (at line 13)\n" +
+ " @Override void foo1(List<@NonNull X> xy) {}\n" +
+ " ^^^^\n" +
+ "Illegal redefinition of parameter xy, inherited method from X declares this parameter as \'List<X>\' (mismatching null constraints)\n" +
"----------\n" +
- "2. ERROR in X.java (at line 12)\n" +
- " class Z extends X {\n" +
- " ^\n" +
- "The method foo2(List<X>) from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "2. ERROR in X.java (at line 14)\n" +
+ " @Override void foo2(List<X> lx) {}\n" +
+ " ^^^^\n" +
+ "Illegal redefinition of parameter lx, inherited method from X declares this parameter as \'List<@NonNull X>\' (mismatching null constraints)\n" +
"----------\n" +
- "3. ERROR in X.java (at line 12)\n" +
- " class Z extends X {\n" +
- " ^\n" +
- "The method foo3(List<X>) from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "3. ERROR in X.java (at line 15)\n" +
+ " @Override void foo3(List<X> lx) {}\n" +
+ " ^^^^\n" +
+ "Illegal redefinition of parameter lx, inherited method from X declares this parameter as \'List<@Nullable X>\' (mismatching null constraints)\n" +
"----------\n");
}
@@ -2971,20 +2971,20 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest {
},
getCompilerOptions(),
"----------\n" +
- "1. ERROR in X.java (at line 18)\n" +
- " abstract class Z extends X {\n" +
- " ^\n" +
- "The method List<@NonNull X> foo1() from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "1. ERROR in X.java (at line 20)\n" +
+ " List<@NonNull X> foo1() {\n" +
+ " ^^^^\n" +
+ "The return type is incompatible with \'List<X>\' returned from X.foo1() (mismatching null constraints)\n" +
"----------\n" +
- "2. ERROR in X.java (at line 18)\n" +
- " abstract class Z extends X {\n" +
- " ^\n" +
- "The method List<@NonNull X> foo2() from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "2. ERROR in X.java (at line 24)\n" +
+ " List<@NonNull X> foo2() {\n" +
+ " ^^^^\n" +
+ "The return type is incompatible with \'List<@Nullable X>\' returned from X.foo2() (mismatching null constraints)\n" +
"----------\n" +
- "3. ERROR in X.java (at line 18)\n" +
- " abstract class Z extends X {\n" +
- " ^\n" +
- "The method @NonNull List<X> foo3() from Z cannot implement the corresponding method from X due to incompatible nullness constraints\n" +
+ "3. ERROR in X.java (at line 28)\n" +
+ " @NonNull List<X> foo3() {\n" +
+ " ^^^^\n" +
+ "The return type is incompatible with \'@NonNull List<@NonNull X>\' returned from X.foo3() (mismatching null constraints)\n" +
"----------\n");
}
@@ -5576,6 +5576,97 @@ public void testTypeVariable13() {
getCompilerOptions(),
"");
}
+// Bug 438469 - [null] How-to use null type annotations with generic methods from interfaces in some library you only have as binary JAR?
+public void testTypeVariable14() {
+ runConformTestWithLibs(
+ new String[] {
+ "ITest.java",
+ "interface ITest {\n" +
+ " <T> T foo(T arg); // or arg Class<T> or TypeToken<T> + return TypeAdapter<T>, etc.\n" +
+ "}"
+ },
+ getCompilerOptions(),
+ "");
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ false,
+ new String[] {
+ "Test.java",
+ "class Test implements ITest {\n" +
+ " @Override\n" +
+ " @SuppressWarnings(\"null\")\n" +
+ " public <T> @org.eclipse.jdt.annotation.Nullable T foo(T arg) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+// Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
+public void testTypeVariable15() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "ITest.java",
+ "interface ITest {\n" +
+ " <T> T foo(T arg); // or arg Class<T> or TypeToken<T> + return TypeAdapter<T>, etc.\n" +
+ "}",
+ "Test.java",
+ "class Test implements ITest {\n" +
+ " @Override\n" +
+ " public <T> @org.eclipse.jdt.annotation.Nullable T foo(T arg) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n",
+ "Test2.java",
+ "class Test2 implements ITest {\n" +
+ " @Override\n" +
+ " public <T> T foo(@org.eclipse.jdt.annotation.NonNull T arg) {\n" +
+ " return arg;\n" +
+ " }\n" +
+ "}\n",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in Test.java (at line 3)\n" +
+ " public <T> @org.eclipse.jdt.annotation.Nullable T foo(T arg) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "The return type is incompatible with 'T' returned from ITest.foo(T) (mismatching null constraints)\n" +
+ "----------\n" +
+ "----------\n" +
+ "1. ERROR in Test2.java (at line 3)\n" +
+ " public <T> T foo(@org.eclipse.jdt.annotation.NonNull T arg) {\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Illegal redefinition of parameter arg, inherited method from ITest does not constrain this parameter\n" +
+ "----------\n");
+}
+// Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
+public void testTypeVariable15a() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "ITest.java",
+ "import java.util.List;\n" +
+ "interface ITest {\n" +
+ " <T> T foo(List<T> arg); // or arg Class<T> or TypeToken<T> + return TypeAdapter<T>, etc.\n" +
+ "}",
+ "Test.java",
+ "import java.util.List;\n" +
+ "class Test implements ITest {\n" +
+ " @Override\n" +
+ " public <T> T foo(List<@org.eclipse.jdt.annotation.NonNull T> arg) {\n" +
+ " return arg.get(0);\n" +
+ " }\n" +
+ "}\n",
+ },
+ getCompilerOptions(),
+ "----------\n" +
+ "1. ERROR in Test.java (at line 4)\n" +
+ " public <T> T foo(List<@org.eclipse.jdt.annotation.NonNull T> arg) {\n" +
+ " ^^^^\n" +
+ "Illegal redefinition of parameter arg, inherited method from ITest declares this parameter as \'List<T>\' (mismatching null constraints)\n" +
+ "----------\n");
+}
public void testBug434600() {
runConformTestWithLibs(
new String[] {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 6f5d0b4251..883da8349f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -193,6 +193,7 @@
* NullNotCompatibleToFreeTypeVariable
* NullityMismatchAgainstFreeTypeVariable
* ImplicitObjectBoundNoNullDefault
+ * IllegalParameterNullityRedefinition
* Jesper S Moller - added the following constants
* TargetTypeNotAFunctionalInterface
* OuterLocalMustBeEffectivelyFinal
@@ -1793,6 +1794,8 @@ void setSourceStart(int sourceStart);
int NullityMismatchAgainstFreeTypeVariable = 970;
/** @since 3.11 */
int ImplicitObjectBoundNoNullDefault = 971;
+ /** @since 3.11 */
+ int IllegalParameterNullityRedefinition = MethodRelated + 972;
// Java 8 work
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
index 348343acc0..cf23eb46ff 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -289,7 +289,10 @@ public class ImplicitNullAnnotationVerifier {
substituteReturnType = substitute.returnType;
}
if (NullAnnotationMatching.analyse(inheritedMethod.returnType, currentMethod.returnType, substituteReturnType, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
+ if (srcMethod != null)
+ scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod, null);
+ else
+ scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
return;
}
}
@@ -404,9 +407,13 @@ public class ImplicitNullAnnotationVerifier {
}
}
if (useTypeAnnotations) {
+ TypeBinding inheritedParameter = inheritedMethod.parameters[i];
TypeBinding substituteParameter = substituteParameters != null ? substituteParameters[i] : null;
- if (NullAnnotationMatching.analyse(currentMethod.parameters[i], inheritedMethod.parameters[i], substituteParameter, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
+ if (NullAnnotationMatching.analyse(currentMethod.parameters[i], inheritedParameter, substituteParameter, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
+ if (currentArgument != null)
+ scope.problemReporter().illegalParameterRedefinition(currentArgument, inheritedMethod.declaringClass, inheritedParameter);
+ else
+ scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index a40eb685f8..f587622426 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -51,6 +51,7 @@
* Bug 430150 - [1.8][null] stricter checking against type variables
* Bug 434600 - Incorrect null analysis error reporting on type parameters
* Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
+ * Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
* bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
@@ -9292,7 +9293,28 @@ public void parameterLackingNonnullAnnotation(Argument argument, ReferenceBindin
sourceStart,
sourceEnd);
}
+public void illegalParameterRedefinition(Argument argument, ReferenceBinding declaringClass, TypeBinding inheritedParameter) {
+ int sourceStart = argument.type.sourceStart;
+ if (argument.annotations != null) {
+ for (int i=0; i<argument.annotations.length; i++) {
+ Annotation annotation = argument.annotations[i];
+ if ( annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNullable
+ || annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNonNull)
+ {
+ sourceStart = annotation.sourceStart;
+ break;
+ }
+ }
+ }
+ this.handle(
+ IProblem.IllegalParameterNullityRedefinition,
+ new String[] { new String(argument.name), new String(declaringClass.readableName()), new String(inheritedParameter.nullAnnotatedReadableName(this.options, false)) },
+ new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedParameter.nullAnnotatedReadableName(this.options, true)) },
+ sourceStart,
+ argument.type.sourceEnd);
+}
public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDecl, MethodBinding inheritedMethod, char[][] nonNullAnnotationName) {
+ // nonNullAnnotationName is not used in 1.8-mode
MethodDeclaration methodDecl = (MethodDeclaration) abstractMethodDecl;
StringBuffer methodSignature = new StringBuffer();
methodSignature
@@ -9311,12 +9333,31 @@ public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDe
if (annotation != null) {
sourceStart = annotation.sourceStart;
}
+ TypeBinding inheritedReturnType = inheritedMethod.returnType;
+ String[] arguments;
+ String[] argumentsShort;
+ if (this.options.complianceLevel < ClassFileConstants.JDK1_8) {
+ StringBuilder returnType = new StringBuilder();
+ returnType.append('@').append(CharOperation.concatWith(nonNullAnnotationName, '.'));
+ returnType.append(' ').append(inheritedReturnType.readableName());
+ arguments = new String[] { methodSignature.toString(), returnType.toString() };
+
+ returnType = new StringBuilder();
+ returnType.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]);
+ returnType.append(' ').append(inheritedReturnType.shortReadableName());
+ argumentsShort = new String[] { shortSignature.toString(), returnType.toString() };
+ } else {
+ arguments = new String[] { methodSignature.toString(),
+ String.valueOf(inheritedReturnType.nullAnnotatedReadableName(this.options, false))};
+ argumentsShort = new String[] { shortSignature.toString(),
+ String.valueOf(inheritedReturnType.nullAnnotatedReadableName(this.options, true))};
+ }
this.handle(
- IProblem.IllegalReturnNullityRedefinition,
- new String[] { methodSignature.toString(), CharOperation.toString(nonNullAnnotationName)},
- new String[] { shortSignature.toString(), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])},
- sourceStart,
- methodDecl.returnType.sourceEnd);
+ IProblem.IllegalReturnNullityRedefinition,
+ arguments,
+ argumentsShort,
+ sourceStart,
+ methodDecl.returnType.sourceEnd);
}
public void referenceExpressionArgumentNullityMismatch(ReferenceExpression location, TypeBinding requiredType, TypeBinding providedType,
MethodBinding descriptorMethod, int idx, NullAnnotationMatching status) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 2f6d243592..9fdb0423ad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -40,6 +40,7 @@
# Bug 430150 - [1.8][null] stricter checking against type variables
# Bug 434600 - Incorrect null analysis error reporting on type parameters
# Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
+# Bug 438467 - [compiler][null] Better error position for "The method _ cannot implement the corresponding method _ due to incompatible nullness constraints"
# Jesper S Moller <jesper@selskabet.org> - Contributions for
# bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
# bug 384567 - [1.5][compiler] Compiler accepts illegal modifiers on package declaration
@@ -774,7 +775,7 @@
911 = Null type mismatch: required ''{0}'' but the provided value is inferred as @{1}
912 = Null type safety: The expression of type ''{0}'' needs unchecked conversion to conform to ''{1}''
913 = A default nullness annotation has not been specified for the package {0}
-914 = The return type is incompatible with the @{1} return from {0}
+914 = The return type is incompatible with ''{1}'' returned from {0} (mismatching null constraints)
915 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as @{2}
916 = Illegal redefinition of parameter {0}, inherited method from {1} does not constrain this parameter
917 = Missing non-null annotation: inherited method from {0} specifies this parameter as @{1}
@@ -825,6 +826,7 @@
969 = Null type mismatch (type annotations): ''null'' is not compatible to the free type variable ''{0}''
970 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}'', where ''{0}'' is a free type variable
971 = The explicit type bound 'Object' is not affected by the nullness default for DefaultLocation.TYPE_BOUND.
+972 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as ''{2}'' (mismatching null constraints)
# Java 8
1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided

Back to the top