diff options
| author | Stephan Herrmann | 2014-07-22 17:47:30 +0000 |
|---|---|---|
| committer | Stephan Herrmann | 2014-07-22 18:37:56 +0000 |
| commit | fa4debd5be46821e4afe7fa2082f7a976e89007c (patch) | |
| tree | 93d630f33e1653d72a201eb854bd6e9aea5665ce | |
| parent | b62a0575eabeb814900afcc3426a14b0da5fd6ad (diff) | |
| download | eclipse.jdt.core-fa4debd5be46821e4afe7fa2082f7a976e89007c.tar.gz eclipse.jdt.core-fa4debd5be46821e4afe7fa2082f7a976e89007c.tar.xz eclipse.jdt.core-fa4debd5be46821e4afe7fa2082f7a976e89007c.zip | |
Bug 440143 - [1.8][null] one more case of contradictory null annotations
regarding type variables
3 files changed, 89 insertions, 29 deletions
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 7c31a77079..9fe7bf05f5 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 @@ -3051,45 +3051,30 @@ public class NullTypeAnnotationTest extends AbstractNullAnnotationTest { " @NonNull T bar1(@NonNull T t) {\n" + " return t;\n" + " }\n" + - " @NonNull T bar2(@Nullable T t) { // argument: contradiction (1)\n" + - " return t;\n" + + " @NonNull T bar2(@Nullable T t) { // argument: no contradiction (1)\n" + + " return t; // mismatch (1)\n" + " }\n" + - " @Nullable T bar3(T t) { // return type: contradiction (2)\n" + - " @Nullable T l = t; // local: contradiction (3)\n" + + " @Nullable T bar3(T t) { // return type: no contradiction (2)\n" + + " @Nullable T l = t; // local: no contradiction (3)\n" + " return l;\n" + " }\n" + " class Inner {\n" + - " @Nullable T f; // field: contradiction (4)\n" + + " @Nullable T f; // field: no contradiction (4)\n" + " }\n" + " T bar3() {\n" + - " return null;\n" + + " return null; // mismatch (2)\n" + " }\n" + "}\n" }, getCompilerOptions(), "----------\n" + - "1. ERROR in X.java (at line 11)\n" + - " @NonNull T bar2(@Nullable T t) { // argument: contradiction (1)\n" + - " ^^^^^^^^^\n" + - "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + - "----------\n" + - "2. ERROR in X.java (at line 14)\n" + - " @Nullable T bar3(T t) { // return type: contradiction (2)\n" + - " ^^^^^^^^^\n" + - "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + - "----------\n" + - "3. ERROR in X.java (at line 15)\n" + - " @Nullable T l = t; // local: contradiction (3)\n" + - " ^^^^^^^^^\n" + - "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + - "----------\n" + - "4. ERROR in X.java (at line 19)\n" + - " @Nullable T f; // field: contradiction (4)\n" + - " ^^^^^^^^^\n" + - "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" + + "1. ERROR in X.java (at line 12)\n" + + " return t; // mismatch (1)\n" + + " ^\n" + + "Null type mismatch (type annotations): required \'@NonNull T\' but this expression has type \'@Nullable T\'\n" + "----------\n" + - "5. ERROR in X.java (at line 22)\n" + - " return null;\n" + + "2. ERROR in X.java (at line 22)\n" + + " return null; // mismatch (2)\n" + " ^^^^\n" + "Null type mismatch: required \'@NonNull T\' but the provided value is null\n" + "----------\n"); @@ -5752,6 +5737,65 @@ public void testTypeVariable16b() { "Null type mismatch: required \'@NonNull Y\' but the provided value is null\n" + "----------\n"); } +// Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables +public void testTypeVariable17() { + runNegativeTestWithLibs( + new String[] { + "Test7.java", + "import org.eclipse.jdt.annotation.*;\n" + + "\n" + + "public class Test7<@Nullable E> {\n" + + " E e;\n" + + "\n" + + " @Nullable\n" + + " E test() {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @NonNull\n" + + " E getNotNull() {\n" + + " if (e == null)\n" + + " throw new NullPointerException();\n" + + " return e;\n" + + " }\n" + + "}\n" + }, + getCompilerOptions(), + "----------\n" + + "1. ERROR in Test7.java (at line 15)\n" + + " return e;\n" + + " ^\n" + + "Null type mismatch (type annotations): required \'@NonNull E\' but this expression has type \'@Nullable E\'\n" + + "----------\n"); +} +// Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables +// use local variable to avoid the null type mismatch +public void testTypeVariable17a() { + runConformTestWithLibs( + new String[] { + "Test7.java", + "import org.eclipse.jdt.annotation.*;\n" + + "\n" + + "public class Test7<@Nullable E> {\n" + + " E e;\n" + + "\n" + + " @Nullable\n" + + " E test() {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @NonNull\n" + + " E getNotNull() {\n" + + " E el = e;\n" + + " if (el == null)\n" + + " throw new NullPointerException();\n" + + " return el;\n" + + " }\n" + + "}\n" + }, + getCompilerOptions(), + ""); +} public void testBug434600() { runConformTestWithLibs( new String[] { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index 9612891912..613b5d42b6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -29,6 +29,7 @@ * Bug 428352 - [1.8][compiler] Resolution errors don't always surface * Bug 427163 - [1.8][null] bogus error "Contradictory null specification" on varags * Bug 432348 - [1.8] Internal compiler error (NPE) after upgrade to 1.8 + * Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables * Jesper S Moller - Contributions for * bug 382721 - [1.8][compiler] Effectively final variables needs special treatment * bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable @@ -1111,7 +1112,12 @@ public abstract class ASTNode implements TypeConstants, TypeIds { // for arrays: @T X[] SE7 associates @T to the type, but in SE8 it affects the leaf component type long prevNullBits = existingType.leafComponentType().tagBits & TagBits.AnnotationNullMASK; if (se8nullBits != 0 && prevNullBits != se8nullBits && ((prevNullBits | se8nullBits) == TagBits.AnnotationNullMASK)) { - scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation); + if (existingType instanceof TypeVariableBinding) { + // let type-use annotations override annotations on the type parameter declaration + existingType = existingType.unannotated(true); + } else { + scope.problemReporter().contradictoryNullAnnotations(se8NullAnnotation); + } } TypeBinding oldLeafType = (unionRef == null) ? existingType.leafComponentType() : unionRef.resolvedType; AnnotationBinding [][] goodies = new AnnotationBinding[typeRef.getAnnotatableLevels()][]; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java index beb1fa92b8..ee94276c83 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java @@ -26,6 +26,7 @@ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables * Bug 438250 - [1.8][null] NPE trying to report bogus null annotation conflict * Bug 438179 - [1.8][null] 'Contradictory null annotations' error on type variable with explicit null-annotation. + * Bug 440143 - [1.8][null] one more case of contradictory null annotations regarding type variables *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -701,7 +702,16 @@ public class TypeVariableBinding extends ReferenceBinding { } public void setTypeAnnotations(AnnotationBinding[] annotations, boolean evalNullAnnotations) { - this.environment.getUnannotatedType(this); // exposes original TVB/capture to type system for id stamping purposes. + if (getClass() == TypeVariableBinding.class) { + // TVB only: if the declaration already carries type annotations, + // clone the unannotated binding first to ensure TypeSystem.getUnnanotatedType() will see it at position 0: + TypeBinding unannotated = clone(null); + this.environment.getUnannotatedType(unannotated); // register unannotated + this.id = unannotated.id; // transfer fresh id + this.environment.typeSystem.cacheDerivedType(this, unannotated, this); // register this + } else { + this.environment.getUnannotatedType(this); // exposes original TVB/capture to type system for id stamping purposes. + } super.setTypeAnnotations(annotations, evalNullAnnotations); } /** |
