Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2014-10-03 20:03:34 +0000
committerStephan Herrmann2014-10-03 20:29:29 +0000
commit881bc14111c034e0b90ec9961e6a7ddeaec8517b (patch)
treedcc271e61766b9814da11408e96bff26b9279c04
parenteb086338780463648761a8e416dab97ac4270c0b (diff)
downloadorg.eclipse.objectteams-881bc14111c034e0b90ec9961e6a7ddeaec8517b.tar.gz
org.eclipse.objectteams-881bc14111c034e0b90ec9961e6a7ddeaec8517b.tar.xz
org.eclipse.objectteams-881bc14111c034e0b90ec9961e6a7ddeaec8517b.zip
update jdt.core to I20140806-2000 (4.5 M1)
-rw-r--r--org.eclipse.jdt.core/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--org.eclipse.jdt.core/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java20
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java15
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java25
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java38
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java23
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java39
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java32
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationWalker.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java20
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java33
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java63
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java39
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java40
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java46
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java21
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java27
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java20
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java18
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFactoryMethodBinding.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java16
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBound.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java18
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java92
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java49
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java85
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties8
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java11
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java2
-rw-r--r--org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java6
-rw-r--r--org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java8
-rw-r--r--org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java17
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java22
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java10
-rw-r--r--org.eclipse.jdt.core/pom.xml6
-rw-r--r--org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java37
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java2
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java4
73 files changed, 884 insertions, 275 deletions
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 000000000..796937ca4
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//scripts/ecj.1=ISO-8859-1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 64f17a935..565079a50 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
-Bundle-Version: 3.10.0.v_OTDT_r240_qualifier
+Bundle-Version: 3.11.0.v_OTDT_r240_qualifier
Bundle-Activator: org.eclipse.jdt.core.JavaCore
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index 4a80caf84..65adef4d6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -583,6 +583,17 @@ public final class SelectionEngine extends Engine implements ISearchRequestor {
case '"':
case '\'':
break lineLoop;
+ case '-':
+ if (source[nextCharacterPosition] == '>') {
+ nextCharacterPosition--; // nextCharacterPosition = currentPosition
+ break lineLoop;
+ }
+ break;
+ case ':':
+ if (source[nextCharacterPosition] == ':') {
+ nextCharacterPosition--; // nextCharacterPosition = currentPosition
+ break lineLoop;
+ }
}
currentPosition--;
}
@@ -620,6 +631,15 @@ public final class SelectionEngine extends Engine implements ISearchRequestor {
break isolateLastName;
}
break;
+ case TerminalTokens.TokenNameARROW:
+ case TerminalTokens.TokenNameCOLON_COLON:
+ if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
+ lastIdentifierStart = scanner.startPosition;
+ lastIdentifierEnd = scanner.currentPosition - 1;
+ lastIdentifier = scanner.getCurrentTokenSource();
+ break isolateLastName;
+ }
+ break;
}
} while (token != TerminalTokens.TokenNameEOF);
} else {
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 7519a318f..a0c391ac5 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, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -194,6 +194,8 @@
* NonNullDefaultDetailIsNotEvaluated
* NullNotCompatibleToFreeTypeVariable
* NullityMismatchAgainstFreeTypeVariable
+ * ImplicitObjectBoundNoNullDefault
+ * IllegalParameterNullityRedefinition
* Jesper S Moller - added the following constants
* TargetTypeNotAFunctionalInterface
* OuterLocalMustBeEffectivelyFinal
@@ -406,6 +408,8 @@ void setSourceStart(int sourceStart);
int NonStaticContextForEnumMemberType = Internal + 32;
/** @since 3.3 */
int TypeHidingType = TypeRelated + 33;
+ /** @since 3.11 */
+ int NotAnnotationType = TypeRelated + 34;
// variables
int UndefinedName = Internal + FieldRelated + 50;
@@ -459,6 +463,10 @@ void setSourceStart(int sourceStart);
int UnresolvedVariable = FieldRelated + 83;
/** @since 3.10 */
int NonStaticOrAlienTypeReceiver = MethodRelated + 84;
+
+ /** @since 3.11 */
+ int ExceptionParameterIsNeverUsed = Internal + 85;
+
// variable hiding
/** @since 3.0 */
int LocalVariableHidingLocalVariable = Internal + 90;
@@ -1789,6 +1797,11 @@ void setSourceStart(int sourceStart);
int NullNotCompatibleToFreeTypeVariable = 969;
/** @since 3.10 */
int NullityMismatchAgainstFreeTypeVariable = 970;
+ /** @since 3.11 */
+ int ImplicitObjectBoundNoNullDefault = 971;
+ /** @since 3.11 */
+ int IllegalParameterNullityRedefinition = MethodRelated + 972;
+
// Java 8 work
/** @since 3.10 */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 999aee20c..f1a0c185d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -22,6 +22,8 @@
* Bug 415399 - [1.8][compiler] Type annotations on constructor results dropped by the code generator
* Bug 415470 - [1.8][compiler] Type annotations on class declaration go vanishing
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ * Stephan Herrmann - Contribution for
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.internal.compiler;
@@ -2994,7 +2996,8 @@ public class ClassFile implements TypeConstants, TypeIds {
// functional expressions, we know the size ahead of time - this less general
// than the full invokedynamic scope, but fine for Java 8
- int exSize = 10 * numberOfBootstraps + 8;
+ final int contentsEntries = 10;
+ int exSize = contentsEntries * numberOfBootstraps + 8;
if (exSize + localContentsOffset >= this.contents.length) {
resizeContents(exSize);
}
@@ -3028,8 +3031,8 @@ public class ClassFile implements TypeConstants, TypeIds {
// 2 for bridge count then 2 per bridge method type.
extraSpace += (2 + 2 * bridges.length);
}
- if (extraSpace + localContentsOffset >= this.contents.length) {
- resizeContents(extraSpace);
+ if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(extraSpace + contentsEntries);
}
if (indexForAltMetaFactory == 0) {
@@ -5296,11 +5299,11 @@ public class ClassFile implements TypeConstants, TypeIds {
this.innerClassesBindings = new HashSet(INNER_CLASSES_SIZE);
}
ReferenceBinding innerClass = (ReferenceBinding) binding;
- this.innerClassesBindings.add(innerClass.erasure().unannotated()); // should not emit yet another inner class for Outer.@Inner Inner.
+ this.innerClassesBindings.add(innerClass.erasure().unannotated(false)); // should not emit yet another inner class for Outer.@Inner Inner.
ReferenceBinding enclosingType = innerClass.enclosingType();
while (enclosingType != null
&& enclosingType.isNestedType()) {
- this.innerClassesBindings.add(enclosingType.erasure().unannotated());
+ this.innerClassesBindings.add(enclosingType.erasure().unannotated(false));
enclosingType = enclosingType.enclosingType();
}
}
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 9cf550f9f..4a414f6b3 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
@@ -31,6 +31,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
@@ -1035,7 +1036,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
}
}
if (copySE8AnnotationsToType)
- copySE8AnnotationsToType(scope, recipient, sourceAnnotations, true);
+ copySE8AnnotationsToType(scope, recipient, sourceAnnotations, false);
return annotations;
}
@@ -1061,7 +1062,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
}
// When SE8 annotations feature in SE7 locations, they get attributed to the declared entity. Copy/move these to the type of the declared entity (field, local, argument etc.)
- public static void copySE8AnnotationsToType(BlockScope scope, Binding recipient, Annotation[] annotations, boolean isLegalLocation) {
+ public static void copySE8AnnotationsToType(BlockScope scope, Binding recipient, Annotation[] annotations, boolean annotatingEnumerator) {
if (annotations == null || annotations.length == 0 || recipient == null)
return;
@@ -1085,15 +1086,20 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
int se8count = 0;
long se8nullBits = 0;
Annotation se8NullAnnotation = null;
- int firstSE8 = -1, lastSE8 = 0;
+ int firstSE8 = -1;
for (int i = 0, length = annotations.length; i < length; i++) {
AnnotationBinding annotation = annotations[i].getCompilerAnnotation();
if (annotation == null) continue;
final ReferenceBinding annotationType = annotation.getAnnotationType();
long metaTagBits = annotationType.getAnnotationTagBits();
if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+ if (annotatingEnumerator) {
+ if ((metaTagBits & recipientTargetMask) == 0) {
+ scope.problemReporter().misplacedTypeAnnotations(annotations[i], annotations[i]);
+ }
+ continue;
+ }
if (firstSE8 == -1) firstSE8 = i;
- lastSE8 = i;
if (se8Annotations == null) {
se8Annotations = new AnnotationBinding[] { annotation };
se8count = 1;
@@ -1111,10 +1117,6 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
}
}
if (se8Annotations != null) {
- if (!isLegalLocation) {
- scope.problemReporter().misplacedTypeAnnotations(annotations[firstSE8], annotations[lastSE8]);
- return;
- }
switch (recipient.kind()) {
case Binding.LOCAL:
LocalVariableBinding local = (LocalVariableBinding) recipient;
@@ -1175,7 +1177,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/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 1a758068a..d3ff2fb0b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -23,6 +23,7 @@
* Bug 403216 - [1.8][null] TypeReference#captureTypeAnnotations treats type annotations as type argument annotations
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -882,7 +883,7 @@ public abstract class AbstractMethodDeclaration
this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver);
}
- if (resolvedReceiverType.hasNullTypeAnnotations()) {
+ if (this.receiver.type.hasNullTypeAnnotation()) {
this.scope.problemReporter().nullAnnotationUnsupportedLocation(this.receiver.type);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index d1f1ac40c..fa9b241f7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -338,7 +338,7 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl
// perform some emulation work in case there is some and we are inside a local type only
if (allocatedTypeErasure.isNestedType()
- && currentScope.enclosingSourceType().isLocalType()) {
+ && (currentScope.enclosingSourceType().isLocalType() || currentScope.isLambdaScope())) {
if (allocatedTypeErasure.isLocalType()) {
((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, false);
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 74c88b26d..9e4982478 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
@@ -808,7 +808,7 @@ public abstract class Annotation extends Expression {
this.resolvedType = typeBinding;
// ensure type refers to an annotation type
if (!typeBinding.isAnnotationType() && typeBinding.isValidBinding()) {
- scope.problemReporter().typeMismatchError(typeBinding, scope.getJavaLangAnnotationAnnotation(), this.type, null);
+ scope.problemReporter().notAnnotationType(typeBinding, this.type);
return null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 83b3cd0b6..74feee392 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -14,6 +14,8 @@
* bug 365519 - editorial cleanup after bug 186342 and bug 365387
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
+ * Bug 438012 - [1.8][null] Bogus Warning: The nullness annotation is redundant with a default that applies to this location
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 409246 - [1.8][compiler] Type annotations on catch parameters not handled properly
*******************************************************************************/
@@ -175,6 +177,12 @@ public class Argument extends LocalDeclaration {
return (this.bits & IsTypeElided) != 0;
}
+ public boolean hasNullTypeAnnotation() {
+ // parser associates SE8 annotations to the declaration
+ return TypeReference.containsNullAnnotation(this.annotations) ||
+ (this.type != null && this.type.hasNullTypeAnnotation()); // just in case
+ }
+
public StringBuffer print(int indent, StringBuffer output) {
printIndent(indent, output);
@@ -245,7 +253,9 @@ public class Argument extends LocalDeclaration {
}
resolveAnnotations(scope, this.annotations, this.binding, true);
Annotation.isTypeUseCompatible(this.type, scope, this.annotations);
- if (this.type.resolvedType != null && this.type.resolvedType.hasNullTypeAnnotations()) {
+ if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled &&
+ (this.type.hasNullTypeAnnotation() || TypeReference.containsNullAnnotation(this.annotations)))
+ {
scope.problemReporter().nullAnnotationUnsupportedLocation(this.type);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
index 05136255a..5ea23f716 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contribution for
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -179,4 +180,20 @@ public class ArrayTypeReference extends SingleTypeReference {
TypeBinding internalResolveType = super.internalResolveType(scope, location);
return internalResolveType;
}
+
+ @Override
+ public boolean hasNullTypeAnnotation() {
+ if (super.hasNullTypeAnnotation())
+ return true;
+ if (this.resolvedType != null && !this.resolvedType.hasNullTypeAnnotations())
+ return false; // shortcut
+ if (this.annotationsOnDimensions != null) {
+ for (int i = 0; i < this.annotationsOnDimensions.length; i++) {
+ Annotation[] innerAnnotations = this.annotationsOnDimensions[i];
+ if (containsNullAnnotation(innerAnnotations))
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
index f0656acd7..426f48d82 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -264,14 +264,14 @@ public abstract class FunctionalExpression extends Expression {
VisibilityInspector inspector = new VisibilityInspector(this, scope, shouldChatter);
boolean status = true;
-
if (!inspector.visible(sam.returnType))
status = false;
if (!inspector.visible(sam.parameters))
status = false;
if (!inspector.visible(sam.thrownExceptions))
status = false;
-
+ if (!inspector.visible(sam.declaringClass))
+ status = false;
return status;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index 05983ea35..f50126f30 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -16,6 +16,7 @@
* Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Andy Clement - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
@@ -152,7 +153,7 @@ public TypeBinding resolveType(BlockScope scope) {
this.constant = Constant.NotAConstant;
TypeBinding expressionType = this.expression.resolveType(scope);
TypeBinding checkedType = this.type.resolveType(scope, true /* check bounds*/);
- if (expressionType != null && checkedType != null && checkedType.hasNullTypeAnnotations()) {
+ if (expressionType != null && checkedType != null && this.type.hasNullTypeAnnotation()) {
// don't complain if the entire operation is redundant anyway
if (!expressionType.isCompatibleWith(checkedType) || NullAnnotationMatching.analyse(checkedType, expressionType, -1).isAnyMismatch())
scope.problemReporter().nullAnnotationUnsupportedLocation(this.type);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
index 9fcca2c0a..b90060ddc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -31,6 +31,7 @@
* Bug 428980 - [1.8][null] simple expression as lambda body doesn't leverage null annotation on argument
* Bug 429430 - [1.8] Lambdas and method reference infer wrong exception type with generics (RuntimeException instead of IOException)
* Bug 432110 - [1.8][compiler] nested lambda type incorrectly inferred vs javac
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
*******************************************************************************/
@@ -52,6 +53,7 @@ import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
@@ -114,6 +116,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
private ReferenceBinding classType;
public int ordinal;
private Set thrownExceptions;
+ public char[] text; // source representation of the lambda.
private static final SyntheticArgumentBinding [] NO_SYNTHETIC_ARGUMENTS = new SyntheticArgumentBinding[0];
private static final Block NO_BODY = new Block(0, true);
@@ -333,9 +336,6 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
}
}
- TypeBinding leafType = parameterType.leafComponentType();
- if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
- this.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
newParameters[i] = argument.bind(this.scope, parameterType, false);
if (argument.annotations != null) {
this.binding.tagBits |= TagBits.HasParameterAnnotations;
@@ -371,7 +371,6 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if ((exception.tagBits & TagBits.HasMissingType) != 0) {
this.binding.tagBits |= TagBits.HasMissingType;
}
- this.binding.modifiers |= (exception.modifiers & ExtraCompilerModifiers.AccGenericSignature);
}
TypeBinding returnType = this.binding.returnType;
@@ -379,9 +378,6 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if ((returnType.tagBits & TagBits.HasMissingType) != 0) {
this.binding.tagBits |= TagBits.HasMissingType;
}
- TypeBinding leafType = returnType.leafComponentType();
- if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
- this.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
} // TODO (stephan): else? (can that happen?)
if (haveDescriptor && !buggyArguments && blockScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
@@ -514,7 +510,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
int length = this.binding.parameters.length;
for (int i=0; i<length; i++) {
if (!this.scope.validateNullAnnotation(this.binding.returnType.tagBits, this.arguments[i].type, this.arguments[i].annotations))
- this.binding.returnType = this.binding.returnType.unannotated();
+ this.binding.returnType = this.binding.returnType.unannotated(true);
}
}
}
@@ -943,8 +939,9 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
LambdaExpression copy() {
final Parser parser = new Parser(this.enclosingScope.problemReporter(), false);
- final char[] source = this.compilationResult.getCompilationUnit().getContents();
- LambdaExpression copy = (LambdaExpression) parser.parseLambdaExpression(source, this.sourceStart, this.sourceEnd - this.sourceStart + 1,
+ final ICompilationUnit compilationUnit = this.compilationResult.getCompilationUnit();
+ char[] source = compilationUnit != null ? compilationUnit.getContents() : this.text;
+ LambdaExpression copy = (LambdaExpression) parser.parseLambdaExpression(source, compilationUnit != null ? this.sourceStart : 0, this.sourceEnd - this.sourceStart + 1,
this.enclosingScope.referenceCompilationUnit(), false /* record line separators */);
if (copy != null) { // ==> syntax errors == null
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 66a6d52ea..f2dbaaf3f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -19,6 +19,7 @@
* Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
* Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables
+ * Bug 438012 - [1.8][null] Bogus Warning: The nullness annotation is redundant with a default that applies to this location
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 378674 - "The method can be declared as static" is wrong
*******************************************************************************/
@@ -241,6 +242,12 @@ public class MethodDeclaration extends AbstractMethodDeclaration {
annotation.traverse(collector, (BlockScope) null);
}
}
+
+ public boolean hasNullTypeAnnotation() {
+ // parser associates SE8 annotations to the declaration
+ return TypeReference.containsNullAnnotation(this.annotations) ||
+ (this.returnType != null && this.returnType.hasNullTypeAnnotation()); // just in case
+ }
public boolean isDefaultMethod() {
return (this.modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index f815a4582..ca0929a80 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -175,18 +175,16 @@ public class NullAnnotationMatching {
int dims = requiredType.dimensions();
if (requiredType.dimensions() == providedType.dimensions()) {
long[] providedDimsTagBits = ((ArrayBinding)providedType).nullTagBitsPerDimension;
- if (providedDimsTagBits == null) {
- severity = 1; // required is annotated, provided not, need unchecked conversion
- } else {
- for (int i=0; i<=dims; i++) {
- long requiredBits = validNullTagBits(requiredDimsTagBits[i]);
- long providedBits = validNullTagBits(providedDimsTagBits[i]);
- if (i > 0)
- nullStatus = -1; // don't use beyond the outermost dimension
- severity = Math.max(severity, computeNullProblemSeverity(requiredBits, providedBits, nullStatus, mode == CheckMode.OVERRIDE));
- if (severity == 2)
- return NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH;
- }
+ if (providedDimsTagBits == null)
+ providedDimsTagBits = new long[dims+1]; // set to unspec'd at all dimensions
+ for (int i=0; i<=dims; i++) {
+ long requiredBits = validNullTagBits(requiredDimsTagBits[i]);
+ long providedBits = validNullTagBits(providedDimsTagBits[i]);
+ if (i > 0)
+ nullStatus = -1; // don't use beyond the outermost dimension
+ severity = Math.max(severity, computeNullProblemSeverity(requiredBits, providedBits, nullStatus, mode == CheckMode.OVERRIDE && nullStatus == -1));
+ if (severity == 2)
+ return NullAnnotationMatching.NULL_ANNOTATIONS_MISMATCH;
}
} else if (providedType.id == TypeIds.T_null) {
if (dims > 0 && requiredDimsTagBits[0] == TagBits.AnnotationNonNull)
@@ -389,13 +387,25 @@ public class NullAnnotationMatching {
return one;
}
- private static int computeNullProblemSeverity(long requiredBits, long providedBits, int nullStatus, boolean strict) {
- if ((requiredBits != 0 || strict) && requiredBits != providedBits) {
+ /**
+ * Evaluate problem severity from the given details:
+ * @param requiredBits null tagBits of the required type
+ * @param providedBits null tagBits of the provided type
+ * @param nullStatus -1 means: don't use, other values see constants in FlowInfo
+ * @param overrideDetailChecking true enables strictest mode during override analysis when checking type details (type argument, array content)
+ * @return see {@link #severity} for interpretation of values
+ */
+ private static int computeNullProblemSeverity(long requiredBits, long providedBits, int nullStatus, boolean overrideDetailChecking) {
+ // nullStatus:
+ // overrideDetailChecking:
+ if ((requiredBits != 0 || overrideDetailChecking) && requiredBits != providedBits) {
if (requiredBits == TagBits.AnnotationNonNull && nullStatus == FlowInfo.NON_NULL) {
return 0; // OK by flow analysis
}
if (requiredBits == TagBits.AnnotationNullMASK)
return 0; // OK since LHS accepts either
+ if (nullStatus != -1 && !overrideDetailChecking && requiredBits == TagBits.AnnotationNullable)
+ return 0; // when using flow info, everything is compatible to nullable
if (providedBits != 0) {
return 2; // mismatching annotations
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
index c650029bb..218cdddd4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -13,9 +13,10 @@
* bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
* bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
- * Bug 416181 – [1.8][compiler][null] Invalid assignment is not rejected by the compiler
+ * Bug 416181 - [1.8][compiler][null] Invalid assignment is not rejected by the compiler
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 434600 - Incorrect null analysis error reporting on type parameters
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Andy Clement - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
@@ -116,6 +117,24 @@ public class ParameterizedQualifiedTypeReference extends ArrayQualifiedTypeRefer
return true;
}
+ @Override
+ public boolean hasNullTypeAnnotation() {
+ if (super.hasNullTypeAnnotation())
+ return true;
+ if (this.resolvedType != null && !this.resolvedType.hasNullTypeAnnotations())
+ return false; // shortcut
+ if (this.typeArguments != null) {
+ for (int i = 0; i < this.typeArguments.length; i++) {
+ TypeReference[] arguments = this.typeArguments[i];
+ for (int j = 0; j < arguments.length; j++) {
+ if (arguments[i].hasNullTypeAnnotation())
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* @return char[][]
*/
@@ -341,7 +360,7 @@ public class ParameterizedQualifiedTypeReference extends ArrayQualifiedTypeRefer
if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this))
return null;
if (currentOriginal.isGenericType()) {
- if (typeIsConsistent && qualifyingType != null && qualifyingType.isParameterizedType()) {
+ if (typeIsConsistent && qualifyingType != null && qualifyingType.isParameterizedType() && !currentOriginal.isStatic()) {
scope.problemReporter().parameterizedMemberTypeMissingArguments(this, scope.environment().createParameterizedType(currentOriginal, null, qualifyingType), i);
typeIsConsistent = false;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
index d9e4fd121..93fac3cc0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -16,6 +16,7 @@
* Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 434600 - Incorrect null analysis error reporting on type parameters
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Andy Clement - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
@@ -165,6 +166,21 @@ public class ParameterizedSingleTypeReference extends ArrayTypeReference {
return true;
}
+ @Override
+ public boolean hasNullTypeAnnotation() {
+ if (super.hasNullTypeAnnotation())
+ return true;
+ if (this.resolvedType != null && !this.resolvedType.hasNullTypeAnnotations())
+ return false; // shortcut
+ if (this.typeArguments != null) {
+ for (int i = 0; i < this.typeArguments.length; i++) {
+ if (this.typeArguments[i].hasNullTypeAnnotation())
+ return true;
+ }
+ }
+ return false;
+ }
+
/*
* No need to check for reference to raw type per construction
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index a2ab15d3b..9e7c2a074 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -333,7 +333,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
// perform some extra emulation work in case there is some and we are inside a local type only
if (allocatedTypeErasure.isNestedType()
- && currentScope.enclosingSourceType().isLocalType()) {
+ && (currentScope.enclosingSourceType().isLocalType() || currentScope.isLambdaScope())) {
if (allocatedTypeErasure.isLocalType()) {
((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, this.enclosingInstance != null);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
index 51a63781e..9ce03b569 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -26,6 +26,9 @@
* Bug 428264 - [1.8] method reference of generic class causes problems (wrong inference result or NPE)
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
* Bug 426537 - [1.8][inference] Eclipse compiler thinks I<? super J> is compatible with I<J<?>> - raw type J involved
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
+ * Bug 435689 - [1.8][inference] Type inference not occurring with lambda expression and method reference
+ * Bug 438383 - [1.8][null] Bogus warning: Null type safety at method return type
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contribution for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*******************************************************************************/
@@ -385,9 +388,10 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.resolvedType = null;
}
+ if (lhsType != null && !lhsType.isRawType()) // RawType::m and RawType::new are not exact method references
+ this.exactMethodBinding = isMethodReference() ? scope.getExactMethod(lhsType, this.selector, this) : scope.getExactConstructor(lhsType, this);
+
if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
- if (lhsType != null && !lhsType.isRawType()) // RawType::m and RawType::new are not exact method references
- this.exactMethodBinding = isMethodReference() ? scope.getExactMethod(lhsType, this.selector, this) : scope.getExactConstructor(lhsType, this);
return new PolyTypeBinding(this);
}
super.resolveType(scope);
@@ -409,7 +413,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.resolvedType = null;
}
- if (this.lhs instanceof TypeReference && lhsType.hasNullTypeAnnotations()) {
+ if (this.lhs instanceof TypeReference && ((TypeReference)this.lhs).hasNullTypeAnnotation()) {
scope.problemReporter().nullAnnotationUnsupportedLocation((TypeReference) this.lhs);
}
@@ -602,7 +606,8 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
scope.problemReporter().referenceExpressionArgumentNullityMismatch(this, bindingParameter, descriptorParameter, this.descriptor, i, annotationStatus);
}
}
- if ((this.descriptor.returnType.tagBits & TagBits.AnnotationNonNull) != 0) {
+ if (!this.binding.isConstructor() && (this.descriptor.returnType.tagBits & TagBits.AnnotationNonNull) != 0) {
+ // since constructors never return null we don't have to check those anyway.
if ((this.binding.returnType.tagBits & TagBits.AnnotationNonNull) == 0) {
char[][] providedAnnotationName = ((this.binding.returnType.tagBits & TagBits.AnnotationNullable) != 0) ?
scope.environment().getNullableAnnotationName() : null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 1bdffbcd3..e4ca0bc35 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -1175,6 +1175,8 @@ protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes
int totalCount = 0;
ReferenceBinding[][] allExceptionTypes = new ReferenceBinding[length][];
for (int i = 0; i < length; i++) {
+ if (argumentTypes[i] instanceof ArrayBinding)
+ continue;
ReferenceBinding currentExceptionType = (ReferenceBinding) argumentTypes[i];
TypeReference catchArgumentType = this.catchArguments[i].type;
if ((catchArgumentType.bits & ASTNode.IsUnionType) != 0) {
@@ -1195,6 +1197,7 @@ protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes
this.caughtExceptionsCatchBlocks = new int[totalCount];
for (int i = 0, l = 0; i < length; i++) {
ReferenceBinding[] currentExceptions = allExceptionTypes[i];
+ if (currentExceptions == null) continue;
loop: for (int j = 0, max = currentExceptions.length; j < max; j++) {
ReferenceBinding exception = currentExceptions[j];
this.caughtExceptionTypes[l] = exception;
@@ -1202,6 +1205,7 @@ protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes
// now iterate over all previous exceptions
for (int k = 0; k < i; k++) {
ReferenceBinding[] exceptions = allExceptionTypes[k];
+ if (exceptions == null) continue;
for (int n = 0, max2 = exceptions.length; n < max2; n++) {
ReferenceBinding currentException = exceptions[n];
if (exception.isCompatibleWith(currentException)) {
@@ -1222,6 +1226,8 @@ protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes
} else {
this.caughtExceptionTypes = new ReferenceBinding[length];
for (int i = 0; i < length; i++) {
+ if (argumentTypes[i] instanceof ArrayBinding)
+ continue;
this.caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i];
for (int j = 0; j < i; j++) {
if (this.caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 6f27fb007..998bcdeda 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -1406,8 +1406,8 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl
ReferenceBinding superclassBinding = (ReferenceBinding)nestedType.superclass.erasure();
if (superclassBinding.enclosingType() != null && !superclassBinding.isStatic()) {
if (!superclassBinding.isLocalType()
- || ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null){
-
+ || ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null
+ || superclassBinding.isMemberType()){
nestedType.addSyntheticArgument(superclassBinding.enclosingType());
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 5e96f02bf..3b974833a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -20,6 +20,9 @@
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
* 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 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
* Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
@@ -803,12 +806,16 @@ protected void resolveAnnotations(Scope scope, int location) {
&& (this.resolvedType.tagBits & TagBits.AnnotationNullMASK) == 0
&& !this.resolvedType.isTypeVariable()
&& !this.resolvedType.isWildcard()
- && location != 0
+ && location != 0
&& scope.hasDefaultNullnessFor(location))
{
- LookupEnvironment environment = scope.environment();
- AnnotationBinding[] annots = new AnnotationBinding[]{environment.getNonNullAnnotation()};
- this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots);
+ if (location == Binding.DefaultLocationTypeBound && this.resolvedType.id == TypeIds.T_JavaLangObject) {
+ scope.problemReporter().implicitObjectBoundNoNullDefault(this);
+ } else {
+ LookupEnvironment environment = scope.environment();
+ AnnotationBinding[] annots = new AnnotationBinding[]{environment.getNonNullAnnotation()};
+ this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots);
+ }
}
}
public int getAnnotatableLevels() {
@@ -824,12 +831,12 @@ protected void checkNullConstraints(Scope scope, TypeReference[] typeArguments)
TypeVariableBinding[] typeVariables = this.resolvedType.original().typeVariables();
for (int i = 0; i < typeArguments.length; i++) {
TypeReference arg = typeArguments[i];
- if (arg.resolvedType != null && arg.resolvedType.hasNullTypeAnnotations())
+ if (arg.resolvedType != null)
arg.checkNullConstraints(scope, typeVariables, i);
}
}
}
-/** Check whether this type reference conforms to all null constraints defined for any of the given type variables. */
+/** Check whether this type reference conforms to the null constraints defined for the corresponding type variable. */
protected void checkNullConstraints(Scope scope, TypeBinding[] variables, int rank) {
if (variables != null && variables.length > rank) {
TypeBinding variable = variables[rank];
@@ -855,6 +862,26 @@ public Annotation findAnnotation(long nullTagBits) {
}
return null;
}
+public boolean hasNullTypeAnnotation() {
+ if (this.annotations != null) {
+ Annotation[] innerAnnotations = this.annotations[this.annotations.length-1];
+ if (containsNullAnnotation(innerAnnotations))
+ return true;
+ }
+ return false;
+}
+public static boolean containsNullAnnotation(Annotation[] annotations) {
+ if (annotations != null) {
+ for (int i = 0; i < annotations.length; i++) {
+ if (annotations[i] != null
+ && annotations[i].resolvedType != null
+ && (annotations[i].resolvedType.id == TypeIds.T_ConfiguredAnnotationNonNull
+ || annotations[i].resolvedType.id == TypeIds.T_ConfiguredAnnotationNullable))
+ return true;
+ }
+ }
+ return false;
+}
public TypeReference[] getTypeReferences() {
return new TypeReference [] { this };
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
index 7f908cc37..adb00abf1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
@@ -13,6 +13,7 @@
* Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
+ * Bug 440462 - [null][compiler]NPE in EJC for erroneous null annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -75,7 +76,13 @@ public class Wildcard extends SingleTypeReference {
if (boundType != null && boundType.hasNullTypeAnnotations() && this.resolvedType.hasNullTypeAnnotations()) {
if (((boundType.tagBits | this.resolvedType.tagBits) & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) { // are both set?
Annotation annotation = this.bound.findAnnotation(boundType.tagBits & TagBits.AnnotationNullMASK);
- scope.problemReporter().contradictoryNullAnnotationsOnBounds(annotation, this.resolvedType.tagBits);
+ if (annotation == null) { // false alarm, implicit annotation is no conflict, but should be removed:
+ TypeBinding newBound = boundType.unannotated(true);
+ ((WildcardBinding)this.resolvedType).bound = newBound;
+ this.bound.resolvedType = newBound;
+ } else {
+ scope.problemReporter().contradictoryNullAnnotationsOnBounds(annotation, this.resolvedType.tagBits);
+ }
}
}
return this.resolvedType;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
index fd8105b6b..cac02c8e7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/NonNullDefaultAwareTypeAnnotationWalker.java
@@ -16,6 +16,7 @@ import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
/**
* A type annotation walker that adds missing NonNull annotations according to the current default.
@@ -25,6 +26,8 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
private int defaultNullness;
private boolean atDefaultLocation;
private boolean nextIsDefaultLocation;
+ private boolean atTypeBound;
+ private boolean nextIsTypeBound;
private boolean isEmpty;
IBinaryAnnotation nonNullAnnotation;
@@ -38,24 +41,26 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
/** Create an initial walker without 'real' type annotations, but with a nonnull default. */
public NonNullDefaultAwareTypeAnnotationWalker(int defaultNullness, LookupEnvironment environment) {
- this(defaultNullness, getNonNullAnnotation(environment), false);
+ this(defaultNullness, getNonNullAnnotation(environment), false, false);
}
/** Get restricted walker, still with non-empty type annotations. */
NonNullDefaultAwareTypeAnnotationWalker(IBinaryTypeAnnotation[] typeAnnotations, long newMatches, int newPathPtr,
- int defaultNullness, IBinaryAnnotation nonNullAnnotation, boolean atDefaultLocation) {
+ int defaultNullness, IBinaryAnnotation nonNullAnnotation, boolean atDefaultLocation, boolean atTypeBound) {
super(typeAnnotations, newMatches, newPathPtr);
this.defaultNullness = defaultNullness;
this.nonNullAnnotation = nonNullAnnotation;
this.atDefaultLocation = atDefaultLocation;
+ this.atTypeBound = atTypeBound;
}
/** Create a restricted walker without 'real' type annotations, but with a nonnull default. */
- NonNullDefaultAwareTypeAnnotationWalker(int defaultNullness, IBinaryAnnotation nonNullAnnotation, boolean atDefaultLocation) {
+ NonNullDefaultAwareTypeAnnotationWalker(int defaultNullness, IBinaryAnnotation nonNullAnnotation, boolean atDefaultLocation, boolean atTypeBound) {
super(null, 0, 0);
this.nonNullAnnotation = nonNullAnnotation;
this.defaultNullness = defaultNullness;
this.atDefaultLocation = atDefaultLocation;
+ this.atTypeBound = atTypeBound;
this.isEmpty = true;
}
@@ -79,16 +84,19 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
// considers nextIsDefaultLocation as the new atDefaultLocation
try {
// do we have any change at all?
- if (this.matches == newMatches && this.pathPtr == newPathPtr && this.atDefaultLocation == this.nextIsDefaultLocation)
+ if (this.matches == newMatches && this.pathPtr == newPathPtr
+ && this.atDefaultLocation == this.nextIsDefaultLocation && this.atTypeBound == this.nextIsTypeBound)
return this;
// are we running out of real type annotations?
if (newMatches == 0 || this.typeAnnotations == null || this.typeAnnotations.length == 0)
- return new NonNullDefaultAwareTypeAnnotationWalker(this.defaultNullness, this.nonNullAnnotation, this.nextIsDefaultLocation);
+ return new NonNullDefaultAwareTypeAnnotationWalker(this.defaultNullness, this.nonNullAnnotation,
+ this.nextIsDefaultLocation, this.nextIsTypeBound);
// proceed as normal, but pass on our specific fields, too:
return new NonNullDefaultAwareTypeAnnotationWalker(this.typeAnnotations, newMatches, newPathPtr,
- this.defaultNullness, this.nonNullAnnotation, this.nextIsDefaultLocation);
+ this.defaultNullness, this.nonNullAnnotation, this.nextIsDefaultLocation, this.nextIsTypeBound);
} finally {
this.nextIsDefaultLocation = false; // expire
+ this.nextIsTypeBound = false;
}
}
@@ -109,6 +117,7 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
@Override
public TypeAnnotationWalker toTypeBound(short boundIndex) {
this.nextIsDefaultLocation = (this.defaultNullness & Binding.DefaultLocationTypeBound) != 0;
+ this.nextIsTypeBound = true;
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toTypeBound(boundIndex);
}
@@ -116,6 +125,7 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
@Override
public TypeAnnotationWalker toTypeParameterBounds(boolean isClassTypeParameter, int parameterRank) {
this.nextIsDefaultLocation = (this.defaultNullness & Binding.DefaultLocationTypeBound) != 0;
+ this.nextIsTypeBound = true;
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toTypeParameterBounds(isClassTypeParameter, parameterRank);
}
@@ -123,6 +133,7 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
@Override
public TypeAnnotationWalker toTypeArgument(int rank) {
this.nextIsDefaultLocation = (this.defaultNullness & Binding.DefaultLocationTypeArgument) != 0;
+ this.nextIsTypeBound = false;
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toTypeArgument(rank);
}
@@ -130,14 +141,17 @@ public class NonNullDefaultAwareTypeAnnotationWalker extends TypeAnnotationWalke
@Override
public TypeAnnotationWalker toTypeParameter(boolean isClassTypeParameter, int rank) {
this.nextIsDefaultLocation = (this.defaultNullness & Binding.DefaultLocationTypeParameter) != 0;
+ this.nextIsTypeBound = false;
if (this.isEmpty) return restrict(this.matches, this.pathPtr);
return super.toTypeParameter(isClassTypeParameter, rank);
}
@Override
- public IBinaryAnnotation[] getAnnotationsAtCursor() {
- IBinaryAnnotation[] normalAnnotations = this.isEmpty ? null : super.getAnnotationsAtCursor();
- if (this.atDefaultLocation) {
+ public IBinaryAnnotation[] getAnnotationsAtCursor(int currentTypeId) {
+ IBinaryAnnotation[] normalAnnotations = this.isEmpty ? null : super.getAnnotationsAtCursor(currentTypeId);
+ if (this.atDefaultLocation &&
+ !(this.atTypeBound && currentTypeId == TypeIds.T_JavaLangObject)) // for CLIMB-to-top consider a j.l.Object type bound as no explicit type bound
+ {
if (normalAnnotations == null || normalAnnotations.length == 0)
return new IBinaryAnnotation[] { this.nonNullAnnotation };
int len = normalAnnotations.length;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationWalker.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationWalker.java
index 9f189b7cf..3e525b787 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationWalker.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationWalker.java
@@ -41,7 +41,7 @@ public class TypeAnnotationWalker {
public TypeAnnotationWalker toTypeBound(short boundIndex) { return this; }
public TypeAnnotationWalker toTypeParameter(boolean isClassTypeParameter, int rank) { return this; }
public TypeAnnotationWalker toNextDetail(int detailKind) { return this; }
- public IBinaryAnnotation[] getAnnotationsAtCursor() { return NO_ANNOTATIONS; }
+ public IBinaryAnnotation[] getAnnotationsAtCursor(int currentTypeId) { return NO_ANNOTATIONS; }
};
final protected IBinaryTypeAnnotation[] typeAnnotations; // the actual material we're managing here
@@ -298,7 +298,7 @@ public class TypeAnnotationWalker {
* Retrieve the type annotations at the current position
* reached by invocations of toXYZ() methods.
*/
- public IBinaryAnnotation[] getAnnotationsAtCursor() {
+ public IBinaryAnnotation[] getAnnotationsAtCursor(int currentTypeId) {
int length = this.typeAnnotations.length;
IBinaryAnnotation[] filtered = new IBinaryAnnotation[length];
long ptr = 1;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index a09369de7..bcd345fa4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -14,6 +14,7 @@
* Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
* Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
* Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ * Bug 439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization"
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
@@ -786,6 +787,7 @@ public class ConstantPool implements ClassFileConstants, TypeIds {
isInterface ? binding.isStatic() ? MethodHandleRefKindInvokeStatic : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial : MethodHandleRefKindInvokeInterface
: binding.isConstructor() ? MethodHandleRefKindNewInvokeSpecial
: binding.isStatic() ? MethodHandleRefKindInvokeStatic
+ : binding.isPrivate() ? MethodHandleRefKindInvokeSpecial
: MethodHandleRefKindInvokeVirtual;
return literalIndexForMethodHandle(referenceKind, binding.declaringClass, binding.selector, binding.signature(), isInterface);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index e2cd3329d..5d652aa0c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -21,6 +21,8 @@
* Bug 425460 - [1.8] [inference] Type not inferred on stream.toArray
* Bug 426792 - [1.8][inference][impl] generify new type inference engine
* Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -476,8 +478,17 @@ public TypeBinding maybeWrapRoleType(ASTNode typedNode, TypeArgumentUpdater upda
public String toString() {
return this.leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
}
-public TypeBinding unannotated() {
- return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (!hasTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations) {
+ if (!hasNullTypeAnnotations())
+ return this;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createArrayType(this.leafComponentType.unannotated(false), this.dimensions, newAnnotations);
+ }
+ return this.environment.getUnannotatedType(this);
}
@Override
public TypeBinding uncapture(Scope scope) {
@@ -486,5 +497,8 @@ public TypeBinding uncapture(Scope scope) {
TypeBinding leafType = this.leafComponentType.uncapture(scope);
return scope.environment().createArrayType(leafType, this.dimensions, this.typeAnnotations);
}
-
+@Override
+public boolean acceptsNonNullDefault() {
+ return true;
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
index 6e0bd31fe..aad394b07 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -10,6 +10,7 @@
* Stephan Herrmann - Contribution for
* bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -172,7 +173,7 @@ public class BaseTypeBinding extends TypeBinding {
super.setTypeAnnotations(annotations, false); // never set nullTagBits on base types
}
- public TypeBinding unannotated() {
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
if (!this.hasTypeAnnotations())
return this;
switch (this.id) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 8c7f6feb6..87c7cf542 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -28,6 +28,9 @@
* Bug 392245 - [1.8][compiler][null] Define whether / how @NonNullByDefault applies to TYPE_USE locations
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
+ * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
* Jesper Steen Moller - Contributions for
* Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing
* Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -1003,7 +1006,7 @@ private MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[
? new MethodBinding(methodModifiers, parameters, exceptions, this)
: new MethodBinding(methodModifiers, method.getSelector(), returnType, parameters, exceptions, this);
- IBinaryAnnotation[] receiverAnnotations = walker.toReceiver().getAnnotationsAtCursor();
+ IBinaryAnnotation[] receiverAnnotations = walker.toReceiver().getAnnotationsAtCursor(0);
if (receiverAnnotations != null && receiverAnnotations.length > 0) {
result.receiver = this.environment.createAnnotatedType(this, createAnnotations(receiverAnnotations, this.environment, missingTypeNames));
}
@@ -1012,7 +1015,7 @@ private MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[
IBinaryAnnotation[] annotations = method.getAnnotations();
if (annotations == null || annotations.length == 0)
if (method.isConstructor())
- annotations = walker.toMethodReturn().getAnnotationsAtCursor(); // FIXME: When both exist, order could become an issue.
+ annotations = walker.toMethodReturn().getAnnotationsAtCursor(0); // FIXME: When both exist, order could become an issue.
result.setAnnotations(
createAnnotations(annotations, this.environment, missingTypeNames),
paramAnnotations,
@@ -1025,9 +1028,9 @@ private MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[
if (use15specifics)
result.tagBits |= method.getTagBits();
result.typeVariables = typeVars;
- // fixup the declaring element of the type variable
+ // fixup the declaring element of all type variables
for (int i = 0, length = typeVars.length; i < length; i++)
- typeVars[i].declaringElement = result;
+ this.environment.typeSystem.fixTypeVariableDeclaringElement(typeVars[i], result);
//{ObjectTeams:
// transfer "callsBaseCtor":
if (method instanceof MethodInfo && ((MethodInfo)method).callsBaseCtor()) {
@@ -1190,7 +1193,7 @@ private TypeVariableBinding[] createTypeVariables(SignatureWrapper wrapper, bool
int colon = CharOperation.indexOf(Util.C_COLON, typeSignature, i);
char[] variableName = CharOperation.subarray(typeSignature, i, colon);
TypeVariableBinding typeVariable = new TypeVariableBinding(variableName, this, rank, this.environment);
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.toTypeParameter(isClassTypeParameter, rank++).getAnnotationsAtCursor(),
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.toTypeParameter(isClassTypeParameter, rank++).getAnnotationsAtCursor(0),
this.environment, missingTypeNames);
if (annotations != null && annotations != Binding.NO_ANNOTATIONS)
typeVariable.setTypeAnnotations(annotations, this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled);
@@ -1892,6 +1895,12 @@ SimpleLookupTable storedAnnotations(boolean forceInitialize) {
//pre: null annotation analysis is enabled
private void scanFieldForNullAnnotation(IBinaryField field, FieldBinding fieldBinding, boolean isEnum) {
if (!isPrototype()) throw new IllegalStateException();
+
+ if (isEnum && (field.getModifiers() & ClassFileConstants.AccEnum) != 0) {
+ fieldBinding.tagBits |= TagBits.AnnotationNonNull;
+ return; // we know it's nonnull, no need to look for null *annotations* on enum constants.
+ }
+
if (this.environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
TypeBinding fieldType = fieldBinding.type;
if (fieldType != null
@@ -1935,11 +1944,6 @@ private void scanFieldForNullAnnotation(IBinaryField field, FieldBinding fieldBi
if (!explicitNullness && (this.tagBits & TagBits.AnnotationNonNullByDefault) != 0) {
fieldBinding.tagBits |= TagBits.AnnotationNonNull;
}
- if (isEnum) {
- if ((field.getModifiers() & ClassFileConstants.AccEnum) != 0) {
- fieldBinding.tagBits |= TagBits.AnnotationNonNull;
- }
- }
}
private void scanMethodForNullAnnotation(IBinaryMethod method, MethodBinding methodBinding) {
@@ -2369,7 +2373,14 @@ public String toString() {
return buffer.toString();
}
-public TypeBinding unannotated() {
+public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (removeOnlyNullAnnotations) {
+ if (!hasNullTypeAnnotations())
+ return this;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(this.prototype, newAnnotations);
+ }
return this.prototype;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 8a88b1bf3..59506820f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -296,8 +296,12 @@ void computeLocalVariablePositions(int ilocal, int initOffset, CodeStream codeSt
// SH}
&& ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { // declaration is reachable
- if (!(local.declaration instanceof Argument)) // do not report unused catch arguments
+ if (local.isCatchParameter()) {
+ problemReporter().unusedExceptionParameter(local.declaration); // report unused catch arguments
+ }
+ else {
problemReporter().unusedLocalVariable(local.declaration);
+ }
}
// could be optimized out, but does need to preserve unread variables ?
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
index 24f9b2a07..d121d3edc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java
@@ -116,6 +116,7 @@ class BoundSet {
InferenceContext18.sortTypes(rights);
return rights;
}
+ // pre: beta is a prototype
public boolean hasDependency(InferenceVariable beta) {
if (this.superBounds != null && hasDependency(this.superBounds, beta))
return true;
@@ -131,11 +132,12 @@ class BoundSet {
}
return false;
}
+ // pre: var is a prototype
private boolean hasDependency(Set<TypeBound> someBounds, InferenceVariable var) {
Iterator<TypeBound> bIt = someBounds.iterator();
while (bIt.hasNext()) {
TypeBound bound = bIt.next();
- if (bound.right == var || bound.right.mentionsAny(new TypeBinding[] {var}, -1)) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(bound.right, var) || bound.right.mentionsAny(new TypeBinding[] {var}, -1))
return true;
}
return false;
@@ -236,7 +238,7 @@ class BoundSet {
if (nullHints == TagBits.AnnotationNullMASK) {
// on contradiction remove null type annotations
for (int i = 0; i < boundTypes.length; i++)
- boundTypes[i] = boundTypes[i].unannotated();
+ boundTypes[i] = boundTypes[i].unannotated(true);
} else {
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(nullHints);
if (annot != null) {
@@ -266,7 +268,7 @@ class BoundSet {
nullHints |= it.next().nullHints;
}
if (nullHints == TagBits.AnnotationNullMASK) // on contradiction remove null type annotations
- return type.unannotated();
+ return type.unannotated(true);
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(nullHints);
if (annot != null)
// only get here if exactly one of @NonNull or @Nullable was hinted; now apply this hint:
@@ -286,7 +288,7 @@ class BoundSet {
// adjust 'type' to fit the newBits
AnnotationBinding[] annot = environment.nullAnnotationsFromTagBits(newBits);
if (annot != null)
- type = environment.createAnnotatedType(type.unannotated(), annot);
+ type = environment.createAnnotatedType(type.unannotated(true), annot);
}
}
this.instantiation = type;
@@ -355,19 +357,20 @@ class BoundSet {
}
public void addBound(TypeBound bound, LookupEnvironment environment) {
- ThreeSets three = this.boundsPerVariable.get(bound.left);
+ InferenceVariable variable = bound.left.prototype();
+ ThreeSets three = this.boundsPerVariable.get(variable);
if (three == null)
- this.boundsPerVariable.put(bound.left, (three = new ThreeSets()));
+ this.boundsPerVariable.put(variable, (three = new ThreeSets()));
three.addBound(bound);
// check if this makes the inference variable instantiated:
TypeBinding typeBinding = bound.right;
if (bound.relation == ReductionResult.SAME && typeBinding.isProperType(true))
- three.setInstantiation(typeBinding, bound.left, environment);
+ three.setInstantiation(typeBinding, variable, environment);
if (bound.right instanceof InferenceVariable) {
// for a dependency between two IVs make a note about the inverse bound.
// this should be needed to determine IV dependencies independent of direction.
// TODO: so far no test could be identified which actually needs it ...
- InferenceVariable rightIV = (InferenceVariable) bound.right;
+ InferenceVariable rightIV = (InferenceVariable) bound.right.prototype();
three = this.boundsPerVariable.get(rightIV);
if (three == null)
this.boundsPerVariable.put(rightIV, (three = new ThreeSets()));
@@ -387,14 +390,14 @@ class BoundSet {
}
public boolean isInstantiated(InferenceVariable inferenceVariable) {
- ThreeSets three = this.boundsPerVariable.get(inferenceVariable);
+ ThreeSets three = this.boundsPerVariable.get(inferenceVariable.prototype());
if (three != null)
return three.instantiation != null;
return false;
}
public TypeBinding getInstantiation(InferenceVariable inferenceVariable, LookupEnvironment environment) {
- ThreeSets three = this.boundsPerVariable.get(inferenceVariable);
+ ThreeSets three = this.boundsPerVariable.get(inferenceVariable.prototype());
if (three != null) {
TypeBinding instantiation = three.instantiation;
if (environment != null && environment.globalOptions.isAnnotationBasedNullAnalysisEnabled
@@ -531,7 +534,7 @@ class BoundSet {
if (ai instanceof WildcardBinding) {
WildcardBinding wildcardBinding = (WildcardBinding)ai;
TypeBinding t = wildcardBinding.bound;
- ThreeSets three = this.boundsPerVariable.get(alpha);
+ ThreeSets three = this.boundsPerVariable.get(alpha.prototype());
if (three != null) {
Iterator<TypeBound> it;
if (three.sameBounds != null) {
@@ -617,7 +620,7 @@ class BoundSet {
private ConstraintTypeFormula combineSameSame(TypeBound boundS, TypeBound boundT) {
// α = S and α = T imply ⟨S = T⟩
- if (boundS.left == boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(boundS.left, boundT.left))
return ConstraintTypeFormula.create(boundS.right, boundT.right, ReductionResult.SAME, boundS.isSoft||boundT.isSoft);
// match against more shapes:
@@ -649,25 +652,25 @@ class BoundSet {
// α = S and T <: α imply ⟨T <: S⟩
InferenceVariable alpha = boundS.left;
TypeBinding s = boundS.right;
- if (alpha == boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha,boundT.left))
return ConstraintTypeFormula.create(s, boundT.right, boundT.relation, boundT.isSoft||boundS.isSoft);
- if (alpha == boundT.right) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha, boundT.right))
return ConstraintTypeFormula.create(boundT.right, s, boundT.relation, boundT.isSoft||boundS.isSoft);
if (boundS.right instanceof InferenceVariable) {
// reverse:
alpha = (InferenceVariable) boundS.right;
s = boundS.left;
- if (alpha == boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha, boundT.left))
return ConstraintTypeFormula.create(s, boundT.right, boundT.relation, boundT.isSoft||boundS.isSoft);
- if (alpha == boundT.right) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha, boundT.right))
return ConstraintTypeFormula.create(boundT.right, s, boundT.relation, boundT.isSoft||boundS.isSoft);
}
// α = U and S <: T imply ⟨S[α:=U] <: T[α:=U]⟩
TypeBinding u = boundS.right;
if (u.isProperType(true)) {
- TypeBinding left = (alpha == boundT.left) ? u : boundT.left; //$IDENTITY-COMPARISON$ InferenceVariable
+ TypeBinding left = (TypeBinding.equalsEquals(alpha, boundT.left)) ? u : boundT.left;
TypeBinding right = boundT.right.substituteInferenceVariable(alpha, u);
return ConstraintTypeFormula.create(left, right, boundT.relation, boundT.isSoft||boundS.isSoft);
}
@@ -677,13 +680,13 @@ class BoundSet {
private ConstraintTypeFormula combineSuperAndSub(TypeBound boundS, TypeBound boundT) {
// permutations of: S <: α and α <: T imply ⟨S <: T⟩
InferenceVariable alpha = boundS.left;
- if (alpha == boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha, boundT.left))
// α >: S and α <: T imply ⟨S <: T⟩
return ConstraintTypeFormula.create(boundS.right, boundT.right, ReductionResult.SUBTYPE, boundT.isSoft||boundS.isSoft);
if (boundS.right instanceof InferenceVariable) {
// try reverse:
alpha = (InferenceVariable) boundS.right;
- if (alpha == boundT.right) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(alpha, boundT.right))
// S :> α and T <: α imply ⟨S :> T⟩
return ConstraintTypeFormula.create(boundS.left, boundT.left, ReductionResult.SUPERTYPE, boundT.isSoft||boundS.isSoft);
}
@@ -692,10 +695,10 @@ class BoundSet {
private ConstraintTypeFormula combineEqualSupers(TypeBound boundS, TypeBound boundT) {
// more permutations of: S <: α and α <: T imply ⟨S <: T⟩
- if (boundS.left == boundT.right) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(boundS.left, boundT.right))
// came in as: α REL S and T REL α imply ⟨T REL S⟩
return ConstraintTypeFormula.create(boundT.left, boundS.right, boundS.relation, boundT.isSoft||boundS.isSoft);
- if (boundS.right == boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(boundS.right, boundT.left))
// came in as: S REL α and α REL T imply ⟨S REL T⟩
return ConstraintTypeFormula.create(boundS.left, boundT.right, boundS.relation, boundT.isSoft||boundS.isSoft);
return null;
@@ -710,7 +713,7 @@ class BoundSet {
*/
if (boundS.relation != ReductionResult.SUBTYPE || boundT.relation != ReductionResult.SUBTYPE)
return null;
- if (boundS.left != boundT.left) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.notEquals(boundS.left, boundT.left))
return null;
TypeBinding[] supers = superTypesWithCommonGenericType(boundS.right, boundT.right);
if (supers != null)
@@ -776,13 +779,15 @@ class BoundSet {
* Does this bound set define a direct dependency between the two given inference variables?
*/
public boolean dependsOnResolutionOf(InferenceVariable alpha, InferenceVariable beta) {
+ alpha = alpha.prototype();
+ beta = beta.prototype();
Iterator<Map.Entry<ParameterizedTypeBinding, ParameterizedTypeBinding>> captureIter = this.captures.entrySet().iterator();
boolean betaIsInCaptureLhs = false;
while (captureIter.hasNext()) { // TODO: optimization: consider separate index structure (by IV)
Entry<ParameterizedTypeBinding, ParameterizedTypeBinding> entry = captureIter.next();
ParameterizedTypeBinding g = entry.getKey();
for (int i = 0; i < g.arguments.length; i++) {
- if (g.arguments[i] == alpha) { //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(g.arguments[i], alpha)) {
// An inference variable α appearing on the left-hand side of a bound of the form G<..., α, ...> = capture(G<...>)
// depends on the resolution of every other inference variable mentioned in this bound (on both sides of the = sign).
ParameterizedTypeBinding captured = entry.getValue();
@@ -790,7 +795,7 @@ class BoundSet {
return true;
if (g.mentionsAny(new TypeBinding[]{beta}, i)) // exclude itself
return true;
- } else if (g.arguments[i] == beta) { //$IDENTITY-COMPARISON$ InferenceVariable
+ } else if (TypeBinding.equalsEquals(g.arguments[i], beta)) {
betaIsInCaptureLhs = true;
}
}
@@ -840,7 +845,7 @@ class BoundSet {
* Answer all upper bounds for the given inference variable as defined by any bounds in this set.
*/
public TypeBinding[] upperBounds(InferenceVariable variable, boolean onlyProper) {
- ThreeSets three = this.boundsPerVariable.get(variable);
+ ThreeSets three = this.boundsPerVariable.get(variable.prototype());
if (three == null || three.subBounds == null)
return Binding.NO_TYPES;
return three.upperBounds(onlyProper, variable);
@@ -853,7 +858,7 @@ class BoundSet {
* Answer all lower bounds for the given inference variable as defined by any bounds in this set.
*/
TypeBinding[] lowerBounds(InferenceVariable variable, boolean onlyProper) {
- ThreeSets three = this.boundsPerVariable.get(variable);
+ ThreeSets three = this.boundsPerVariable.get(variable.prototype());
if (three == null || three.superBounds == null)
return Binding.NO_TYPES;
return three.lowerBounds(onlyProper, variable);
@@ -881,7 +886,7 @@ class BoundSet {
}
public TypeBinding findWrapperTypeBound(InferenceVariable variable) {
- ThreeSets three = this.boundsPerVariable.get(variable);
+ ThreeSets three = this.boundsPerVariable.get(variable.prototype());
if (three == null) return null;
return three.findSingleWrapperType();
}
@@ -892,7 +897,7 @@ class BoundSet {
// i) B2 contains a bound of one of the forms α = S or S <: α, where S is a wildcard-parameterized type, or ...
if (targetType.isBaseType()) return false;
if (InferenceContext18.parameterizedWithWildcard(targetType) != null) return false;
- ThreeSets ts = this.boundsPerVariable.get(alpha);
+ ThreeSets ts = this.boundsPerVariable.get(alpha.prototype());
if (ts.sameBounds != null) {
Iterator<TypeBound> bounds = ts.sameBounds.iterator();
while (bounds.hasNext()) {
@@ -933,7 +938,7 @@ class BoundSet {
// where there exists no type of the form G<...> that is a supertype of S, but the raw type G is a supertype of S.
if (!targetType.isParameterizedType()) return false;
TypeBinding g = targetType.original();
- ThreeSets ts = this.boundsPerVariable.get(alpha);
+ ThreeSets ts = this.boundsPerVariable.get(alpha.prototype());
Iterator<TypeBound> boundIterator;
if (ts.sameBounds != null) {
boundIterator = ts.sameBounds.iterator();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
index a64e7ebad..c3c30a220 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -11,7 +11,6 @@
* Stephan Herrmann - Contribution for
* Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
* Bug 429384 - [1.8][null] implement conformance rules for null-annotated lower / upper type bounds
- * Bug 434044 - Java 8 generics thinks single method is ambiguous
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -198,14 +197,8 @@ public class CaptureBinding extends TypeVariableBinding {
} else {
int length = substitutedVariableInterfaces.length;
System.arraycopy(substitutedVariableInterfaces, 0, substitutedVariableInterfaces = new ReferenceBinding[length+1], 1, length);
- // to properly support glb, perform capture *after* glb, so restart from the original bound:
- substitutedVariableInterfaces[0] = (ReferenceBinding) originalWildcardBound;
- ReferenceBinding[] glb = Scope.greaterLowerBound(substitutedVariableInterfaces);
- if (glb != null) {
- for (int i = 0; i < glb.length; i++)
- glb[i] = (ReferenceBinding) glb[i].capture(scope, this.position);
- }
- this.setSuperInterfaces(glb);
+ substitutedVariableInterfaces[0] = (ReferenceBinding) capturedWildcardBound;
+ this.setSuperInterfaces(Scope.greaterLowerBound(substitutedVariableInterfaces));
}
} else {
// the wildcard bound should be a subtype of variable superclass
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
index 499021160..00bf7252d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExceptionFormula.java
@@ -104,7 +104,7 @@ public class ConstraintExceptionFormula extends ConstraintFormula {
result.add(ConstraintTypeFormula.create(ePrime[i], e[j], SUBTYPE));
}
for (int j = 0; j < n; j++)
- inferenceContext.currentBounds.inThrows.add(e[j]);
+ inferenceContext.currentBounds.inThrows.add(e[j].prototype());
return result.toArray(new ConstraintFormula[result.size()]);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index 7b40ba482..f8f3f81e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -435,7 +435,8 @@ class ConstraintExpressionFormula extends ConstraintFormula {
if (sam.returnType != TypeBinding.VOID) {
// ii)
final TypeBinding r = sam.returnType;
- Statement body = lambda.body();
+ LambdaExpression resolved = lambda.getResolvedCopyForInferenceTargeting(this.right);
+ Statement body = resolved != null ? resolved.body() : lambda.body();
if (body instanceof Expression) {
variables.addAll(new ConstraintExpressionFormula((Expression) body, r, COMPATIBLE).inputVariables(context));
} else {
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 c97efeaa0..8b6b04496 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
@@ -84,8 +84,11 @@ public class ImplicitNullAnnotationVerifier {
return;
// SH}
long sourceLevel = scope.compilerOptions().sourceLevel;
- boolean needToApplyNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter|Binding.DefaultLocationReturnType,
- sourceLevel >= ClassFileConstants.JDK1_8);
+ boolean needToApplyReturnNonNullDefault =
+ currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationReturnType, sourceLevel >= ClassFileConstants.JDK1_8);
+ boolean needToApplyParameterNonNullDefault =
+ currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter, sourceLevel >= ClassFileConstants.JDK1_8);
+ boolean needToApplyNonNullDefault = needToApplyReturnNonNullDefault | needToApplyParameterNonNullDefault;
// compatibility & inheritance do not consider constructors / static methods:
boolean isInstanceMethod = !currentMethod.isConstructor() && !currentMethod.isStatic();
complain &= isInstanceMethod;
@@ -118,7 +121,7 @@ public class ImplicitNullAnnotationVerifier {
// recurse to prepare currentSuper
checkImplicitNullAnnotations(currentSuper, null, false, scope); // TODO (stephan) complain=true if currentSuper is source method??
}
- checkNullSpecInheritance(currentMethod, srcMethod, needToApplyNonNullDefault, complain, currentSuper, scope, inheritedNonNullnessInfos);
+ checkNullSpecInheritance(currentMethod, srcMethod, needToApplyReturnNonNullDefault, needToApplyParameterNonNullDefault, complain, currentSuper, scope, inheritedNonNullnessInfos);
needToApplyNonNullDefault = false;
}
@@ -218,7 +221,8 @@ public class ImplicitNullAnnotationVerifier {
* The main algorithm in this class.
* @param currentMethod focus method
* @param srcMethod AST of 'currentMethod' if present
- * @param hasNonNullDefault is a @NonNull default applicable at the site of currentMethod?
+ * @param hasReturnNonNullDefault is a @NonNull default applicable for the return type of currentMethod?
+ * @param hasParameterNonNullDefault is a @NonNull default applicable for parameters of currentMethod?
* @param shouldComplain should we report any errors found?
* (see also comment about flows into this method, below).
* @param inheritedMethod one overridden method from a super type
@@ -228,7 +232,7 @@ public class ImplicitNullAnnotationVerifier {
* Index position 0 is used for the return type, positions i+1 for argument i.
*/
void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod,
- boolean hasNonNullDefault, boolean shouldComplain,
+ boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean shouldComplain,
MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
{
// Note that basically two different flows lead into this method:
@@ -259,7 +263,7 @@ public class ImplicitNullAnnotationVerifier {
// unspecified, may fill in either from super or from default
if (shouldInherit) {
if (inheritedNullnessBits != 0) {
- if (hasNonNullDefault) {
+ if (hasReturnNonNullDefault) {
// both inheritance and default: check for conflict?
if (shouldComplain && inheritedNullnessBits == TagBits.AnnotationNullable)
scope.problemReporter().conflictingNullAnnotations(currentMethod, ((MethodDeclaration) srcMethod).returnType, inheritedMethod);
@@ -275,7 +279,7 @@ public class ImplicitNullAnnotationVerifier {
break returnType; // compatible by construction, skip complain phase below
}
}
- if (hasNonNullDefault) { // conflict with inheritance already checked
+ if (hasReturnNonNullDefault && currentMethod.returnType.acceptsNonNullDefault()) { // conflict with inheritance already checked
currentNullnessBits = TagBits.AnnotationNonNull;
applyReturnNullBits(currentMethod, currentNullnessBits);
}
@@ -301,7 +305,10 @@ public class ImplicitNullAnnotationVerifier {
substituteReturnType = substitute.returnType;
}
if (NullAnnotationMatching.analyse(inheritedMethod.returnType, currentMethod.returnType, substituteReturnType, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
+ if (srcMethod != null)
+ scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod, null);
+ else
+ scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, useTypeAnnotations);
return;
}
}
@@ -342,7 +349,7 @@ public class ImplicitNullAnnotationVerifier {
// unspecified, may fill in either from super or from default
if (inheritedNonNullNess != null) {
if (shouldInherit) {
- if (hasNonNullDefault) {
+ if (hasParameterNonNullDefault) {
// both inheritance and default: check for conflict?
if (shouldComplain
&& inheritedNonNullNess == Boolean.FALSE
@@ -365,12 +372,14 @@ public class ImplicitNullAnnotationVerifier {
continue; // compatible by construction, skip complain phase below
}
}
- if (hasNonNullDefault) { // conflict with inheritance already checked
+ if (hasParameterNonNullDefault) { // conflict with inheritance already checked
currentNonNullNess = Boolean.TRUE;
if (!useTypeAnnotations)
recordArgNonNullness(currentMethod, length, i, currentArgument, Boolean.TRUE);
- else
+ else if (currentMethod.parameters[i].acceptsNonNullDefault())
recordArgNonNullness18(currentMethod, i, currentArgument, Boolean.TRUE, this.environment);
+ else
+ currentNonNullNess = null; // cancel if parameter doesn't accept the default
}
}
if (shouldComplain) {
@@ -416,9 +425,13 @@ public class ImplicitNullAnnotationVerifier {
}
}
if (useTypeAnnotations) {
+ TypeBinding inheritedParameter = inheritedMethod.parameters[i];
TypeBinding substituteParameter = substituteParameters != null ? substituteParameters[i] : null;
- if (NullAnnotationMatching.analyse(currentMethod.parameters[i], inheritedMethod.parameters[i], substituteParameter, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
- scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
+ if (NullAnnotationMatching.analyse(currentMethod.parameters[i], inheritedParameter, substituteParameter, 0, CheckMode.OVERRIDE).isAnyMismatch()) {
+ if (currentArgument != null)
+ scope.problemReporter().illegalParameterRedefinition(currentArgument, inheritedMethod.declaringClass, inheritedParameter);
+ else
+ scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod, false);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index a0df8bcb7..5d01de1a2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -292,7 +292,8 @@ public class InferenceContext18 {
}
}
if (checkVararg && varArgsType instanceof ArrayBinding) {
- TypeBinding thetaF = substitute(((ArrayBinding) varArgsType).elementsType());
+ varArgsType = ((ArrayBinding)varArgsType).elementsType();
+ TypeBinding thetaF = substitute(varArgsType);
for (int i = len; i < this.invocationArguments.length; i++) {
if (this.invocationArguments[i].isPertinentToApplicability(varArgsType, method)) {
this.initialConstraints[numConstraints++] = new ConstraintExpressionFormula(this.invocationArguments[i], thetaF, ReductionResult.COMPATIBLE, ARGUMENT_CONSTRAINTS_ARE_SOFT);
@@ -330,22 +331,26 @@ public class InferenceContext18 {
public InferenceVariable[] addTypeVariableSubstitutions(TypeBinding[] typeVariables) {
int len2 = typeVariables.length;
InferenceVariable[] newVariables = new InferenceVariable[len2];
+ InferenceVariable[] toAdd = new InferenceVariable[len2];
+ int numToAdd = 0;
for (int i = 0; i < typeVariables.length; i++) {
if (typeVariables[i] instanceof InferenceVariable)
newVariables[i] = (InferenceVariable) typeVariables[i]; // prevent double substitution of an already-substituted inferenceVariable
else
- newVariables[i] = new InferenceVariable(typeVariables[i], this.variableCount++, this.currentInvocation, this.environment, this.object);
+ toAdd[numToAdd++] =
+ newVariables[i] = new InferenceVariable(typeVariables[i], this.variableCount++, this.currentInvocation, this.environment, this.object);
}
-
- int start = 0;
- if (this.inferenceVariables != null) {
- int len1 = this.inferenceVariables.length;
- System.arraycopy(this.inferenceVariables, 0, this.inferenceVariables = new InferenceVariable[len1+len2], 0, len1);
- start = len1;
- } else {
- this.inferenceVariables = new InferenceVariable[len2];
+ if (numToAdd > 0) {
+ int start = 0;
+ if (this.inferenceVariables != null) {
+ int len1 = this.inferenceVariables.length;
+ System.arraycopy(this.inferenceVariables, 0, this.inferenceVariables = new InferenceVariable[len1+numToAdd], 0, len1);
+ start = len1;
+ } else {
+ this.inferenceVariables = new InferenceVariable[numToAdd];
+ }
+ System.arraycopy(toAdd, 0, this.inferenceVariables, start, numToAdd);
}
- System.arraycopy(newVariables, 0, this.inferenceVariables, start, len2);
return newVariables;
}
@@ -355,7 +360,7 @@ public class InferenceContext18 {
TypeBinding parameter = parameters[i];
for (int j = 0; j < thrownExceptions.length; j++) {
if (TypeBinding.equalsEquals(parameter, thrownExceptions[j])) {
- this.currentBounds.inThrows.add(variables[i]);
+ this.currentBounds.inThrows.add(variables[i].prototype());
break;
}
}
@@ -413,7 +418,8 @@ public class InferenceContext18 {
}
InferenceVariable[] variablesArray = allInputs.toArray(new InferenceVariable[allInputs.size()]);
// ... is resolved
- this.currentBounds.incorporate(this);
+ if (!this.currentBounds.incorporate(this))
+ return null;
BoundSet solution = resolve(variablesArray);
// in rare cases resolving just one set of variables doesn't suffice,
// don't bother with finding the necessary superset, just resolve all:
@@ -955,7 +961,7 @@ public class InferenceContext18 {
} else {
TypeBinding[] upperBounds = tmpBoundSet.upperBounds(variable, true/*onlyProper*/);
// check exception bounds:
- if (tmpBoundSet.inThrows.contains(variable) && tmpBoundSet.hasOnlyTrivialExceptionBounds(variable, upperBounds)) {
+ if (tmpBoundSet.inThrows.contains(variable.prototype()) && tmpBoundSet.hasOnlyTrivialExceptionBounds(variable, upperBounds)) {
TypeBinding runtimeException = this.scope.getType(TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION, 3);
tmpBoundSet.addBound(new TypeBound(variable, runtimeException, ReductionResult.SAME), this.environment);
} else {
@@ -1002,7 +1008,7 @@ public class InferenceContext18 {
}
public TypeBinding substitute(TypeVariableBinding typeVariable) {
for (int j = 0; j < numVars; j++)
- if (variables[j] == typeVariable) //$IDENTITY-COMPARISON$ InferenceVariable does not participate in type annotation encoding
+ if (TypeBinding.equalsEquals(variables[j], typeVariable))
return zs[j];
return typeVariable;
}
@@ -1039,7 +1045,7 @@ public class InferenceContext18 {
ParameterizedTypeBinding key = captureKeys.next();
int len = key.arguments.length;
for (int i = 0; i < len; i++) {
- if (key.arguments[i] == variable) { //$IDENTITY-COMPARISON$
+ if (TypeBinding.equalsEquals(key.arguments[i], variable)) {
toRemove.add(key);
break;
}
@@ -1137,7 +1143,7 @@ public class InferenceContext18 {
if (!variableSet.add(currentVariable)) return true; // already present
for (int j = 0; j < this.inferenceVariables.length; j++) {
InferenceVariable nextVariable = this.inferenceVariables[j];
- if (nextVariable == currentVariable) continue; //$IDENTITY-COMPARISON$ Inference variables
+ if (TypeBinding.equalsEquals(nextVariable, currentVariable)) continue;
if (boundSet.dependsOnResolutionOf(currentVariable, nextVariable))
if (!addDependencies(boundSet, variableSet, nextVariable, min))
return false; // abort traversal: no improvement
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
index eb5b260d0..a6a5b0923 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceVariable.java
@@ -22,6 +22,7 @@ public class InferenceVariable extends TypeVariableBinding {
InvocationSite site;
TypeBinding typeParameter;
long nullHints;
+ private InferenceVariable prototype;
public InferenceVariable(TypeBinding typeParameter, int variableRank, InvocationSite site, LookupEnvironment environment, ReferenceBinding object) {
super(CharOperation.concat(typeParameter.shortReadableName(), Integer.toString(variableRank).toCharArray(), '#'),
@@ -40,6 +41,20 @@ public class InferenceVariable extends TypeVariableBinding {
}
}
this.superclass = object;
+ this.prototype = this;
+ }
+
+ @Override
+ public TypeBinding clone(TypeBinding enclosingType) {
+ InferenceVariable clone = new InferenceVariable(this.typeParameter, this.rank, this.site, this.environment, this.superclass);
+ clone.tagBits = this.tagBits;
+ clone.nullHints = this.nullHints;
+ clone.prototype = this;
+ return clone;
+ }
+
+ public InferenceVariable prototype() {
+ return this.prototype;
}
public char[] constantPoolName() {
@@ -65,7 +80,7 @@ public class InferenceVariable extends TypeVariableBinding {
protected
// SH}
TypeBinding substituteInferenceVariable(InferenceVariable var, TypeBinding substituteType) {
- if (this == var) //$IDENTITY-COMPARISON$ InferenceVariable
+ if (TypeBinding.equalsEquals(this, var))
return substituteType;
return this;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
index ab058a8ec..356768613 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contribution for
- * bug 384380 - False positive on a « Potential null pointer access » after a continue
+ * bug 384380 - False positive on a "Potential null pointer access" after a continue
* Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 903c634e1..12aa5e4c6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -26,6 +26,9 @@
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
* Bug 416190 - [1.8][null] detect incompatible overrides due to null type annotations
* Bug 424624 - [1.8][null] if a static-object with annotation @NonNull is used, a warning is shown
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 439516 - [1.8][null] NonNullByDefault wrongly applied to implicit type bound of binary type
+ * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -111,7 +114,7 @@ public class LookupEnvironment implements ProblemReasons, TypeConstants {
private int lastCompletedUnitIndex = -1;
private int lastUnitIndex = -1;
- private TypeSystem typeSystem;
+ TypeSystem typeSystem;
public INameEnvironment nameEnvironment;
public CompilerOptions globalOptions;
@@ -1575,7 +1578,7 @@ TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean i
AnnotationBinding [][] annotationsOnDimensions = null;
if (dimension > 0 && walker != TypeAnnotationWalker.EMPTY_ANNOTATION_WALKER) {
for (int i = 0; i < dimension; i++) {
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
if (annotations != Binding.NO_ANNOTATIONS) {
if (annotationsOnDimensions == null)
annotationsOnDimensions = new AnnotationBinding[dimension][];
@@ -1660,7 +1663,7 @@ private TypeBinding annotateType(TypeBinding binding, TypeAnnotationWalker walke
}
AnnotationBinding [][] annotations = null;
for (int i = 0; i < depth; i++) {
- AnnotationBinding[] annots = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding[] annots = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(binding.id), this, missingTypeNames);
if (annots != null && annots.length > 0) {
if (annotations == null)
annotations = new AnnotationBinding[depth][];
@@ -1705,7 +1708,7 @@ public TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariab
AnnotationBinding [][] annotationsOnDimensions = null;
if (dimension > 0 && walker != TypeAnnotationWalker.EMPTY_ANNOTATION_WALKER) {
for (int i = 0; i < dimension; i++) {
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
if (annotations != Binding.NO_ANNOTATIONS) {
if (annotationsOnDimensions == null)
annotationsOnDimensions = new AnnotationBinding[dimension][];
@@ -1750,7 +1753,7 @@ public TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariab
if (actualEnclosing != null) { // convert needed if read some static member type
actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing, false /*do not force conversion of enclosing types*/);
}
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(actualType.id), this, missingTypeNames);
TypeBinding[] typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, actualType, missingTypeNames, walker);
ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, actualEnclosing, annotations);
@@ -1764,7 +1767,7 @@ public TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariab
if (memberType == null)
this.problemReporter.corruptedSignature(parameterizedType, wrapper.signature, memberStart); // aborts
walker = walker.toNextNestedType();
- annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(memberType.id), this, missingTypeNames);
if (wrapper.signature[wrapper.start] == '<') {
wrapper.start++; // skip '<'
typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, memberType, missingTypeNames, walker);
@@ -1778,7 +1781,7 @@ public TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariab
}
private TypeBinding getTypeFromTypeVariable(TypeVariableBinding typeVariableBinding, int dimension, AnnotationBinding [][] annotationsOnDimensions, TypeAnnotationWalker walker, char [][][] missingTypeNames) {
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
if (annotations != null && annotations != Binding.NO_ANNOTATIONS)
typeVariableBinding = (TypeVariableBinding) createAnnotatedType(typeVariableBinding, new AnnotationBinding [][] { annotations });
@@ -1805,18 +1808,18 @@ TypeBinding getTypeFromVariantTypeSignature(
// ? super aType
wrapper.start++;
TypeBinding bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames, walker.toWildcardBound());
- AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ AnnotationBinding [] annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
return this.typeSystem.getWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.SUPER, annotations);
case '+' :
// ? extends aType
wrapper.start++;
bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames, walker.toWildcardBound());
- annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
return this.typeSystem.getWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.EXTENDS, annotations);
case '*' :
// ?
wrapper.start++;
- annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(), this, missingTypeNames);
+ annotations = BinaryTypeBinding.createAnnotations(walker.getAnnotationsAtCursor(0), this, missingTypeNames);
return this.typeSystem.getWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND, annotations);
default :
return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames, walker);
@@ -1943,4 +1946,27 @@ public TypeBinding getUnannotatedType(TypeBinding typeBinding) {
public TypeBinding[] getAnnotatedTypes(TypeBinding type) {
return this.typeSystem.getAnnotatedTypes(type);
}
+
+public AnnotationBinding[] filterNullTypeAnnotations(AnnotationBinding[] typeAnnotations) {
+ if (typeAnnotations.length == 0)
+ return typeAnnotations;
+ AnnotationBinding[] filtered = new AnnotationBinding[typeAnnotations.length];
+ int count = 0;
+ for (int i = 0; i < typeAnnotations.length; i++) {
+ AnnotationBinding typeAnnotation = typeAnnotations[i];
+ if (typeAnnotation == null) {
+ count++; // sentinel in annotation sequence for array dimensions
+ } else {
+ int id = typeAnnotation.type.id;
+ if (id != TypeIds.T_ConfiguredAnnotationNonNull && id != TypeIds.T_ConfiguredAnnotationNullable)
+ filtered[count++] = typeAnnotation;
+ }
+ }
+ if (count == 0)
+ return Binding.NO_ANNOTATIONS;
+ if (count == typeAnnotations.length)
+ return typeAnnotations;
+ System.arraycopy(filtered, 0, filtered = new AnnotationBinding[count], 0, count);
+ return filtered;
+}
}
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 b0ede4a0d..2ba813598 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
@@ -22,6 +22,8 @@
* Bug 425152 - [1.8] [compiler] Lambda Expression not resolved but flow analyzed leading to NPE.
* Bug 423505 - [1.8] Implement "18.5.4 More Specific Method Inference"
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
+ * Bug 438012 - [1.8][null] Bogus Warning: The nullness annotation is redundant with a default that applies to this location
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
* Jesper Steen Moller - Contributions for
* Bug 412150 [1.8] [compiler] Enable reflected parameter names during annotation processing
*******************************************************************************/
@@ -35,6 +37,7 @@ import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
@@ -939,7 +942,7 @@ protected void fillInDefaultNonNullness18(AbstractMethodDeclaration sourceMethod
int length = this.parameters.length;
for (int i = 0; i < length; i++) {
TypeBinding parameter = this.parameters[i];
- if (parameter.isBaseType())
+ if (!parameter.acceptsNonNullDefault())
continue;
long existing = parameter.tagBits & TagBits.AnnotationNullMASK;
if (existing == 0L) {
@@ -949,7 +952,8 @@ protected void fillInDefaultNonNullness18(AbstractMethodDeclaration sourceMethod
if (sourceMethod != null)
sourceMethod.arguments[i].binding.type = this.parameters[i];
}
- } else if (sourceMethod != null && (parameter.tagBits & TagBits.AnnotationNonNull) != 0) {
+ } else if (sourceMethod != null && (parameter.tagBits & TagBits.AnnotationNonNull) != 0
+ && sourceMethod.arguments[i].hasNullTypeAnnotation()) {
sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i);
}
}
@@ -957,9 +961,10 @@ protected void fillInDefaultNonNullness18(AbstractMethodDeclaration sourceMethod
this.tagBits |= TagBits.HasParameterAnnotations;
}
if (this.returnType != null && hasNonNullDefaultFor(DefaultLocationReturnType, true)) {
- if (!this.returnType.isBaseType() && (this.returnType.tagBits & TagBits.AnnotationNullMASK) == 0) {
+ if (this.returnType.acceptsNonNullDefault() && (this.returnType.tagBits & TagBits.AnnotationNullMASK) == 0) {
this.returnType = env.createAnnotatedType(this.returnType, new AnnotationBinding[]{env.getNonNullAnnotation()});
- } else if (sourceMethod != null && (this.returnType.tagBits & TagBits.AnnotationNonNull) != 0) {
+ } else if (sourceMethod instanceof MethodDeclaration && (this.returnType.tagBits & TagBits.AnnotationNonNull) != 0
+ && ((MethodDeclaration)sourceMethod).hasNullTypeAnnotation()) {
sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index 8ba482283..56960dd1d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -29,6 +29,7 @@
* Bug 410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
+ * Bug 440773 - [1.8][null]DefaultLocation.RETURN_TYPE erroneously affects method parameters in @NonNullByDefault
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -90,8 +91,9 @@ void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[]
if (analyseNullAnnotations && this.type.equals(concreteMethod.declaringClass)) // is currentMethod from the current type?
srcMethod = concreteMethod.sourceMethod();
boolean useTypeAnnotations = this.environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_8;
- boolean hasNonNullDefault = analyseNullAnnotations &&
- concreteMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter|Binding.DefaultLocationReturnType, useTypeAnnotations);
+ boolean hasReturnNonNullDefault = analyseNullAnnotations && concreteMethod.hasNonNullDefaultFor(Binding.DefaultLocationReturnType, useTypeAnnotations);
+ boolean hasParameterNonNullDefault = analyseNullAnnotations && concreteMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter, useTypeAnnotations);
+
for (int i = 0, l = abstractMethods.length; i < l; i++) {
MethodBinding abstractMethod = abstractMethods[i];
if (concreteMethod.isVarargs() != abstractMethod.isVarargs())
@@ -113,7 +115,7 @@ void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[]
this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
}
if (analyseNullAnnotations && !concreteMethod.isStatic() && !abstractMethod.isStatic()) {
- checkNullSpecInheritance(concreteMethod, srcMethod, hasNonNullDefault, true, abstractMethod, this.type.scope, null);
+ checkNullSpecInheritance(concreteMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, abstractMethod, this.type.scope, null);
}
}
}
@@ -413,18 +415,19 @@ void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] m
if (this.type.equals(currentMethod.declaringClass)) // is currentMethod from the current type?
srcMethod = currentMethod.sourceMethod();
boolean useTypeAnnotations = options.sourceLevel >= ClassFileConstants.JDK1_8;
- boolean hasNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter|Binding.DefaultLocationReturnType, useTypeAnnotations);
+ boolean hasReturnNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationReturnType, useTypeAnnotations);
+ boolean hasParameterNonNullDefault = currentMethod.hasNonNullDefaultFor(Binding.DefaultLocationParameter, useTypeAnnotations);
for (int i = length; --i >= 0;)
if (!currentMethod.isStatic() && !methods[i].isStatic())
- checkNullSpecInheritance(currentMethod, srcMethod, hasNonNullDefault, true, methods[i], this.type.scope, null);
+ checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, true, methods[i], this.type.scope, null);
}
}
void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod,
- boolean hasNonNullDefault, boolean complain, MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
+ boolean hasReturnNonNullDefault, boolean hasParameterNonNullDefault, boolean complain, MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
{
complain &= !currentMethod.isConstructor();
- if (!hasNonNullDefault && !complain && !this.environment.globalOptions.inheritNullAnnotations) {
+ if (!hasReturnNonNullDefault && !hasParameterNonNullDefault && !complain && !this.environment.globalOptions.inheritNullAnnotations) {
// nothing to be done, take the shortcut
currentMethod.tagBits |= TagBits.IsNullnessKnown;
return;
@@ -435,7 +438,7 @@ void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclara
{
this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, scope);
}
- super.checkNullSpecInheritance(currentMethod, srcMethod, hasNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
+ super.checkNullSpecInheritance(currentMethod, srcMethod, hasReturnNonNullDefault, hasParameterNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
}
void reportRawReferences() {
@@ -1057,7 +1060,7 @@ public boolean isMethodSubsignature(MethodBinding method, MethodBinding inherite
boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
// called when currentMethod's return type is NOT compatible with inheritedMethod's return type
- // JLS 3 �8.4.5: more are accepted, with an unchecked conversion
+ // JLS 3 §8.4.5: more are accepted, with an unchecked conversion
if (TypeBinding.equalsEquals(currentMethod.returnType, inheritedMethod.returnType.erasure())) {
TypeBinding[] currentParams = currentMethod.parameters;
TypeBinding[] inheritedParams = inheritedMethod.parameters;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
index 5880f4677..49eb52c1f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NullTypeBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2014 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -25,7 +27,7 @@ public class NullTypeBinding extends BaseTypeBinding {
return; // reject misguided attempt.
}
- public TypeBinding unannotated() {
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
return this;
}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index e04f9fa9e..74f6d8102 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -20,6 +20,7 @@
* Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported
* Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
+ * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -813,7 +814,7 @@ public class ParameterizedGenericMethodBinding extends ParameterizedMethodBindin
// check this variable can be substituted given parameterized type
if (originalVariable.rank < length && TypeBinding.equalsEquals(variables[originalVariable.rank], originalVariable)) {
TypeBinding substitute = this.typeArguments[originalVariable.rank];
- return originalVariable.hasTypeAnnotations() ? this.environment.createAnnotatedType(substitute, originalVariable.getTypeAnnotations()) : substitute;
+ return originalVariable.combineTypeAnnotations(substitute);
}
return originalVariable;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index ae8db169b..45b85d059 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -34,6 +34,8 @@
* Bug 428294 - [1.8][compiler] Type mismatch: cannot convert from List<Object> to Collection<Object[]>
* Bug 427199 - [1.8][resource] avoid resource leak warnings on Streams that have no resource
* Bug 416182 - [1.8][compiler][null] Contradictory null annotations not rejected
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 438179 - [1.8][null] 'Contradictory null annotations' error on type variable with explicit null-annotation.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -966,8 +968,27 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi
return isRawType();
}
- public TypeBinding unannotated() {
- return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (!hasTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations) {
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.type);
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ TypeBinding[] newArguments = null;
+ if (this.arguments != null) {
+ newArguments = new TypeBinding[this.arguments.length];
+ for (int i = 0; i < this.arguments.length; i++) {
+ newArguments[i] = this.arguments[i].unannotated(removeOnlyNullAnnotations);
+ }
+ }
+ ReferenceBinding newEnclosing = null;
+ if (this.enclosingType != null)
+ newEnclosing = (ReferenceBinding)this.enclosingType.unannotated(removeOnlyNullAnnotations);
+ return this.environment.createParameterizedType(unannotatedGenericType, newArguments, newEnclosing, newAnnotations);
+ }
+ return this.environment.getUnannotatedType(this);
}
public int kind() {
@@ -1360,7 +1381,7 @@ public class ParameterizedTypeBinding extends ReferenceBinding implements Substi
return originalVariable;
}
TypeBinding substitute = currentType.arguments[originalVariable.rank];
- return originalVariable.hasTypeAnnotations() ? this.environment.createAnnotatedType(substitute, originalVariable.getTypeAnnotations()) : substitute;
+ return originalVariable.combineTypeAnnotations(substitute);
}
}
// recurse on enclosing type, as it may hold more substitutions to perform
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
index 9be376cc1..78eff9faf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -13,6 +13,7 @@
* Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables
* Bug 423504 - [1.8] Implement "18.5.3 Functional Interface Parameterization Inference"
* Bug 425783 - An internal error occurred during: "Requesting Java AST from selection". java.lang.StackOverflowError
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -79,6 +80,22 @@ public class RawTypeBinding extends ParameterizedTypeBinding {
return new RawTypeBinding(this.actualType(), (ReferenceBinding) outerType, this.environment);
}
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (!hasTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations) {
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.environment.getUnannotatedType(this.genericType());
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ ReferenceBinding newEnclosing = null;
+ if (this.enclosingType() != null)
+ newEnclosing = (ReferenceBinding)this.enclosingType().unannotated(removeOnlyNullAnnotations);
+ return this.environment.createRawType(unannotatedGenericType, newEnclosing, newAnnotations);
+ }
+ return this.environment.getUnannotatedType(this);
+ }
+
/**
* @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
*/
@@ -228,6 +245,9 @@ public class RawTypeBinding extends ParameterizedTypeBinding {
}
return this.singleAbstractMethod[index];
}
+ public boolean mentionsAny(TypeBinding[] parameters, int idx) {
+ return false;
+ }
/**
* @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index 01233df1e..cbfe59e20 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -33,6 +33,7 @@
* Bug 418743 - [1.8][null] contradictory annotations on invocation of generic method not reported
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 431581 - Eclipse compiles what it should not
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
* Jesper S Moller - Contributions for
* bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
* bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
@@ -1411,6 +1412,10 @@ int getNullDefault() {
return 0;
}
+public boolean acceptsNonNullDefault() {
+ return true;
+}
+
public final boolean hasRestrictedAccess() {
return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 9105cb756..d305327f8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -1412,7 +1412,7 @@ public abstract class Scope {
if (methodVerifier.areMethodsCompatible(concreteMatch, compatibleMethod))
continue; // can skip this method since concreteMatch overrides it
}
- if (sourceLevel18) {
+ if (sourceLevel18 || !(compatibleMethod.isVarargs() && compatibleMethod instanceof ParameterizedGenericMethodBinding)) {
for (int j = 0; j < startFoundSize; j++) {
MethodBinding classMethod = (MethodBinding) found.elementAt(j);
if (classMethod != null && methodVerifier.areMethodsCompatible(classMethod, compatibleMethod))
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 2133ad4e5..93bc35be3 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
@@ -26,7 +26,6 @@
* bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
* Bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
* Bug 415043 - [1.8][null] Follow-up re null type annotations after bug 392099
- * Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
* Bug 415850 - [1.8] Ensure RunJDTCoreTests can cope with null annotations enabled
* Bug 416172 - [1.8][compiler][null] null type annotation not evaluated on method return type
* Bug 417295 - [1.8[[null] Massage type annotated null analysis to gel well with deep encoded type bindings.
@@ -34,6 +33,8 @@
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
* Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
* Bug 432348 - [1.8] Internal compiler error (NPE) after upgrade to 1.8
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 435570 - [1.8][null] @NonNullByDefault illegally tries to affect "throws E"
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* Bug 412153 - [1.8][compiler] Check validity of annotations which may be repeatable
* Till Brychcy - Contributions for
@@ -2307,7 +2308,7 @@ public FieldBinding resolveTypeFor(FieldBinding field) {
Annotation [] annotations = fieldDecl.annotations;
if (annotations != null && annotations.length != 0) {
ASTNode.copySE8AnnotationsToType(initializationScope, field, annotations,
- fieldDecl.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT); // type annotation is illegal on enum constant
+ fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT); // type annotation is illegal on enum constant
}
Annotation.isTypeUseCompatible(fieldDecl.type, this.scope, annotations);
}
@@ -2459,7 +2460,7 @@ public MethodBinding resolveTypesFor(MethodBinding method, boolean fromSynthetic
if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
method.tagBits |= TagBits.HasMissingType;
}
- if (resolvedExceptionType.hasNullTypeAnnotations()) {
+ if (exceptionTypes[i].hasNullTypeAnnotation()) {
methodDecl.scope.problemReporter().nullAnnotationUnsupportedLocation(exceptionTypes[i]);
}
method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
@@ -2657,7 +2658,7 @@ public MethodBinding resolveTypesFor(MethodBinding method, boolean fromSynthetic
if (sourceLevel >= ClassFileConstants.JDK1_8 && !method.isVoidMethod()) {
Annotation [] annotations = methodDecl.annotations;
if (annotations != null && annotations.length != 0) {
- ASTNode.copySE8AnnotationsToType(methodDecl.scope, method, methodDecl.annotations, true);
+ ASTNode.copySE8AnnotationsToType(methodDecl.scope, method, methodDecl.annotations, false);
}
Annotation.isTypeUseCompatible(returnType, this.scope, methodDecl.annotations);
}
@@ -3532,7 +3533,14 @@ void verifyMethods(MethodVerifier verifier) {
// SH}
}
-public TypeBinding unannotated() {
+public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (removeOnlyNullAnnotations) {
+ if (!hasNullTypeAnnotations())
+ return this;
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(this.prototype, newAnnotations);
+ }
return this.prototype;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFactoryMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFactoryMethodBinding.java
index 349c0a3db..93849cd01 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFactoryMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFactoryMethodBinding.java
@@ -36,6 +36,11 @@ public class SyntheticFactoryMethodBinding extends MethodBinding {
for (MethodBinding parameterizedMethod : parameterizedType.methods()) {
if (parameterizedMethod.original() == this.staticFactoryFor)
return (ParameterizedMethodBinding) parameterizedMethod;
+ if (parameterizedMethod instanceof ProblemMethodBinding) {
+ MethodBinding closestMatch = ((ProblemMethodBinding)parameterizedMethod).closestMatch;
+ if (closestMatch instanceof ParameterizedMethodBinding && closestMatch.original() == this.staticFactoryFor)
+ return (ParameterizedMethodBinding) closestMatch;
+ }
}
throw new IllegalArgumentException("Type doesn't have its own method?"); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 142a156d1..29da06df1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -26,6 +26,8 @@
* Bug 427626 - [1.8] StackOverflow while typing new ArrayList<String>().toArray( and asking for code completion
* Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
* Bug 435962 - [RC2] StackOverFlowError when building
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
*******************************************************************************/
@@ -724,6 +726,13 @@ public boolean isParameterizedType() {
public boolean hasNullTypeAnnotations() {
return (this.tagBits & TagBits.HasNullTypeAnnotation) != 0;
}
+/**
+ * Used to implement this sentence from o.e.j.annotation.DefaultLocation:
+ * "Wildcards and the use of type variables are always excluded from NonNullByDefault."
+ */
+public boolean acceptsNonNullDefault() {
+ return false;
+}
public boolean isIntersectionCastType() {
return false;
@@ -1461,16 +1470,17 @@ public TypeBinding original() {
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
case Binding.ARRAY_TYPE :
- return erasure().unannotated();
+ return erasure().unannotated(false);
default :
- return this.unannotated();
+ return this.unannotated(false);
}
}
/**
* Return this type minus its type annotations
+ * @param removeOnlyNullAnnotations if true only null type annotations are removed, otherwise all type annotations.
*/
-public TypeBinding unannotated() {
+public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
return this;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBound.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBound.java
index 59845e32d..ad520b73f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBound.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBound.java
@@ -65,7 +65,7 @@ public class TypeBound extends ReductionResult {
public boolean equals(Object obj) {
if (obj instanceof TypeBound) {
TypeBound other = (TypeBound) obj;
- return this.left == other.left && TypeBinding.equalsEquals(this.right, other.right) && this.relation == other.relation; //$IDENTITY-COMPARISON$ InferenceVariable
+ return TypeBinding.equalsEquals(this.left, other.left) && TypeBinding.equalsEquals(this.right, other.right) && this.relation == other.relation;
}
return false;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
index 01da4f297..749f421f5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 434602 - Possible error with inferred null annotations leading to contradictory null annotations
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -425,6 +427,22 @@ public class TypeSystem {
}
return cacheDerivedType(keyType, new IntersectionCastTypeBinding(intersectingTypes, this.environment));
}
+
+ /**
+ * If a TVB was created with a dummy declaring element and needs to be fixed now,
+ * make sure that this update affects all early clones, too.
+ */
+ public void fixTypeVariableDeclaringElement(TypeVariableBinding var, Binding declaringElement) {
+ int id = var.id;
+ if (id < this.typeid && this.types[id] != null) {
+ for (TypeBinding t : this.types[id]) {
+ if (t instanceof TypeVariableBinding)
+ ((TypeVariableBinding)t).declaringElement = declaringElement;
+ }
+ } else {
+ var.declaringElement = declaringElement;
+ }
+ }
//{ObjectTeams: compare role types:
boolean isRoleTypeMatch(ITeamAnchor teamAnchor, int valueParamPosition, TypeBinding cachedType) {
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 b853a8a54..6ae69c83d 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
@@ -24,6 +24,11 @@
* Bug 431269 - [1.8][compiler][null] StackOverflow in nullAnnotatedReadableName
* Bug 431408 - Java 8 (1.8) generics bug
* Bug 435962 - [RC2] StackOverFlowError when building
+ * 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
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -829,7 +834,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);
}
/**
@@ -909,9 +923,19 @@ public class TypeVariableBinding extends ReferenceBinding {
return readableName;
}
- // May still carry declaration site annotations.
- public TypeBinding unannotated() {
- return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (!hasTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ return this;
+ TypeBinding unannotated = this.environment.getUnannotatedType(this);
+ if (removeOnlyNullAnnotations) {
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(this.typeAnnotations);
+ if (newAnnotations.length > 0)
+ return this.environment.createAnnotatedType(unannotated, newAnnotations);
+ // FIXME: selectively keep type annotations on bounds
+ }
+ return unannotated;
}
/**
* Upper bound doesn't perform erasure
@@ -931,11 +955,7 @@ public class TypeVariableBinding extends ReferenceBinding {
if (nullTagBits == 0L) {
nullTagBits |= superNullTagBits;
} else if (superNullTagBits != nullTagBits) {
- // not finding either bound or ann should be considered a compiler bug
- TypeReference bound = findBound(this.firstBound, parameter);
- Annotation ann = bound.findAnnotation(superNullTagBits);
- scope.problemReporter().contradictoryNullAnnotationsOnBounds(ann, nullTagBits);
- this.tagBits &= ~TagBits.AnnotationNullMASK;
+ this.firstBound = nullMismatchOnBound(parameter, this.firstBound, superNullTagBits, nullTagBits, scope);
}
}
}
@@ -949,11 +969,7 @@ public class TypeVariableBinding extends ReferenceBinding {
if (nullTagBits == 0L) {
nullTagBits |= superNullTagBits;
} else if (superNullTagBits != nullTagBits) {
- // not finding either bound or ann should be considered a compiler bug
- TypeReference bound = findBound(this.firstBound, parameter);
- Annotation ann = bound.findAnnotation(superNullTagBits);
- scope.problemReporter().contradictoryNullAnnotationsOnBounds(ann, nullTagBits);
- this.tagBits &= ~TagBits.AnnotationNullMASK;
+ interfaces[i] = (ReferenceBinding) nullMismatchOnBound(parameter, resolveType, superNullTagBits, nullTagBits, scope);
}
}
interfaces[i] = resolveType;
@@ -962,6 +978,20 @@ public class TypeVariableBinding extends ReferenceBinding {
if (nullTagBits != 0)
this.tagBits |= nullTagBits | TagBits.HasNullTypeAnnotation;
}
+ private TypeBinding nullMismatchOnBound(TypeParameter parameter, TypeBinding boundType, long superNullTagBits, long nullTagBits, Scope scope) {
+ // not finding bound should be considered a compiler bug
+ TypeReference bound = findBound(boundType, parameter);
+ Annotation ann = bound.findAnnotation(superNullTagBits);
+ if (ann != null) {
+ // explicit annotation: error
+ scope.problemReporter().contradictoryNullAnnotationsOnBounds(ann, nullTagBits);
+ this.tagBits &= ~TagBits.AnnotationNullMASK;
+ } else {
+ // implicit annotation: let the new one override
+ return boundType.unannotated(true);
+ }
+ return boundType;
+ }
private TypeReference findBound(TypeBinding bound, TypeParameter parameter) {
if (parameter.type != null && TypeBinding.equalsEquals(parameter.type.resolvedType, bound))
return parameter.type;
@@ -1019,4 +1049,38 @@ public class TypeVariableBinding extends ReferenceBinding {
}
return superInterfaces;
}
+
+ public TypeBinding combineTypeAnnotations(TypeBinding substitute) {
+ if (hasTypeAnnotations()) {
+ // may need to merge annotations from the original variable and from substitution:
+ if (hasRelevantTypeUseNullAnnotations()) {
+ // explicit type use null annotation overrides any annots on type parameter and concrete type arguments
+ substitute = substitute.unannotated(true);
+ }
+ if (this.typeAnnotations != Binding.NO_ANNOTATIONS)
+ return this.environment.createAnnotatedType(substitute, this.typeAnnotations);
+ // annots on originalVariable not relevant, and substitute has annots, keep substitute unmodified:
+ }
+ return substitute;
+ }
+
+ private boolean hasRelevantTypeUseNullAnnotations() {
+ TypeVariableBinding[] parameters;
+ if (this.declaringElement instanceof ReferenceBinding) {
+ parameters = ((ReferenceBinding)this.declaringElement).original().typeVariables();
+ } else if (this.declaringElement instanceof MethodBinding) {
+ parameters = ((MethodBinding)this.declaringElement).original().typeVariables;
+ } else {
+ throw new IllegalStateException("Unexpected declaring element:"+String.valueOf(this.declaringElement.readableName())); //$NON-NLS-1$
+ }
+ TypeVariableBinding parameter = parameters[this.rank];
+ // recognize explicit annots by their effect on null tag bits, if there's no effect, then the annot is not considered relevant
+ long currentNullBits = this.tagBits & TagBits.AnnotationNullMASK;
+ long declarationNullBits = parameter.tagBits & TagBits.AnnotationNullMASK;
+ return (currentNullBits & ~declarationNullBits) != 0;
+ }
+
+ public boolean acceptsNonNullDefault() {
+ return false;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
index 5fdbc1a01..3ad8be42c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VoidTypeBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2014 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
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -25,7 +27,7 @@ public class VoidTypeBinding extends BaseTypeBinding {
return; // reject misguided attempt.
}
- public TypeBinding unannotated() {
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
return this;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index ef9484cf9..7d2cce697 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -19,6 +19,8 @@
* Bug 427411 - [1.8][generics] JDT reports type mismatch when using method that returns generic type
* Bug 428019 - [1.8][compiler] Type inference failure with nested generic invocation.
* Bug 435962 - [RC2] StackOverFlowError when building
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
+ * Bug 440759 - [1.8][null] @NonNullByDefault should never affect wildcards and uses of a type variable
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -933,8 +935,24 @@ public class WildcardBinding extends ReferenceBinding {
return this.typeVariable;
}
- public TypeBinding unannotated() {
- return this.hasTypeAnnotations() ? this.environment.getUnannotatedType(this) : this;
+ public TypeBinding unannotated(boolean removeOnlyNullAnnotations) {
+ if (!hasTypeAnnotations())
+ return this;
+ if (removeOnlyNullAnnotations && !hasNullTypeAnnotations())
+ return this;
+ ReferenceBinding unannotatedGenericType = (ReferenceBinding) this.genericType.unannotated(removeOnlyNullAnnotations);
+ if (removeOnlyNullAnnotations) {
+ // cf. structure of uncapture():
+ TypeBinding unannotatedBound = this.bound != null ? this.bound.unannotated(removeOnlyNullAnnotations) : null;
+ int length = 0;
+ TypeBinding [] unannotatedOtherBounds = this.otherBounds == null ? null : new TypeBinding[length = this.otherBounds.length];
+ for (int i = 0; i < length; i++) {
+ unannotatedOtherBounds[i] = this.otherBounds[i] == null ? null : this.otherBounds[i].unannotated(removeOnlyNullAnnotations);
+ }
+ AnnotationBinding[] newAnnotations = this.environment.filterNullTypeAnnotations(getTypeAnnotations());
+ return this.environment.createWildcard(unannotatedGenericType, this.rank, unannotatedBound, unannotatedOtherBounds, this.boundKind, newAnnotations);
+ }
+ return unannotatedGenericType;
}
@Override
public TypeBinding uncapture(Scope scope) {
@@ -961,15 +979,26 @@ public class WildcardBinding extends ReferenceBinding {
}
@Override
public boolean mentionsAny(TypeBinding[] parameters, int idx) {
- if (super.mentionsAny(parameters, idx))
- return true;
- if (this.bound != null && this.bound.mentionsAny(parameters, -1))
- return true;
- if (this.otherBounds != null) {
- for (int i = 0, length = this.otherBounds.length; i < length; i++)
- if (this.otherBounds[i].mentionsAny(parameters, -1))
- return true;
+ if (this.inRecursiveFunction)
+ return false;
+ this.inRecursiveFunction = true;
+ try {
+ if (super.mentionsAny(parameters, idx))
+ return true;
+ if (this.bound != null && this.bound.mentionsAny(parameters, -1))
+ return true;
+ if (this.otherBounds != null) {
+ for (int i = 0, length = this.otherBounds.length; i < length; i++)
+ if (this.otherBounds[i].mentionsAny(parameters, -1))
+ return true;
+ }
+ } finally {
+ this.inRecursiveFunction = false;
}
return false;
}
+
+ public boolean acceptsNonNullDefault() {
+ return false;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index b62c2d496..bebcdc31c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -10120,6 +10120,11 @@ protected void consumeLambdaExpression() {
}
this.referenceContext.compilationResult().hasFunctionalTypes = true;
markEnclosingMemberWithLocalOrFunctionalType(LocalTypeKind.LAMBDA);
+ if (lexp.compilationResult.getCompilationUnit() == null) {
+ // unit built out of model. Stash a textual representation of lambda to enable LE.copy().
+ int length = lexp.sourceEnd - lexp.sourceStart + 1;
+ System.arraycopy(this.scanner.getSource(), lexp.sourceStart, lexp.text = new char [length], 0, length);
+ }
}
protected Argument typeElidedArgument() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
index 5a85fd6ca..81466874a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
@@ -15,7 +15,7 @@ package org.eclipse.jdt.internal.compiler.parser;
/**
* Internal structure for parsing recovery
*/
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
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 a5f398391..fbda4b7b0 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
@@ -52,6 +52,9 @@
* Bug 390889 - [1.8][compiler] Evaluate options to support 1.7- projects against 1.8 JRE.
* Bug 430150 - [1.8][null] stricter checking against type variables
* 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 439298 - [null] "Missing code implementation in the compiler" when using @NonNullByDefault in package-info.java
* 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
@@ -288,6 +291,7 @@ public static int getIrritant(int problemID) {
return CompilerOptions.UnusedLocalVariable;
case IProblem.ArgumentIsNeverUsed :
+ case IProblem.ExceptionParameterIsNeverUsed:
return CompilerOptions.UnusedArgument;
case IProblem.NoImplicitStringConversionForCharArrayExpression :
@@ -4038,6 +4042,10 @@ public void invalidConstructor(Statement statement, MethodBinding targetConstruc
statement.sourceStart,
statement.sourceEnd);
return;
+ case ProblemReasons.ContradictoryNullAnnotations:
+ problemConstructor = (ProblemMethodBinding) targetConstructor;
+ contradictoryNullAnnotationsInferred(problemConstructor.closestMatch, statement);
+ return;
case ProblemReasons.NoError : // 0
default :
needImplementation(statement); // want to fail to see why we were here...
@@ -8454,6 +8462,14 @@ public void typeHiding(TypeParameter typeParam, Binding hidden) {
typeParam.sourceStart,
typeParam.sourceEnd);
}
+public void notAnnotationType(TypeBinding actualType, ASTNode location) {
+ this.handle(
+ IProblem.NotAnnotationType,
+ new String[] {new String(actualType.leafComponentType().readableName())},
+ new String[] {new String(actualType.leafComponentType().shortReadableName())},
+ location.sourceStart,
+ location.sourceEnd);
+}
public void typeMismatchError(TypeBinding actualType, TypeBinding expectedType, ASTNode location, ASTNode expectingLocation) {
if (this.options.sourceLevel < ClassFileConstants.JDK1_5) { // don't expose type variable names, complain on erased types
if (actualType instanceof TypeVariableBinding)
@@ -9253,6 +9269,18 @@ public void unusedArgument(LocalDeclaration localDecl) {
localDecl.sourceStart,
localDecl.sourceEnd);
}
+public void unusedExceptionParameter(LocalDeclaration exceptionParameter) {
+ int severity = computeSeverity(IProblem.ExceptionParameterIsNeverUsed);
+ if (severity == ProblemSeverities.Ignore) return;
+ String[] arguments = new String[] {new String(exceptionParameter.name)};
+ this.handle(
+ IProblem.ExceptionParameterIsNeverUsed,
+ arguments,
+ arguments,
+ severity,
+ exceptionParameter.sourceStart,
+ exceptionParameter.sourceEnd);
+}
public void unusedDeclaredThrownException(ReferenceBinding exceptionType, AbstractMethodDeclaration method, ASTNode location) {
boolean isConstructor = method.isConstructor();
int severity = computeSeverity(isConstructor ? IProblem.UnusedConstructorDeclaredThrownException : IProblem.UnusedMethodDeclaredThrownException);
@@ -13661,7 +13689,28 @@ public void parameterLackingNonnullAnnotation(Argument argument, ReferenceBindin
sourceStart,
sourceEnd);
}
+public void illegalParameterRedefinition(Argument argument, ReferenceBinding declaringClass, TypeBinding inheritedParameter) {
+ int sourceStart = argument.type.sourceStart;
+ if (argument.annotations != null) {
+ for (int i=0; i<argument.annotations.length; i++) {
+ Annotation annotation = argument.annotations[i];
+ if ( annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNullable
+ || annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNonNull)
+ {
+ sourceStart = annotation.sourceStart;
+ break;
+ }
+ }
+ }
+ this.handle(
+ IProblem.IllegalParameterNullityRedefinition,
+ new String[] { new String(argument.name), new String(declaringClass.readableName()), new String(inheritedParameter.nullAnnotatedReadableName(this.options, false)) },
+ new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedParameter.nullAnnotatedReadableName(this.options, true)) },
+ sourceStart,
+ argument.type.sourceEnd);
+}
public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDecl, MethodBinding inheritedMethod, char[][] nonNullAnnotationName) {
+ // nonNullAnnotationName is not used in 1.8-mode
MethodDeclaration methodDecl = (MethodDeclaration) abstractMethodDecl;
StringBuffer methodSignature = new StringBuffer();
methodSignature
@@ -13680,12 +13729,31 @@ public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDe
if (annotation != null) {
sourceStart = annotation.sourceStart;
}
+ TypeBinding inheritedReturnType = inheritedMethod.returnType;
+ String[] arguments;
+ String[] argumentsShort;
+ if (this.options.complianceLevel < ClassFileConstants.JDK1_8) {
+ StringBuilder returnType = new StringBuilder();
+ 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))};
+ }
this.handle(
- IProblem.IllegalReturnNullityRedefinition,
- new String[] { methodSignature.toString(), CharOperation.toString(nonNullAnnotationName)},
- new String[] { shortSignature.toString(), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])},
- sourceStart,
- methodDecl.returnType.sourceEnd);
+ IProblem.IllegalReturnNullityRedefinition,
+ arguments,
+ argumentsShort,
+ sourceStart,
+ methodDecl.returnType.sourceEnd);
}
public void referenceExpressionArgumentNullityMismatch(ReferenceExpression location, TypeBinding requiredType, TypeBinding providedType,
MethodBinding descriptorMethod, int idx, NullAnnotationMatching status) {
@@ -14159,6 +14227,13 @@ public void nullityMismatchTypeArgument(TypeBinding typeVariable, TypeBinding ty
location.sourceEnd);
}
+public void implicitObjectBoundNoNullDefault(TypeReference reference) {
+ this.handle(IProblem.ImplicitObjectBoundNoNullDefault,
+ NoArgument, NoArgument,
+ ProblemSeverities.Warning,
+ reference.sourceStart, reference.sourceEnd);
+}
+
public void dereferencingNullableExpression(Expression expression) {
if (expression instanceof MessageSend) {
MessageSend send = (MessageSend) expression;
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 0d8f5b753..07f258500 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,8 @@
# Bug 392245 - [1.8][compiler][null] Define whether / how @NonNullByDefault applies to TYPE_USE locations
# Bug 430150 - [1.8][null] stricter checking against type variables
# 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"
# 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
@@ -76,6 +78,7 @@
31 = The member enum {0} can only be defined inside a top-level class or interface or in a static context
32 = The member enum {0} must be defined inside a static member type
33 = The type {0} is hiding the type {1}
+34 = {0} is not an annotation type
50 = {0} cannot be resolved
51 = The local variable {0} may not have been initialized
@@ -112,6 +115,7 @@
82 = The final field {0} may already have been assigned
83 = {0} cannot be resolved to a variable
84 = This static method of interface {0} can only be accessed as {0}.{1}
+85 = The value of the exception parameter {0} is not used
90 = The local variable {0} is hiding another local variable defined in an enclosing scope
91 = The local variable {0} is hiding a field from type {1}
@@ -773,7 +777,7 @@
911 = Null type mismatch: required ''{0}'' but the provided value is inferred as @{1}
912 = Null type safety: The expression of type ''{0}'' needs unchecked conversion to conform to ''{1}''
913 = A default nullness annotation has not been specified for the package {0}
-914 = The return type is incompatible with the @{1} return from {0}
+914 = The return type is incompatible with ''{1}'' returned from {0} (mismatching null constraints)
915 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as @{2}
916 = Illegal redefinition of parameter {0}, inherited method from {1} does not constrain this parameter
917 = Missing non-null annotation: inherited method from {0} specifies this parameter as @{1}
@@ -823,6 +827,8 @@
#968 temporary warning has been removed
969 = Null type mismatch (type annotations): ''null'' is not compatible to the free type variable ''{0}''
970 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}'', where ''{0}'' is a free type variable
+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)
# Java 8
1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index c1c23b493..6235afe0e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -9,6 +9,8 @@
* IBM Corporation - initial API and implementation
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended API and implementation
+ * Stephan Herrmann - Contribution for
+ * Bug 438458 - [1.8][null] clean up handling of null type annotations wrt type variables
*******************************************************************************/
package org.eclipse.jdt.core.dom;
@@ -27,6 +29,7 @@ import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
@@ -532,7 +535,7 @@ class TypeBinding implements ITypeBinding {
public ITypeBinding getTypeDeclaration() {
if (this.binding instanceof ParameterizedTypeBinding)
return this.resolver.getTypeBinding(((ParameterizedTypeBinding)this.binding).genericType());
- return this.resolver.getTypeBinding(this.binding.unannotated());
+ return this.resolver.getTypeBinding(this.binding.unannotated(false));
}
/* (non-Javadoc)
@@ -796,6 +799,10 @@ class TypeBinding implements ITypeBinding {
buffer.append(brackets);
return String.valueOf(buffer);
+ case Binding.INTERSECTION_CAST_TYPE :
+ // just use the first bound for now (same kludge as in IntersectionCastTypeBinding#constantPoolName())
+ return new String(((IntersectionCastTypeBinding) this.binding).getIntersectingTypes()[0].sourceName());
+
default :
if (isPrimitive() || isNullType()) {
BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
@@ -1293,7 +1300,7 @@ class TypeBinding implements ITypeBinding {
return false;
}
org.eclipse.jdt.internal.compiler.lookup.TypeBinding otherBinding = ((TypeBinding) other).binding;
- if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(otherBinding.unannotated(), this.binding.unannotated())) {
+ if (org.eclipse.jdt.internal.compiler.lookup.TypeBinding.equalsEquals(otherBinding.unannotated(false), this.binding.unannotated(false))) {
return true;
}
// check return type
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java
index edcbde688..f13a31bd3 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java
@@ -18,7 +18,7 @@ import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
-@SuppressWarnings("rawtypes")
+@SuppressWarnings("rawtypes")
public class SourceRangeVerifier extends ASTVisitor {
public static boolean DEBUG = false;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 096876ef5..1023e418a 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -3625,7 +3625,7 @@ public class DefaultCodeFormatterConstants {
* FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
* - option id: "org.eclipse.jdt.core.formatter.lineSplit"
* - possible values: "&lt;n&gt;", where n is zero or a positive integer
- * - default: "80"
+ * - default: "120"
* </pre>
* @since 3.0
*/
@@ -4036,7 +4036,9 @@ public class DefaultCodeFormatterConstants {
* @since 3.0
*/
public static Map getEclipse21Settings() {
- return DefaultCodeFormatterOptions.getDefaultSettings().getMap();
+ DefaultCodeFormatterOptions options = DefaultCodeFormatterOptions.getDefaultSettings();
+ options.page_width = 80; // changed with bug 356841
+ return options.getMap();
}
/**
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index 9a1a40500..da2d3cebd 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -2059,9 +2059,9 @@ public class DefaultCodeFormatterOptions {
try {
this.page_width = Integer.parseInt((String) pageWidthOption);
} catch (NumberFormatException e) {
- this.page_width = 80;
+ this.page_width = 120;
} catch(ClassCastException e) {
- this.page_width = 80;
+ this.page_width = 120;
}
}
final Object useTabOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
@@ -2492,7 +2492,7 @@ public class DefaultCodeFormatterOptions {
this.join_wrapped_lines = true;
this.put_empty_statement_on_new_line = false;
this.tab_size = 4;
- this.page_width = 80;
+ this.page_width = 120;
this.tab_char = TAB; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49081
this.use_tabs_only_for_leading_indentations = false;
this.wrap_before_binary_operator = true;
@@ -2787,7 +2787,7 @@ public class DefaultCodeFormatterOptions {
this.join_wrapped_lines = true;
this.put_empty_statement_on_new_line = true;
this.tab_size = 8;
- this.page_width = 80;
+ this.page_width = 120;
this.tab_char = MIXED;
this.use_tabs_only_for_leading_indentations = false;
this.wrap_before_binary_operator = true;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
index 5e612beba..7a10ac261 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
@@ -1146,14 +1146,17 @@ public class Scribe implements IJavaDocTagConstants {
if (linesCount > length) {
System.arraycopy(this.newEmptyLines, 0, this.newEmptyLines = new String[linesCount+10], 0, length);
}
- String newLineString = this.newEmptyLines[linesCount-1];
- if (newLineString == null) {
- this.tempBuffer.setLength(0);
- for (int j=0; j<linesCount; j++) {
- this.tempBuffer.append(this.lineSeparator);
+ String newLineString = Util.EMPTY_STRING;
+ if (linesCount > 0) {
+ newLineString = this.newEmptyLines[linesCount-1];
+ if (newLineString == null) {
+ this.tempBuffer.setLength(0);
+ for (int j=0; j<linesCount; j++) {
+ this.tempBuffer.append(this.lineSeparator);
+ }
+ newLineString = this.tempBuffer.toString();
+ this.newEmptyLines[linesCount-1] = newLineString;
}
- newLineString = this.tempBuffer.toString();
- this.newEmptyLines[linesCount-1] = newLineString;
}
return newLineString;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
index 1c871ba99..beed86a1e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 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
@@ -52,9 +52,25 @@ public void addAll(IType[] newElements) {
this.size += newElements.length;
}
public boolean contains(IType element) {
- for (int i = this.size; --i >= 0;)
- if (element.equals(this.elements[i]))
+ for (int i = this.size; --i >= 0;) {
+ /* Note: When creating new subtypes of RST, need to check whether this code
+ * which gives special treatment to lambda needs modification or not - refer to bug 436139
+ * An alternate could have been the following:
+ * if (element.equals(this.elements[i) && this.elements[i].equals(element)) return true;
+ * but the above has the issue of repeating the steps in most of the cases.
+ */
+ IType firstElement = null;
+ IType secondElement = null;
+ if (element.isLambda()) {
+ firstElement = element;
+ secondElement = this.elements[i];
+ } else {
+ firstElement = this.elements[i];
+ secondElement = element;
+ }
+ if (firstElement.equals(secondElement))
return true;
+ }
return false;
}
public TypeVector copy() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index 4e67ba2ee..5db5a3852 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -1575,14 +1575,14 @@ public class Disassembler extends ClassFileBytesDisassembler {
private String bootstrapMethodDescription(IBootstrapMethodsEntry entry, IConstantPool constantPool) {
// http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
// The BootstrapMethods attribute records bootstrap method specifiers referenced by invokedynamic instructions.
- // The value of the bootstrap_method_ref item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_MethodHandle_info structure (�4.4.8).
+ // The value of the bootstrap_method_ref item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_MethodHandle_info structure (§4.4.8).
// http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.8
// constantpoolentry.getKind() = IConstantPoolConstant.CONSTANT_MethodHandle
ConstantPoolEntry2 constantPoolEntry2 = (ConstantPoolEntry2) constantPool.decodeEntry(entry.getBootstrapMethodReference());
// The reference_kind item of the CONSTANT_MethodHandle_info structure should have the value 6 (REF_invokeStatic) or 8 (REF_newInvokeSpecial)
- // (�5.4.3.5) or else invocation of the bootstrap method handle during call site specifier resolution for an invokedynamic instruction will complete abruptly.
+ // (§5.4.3.5) or else invocation of the bootstrap method handle during call site specifier resolution for an invokedynamic instruction will complete abruptly.
// If the value of the reference_kind item is 5 (REF_invokeVirtual), 6 (REF_invokeStatic), 7 (REF_invokeSpecial),
// or 9 (REF_invokeInterface), the name of the method represented by a CONSTANT_Methodref_info structure must not be <init> or <clinit>.
@@ -1601,7 +1601,7 @@ public class Disassembler extends ClassFileBytesDisassembler {
// Each entry in the bootstrap_arguments array must be a valid index into the constant_pool table.
// The constant_pool entry at that index must be a CONSTANT_String_info, CONSTANT_Class_info, CONSTANT_Integer_info
// CONSTANT_Long_info, CONSTANT_Float_info, CONSTANT_Double_info, CONSTANT_MethodHandle_info, or
- // CONSTANT_MethodType_info structure (�4.4.3, �4.4.1, �4.4.4, �4.4.5), �4.4.8, �4.4.9).
+ // CONSTANT_MethodType_info structure (§4.4.3, §4.4.1, §4.4.4, §4.4.5), §4.4.8, §4.4.9).
if (entry.getBootstrapArguments().length == 0)
return null;
int[] bootstrapArguments = entry.getBootstrapArguments();
@@ -1616,8 +1616,8 @@ public class Disassembler extends ClassFileBytesDisassembler {
// http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.8
// If the value of the reference_kind item is 5 (REF_invokeVirtual), 6 (REF_invokeStatic),
// 7 (REF_invokeSpecial), or 8 (REF_newInvokeSpecial), then the constant_pool entry at that
- // index must be a CONSTANT_Methodref_info structure (�4.4.2) representing a class's method or
- // constructor (�2.9) for which a method handle is to be created.
+ // index must be a CONSTANT_Methodref_info structure (§4.4.2) representing a class's method or
+ // constructor (§2.9) for which a method handle is to be created.
ConstantPoolEntry2 constantPoolEntry2 = (ConstantPoolEntry2) constantPoolEntry;
StringBuilder builder = new StringBuilder(10);
switch(constantPoolEntry2.getReferenceKind()) {
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
index afab9ca37..b4dbbf6a5 100644
--- a/org.eclipse.jdt.core/pom.xml
+++ b/org.eclipse.jdt.core/pom.xml
@@ -14,11 +14,11 @@
<parent>
<artifactId>eclipse.jdt.core</artifactId>
<groupId>eclipse.jdt.core</groupId>
- <version>4.4.0-SNAPSHOT</version>
+ <version>4.5.0-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
- <version>3.10.0-SNAPSHOT</version>
+ <version>3.11.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
@@ -39,7 +39,7 @@
<include name="org/eclipse/jdt/internal/compiler/batch/messages.properties"/>
</replace>
<replace token="bundle_version" value="${unqualifiedVersion}" dir="${project.build.directory}/classes">
- <include name="org/eclipse/jdt/internal/compiler/batch/messages.properties" />
+ <include name="org/eclipse/jdt/internal/compiler/batch/messages.properties"/>
</replace>
</tasks>
</configuration>
diff --git a/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
index 46955781b..2fa22c5f5 100644
--- a/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch
-Bundle-Version: 3.10.0.qualifier
+Bundle-Version: 3.11.0.qualifier
Bundle-ClassPath: .
Bundle-Vendor: Eclipse.org
Export-Package: org.eclipse.jdt.core,
diff --git a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
index d50abcb82..783aecc66 100644
--- a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
@@ -1,7 +1,6 @@
Bundle-ManifestVersion: 2
Bundle-Name: Source of Eclipse Compiler for Java(TM)
Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch.source
-Bundle-Version: 3.10.0.qualifier
-Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-Version: 3.11.0.qualifier
Bundle-Vendor: Eclipse.org
-Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.10.0.${buildQualifier}";roots:="."
+Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.11.0.${buildQualifier}";roots:="."
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
index 6eedd419a..a79d15bbc 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -62,6 +62,7 @@ private static final int DELETED = -2;
private static final int CHUNK_SIZE = 100;
private static final SimpleSetOfCharArray INTERNED_CATEGORY_NAMES = new SimpleSetOfCharArray(20);
+private static final String TMP_EXT = ".tmp"; //$NON-NLS-1$
static class IntList {
@@ -254,6 +255,7 @@ private void cacheDocumentNames() throws IOException {
throw e;
} finally {
stream.close();
+ this.indexLocation.close();
this.streamBuffer = null;
BUFFER_READ_SIZE = DEFAULT_BUFFER_SIZE;
}
@@ -400,6 +402,7 @@ void initialize(boolean reuseExistingFile) throws IOException {
}
} finally {
stream.close();
+ this.indexLocation.close();
}
return;
}
@@ -526,8 +529,16 @@ DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
newDiskIndex.initialize(false);
return newDiskIndex;
}
+ boolean usingTmp = false;
File oldIndexFile = this.indexLocation.getIndexFile();
- DiskIndex newDiskIndex = new DiskIndex(new FileIndexLocation(new File(oldIndexFile.getPath() + ".tmp"))); //$NON-NLS-1$
+ String indexFilePath = oldIndexFile.getPath();
+ if (indexFilePath.endsWith(TMP_EXT)) { // the tmp file could not be renamed last time
+ indexFilePath = indexFilePath.substring(0, indexFilePath.length()-TMP_EXT.length());
+ usingTmp = true;
+ } else {
+ indexFilePath += TMP_EXT;
+ }
+ DiskIndex newDiskIndex = new DiskIndex(new FileIndexLocation(new File(indexFilePath)));
File newIndexFile = newDiskIndex.indexLocation.getIndexFile();
try {
newDiskIndex.initializeFrom(this, newIndexFile);
@@ -568,10 +579,18 @@ DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
System.out.println("mergeWith - Failed to delete " + this.indexLocation); //$NON-NLS-1$
throw new IOException("Failed to delete index file " + this.indexLocation); //$NON-NLS-1$
}
- if (!newIndexFile.renameTo(oldIndexFile)) {
- if (DEBUG)
- System.out.println("mergeWith - Failed to rename " + this.indexLocation); //$NON-NLS-1$
- throw new IOException("Failed to rename index file " + this.indexLocation); //$NON-NLS-1$
+ if (!usingTmp && !newIndexFile.renameTo(oldIndexFile)) {
+ // try again after waiting for two milli secs
+ try {
+ Thread.sleep(2);
+ } catch (InterruptedException e) {
+ //ignore
+ }
+ if (!newIndexFile.renameTo(oldIndexFile)) {
+ if (DEBUG)
+ System.out.println("mergeWith - Failed to rename " + this.indexLocation); //$NON-NLS-1$
+ usingTmp = true;
+ }
}
} catch (IOException e) {
if (newIndexFile.exists() && !newIndexFile.delete())
@@ -580,7 +599,8 @@ DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
throw e;
}
- newDiskIndex.indexLocation = this.indexLocation;
+ if (!usingTmp) // rename done, use the new file
+ newDiskIndex.indexLocation = this.indexLocation;
return newDiskIndex;
}
private synchronized String[] readAllDocumentNames() throws IOException {
@@ -601,6 +621,7 @@ private synchronized String[] readAllDocumentNames() throws IOException {
return docNames;
} finally {
stream.close();
+ this.indexLocation.close();
this.streamBuffer = null;
}
}
@@ -689,6 +710,7 @@ private synchronized HashtableOfObject readCategoryTable(char[] categoryName, bo
throw ioe;
} finally {
stream.close();
+ this.indexLocation.close();
}
if (matchingWords != null && count > 0) {
@@ -705,6 +727,7 @@ private synchronized HashtableOfObject readCategoryTable(char[] categoryName, bo
throw ioe;
} finally {
stream.close();
+ this.indexLocation.close();
}
}
this.streamBuffer = null;
@@ -758,6 +781,7 @@ synchronized String readDocumentName(int docNumber) throws IOException {
throw ioe;
} finally {
file.close();
+ this.indexLocation.close();
}
int numberOfNames = isLastChunk ? this.sizeOfLastChunk : CHUNK_SIZE;
chunk = new String[numberOfNames];
@@ -787,6 +811,7 @@ synchronized int[] readDocumentNumbers(Object arrayOffset) throws IOException {
return readStreamDocumentArray(stream, readStreamInt(stream));
} finally {
stream.close();
+ this.indexLocation.close();
this.streamBuffer = null;
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java
index a93a26498..8898670fd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java
@@ -59,6 +59,7 @@ public class JarIndexLocation extends IndexLocation {
try {
if (this.jarFile == null) {
JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
+ connection.setUseCaches(false);
JarFile file = connection.getJarFile();
if (file == null)
return false;
@@ -81,6 +82,7 @@ public class JarIndexLocation extends IndexLocation {
InputStream getInputStream() throws IOException {
if (this.jarFile == null) {
JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
+ connection.setUseCaches(false);
this.jarFile = connection.getJarFile();
this.jarEntry = connection.getJarEntry();
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
index 85d122266..24bd1c755 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -448,7 +448,9 @@ protected void convertTypeAnchor(int annotationKind) {
// SH}
protected void consumeMemberValuePair() {
super.consumeMemberValuePair();
- this.patternLocator.match((MemberValuePair) this.astStack[this.astPtr], this.nodeSet);
+ if ((this.patternFineGrain & ~IJavaSearchConstants.METHOD_REFERENCE_EXPRESSION) != 0) {
+ this.patternLocator.match((MemberValuePair) this.astStack[this.astPtr], this.nodeSet);
+ }
}
protected void consumeMethodHeaderName(boolean isAnnotationMethod) {

Back to the top