diff --git a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java
index 78aa71c..9372739 100644
--- a/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java
+++ b/org.eclipse.jdt.annotation/src/org/eclipse/jdt/annotation/NonNull.java
@@ -35,8 +35,8 @@
*
Nullness of the value can be statically determined, the entity is definitely bound from either of:
* - the value
null
, or
* - an entity with a {@link Nullable @Nullable} type.
- * Nullness can not definitely be determined, because different code branches yield different results.
- * Nullness can not be determined, because other program elements are involved for which
+ * Nullness cannot definitely be determined, because different code branches yield different results.
+ * Nullness cannot be determined, because other program elements are involved for which
* null annotations are lacking.
*
*
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 6c6bd01..025c21c 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
@@ -52,7 +52,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_illegal_annotation_007" };
+// TESTS_NAMES = new String[] { "test_assignment_expression_1" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -2474,6 +2474,36 @@
"Type mismatch: required \'@NonNull String\' but the provided value can be null\n" +
"----------\n");
}
+public void test_assignment_expression_1() {
+ Map customOptions = getCompilerOptions();
+// customOptions.put(CompilerOptions.OPTION_ReportPotentialNullSpecViolation, JavaCore.ERROR);
+ customOptions.put(JavaCore.COMPILER_NONNULL_IS_DEFAULT, JavaCore.ENABLED);
+ customOptions.put(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK, JavaCore.ERROR);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object foo() {\n" +
+ " Object o = null;\n" +
+ " boolean keepLooking = true;\n" +
+ " while(keepLooking) {\n" +
+ " if ((o=getO()) != null) {\n" +
+ " return o;\n" +
+ " }\n" +
+ " }\n" +
+ " return null;\n" +
+ " }\n" +
+ "\n" +
+ " private @Nullable Object getO() {\n" +
+ " return new Object();\n" +
+ " }\n" +
+ "}\n",
+
+ },
+ customOptions,
+ "");
+}
// a nonnull variable is dereferenced method of a nested type
public void test_nesting_1() {
Map customOptions = getCompilerOptions();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
index 1e06c11..9c7b8e9 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
@@ -7476,7 +7476,6 @@
assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(typeBinding2));
assertTrue("Not assignement compatible", typeBinding.isAssignmentCompatible(collectionTypeBinding));
}
-
/*
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=156352
*/
@@ -7495,10 +7494,13 @@
buffer.append(typeBinding.getAnnotations().length);
typeBinding= typeBinding.getSuperclass();
}
- // initially, this test expected "000", but after https://bugs.eclipse.org/186342
- // annotations are resolved more eagerly, which makes the annotations on Test2 show up,
- // which is actually the right outcome.
- assertEquals("Wrong number of annotations", "020", String.valueOf(buffer));
+ // the right outcome would be "020", but depending on the strategy when exactly
+ // annotations are resolved the annotations on Test2 are (not) present when
+ // traversing the super-class chain.
+ // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but
+ // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387
+ // (see the change in SourceTypeBinding.resolveTypesFor(..))
+ assertEquals("Wrong number of annotations", "000", String.valueOf(buffer));
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
index e89ba8f..fd388a6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
@@ -7498,10 +7498,13 @@
buffer.append(typeBinding.getAnnotations().length);
typeBinding= typeBinding.getSuperclass();
}
- // initially, this test expected "000", but after https://bugs.eclipse.org/186342
- // annotations are resolved more eagerly, which makes the annotations on Test2 show up,
- // which is actually the right outcome.
- assertEquals("Wrong number of annotations", "020", String.valueOf(buffer));
+ // the right outcome would be "020", but depending on the strategy when exactly
+ // annotations are resolved the annotations on Test2 are (not) present when
+ // traversing the super-class chain.
+ // The patch in https://bugs.eclipse.org/186342#c196 produced "020" but
+ // the previous behavior ("000") was restored in https://bugs.eclipse.org/365387
+ // (see the change in SourceTypeBinding.resolveTypesFor(..))
+ assertEquals("Wrong number of annotations", "000", String.valueOf(buffer));
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 59a7ecd..46d4540 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -119,7 +119,7 @@
}
public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
super.checkNPE(scope, flowContext, flowInfo);
- if (nullStatus(flowInfo) == FlowInfo.POTENTIALLY_NULL)
+ if ((nullStatus(flowInfo) & FlowInfo.POTENTIALLY_NULL) != 0)
scope.problemReporter().messageSendPotentialNullReference(this.binding, this);
}
/**
@@ -281,7 +281,7 @@
if ((tagBits & TagBits.AnnotationNonNull) != 0)
return FlowInfo.NON_NULL;
if ((tagBits & TagBits.AnnotationNullable) != 0)
- return FlowInfo.POTENTIALLY_NULL;
+ return FlowInfo.POTENTIALLY_NULL | FlowInfo.POTENTIALLY_NON_NULL;
}
return FlowInfo.UNKNOWN;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 7df8a71..98caf30 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -564,9 +564,10 @@
while (size <= nullCount) size *= 2;
this.expectedTypes = new TypeBinding[size];
}
- else if (nullCount == this.expectedTypes.length) {
+ else if (nullCount >= this.expectedTypes.length) {
+ int oldLen = this.expectedTypes.length;
System.arraycopy(this.expectedTypes, 0,
- this.expectedTypes = new TypeBinding[nullCount * 2], 0, nullCount);
+ this.expectedTypes = new TypeBinding[nullCount * 2], 0, oldLen);
}
this.expectedTypes[nullCount] = expectedType;
}
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 0ac09c9..c973fd3 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
@@ -778,6 +778,7 @@
OPTION_NonNullIsDefault,
OPTION_ReportNullSpecViolation,
OPTION_ReportPotentialNullSpecViolation,
+ OPTION_ReportNullSpecInsufficientInfo,
OPTION_ReportRedundantNullAnnotation
};
return result;
@@ -1225,6 +1226,7 @@
this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
this.nonNullByDefaultAnnotationName = DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME;
+ this.defaultNonNullness = 0;
}
public void set(Map optionsMap) {
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 094c155..e8b277c 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
@@ -1597,7 +1597,8 @@
typeParameters[i].binding = null;
return null;
}
- createArgumentBindings(method);
+ if (this.scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
+ createArgumentBindings(method); // need annotations resolved already at this point
if (foundReturnTypeProblem)
return method; // but its still unresolved with a null return type & is still connected to its method declaration
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index ca6b9fa..b381b01 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -547,11 +547,11 @@
if (this.lineEnds == null || this.linePtr == -1)
return -1;
- if (lineNumber > this.linePtr + 2)
+ if (lineNumber > this.lineEnds.length+1)
return -1;
if (lineNumber <= 0)
return -1;
- if (lineNumber == this.linePtr + 2)
+ if (lineNumber == this.lineEnds.length + 1)
return this.eofPosition;
return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
}