Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 209776 Details for
Bug 365662
[compiler][null] warn on contradictory and redundant null annotations
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Tests & fix
Bug_365662.patch (text/plain), 36.26 KB, created by
Stephan Herrmann
on 2012-01-19 15:25:29 EST
(
hide
)
Description:
Tests & fix
Filename:
MIME Type:
Creator:
Stephan Herrmann
Created:
2012-01-19 15:25:29 EST
Size:
36.26 KB
patch
obsolete
>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 95fa1b1..5aafa8f 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 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2006, 2011 IBM Corporation and others. >+ * Copyright (c) 2006, 2012 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -397,6 +397,7 @@ > expectedProblemAttributes.put("CodeCannotBeReached", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("CodeSnippetMissingClass", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("CodeSnippetMissingMethod", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); >+ expectedProblemAttributes.put("ContradictoryNullAnnotations", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL)); > expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("ConflictingImport", new ProblemAttributes(CategorizedProblem.CAT_IMPORT)); > expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >@@ -790,6 +791,10 @@ > expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationType", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationMethod", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); > expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM)); >@@ -1089,6 +1094,7 @@ > expectedProblemAttributes.put("CodeSnippetMissingMethod", SKIP); > expectedProblemAttributes.put("ComparingIdentical", new ProblemAttributes(JavaCore.COMPILER_PB_COMPARING_IDENTICAL)); > expectedProblemAttributes.put("ConflictingImport", SKIP); >+ expectedProblemAttributes.put("ContradictoryNullAnnotations", SKIP); > expectedProblemAttributes.put("ConstructorVarargsArgumentNeedCast", new ProblemAttributes(JavaCore.COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST)); > expectedProblemAttributes.put("CorruptedSignature", SKIP); > expectedProblemAttributes.put("DeadCode", new ProblemAttributes(JavaCore.COMPILER_PB_DEAD_CODE)); >@@ -1480,6 +1486,10 @@ > expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS)); > expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); > expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationPackage", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationType", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); >+ expectedProblemAttributes.put("RedundantNullDefaultAnnotationMethod", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); > expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); > expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK)); >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 2e13dc6..df4bb59 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 >@@ -53,7 +53,7 @@ > // Static initializer to specify tests subset using TESTS_* static variables > // All specified tests which do not belong to the class are skipped... > static { >-// TESTS_NAMES = new String[] { "test_default_nullness_014" }; >+// TESTS_NAMES = new String[] { "test_redundant_annotation_" }; > // TESTS_NUMBERS = new int[] { 561 }; > // TESTS_RANGE = new int[] { 1, 2049 }; > } >@@ -2537,6 +2537,12 @@ > " new C(null);\n" + > " ^^^^\n" + > "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p1\\C.java (at line 2)\n" + >+ " @org.eclipse.jdt.annotation.NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p1\n" + > "----------\n"); > } > // Bug 365836 - [compiler][null] Incomplete propagation of null defaults. >@@ -2654,6 +2660,253 @@ > "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + > "----------\n"); > } >+ >+// redundant default annotations - class vs. inner class >+public void test_redundant_annotation_01() { >+ Map customOptions = getCompilerOptions(); >+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault class Inner {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner2 {\n" + >+ " }\n" + >+ " void foo() {\n" + >+ " @SuppressWarnings(\"unused\") @NonNullByDefault class Local {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" + >+ "@NonNullByDefault class V {}\n", >+ "p3/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault package p3;\n", >+ "p3/Z.java", >+ "package p3;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Z {\n" + >+ "}\n" + >+ "class X {\n" + >+ " @NonNullByDefault class Inner {}\n" + >+ " class Inner2 {\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault class Inner {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 6)\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y.Inner\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault class DeepInner2 {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "4. WARNING in p2\\Y.java (at line 12)\n" + >+ " @SuppressWarnings(\"unused\") @NonNullByDefault class Local {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p3\\Z.java (at line 3)\n" + >+ " @NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n" + >+ "2. WARNING in p3\\Z.java (at line 7)\n" + >+ " @NonNullByDefault class Inner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n" + >+ "3. WARNING in p3\\Z.java (at line 9)\n" + >+ " @NonNullByDefault class DeepInner {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing package p3\n" + >+ "----------\n"); >+} >+// redundant default annotations - class vs. method >+public void test_redundant_annotation_02() { >+ Map customOptions = getCompilerOptions(); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " @NonNullByDefault void fubar() {}\n" + >+ " }\n" + >+ " }\n" + >+ " @NonNullByDefault void zink() {\n" + >+ " @SuppressWarnings(\"unused\") class Bork {\n" + >+ " @NonNullByDefault void jubar() {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method bar()\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 10)\n" + >+ " @NonNullByDefault void fubar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Zork\n" + >+ "----------\n" + >+ "4. WARNING in p2\\Y.java (at line 15)\n" + >+ " @NonNullByDefault void jubar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method zink()\n" + >+ "----------\n"); >+} >+//redundant default annotations - class vs. method - generics >+public void test_redundant_annotation_02g() { >+ Map customOptions = getCompilerOptions(); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y<TY> {\n" + >+ " @NonNullByDefault <TF> void foo(TF arg) {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault <TB> void bar() {\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " @NonNullByDefault void fubar(TB arg) {}\n" + >+ " }\n" + >+ " }\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault <TF> void foo(TF arg) {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y<TY>\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 9)\n" + >+ " @NonNullByDefault @SuppressWarnings(\"unused\") class Zork {\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing method bar()\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 10)\n" + >+ " @NonNullByDefault void fubar(TB arg) {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Zork\n" + >+ "----------\n"); >+} >+ >+// redundant default annotations - package / class / method vs global default >+public void test_redundant_annotation_03() { >+ Map customOptions = getCompilerOptions(); >+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED); >+ runConformTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "@NonNullByDefault\n" + >+ "public class Y {\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ "}\n", >+ "p3/package-info.java", >+ "@org.eclipse.jdt.annotation.NonNullByDefault package p3;\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. WARNING in p2\\Y.java (at line 3)\n" + >+ " @NonNullByDefault\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n" + >+ "2. WARNING in p2\\Y.java (at line 5)\n" + >+ " @NonNullByDefault void foo() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with a default specified for the enclosing type Y\n" + >+ "----------\n" + >+ "3. WARNING in p2\\Y.java (at line 8)\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ " ^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n" + >+ "----------\n" + >+ "1. WARNING in p3\\package-info.java (at line 1)\n" + >+ " @org.eclipse.jdt.annotation.NonNullByDefault package p3;\n" + >+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + >+ "Nullness default is redundant with the global default\n" + >+ "----------\n"); >+} >+ >+// contradictory null annotations >+public void test_contradictory_annotations_01() { >+ Map customOptions = getCompilerOptions(); >+ runNegativeTestWithLibs( >+ new String[] { >+ "p2/Y.java", >+ "package p2;\n" + >+ "import org.eclipse.jdt.annotation.*;\n" + >+ "public class Y {\n" + >+ " void foo(@NonNull @Nullable Object o) {}\n" + >+ " @Nullable @NonNull Object bar() {\n" + >+ " @NonNull @Nullable Object o = null;\n" + >+ " return o;\n" + >+ " }\n" + >+ "}\n" + >+ "class Z {\n" + >+ " @NonNullByDefault void bar() {}\n" + >+ "}\n" >+ }, >+ customOptions, >+ "----------\n" + >+ "1. ERROR in p2\\Y.java (at line 4)\n" + >+ " void foo(@NonNull @Nullable Object o) {}\n" + >+ " ^^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n" + >+ "2. ERROR in p2\\Y.java (at line 5)\n" + >+ " @Nullable @NonNull Object bar() {\n" + >+ " ^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n" + >+ "3. ERROR in p2\\Y.java (at line 6)\n" + >+ " @NonNull @Nullable Object o = null;\n" + >+ " ^^^^^^^^^\n" + >+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + >+ "----------\n"); >+} >+ > // a nonnull variable is dereferenced in a loop > public void test_nonnull_var_in_constrol_structure_1() { > Map customOptions = getCompilerOptions(); >@@ -2915,7 +3168,7 @@ > customOptions, > ""); > } >-// a nonnull variable is dereferenced method of a nested type >+// a nonnull variable is dereferenced in a method of a nested type > public void test_nesting_1() { > Map customOptions = getCompilerOptions(); > // customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR); >@@ -2924,7 +3177,6 @@ > new String[] { > "X.java", > "import org.eclipse.jdt.annotation.*;\n" + >- "@NonNullByDefault\n" + > "public class X {\n" + > " void print4(final String s1) {\n" + > " for (int i=0; i<3; i++)\n" + >@@ -2959,12 +3211,12 @@ > }, > customOptions, > "----------\n" + >- "1. ERROR in X.java (at line 16)\n" + >+ "1. ERROR in X.java (at line 15)\n" + > " print(s2);\n" + > " ^^\n" + > "Type mismatch: required \'@NonNull String\' but the provided value can be null\n" + > "----------\n" + >- "2. ERROR in X.java (at line 25)\n" + >+ "2. ERROR in X.java (at line 24)\n" + > " @NonNull String s3R = s3;\n" + > " ^^\n" + > "Type mismatch: required \'@NonNull String\' but the provided value can be null\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 6b2f414..6a76255 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 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -1460,6 +1460,16 @@ > int RedundantNullAnnotation = MethodRelated + 922; > /** @since 3.8 */ > int IllegalAnnotationForBaseType = TypeRelated + 923; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotation = Internal + 925; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationPackage = Internal + 926; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationType = Internal + 927; >+ /** @since 3.8 */ >+ int RedundantNullDefaultAnnotationMethod = Internal + 928; >+ /** @since 3.8 */ >+ int ContradictoryNullAnnotations = Internal + 929; > > /** > * External problems -- These are problems defined by other plugins >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >index 68ed9eb..dde1d2f 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java >@@ -25,6 +25,8 @@ > public abstract class Annotation extends Expression { > > final static MemberValuePair[] NoValuePairs = new MemberValuePair[0]; >+ private static final long TAGBITS_NULLABLE_OR_NONNULL = TagBits.AnnotationNullable|TagBits.AnnotationNonNull; >+ > public int declarationSourceEnd; > public Binding recipient; > >@@ -387,6 +389,10 @@ > AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod); > recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings); > } >+ if ((sourceMethod.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) { >+ scope.problemReporter().contradictoryNullAnnotations(this); >+ sourceMethod.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems >+ } > break; > case Binding.FIELD : > FieldBinding sourceField = (FieldBinding) this.recipient; >@@ -404,6 +410,10 @@ > LocalDeclaration localDeclaration = variable.declaration; > recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings); > } >+ if ((variable.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) { >+ scope.problemReporter().contradictoryNullAnnotations(this); >+ variable.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems >+ } > break; > } > } >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >index 3cf3183..686f7fd 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2010 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -13,6 +13,7 @@ > import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > import org.eclipse.jdt.internal.compiler.ast.CaseStatement; > import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; > import org.eclipse.jdt.internal.compiler.ast.TypeReference; >@@ -85,6 +86,17 @@ > return this.superclass; // default answer > } > >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ long outerDefault = this.enclosingMethod != null ? this.enclosingMethod.tagBits & ((TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault)) : 0; >+ if (outerDefault != 0) { >+ if (outerDefault == annotationTagBits) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.enclosingMethod); >+ } >+ return; >+ } >+ super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits); >+} >+ > public char[] computeUniqueKey(boolean isLeaf) { > char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf); > int semicolon = CharOperation.lastIndexOf(';', outerKey); >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >index 189497d..5c15b77 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2011 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -570,6 +570,13 @@ > AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod); > if (methodDecl != null) > ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod); >+ long nullDefaultBits = this.tagBits & (TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault); >+ if (nullDefaultBits != 0 && this.declaringClass instanceof SourceTypeBinding) { >+ SourceTypeBinding declaringSourceType = (SourceTypeBinding) this.declaringClass; >+ if (declaringSourceType.checkRedundantNullnessDefaultOne(methodDecl, methodDecl.annotations, nullDefaultBits)) { >+ declaringSourceType.checkRedundantNullnessDefaultRecurse(methodDecl, methodDecl.annotations, nullDefaultBits); >+ } >+ } > } > } > return originalMethod.tagBits; >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >index 4fc8606..d7c3181 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2009 IBM Corporation and others. >+ * Copyright (c) 2000, 2012 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -9,6 +9,9 @@ > * IBM Corporation - initial API and implementation > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.lookup; >+ >+import org.eclipse.jdt.internal.compiler.ast.ASTNode; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > > public class NestedTypeBinding extends SourceTypeBinding { > >@@ -107,6 +110,17 @@ > return synthLocal; > } > >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ ReferenceBinding currentType = this.enclosingType; >+ do { >+ if (!((SourceTypeBinding)currentType).checkRedundantNullnessDefaultOne(location, annotations, annotationTagBits)) { >+ return; >+ } >+ currentType = currentType.enclosingType(); >+ } while (currentType instanceof SourceTypeBinding); >+ super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits); >+} >+ > /* Answer the receiver's enclosing type... null if the receiver is a top level type. > */ > public ReferenceBinding enclosingType() { >diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >index c7ad46f..a0737c2 100644 >--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java >@@ -23,6 +23,7 @@ > import org.eclipse.jdt.internal.compiler.ast.ASTNode; > import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; > import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; >+import org.eclipse.jdt.internal.compiler.ast.Annotation; > import org.eclipse.jdt.internal.compiler.ast.Argument; > import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; > import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; >@@ -1636,11 +1637,47 @@ > if (defaultAnnotation != null) { > if (CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME)) { > getPackage().nullnessDefaultAnnotation = defaultAnnotation; >+ long globalDefault = this.scope.compilerOptions().defaultNonNullness; >+ if (globalDefault == TagBits.AnnotationNonNull && (annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) { >+ TypeDeclaration typeDecl = this.scope.referenceContext; >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(typeDecl, typeDecl.annotations, null); >+ } > } else { > this.nullnessDefaultAnnotation = defaultAnnotation; >+ TypeDeclaration typeDecl = this.scope.referenceContext; >+ long nullDefaultBits = annotationTagBits & (TagBits.AnnotationNullUnspecifiedByDefault|TagBits.AnnotationNonNullByDefault); >+ checkRedundantNullnessDefaultRecurse(typeDecl, typeDecl.annotations, nullDefaultBits); > } > } > } >+ >+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ if (this.fPackage.nullnessDefaultAnnotation != null) { >+ if ((this.fPackage.nullnessDefaultAnnotation.id == TypeIds.T_ConfiguredAnnotationNonNull >+ && ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0))) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.fPackage); >+ } >+ return; >+ } >+ long globalDefault = this.scope.compilerOptions().defaultNonNullness; >+ if (globalDefault == TagBits.AnnotationNonNull && annotationTagBits == TagBits.AnnotationNonNullByDefault) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, null); >+ } >+} >+ >+// return: should caller continue searching? >+protected boolean checkRedundantNullnessDefaultOne(ASTNode location, Annotation[] annotations, long annotationTagBits) { >+ TypeBinding thisDefault = this.nullnessDefaultAnnotation; >+ if (thisDefault != null) { >+ if (thisDefault.id == TypeIds.T_ConfiguredAnnotationNonNull >+ && ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0)) { >+ this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this); >+ } >+ return false; // different default means inner default is not redundant -> we're done >+ } >+ return true; >+} >+ > private TypeBinding getNullnessDefaultAnnotation() { > if (this.nullnessDefaultAnnotation instanceof UnresolvedReferenceBinding) > this.nullnessDefaultAnnotation = this.scope.environment().getNullAnnotationResolved(this.nullnessDefaultAnnotation, this.scope); >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 49bac9d..68f5e44 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 >@@ -96,6 +96,7 @@ > import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; > import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; > import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; >+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; > import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; > import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; >@@ -316,6 +317,10 @@ > case IProblem.RequiredNonNullButProvidedUnknown: > return CompilerOptions.NullSpecInsufficientInfo; > case IProblem.RedundantNullAnnotation: >+ case IProblem.RedundantNullDefaultAnnotation: >+ case IProblem.RedundantNullDefaultAnnotationPackage: >+ case IProblem.RedundantNullDefaultAnnotationType: >+ case IProblem.RedundantNullDefaultAnnotationMethod: > return CompilerOptions.RedundantNullAnnotation; > > case IProblem.BoxingConversion : >@@ -8182,7 +8187,10 @@ > .append(inheritedMethod.shortReadableName()); > int sourceStart = methodDecl.returnType.sourceStart; > Annotation[] annotations = methodDecl.annotations; >- sourceStart = findAnnotationSourceStart(annotations, sourceStart, TypeIds.T_ConfiguredAnnotationNullable); >+ Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNullable); >+ if (annotation != null) { >+ sourceStart = annotation.sourceStart; >+ } > this.handle( > IProblem.IllegalReturnNullityRedefinition, > new String[] { methodSignature.toString(), CharOperation.toString(nonNullAnnotationName)}, >@@ -8242,7 +8250,8 @@ > int sourceStart, sourceEnd; > if (i == -1) { > MethodDeclaration methodDecl = (MethodDeclaration) sourceMethod; >- sourceStart = findAnnotationSourceStart(methodDecl.annotations, methodDecl.returnType.sourceStart, TypeIds.T_ConfiguredAnnotationNonNull); >+ Annotation annotation = findAnnotation(methodDecl.annotations, TypeIds.T_ConfiguredAnnotationNonNull); >+ sourceStart = annotation != null ? annotation.sourceStart : methodDecl.returnType.sourceStart; > sourceEnd = methodDecl.returnType.sourceEnd; > } else { > Argument arg = sourceMethod.arguments[i]; >@@ -8252,30 +8261,66 @@ > this.handle(IProblem.RedundantNullAnnotation, ProblemHandler.NoArgument, ProblemHandler.NoArgument, sourceStart, sourceEnd); > } > >+public void nullDefaultAnnotationIsRedundant(ASTNode location, Annotation[] annotations, Binding outer) { >+ Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNonNullByDefault); >+ int start = annotation != null ? annotation.sourceStart : location.sourceStart; >+ int end = annotation != null ? annotation.sourceEnd : location.sourceStart; >+ String[] args = NoArgument; >+ String[] shortArgs = NoArgument; >+ if (outer != null) { >+ args = new String[] { new String(outer.readableName()) }; >+ shortArgs = new String[] { new String(outer.shortReadableName()) }; >+ } >+ int problemId = IProblem.RedundantNullDefaultAnnotation; >+ if (outer instanceof PackageBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationPackage; >+ } else if (outer instanceof ReferenceBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationType; >+ } else if (outer instanceof MethodBinding) { >+ problemId = IProblem.RedundantNullDefaultAnnotationMethod; >+ } >+ this.handle(problemId, args, shortArgs, start, end); >+} >+ >+public void contradictoryNullAnnotations(Annotation annotation) { >+ // when this error is triggered we can safely assume that both annotations have been configured >+ char[][] nonNullAnnotationName = this.options.nonNullAnnotationName; >+ char[][] nullableAnnotationName = this.options.nullableAnnotationName; >+ String[] arguments = { >+ new String(CharOperation.concatWith(nonNullAnnotationName, '.')), >+ new String(CharOperation.concatWith(nullableAnnotationName, '.')) >+ }; >+ String[] shortArguments = { >+ new String(nonNullAnnotationName[nonNullAnnotationName.length-1]), >+ new String(nullableAnnotationName[nullableAnnotationName.length-1]) >+ }; >+ this.handle(IProblem.ContradictoryNullAnnotations, arguments, shortArguments, annotation.sourceStart, annotation.sourceEnd); >+} >+ > public void illegalAnnotationForBaseType(TypeReference type, Annotation[] annotations, char[] annotationName, long nullAnnotationTagBit) > { > int typeId = (nullAnnotationTagBit == TagBits.AnnotationNullable) > ? TypeIds.T_ConfiguredAnnotationNullable : TypeIds.T_ConfiguredAnnotationNonNull; > String[] args = new String[] { new String(annotationName), new String(type.getLastToken()) }; >+ Annotation annotation = findAnnotation(annotations, typeId); >+ int start = annotation != null ? annotation.sourceStart : type.sourceStart; > this.handle(IProblem.IllegalAnnotationForBaseType, > args, > args, >- findAnnotationSourceStart(annotations, type.sourceStart, typeId), >+ start, > type.sourceEnd); > } > >-private int findAnnotationSourceStart(Annotation[] annotations, int startFallback, int typeId) { >- int sourceStart = startFallback; >+private Annotation findAnnotation(Annotation[] annotations, int typeId) { > if (annotations != null) { > // should have a @NonNull/@Nullable annotation, search for it: > int length = annotations.length; > for (int j=0; j<length; j++) { > if (annotations[j].resolvedType != null && annotations[j].resolvedType.id == typeId) { >- sourceStart = annotations[j].sourceStart; >- break; >+ return annotations[j]; > } > } > } >- return sourceStart; >+ return null; > } > } >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 d05ebd2..7b41d2b 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 >@@ -671,6 +671,11 @@ > 921 = The method {0} from {1} cannot implement the corresponding method from {2} due to incompatible nullness constraints > 922 = The nullness annotation is redundant with a default that applies to this location > 923 = The nullness annotation @{0} is not applicable for the primitive type {1} >+925 = Nullness default is redundant with the global default >+926 = Nullness default is redundant with a default specified for the enclosing package {0} >+927 = Nullness default is redundant with a default specified for the enclosing type {0} >+928 = Nullness default is redundant with a default specified for the enclosing method {0} >+929 = Contradictory null specification; only one of @{0} and @{1} can be specified at any location > > ### ELABORATIONS > ## Access restrictions
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 365662
: 209776