Bug 458361 - [1.8][null] reconciler throws NPE in
ProblemReporter.illegalReturnRedefinition()
Change-Id: I2341a7b74a5c62c2db7fb5ab6568cef74f884a4f
Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de>
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 17944a5..6dc56dd 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, 2014 IBM Corporation and others.
+ * Copyright (c) 2006, 2015 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
@@ -36,6 +36,7 @@
* 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"
* Bug 446442 - [1.8] merge null annotations from super methods
+ * Bug 458361 - [1.8][null] reconciler throws NPE in ProblemReporter.illegalReturnRedefinition()
* 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
@@ -583,6 +584,7 @@
expectedProblemAttributes.put("IllegalQualifierForExplicitThis", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("IllegalQualifierForExplicitThis2", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("IllegalReturnNullityRedefinitionFreeTypeVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("IllegalStaticModifierForMemberType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("IllegalTypeAnnotationsInStaticMemberAccess", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
@@ -1409,6 +1411,7 @@
expectedProblemAttributes.put("IllegalQualifierForExplicitThis2", SKIP);
expectedProblemAttributes.put("IllegalRedefinitionToNonNullParameter", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
expectedProblemAttributes.put("IllegalReturnNullityRedefinition", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+ expectedProblemAttributes.put("IllegalReturnNullityRedefinitionFreeTypeVariable", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
expectedProblemAttributes.put("IllegalStaticModifierForMemberType", SKIP);
expectedProblemAttributes.put("IllegalTypeAnnotationsInStaticMemberAccess", SKIP);
expectedProblemAttributes.put("IllegalTypeArgumentsInRawConstructorReference", 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 818c68f..4ca55c1 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
@@ -5666,7 +5666,7 @@
"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" +
+ "The return type is incompatible with the free type variable 'T' returned from ITest.foo(T) (mismatching null constraints)\n" +
"----------\n" +
"----------\n" +
"1. ERROR in Test2.java (at line 3)\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
index dd65c36..1fcc9eb 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2013 GK Software AG and others.
+ * Copyright (c) 2011, 2015 GK Software AG 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
@@ -45,6 +45,7 @@
public class NullAnnotationModelTests extends ReconcilerTests {
String ANNOTATION_LIB;
+ String ANNOTATION_LIB_V1;
public static Test suite() {
return buildModelTestSuite(NullAnnotationModelTests.class);
@@ -66,6 +67,10 @@
Bundle[] bundles = org.eclipse.jdt.core.tests.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[2.0.0,3.0.0)");
File bundleFile = FileLocator.getBundleFile(bundles[0]);
this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath();
+
+ bundles = org.eclipse.jdt.core.tests.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[1.1.0,2.0.0)");
+ bundleFile = FileLocator.getBundleFile(bundles[0]);
+ this.ANNOTATION_LIB_V1 = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath();
}
protected String testJarPath(String jarName) throws IOException {
@@ -646,4 +651,65 @@
deleteProject(project);
}
}
+
+ // was: NPE in ProblemReporter.illegalReturnRedefinition() from ImplicitNullAnnotationVerifier.checkNullSpecInheritance()
+ public void testBug458361a() throws CoreException {
+ IJavaProject project = null;
+ try {
+ project = createJavaProject("Bug458361", new String[] {"src"}, new String[] {"JCL18_LIB", this.ANNOTATION_LIB}, "bin", "1.8");
+
+ project.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+ project.setOption(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.ERROR);
+
+ setUpWorkingCopy("/Bug458361/src/MyCollection.java",
+ "import java.util.Collection;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public interface MyCollection<T> extends Collection<T> {\n" +
+ " public @Nullable T get(int i);\n" +
+ "}\n");
+ assertProblems(
+ "Unexpected problems",
+ "----------\n" +
+ "1. ERROR in /Bug458361/src/MyCollection.java (at line 4)\n" +
+ " public @Nullable T get(int i);\n" +
+ " ^^^^^^^^^^^\n" +
+ "The return type is incompatible with the free type variable \'T\' returned from Collection<T>.get(int) (mismatching null constraints)\n" +
+ "----------\n");
+ } finally {
+ if (project != null)
+ deleteProject(project);
+ }
+ }
+ public void testBug458361b() throws CoreException {
+ IJavaProject project = null;
+ try {
+ project = createJavaProject("Bug458361", new String[] {"src"}, new String[] {"JCL17_LIB", this.ANNOTATION_LIB_V1}, "bin", "1.7");
+
+ project.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+ project.setOption(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION, JavaCore.ERROR);
+
+ createFile("/Bug458361/src/Super.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public interface Super {\n" +
+ " @NonNull String getName();\n" +
+ "}\n");
+
+ setUpWorkingCopy("/Bug458361/src/Sub.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public interface Sub extends Super {\n" +
+ " @Nullable String getName();\n" +
+ "}\n");
+ assertProblems(
+ "Unexpected problems",
+ "----------\n" +
+ "1. ERROR in /Bug458361/src/Sub.java (at line 3)\n" +
+ " @Nullable String getName();\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "The return type is incompatible with \'@NonNull String\' returned from Super.getName() (mismatching null constraints)\n" +
+ "----------\n");
+ } finally {
+ if (project != null)
+ deleteProject(project);
+ }
+ }
}
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 d1df0cd..d30135f 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, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -195,6 +195,7 @@
* ImplicitObjectBoundNoNullDefault
* IllegalParameterNullityRedefinition
* ContradictoryNullAnnotationsInferredFunctionType
+ * IllegalReturnNullityRedefinitionFreeTypeVariable
* Jesper S Moller - added the following constants
* TargetTypeNotAFunctionalInterface
* OuterLocalMustBeEffectivelyFinal
@@ -1801,6 +1802,8 @@
int IllegalParameterNullityRedefinition = MethodRelated + 972;
/** @since 3.11 */
int ContradictoryNullAnnotationsInferredFunctionType = MethodRelated + 973;
+ /** @since 3.11 */
+ int IllegalReturnNullityRedefinitionFreeTypeVariable = MethodRelated + 974;
// Java 8 work
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 5bcf14a..a1c2a24 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -1971,4 +1971,14 @@
this.warningThreshold.clear(irritant);
}
}
+
+ /**
+ * Note, if you have a LookupEnvironment you should instead ask
+ * {@link org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment#usesNullTypeAnnotations()}. */
+ public boolean usesNullTypeAnnotations() {
+ if (this.useNullTypeAnnotations != null)
+ return this.useNullTypeAnnotations;
+ return this.isAnnotationBasedNullAnalysisEnabled
+ && this.sourceLevel >= ClassFileConstants.JDK1_8;
+ }
}
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 80370ea..384b4b5 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, 2014 GK Software AG, IBM Corporation and others.
+ * Copyright (c) 2012, 2015 GK Software AG, 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
@@ -296,7 +296,8 @@
}
if (NullAnnotationMatching.analyse(inheritedMethod.returnType, currentMethod.returnType, substituteReturnType, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
if (srcMethod != null)
- scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod, null);
+ scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod,
+ this.environment.getNonNullAnnotationName());
else
scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
return;
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 f69fae4..78e4705 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 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
@@ -56,6 +56,7 @@
* Bug 435805 - [1.8][compiler][null] Java 8 compiler does not recognize declaration style null annotations
* Bug 446442 - [1.8] merge null annotations from super methods
* Bug 455723 - Nonnull argument not correctly inferred in loop
+ * Bug 458361 - [1.8][null] reconciler throws NPE in ProblemReporter.illegalReturnRedefinition()
* 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
@@ -393,6 +394,7 @@
case IProblem.RequiredNonNullButProvidedNull:
case IProblem.RequiredNonNullButProvidedSpecdNullable:
case IProblem.IllegalReturnNullityRedefinition:
+ case IProblem.IllegalReturnNullityRedefinitionFreeTypeVariable:
case IProblem.IllegalRedefinitionToNonNullParameter:
case IProblem.IllegalDefinitionToNonNullParameter:
case IProblem.ParameterLackingNullableAnnotation:
@@ -9195,14 +9197,14 @@
nullityMismatchPotentiallyNull(expression, requiredType, annotationName);
return;
}
- if (this.options.useNullTypeAnnotations == Boolean.TRUE)
+ if (this.options.usesNullTypeAnnotations())
nullityMismatchingTypeAnnotation(expression, providedType, requiredType, NullAnnotationMatching.NULL_ANNOTATIONS_UNCHECKED);
else
nullityMismatchIsUnknown(expression, providedType, requiredType, annotationName);
}
public void nullityMismatchIsNull(Expression expression, TypeBinding requiredType) {
int problemId = IProblem.RequiredNonNullButProvidedNull;
- boolean useNullTypeAnnotations = this.options.useNullTypeAnnotations == Boolean.TRUE;
+ boolean useNullTypeAnnotations = this.options.usesNullTypeAnnotations();
if (useNullTypeAnnotations && requiredType.isTypeVariable() && !requiredType.hasNullTypeAnnotations())
problemId = IProblem.NullNotCompatibleToFreeTypeVariable;
if (requiredType instanceof CaptureBinding) {
@@ -9363,26 +9365,32 @@
sourceStart = annotation.sourceStart;
}
TypeBinding inheritedReturnType = inheritedMethod.returnType;
- String[] arguments;
- String[] argumentsShort;
- if (this.options.useNullTypeAnnotations != Boolean.TRUE) {
- StringBuilder returnType = new StringBuilder();
+ int problemId = IProblem.IllegalReturnNullityRedefinition;
+ StringBuilder returnType = new StringBuilder();
+ StringBuilder returnTypeShort = new StringBuilder();
+ if (this.options.usesNullTypeAnnotations()) {
+ // 1.8+
+ if (inheritedReturnType.isTypeVariable() && (inheritedReturnType.tagBits & TagBits.AnnotationNullMASK) == 0) {
+ problemId = IProblem.IllegalReturnNullityRedefinitionFreeTypeVariable;
+
+ returnType.append(inheritedReturnType.readableName());
+ returnTypeShort.append(inheritedReturnType.shortReadableName());
+ } else {
+ returnType.append(inheritedReturnType.nullAnnotatedReadableName(this.options, false));
+ returnTypeShort.append(inheritedReturnType.nullAnnotatedReadableName(this.options, true));
+ }
+ } else {
+ // 1.7-
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))};
+ returnTypeShort.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]);
+ returnTypeShort.append(' ').append(inheritedReturnType.shortReadableName());
}
+ String[] arguments = new String[] { methodSignature.toString(), returnType.toString() };
+ String[] argumentsShort = new String[] { shortSignature.toString(), returnTypeShort.toString() };
this.handle(
- IProblem.IllegalReturnNullityRedefinition,
+ problemId,
arguments,
argumentsShort,
sourceStart,
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 2cacfa0..70ac81b 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
@@ -41,6 +41,7 @@
# 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"
+# Bug 458361 - [1.8][null] reconciler throws NPE in ProblemReporter.illegalReturnRedefinition()
# 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
@@ -829,6 +830,7 @@
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)
973 = Contradictory null annotations: function type was inferred as ''{2} ({4})'', but only one of ''@{0}'' and ''@{1}'' can be effective at any location
+974 = The return type is incompatible with the free type variable ''{1}'' returned from {0} (mismatching null constraints)
# Java 8
1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided