Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2020-01-06 22:12:39 +0000
committerStephan Herrmann2020-01-06 22:53:43 +0000
commitc68c1e4999fba991c5c5d3410da33a3f909b3462 (patch)
tree1fd2de334d192501279590979fb1bb9ebd5ae97c
parentf6ca35bc46a58901d24a836b1dc77576044bdb13 (diff)
downloadeclipse.jdt.core-c68c1e4999fba991c5c5d3410da33a3f909b3462.tar.gz
eclipse.jdt.core-c68c1e4999fba991c5c5d3410da33a3f909b3462.tar.xz
eclipse.jdt.core-c68c1e4999fba991c5c5d3410da33a3f909b3462.zip
Bug 466477 - [null] Improve error message "...inherited method ...I20200106-1805
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java67
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java37
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties1
6 files changed, 88 insertions, 35 deletions
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 7e4e8c3434..5dcaae8a35 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
@@ -628,6 +628,7 @@ public void test011_problem_categories() {
expectedProblemAttributes.put("InheritedIncompatibleReturnType", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("InheritedMethodReducesVisibility", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
+ expectedProblemAttributes.put("InheritedParameterLackingNonNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("InheritedTypeHidesEnclosingName", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("InitializerMustCompleteNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("InstanceFieldDuringConstructorInvocation", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
@@ -1610,6 +1611,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("InheritedIncompatibleReturnType", SKIP);
expectedProblemAttributes.put("InheritedMethodHidesEnclosingName", SKIP);
expectedProblemAttributes.put("InheritedMethodReducesVisibility", SKIP);
+ expectedProblemAttributes.put("InheritedParameterLackingNonNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED));
expectedProblemAttributes.put("InheritedTypeHidesEnclosingName", SKIP);
expectedProblemAttributes.put("InitializerMustCompleteNormally", SKIP);
expectedProblemAttributes.put("InstanceFieldDuringConstructorInvocation", 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 cae1036973..658c2e1e77 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
@@ -1286,44 +1286,44 @@ public void test_parameter_specification_inheritance_014() {
"----------\n" +
"1. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString1(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString2(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"3. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString5(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"4. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString3(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n"
: // at 1.8 we show null type annotations in the message:
"----------\n" +
"1. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method @Nullable String getString1(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method String getString2(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"3. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString5(@NonNull String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n" +
"4. ERROR in p1\\Y.java (at line 2)\n" +
" public class Y extends X implements IY {\n" +
- " ^\n" +
+ " ^\n" +
"The method getString3(String) from X cannot implement the corresponding method from IY due to incompatible nullness constraints\n" +
"----------\n"));
}
@@ -1411,8 +1411,8 @@ public void test_parameter_specification_inheritance_017() {
"----------\n" +
"1. WARNING in XSub.java (at line 1)\n" +
" public class XSub extends X implements IX {\n" +
- " ^^^^\n" +
- "Missing non-null annotation: inherited method from IX specifies this parameter as @NonNull\n" +
+ " ^\n" +
+ "Parameter 1 of method foo(String) lacks a @NonNull annotation as specified in type IX\n" +
"----------\n");
}
@@ -6123,24 +6123,24 @@ public void testBug388281_06() {
"----------\n" +
"1. ERROR in ctest\\C.java (at line 2)\n" +
" public class C extends c.C2 implements i2.I2A {\n" +
- " ^\n" +
+ " ^^^^\n" +
"The method m2(Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in ctest\\C.java (at line 2)\n" +
" public class C extends c.C2 implements i2.I2A {\n" +
- " ^\n" +
+ " ^^^^\n" +
"The method m1(Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" +
"----------\n"
: // at 1.8 we show null type annotations:
"----------\n" +
"1. ERROR in ctest\\C.java (at line 2)\n" +
" public class C extends c.C2 implements i2.I2A {\n" +
- " ^\n" +
+ " ^^^^\n" +
"The method m2(@NonNull Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in ctest\\C.java (at line 2)\n" +
" public class C extends c.C2 implements i2.I2A {\n" +
- " ^\n" +
+ " ^^^^\n" +
"The method m1(@NonNull Object) from C2 cannot implement the corresponding method from I2A due to incompatible nullness constraints\n" +
"----------\n"),
libs,
@@ -9138,24 +9138,24 @@ public void testBug502214() {
"----------\n" +
"1. ERROR in test\\X.java (at line 22)\n" +
" class Y extends A implements I {\n" +
- " ^\n" +
+ " ^\n" +
"The method m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in test\\X.java (at line 22)\n" +
" class Y extends A implements I {\n" +
- " ^\n" +
+ " ^\n" +
"The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
"----------\n"
:
"----------\n" +
"1. ERROR in test\\X.java (at line 22)\n" +
" class Y extends A implements I {\n" +
- " ^\n" +
+ " ^\n" +
"The method @Nullable String m2() from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
"----------\n" +
"2. ERROR in test\\X.java (at line 22)\n" +
" class Y extends A implements I {\n" +
- " ^\n" +
+ " ^\n" +
"The method m1(Object) from A cannot implement the corresponding method from I due to incompatible nullness constraints\n" +
"----------\n"
)
@@ -11076,4 +11076,35 @@ public void testBug459397() {
"Redundant null check: The variable dc cannot be null at this location\n" +
"----------\n");
}
+public void testBug466477() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "SuperI.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "\n" +
+ "public interface SuperI {\n" +
+ " void testNN(@NonNull String s);\n" +
+ " void testNu(@Nullable String s);\n" +
+ "}\n",
+ "Base.java",
+ "public class Base {\n" +
+ " public void testNN(String s) { }\n" +
+ " public void testNu(String s) { }\n" +
+ "}\n",
+ "Custom.java",
+ "public class Custom extends Base implements SuperI {\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in Custom.java (at line 1)\n" +
+ " public class Custom extends Base implements SuperI {\n" +
+ " ^^^^\n" +
+ "The method testNu(String) from Base cannot implement the corresponding method from SuperI due to incompatible nullness constraints\n" +
+ "----------\n" +
+ "2. WARNING in Custom.java (at line 1)\n" +
+ " public class Custom extends Base implements SuperI {\n" +
+ " ^^^^\n" +
+ "Parameter 1 of method testNN(String) lacks a @NonNull annotation as specified in type SuperI\n" +
+ "----------\n");
+}
}
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 de77baa45d..7119bbaf56 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
@@ -1833,6 +1833,8 @@ void setSourceStart(int sourceStart);
int RedundantNullCheckOnConstNonNullField = Internal + 944;
/** @since 3.20 */
int ConstNonNullFieldComparisonYieldsFalse = Internal + 945;
+ /** @since 3.21 */
+ int InheritedParameterLackingNonNullAnnotation = MethodRelated + 946;
/** @since 3.10 */
int ArrayReferencePotentialNullReference = Internal + 951;
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 95594bd7bb..8161215460 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2018 GK Software AG, IBM Corporation and others.
+ * Copyright (c) 2012, 2020 GK Software SE, IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -25,6 +25,7 @@ import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
import org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching.CheckMode;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
/**
@@ -436,10 +437,13 @@ public class ImplicitNullAnnotationVerifier {
if (TypeBinding.equalsEquals(inheritedMethod.declaringClass, one.declaringClass) && getParameterNonNullness(one, i, useTypeAnnotations) != Boolean.TRUE)
continue parameterLoop;
}
- scope.problemReporter().parameterLackingNonnullAnnotation(
- currentArgument,
- inheritedMethod.declaringClass,
- annotationName);
+ if (currentArgument != null) {
+ scope.problemReporter().parameterLackingNonnullAnnotation(currentArgument, inheritedMethod.declaringClass, annotationName);
+ } else {
+ TypeDeclaration type = scope.classScope().referenceContext;
+ ASTNode location = type.superclass != null ? type.superclass : type;
+ scope.problemReporter().inheritedParameterLackingNonnullAnnotation(currentMethod, i+1, inheritedMethod.declaringClass, location, annotationName);
+ }
continue;
}
}
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 74b69a03a9..6932f0aa86 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
@@ -478,6 +478,7 @@ public static int getIrritant(int problemID) {
return CompilerOptions.NonNullTypeVariableFromLegacyInvocation;
case IProblem.ParameterLackingNonNullAnnotation:
+ case IProblem.InheritedParameterLackingNonNullAnnotation:
return CompilerOptions.NonnullParameterAnnotationDropped;
case IProblem.RequiredNonNullButProvidedPotentialNull:
@@ -10089,20 +10090,26 @@ public void parameterLackingNullableAnnotation(Argument argument, ReferenceBindi
argument.type.sourceEnd);
}
public void parameterLackingNonnullAnnotation(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
- int sourceStart = 0, sourceEnd = 0;
- if (argument != null) {
- sourceStart = argument.type.sourceStart;
- sourceEnd = argument.type.sourceEnd;
- } else if (this.referenceContext instanceof TypeDeclaration) {
- sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart;
- sourceEnd = ((TypeDeclaration) this.referenceContext).sourceEnd;
- }
this.handle(
IProblem.ParameterLackingNonNullAnnotation,
new String[] { new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
new String[] { new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
- sourceStart,
- sourceEnd);
+ argument.type.sourceStart,
+ argument.type.sourceEnd);
+}
+public void inheritedParameterLackingNonnullAnnotation(MethodBinding currentMethod, int paramRank, ReferenceBinding specificationType,
+ ASTNode location, char[][] annotationName) {
+ this.handle(IProblem.InheritedParameterLackingNonNullAnnotation,
+ new String[] {
+ String.valueOf(paramRank), new String(currentMethod.readableName()),
+ new String(specificationType.readableName()), CharOperation.toString(annotationName)
+ },
+ new String[] {
+ String.valueOf(paramRank), new String(currentMethod.shortReadableName()),
+ new String(specificationType.shortReadableName()), new String(annotationName[annotationName.length-1])
+ },
+ location.sourceStart, location.sourceEnd
+ );
}
public void illegalParameterRedefinition(Argument argument, ReferenceBinding declaringClass, TypeBinding inheritedParameter) {
int sourceStart = argument.type.sourceStart;
@@ -10260,8 +10267,14 @@ public void expressionPotentialNullReference(ASTNode location) {
public void cannotImplementIncompatibleNullness(ReferenceContext context, MethodBinding currentMethod, MethodBinding inheritedMethod, boolean showReturn) {
int sourceStart = 0, sourceEnd = 0;
if (context instanceof TypeDeclaration) {
- sourceStart = ((TypeDeclaration) context).sourceStart;
- sourceEnd = ((TypeDeclaration) context).sourceEnd;
+ TypeDeclaration type = (TypeDeclaration) context;
+ if (type.superclass != null) {
+ sourceStart = type.superclass.sourceStart;
+ sourceEnd = type.superclass.sourceEnd;
+ } else {
+ sourceStart = type.sourceStart;
+ sourceEnd = type.sourceEnd;
+ }
}
String[] problemArguments = {
showReturn
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 a64e5f35ec..a09df397f3 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
@@ -818,6 +818,7 @@
943 = Nullness default is redundant with a default specified for the enclosing module {0}
944 = Redundant null check: The field {0} is a nonnull constant
945 = Null comparison always yields false: The field {0} is a nonnull constant
+946 = Parameter {0} of method {1} lacks a @{3} annotation as specified in type {2}
951 = Potential null pointer access: array element may be null

Back to the top