diff options
author | Stephan Herrmann | 2020-01-26 20:56:27 +0000 |
---|---|---|
committer | Stephan Herrmann | 2020-01-26 20:56:27 +0000 |
commit | a1de6c1dd7cb7912b7e2b8fdaf34292a4e39cf91 (patch) | |
tree | 51c54c19cfb36b1243cfeab412b281725356eae8 | |
parent | 26442c4da93bb37c148503ede232875b5244e58f (diff) | |
download | eclipse.jdt.core-a1de6c1dd7cb7912b7e2b8fdaf34292a4e39cf91.tar.gz eclipse.jdt.core-a1de6c1dd7cb7912b7e2b8fdaf34292a4e39cf91.tar.xz eclipse.jdt.core-a1de6c1dd7cb7912b7e2b8fdaf34292a4e39cf91.zip |
Bug 482242 - [compiler][null] option to raise problems when unsafelyI20200129-1800I20200129-0935I20200129-0100I20200128-1805I20200127-1800
passing annotated parameterized types into unannotated code
- new IProblem IDs
Change-Id: If80b38dedbb2402af8af8b9e618ab7ccb34375f8
6 files changed, 38 insertions, 27 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 5dcaae8a35..bba613a97b 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 @@ -340,6 +340,8 @@ public void test011_problem_categories() { expectedProblemAttributes.put("AmbiguousField", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("AmbiguousMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("AmbiguousType", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); + expectedProblemAttributes.put("AnnotatedTypeArgumentToUnannotated", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); + expectedProblemAttributes.put("AnnotatedTypeArgumentToUnannotatedSuperHint", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); expectedProblemAttributes.put("AnnotationCannotOverrideMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER)); expectedProblemAttributes.put("AnnotationCircularity", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); expectedProblemAttributes.put("AnnotationCircularitySelfReference", new ProblemAttributes(CategorizedProblem.CAT_TYPE)); @@ -1325,6 +1327,8 @@ public void test012_compiler_problems_tuning() { expectedProblemAttributes.put("AmbiguousField", SKIP); expectedProblemAttributes.put("AmbiguousMethod", SKIP); expectedProblemAttributes.put("AmbiguousType", SKIP); + expectedProblemAttributes.put("AnnotatedTypeArgumentToUnannotated", new ProblemAttributes(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED)); + expectedProblemAttributes.put("AnnotatedTypeArgumentToUnannotatedSuperHint", new ProblemAttributes(JavaCore.COMPILER_PB_ANNOTATED_TYPE_ARGUMENT_TO_UNANNOTATED)); expectedProblemAttributes.put("AnnotationCannotOverrideMethod", SKIP); expectedProblemAttributes.put("AnnotationCircularity", SKIP); expectedProblemAttributes.put("AnnotationCircularitySelfReference", SKIP); 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 19c069027b..bcae7dc48b 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 @@ -3263,7 +3263,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest { "1. INFO in X.java (at line 9)\n" + " X<String> x = new Y();\n" + " ^^^^^^^\n" + - "Null type safety (type annotations): The expression of type '@NonNull Y' needs unchecked conversion to conform to 'X<String>', corresponding supertype is 'X<@NonNull String>'\n" + + "Unsafe null type conversion (type annotations): The value of type '@NonNull Y' is made accessible using the less-annotated type 'X<String>', corresponding supertype is 'X<@NonNull String>'\n" + "----------\n"); } @@ -3679,7 +3679,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest { "2. INFO in X.java (at line 7)\n" + " @NonNull String @NonNull [][] s2 = new @NonNull String [] @NonNull [] { null, { null} }; // problem at both nulls\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Null type safety (type annotations): The expression of type \'@NonNull String [] @NonNull[]\' needs unchecked conversion to conform to \'@NonNull String @NonNull[] []\'\n" + + "Unsafe null type conversion (type annotations): The value of type \'@NonNull String [] @NonNull[]\' is made accessible using the less-annotated type \'@NonNull String @NonNull[] []\'\n" + "----------\n" + "3. ERROR in X.java (at line 7)\n" + " @NonNull String @NonNull [][] s2 = new @NonNull String [] @NonNull [] { null, { null} }; // problem at both nulls\n" + @@ -3715,7 +3715,7 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest { "1. WARNING in X.java (at line 6)\n" + " @NonNull String [][] @NonNull [] s = new @NonNull String []@NonNull [][] { null, { {null}, null/*ok*/ } };\n" + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Null type safety (type annotations): The expression of type \'@NonNull String [] @NonNull[] []\' needs unchecked conversion to conform to \'@NonNull String [] [] @NonNull[]\'\n" + + "Unsafe null type conversion (type annotations): The value of type \'@NonNull String [] @NonNull[] []\' is made accessible using the less-annotated type \'@NonNull String [] [] @NonNull[]\'\n" + "----------\n" + "2. ERROR in X.java (at line 6)\n" + " @NonNull String [][] @NonNull [] s = new @NonNull String []@NonNull [][] { null, { {null}, null/*ok*/ } };\n" + @@ -6640,7 +6640,7 @@ public void testBug439298_comment3() { "1. INFO in Extract.java (at line 9)\n" + " return new R<@NonNull A>(null);\n" + " ^^^^^^^^^^^^^^^^^^^^^^^\n" + - "Null type safety (type annotations): The expression of type '@NonNull R<@NonNull A>' needs unchecked conversion to conform to 'R<A>'\n" + + "Unsafe null type conversion (type annotations): The value of type '@NonNull R<@NonNull A>' is made accessible using the less-annotated type 'R<A>'\n" + "----------\n"); } public void testBug439298_comment4() { @@ -17868,7 +17868,7 @@ public void testBug482242_simple() { "1. ERROR in Test.java (at line 9)\n" + " dangerous(l);\n" + " ^\n" + - "Null type safety (type annotations): The expression of type \'List<@NonNull String>\' needs unchecked conversion to conform to \'List<String>\'\n" + + "Unsafe null type conversion (type annotations): The value of type \'List<@NonNull String>\' is made accessible using the less-annotated type \'List<String>\'\n" + "----------\n"); } public void testBug482242_intermediate() { @@ -17906,7 +17906,7 @@ public void testBug482242_intermediate() { "2. ERROR in Test.java (at line 13)\n" + " insert(list, string); // (2)\n" + " ^^^^\n" + - "Null type safety (type annotations): The expression of type \'List<@NonNull String>\' needs unchecked conversion to conform to \'List<? super String>\'\n" + + "Unsafe null type conversion (type annotations): The value of type \'List<@NonNull String>\' is made accessible using the less-annotated type \'List<? super String>\'\n" + "----------\n"); } public void testBug482242_annotatedTypeVariable() { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java index 4970f51c7b..11e5b2e641 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2017 GK Software AG, and others. + * Copyright (c) 2014, 2020 GK Software AG, and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -2638,8 +2638,8 @@ public class ExternalAnnotations18Test extends ModifyingResourceTests { IProblem[] problems = reconciled.getProblems(); assertProblems(problems, new String[] { - "Pb(955) Null type safety (type annotations): The expression of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' " + - "needs unchecked conversion to conform to 'Collector<? super String,Object,Set<@NonNull String>>'", + "Pb(983) Unsafe null type conversion (type annotations): The value of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' " + + "is made accessible using the less-annotated type 'Collector<? super String,Object,Set<@NonNull String>>'", }, new int[] {11}, new int[] { ProblemSeverities.Warning }); @@ -2648,7 +2648,7 @@ public class ExternalAnnotations18Test extends ModifyingResourceTests { IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); sortMarkers(markers); assertMarkers("Markers after full build", - "Null type safety (type annotations): The expression of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' needs unchecked conversion to conform to 'Collector<? super String,Object,Set<@NonNull String>>'", + "Unsafe null type conversion (type annotations): The value of type 'Collector<@NonNull String,capture#of ?,Set<@NonNull String>>' is made accessible using the less-annotated type 'Collector<? super String,Object,Set<@NonNull String>>'", markers); int[] severities = new int[] { IMarker.SEVERITY_WARNING }; for (int i = 0; i < markers.length; i++) { 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 7119bbaf56..39ea98c996 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 @@ -1900,6 +1900,10 @@ void setSourceStart(int sourceStart); int NonNullMethodTypeVariableFromLegacyMethod = TypeRelated + 981; /** @since 3.21 */ int MissingNullAnnotationImplicitlyUsed = Internal + 982; + /** @since 3.21 */ + int AnnotatedTypeArgumentToUnannotated = Internal + 983; + /** @since 3.21 */ + int AnnotatedTypeArgumentToUnannotatedSuperHint = Internal + 984; // Java 8 work 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 3021f41f8c..e82038d4ee 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 @@ -490,6 +490,9 @@ public static int getIrritant(int problemID) { case IProblem.ReferenceExpressionReturnNullRedefUnchecked: case IProblem.UnsafeNullnessCast: return CompilerOptions.NullUncheckedConversion; + case IProblem.AnnotatedTypeArgumentToUnannotated: + case IProblem.AnnotatedTypeArgumentToUnannotatedSuperHint: + return CompilerOptions.AnnotatedTypeArgumentToUnannotated; case IProblem.RedundantNullAnnotation: case IProblem.RedundantNullDefaultAnnotation: case IProblem.RedundantNullDefaultAnnotationModule: @@ -800,6 +803,7 @@ public static int getProblemCategory(int severity, int problemID) { case CompilerOptions.NullUncheckedConversion : case CompilerOptions.MissingNonNullByDefaultAnnotation: case CompilerOptions.NonnullParameterAnnotationDropped: + case CompilerOptions.AnnotatedTypeArgumentToUnannotated: return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM; case CompilerOptions.RedundantNullAnnotation : return CategorizedProblem.CAT_UNNECESSARY_CODE; @@ -10592,12 +10596,7 @@ public void arrayReferencePotentialNullReference(ArrayReference arrayReference) public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding providedType, TypeBinding requiredType, NullAnnotationMatching status) { if (providedType == requiredType) return; //$IDENTITY-COMPARISON$ - int severity = -1; - if (status.isAnnotatedToUnannotated()) { - severity = this.options.getSeverity(CompilerOptions.AnnotatedTypeArgumentToUnannotated); - if (severity == ProblemSeverities.Ignore) - return; - } + // try to improve nonnull vs. null: if (providedType.id == TypeIds.T_null || status.nullStatus == FlowInfo.NULL) { nullityMismatchIsNull(expression, requiredType); @@ -10623,17 +10622,21 @@ public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding String superHint = null; String superHintShort = null; if (status.superTypeHint != null && requiredType.isParameterizedType()) { - problemId = (status.isUnchecked() - ? IProblem.NullityUncheckedTypeAnnotationDetailSuperHint - : IProblem.NullityMismatchingTypeAnnotationSuperHint); + problemId = (status.isAnnotatedToUnannotated() + ? IProblem.AnnotatedTypeArgumentToUnannotatedSuperHint + : (status.isUnchecked() + ? IProblem.NullityUncheckedTypeAnnotationDetailSuperHint + : IProblem.NullityMismatchingTypeAnnotationSuperHint)); superHint = status.superTypeHintName(this.options, false); superHintShort = status.superTypeHintName(this.options, true); } else { - problemId = (status.isUnchecked() - ? IProblem.NullityUncheckedTypeAnnotationDetail - : (requiredType.isTypeVariable() && !requiredType.hasNullTypeAnnotations()) - ? IProblem.NullityMismatchAgainstFreeTypeVariable - : IProblem.NullityMismatchingTypeAnnotation); + problemId = (status.isAnnotatedToUnannotated() + ? IProblem.AnnotatedTypeArgumentToUnannotated + : (status.isUnchecked() + ? IProblem.NullityUncheckedTypeAnnotationDetail + : (requiredType.isTypeVariable() && !requiredType.hasNullTypeAnnotations()) + ? IProblem.NullityMismatchAgainstFreeTypeVariable + : IProblem.NullityMismatchingTypeAnnotation)); if (problemId == IProblem.NullityMismatchAgainstFreeTypeVariable) { arguments = new String[] { null, null, new String(requiredType.sourceName()) }; // don't show bounds here shortArguments = new String[] { null, null, new String(requiredType.sourceName()) }; @@ -10661,9 +10664,7 @@ public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding arguments = new String[] { requiredName, providedName }; shortArguments = new String[] { requiredNameShort, providedNameShort }; } - if (severity == -1) - severity = computeSeverity(problemId); - this.handle(problemId, arguments, shortArguments, severity, expression.sourceStart, expression.sourceEnd); + this.handle(problemId, arguments, shortArguments, expression.sourceStart, expression.sourceEnd); } public void nullityMismatchTypeArgument(TypeBinding typeVariable, TypeBinding typeArgument, ASTNode location) { 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 a09df397f3..29d14cc2a4 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 @@ -853,6 +853,8 @@ 980 = Unsafe interpretation of method return type as ''@{0}'' based on the receiver type ''{1}''. Type ''{2}'' doesn''t seem to be designed with null type annotations in mind 981 = Unsafe interpretation of method return type as ''@{0}'' based on substitution ''{1}={2}''. Declaring type ''{3}'' doesn''t seem to be designed with null type annotations in mind 982 = Annotation type ''{0}'' cannot be found on the build path, which is implicitly needed for null analysis +983 = Unsafe null type conversion (type annotations): The value of type ''{1}'' is made accessible using the less-annotated type ''{0}'' +984 = Unsafe null type conversion (type annotations): The value of type ''{1}'' is made accessible using the less-annotated type ''{0}'', corresponding supertype is ''{2}'' # Java 8 1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided |