diff options
| author | Stephan Herrmann | 2014-07-20 10:31:10 +0000 |
|---|---|---|
| committer | Stephan Herrmann | 2014-07-22 14:28:00 +0000 |
| commit | 61133b8c5e6da454f7cea747a5c83744e4b067c9 (patch) | |
| tree | bb4298042628868e2ba4c0ddade0fd867a5014c2 | |
| parent | 41321e271ce9d99e44edf867f5f75e8abc4a221f (diff) | |
| download | eclipse.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"
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 |
