Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-11-03 15:07:28 +0000
committerStephan Herrmann2013-11-03 15:07:28 +0000
commit7941b7c4269f2a90459634e65c6a88cd0889897f (patch)
treeb67fd7be1a8e160a24a74d10b5908c9edf0c119d /org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler
parentbceeef60c17b90b133b5935ea20d307681775a38 (diff)
downloadorg.eclipse.objectteams-7941b7c4269f2a90459634e65c6a88cd0889897f.tar.gz
org.eclipse.objectteams-7941b7c4269f2a90459634e65c6a88cd0889897f.tar.xz
org.eclipse.objectteams-7941b7c4269f2a90459634e65c6a88cd0889897f.zip
Update jdt.core & tests to I20131030-2000 for 4.4M3
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler')
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java11
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java180
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java75
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java127
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java28
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties7
17 files changed, 259 insertions, 242 deletions
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 2b634b2aa..9d5b485b8 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
@@ -234,8 +234,8 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
// for if statement
public static final int IsElseIfStatement = Bit30;
public static final int ThenExit = Bit31;
- public static final int IsElseStatementUnreachable = Bit8;
- public static final int IsThenStatementUnreachable = Bit9;
+ public static final int IsElseStatementUnreachable = Bit8; // as computed by control flow analysis or null analysis.
+ public static final int IsThenStatementUnreachable = Bit9; // as computed by control flow analysis or null analysis
// for type reference
public static final int IsSuperType = Bit5;
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 8159393e8..46fc8ea1f 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
@@ -20,6 +20,7 @@
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
* bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
* bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 378674 - "The method can be declared as static" is wrong
* Till Brychcy - Contributions for
@@ -540,12 +541,7 @@ public TypeBinding resolveType(BlockScope scope) {
}
final CompilerOptions compilerOptions = scope.compilerOptions();
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
-//{ObjectTeams: added 2nd arg:
-/* orig:
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations)
- :giro */
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations, scope.environment())
-// SH}
+ new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
}
//{ObjectTeams: may need to wrap the resolved type
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 0a8475c11..85f7c4ecb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -836,8 +836,12 @@ public class EqualExpression extends BinaryExpression {
return null;
}
+ final CompilerOptions compilerOptions = scope.compilerOptions();
+ if (compilerOptions.complainOnUninternedIdentityComparison && originalRightType.hasTypeBit(TypeIds.BitUninternedType) && originalLeftType.hasTypeBit(TypeIds.BitUninternedType))
+ scope.problemReporter().uninternedIdentityComparison(this, originalLeftType, originalRightType);
+
// autoboxing support
- boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+ boolean use15specifics = compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5;
TypeBinding leftType = originalLeftType, rightType = originalRightType;
if (use15specifics) {
if (leftType != TypeBinding.NULL && leftType.isBaseType()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 912d2abbd..c20ea5a76 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -29,6 +29,7 @@
* bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
* bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
* Bug 405569 - Resource leak check false positive when using DbUtils.closeQuietly
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
* Jesper S Moller - Contributions for
* Bug 378674 - "The method can be declared as static" is wrong
*******************************************************************************/
@@ -1083,9 +1084,7 @@ public TypeBinding resolveType(BlockScope scope) {
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
// not interested in reporting problems against this.binding:
-//{ObjectTeams: added 2nd arg:
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations, scope.environment())
-// SH}
+ new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
}
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 2fade8c7f..3fd2fd422 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
@@ -20,6 +20,7 @@
* bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
* bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
* Bug 416267 - NPE in QualifiedAllocationExpression.resolveType
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
* Jesper S Moller <jesper@selskabet.org> - Contributions for
* bug 378674 - "The method can be declared as static" is wrong
* Till Brychcy - Contributions for
@@ -346,12 +347,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
if(result != null && this.binding != null) {
final CompilerOptions compilerOptions = scope.compilerOptions();
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
-//{ObjectTeams: added 2nd arg:
-/* orig:
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations)
- :giro */
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations, scope.environment())
-// SH}
+ new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 5729c8440..c7cbf5750 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -544,7 +544,11 @@ public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
// if a variable is only initialized in one branch and not initialized in the other,
// then we need to cast a doubt on its initialization in the merged info
mergedInfo.definiteInits &= initsWhenFalse.unconditionalCopy().definiteInits;
-
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsElseStatementUnreachable could be due to null analysis
+ if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenFalse.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) {
+ mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD;
+ mergedInfo.tagBits |= UNREACHABLE_BY_NULLANALYSIS;
+ }
}
else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
(ifStatement.bits & ASTNode.IsThenStatementUnreachable) != 0 && initsWhenTrue != FlowInfo.DEAD_END
@@ -560,6 +564,11 @@ public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
// if a variable is only initialized in one branch and not initialized in the other,
// then we need to cast a doubt on its initialization in the merged info
mergedInfo.definiteInits &= initsWhenTrue.unconditionalCopy().definiteInits;
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsThenStatementUnreachable could be due to null analysis
+ if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenTrue.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) {
+ mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD;
+ mergedInfo.tagBits |= UNREACHABLE_BY_NULLANALYSIS;
+ }
}
else {
mergedInfo = initsWhenTrue.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 129ad7f9d..2cae1d9bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -241,6 +241,7 @@ public class CompilerOptions {
public static final String OPTION_NullableAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$
public static final String OPTION_NonNullAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$
public static final String OPTION_NonNullByDefaultAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"; //$NON-NLS-1$
+ public static final String OPTION_ReportUninternedIdentityComparison = "org.eclipse.jdt.core.compiler.problem.uninternedIdentityComparison"; //$NON-NLS-1$
// defaults for the above:
static final char[][] DEFAULT_NULLABLE_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.Nullable".toCharArray()); //$NON-NLS-1$
static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$
@@ -555,6 +556,8 @@ public class CompilerOptions {
/** Should immediate null-check for fields be considered during null analysis (syntactical match)? */
public boolean enableSyntacticNullAnalysisForFields;
+ public boolean complainOnUninternedIdentityComparison;
+
// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
public final static String[] warningTokens = {
"all", //$NON-NLS-1$
@@ -1474,6 +1477,7 @@ public class CompilerOptions {
optionsMap.put(OPTION_SyntacticNullAnalysisForFields, this.enableSyntacticNullAnalysisForFields ? ENABLED : DISABLED);
optionsMap.put(OPTION_InheritNullAnnotations, this.inheritNullAnnotations ? ENABLED : DISABLED);
optionsMap.put(OPTION_ReportNonnullParameterAnnotationDropped, getSeverityString(NonnullParameterAnnotationDropped));
+ optionsMap.put(OPTION_ReportUninternedIdentityComparison, this.complainOnUninternedIdentityComparison ? ENABLED : DISABLED);
return optionsMap;
}
@@ -1639,6 +1643,8 @@ public class CompilerOptions {
this.analyseResourceLeaks = true;
this.reportMissingEnumCaseDespiteDefault = false;
+
+ this.complainOnUninternedIdentityComparison = false;
}
public void set(Map optionsMap) {
@@ -2139,6 +2145,13 @@ public class CompilerOptions {
this.storeAnnotations = false;
}
}
+ if ((optionValue = optionsMap.get(OPTION_ReportUninternedIdentityComparison)) != null) {
+ if (ENABLED.equals(optionValue)) {
+ this.complainOnUninternedIdentityComparison = true;
+ } else if (DISABLED.equals(optionValue)) {
+ this.complainOnUninternedIdentityComparison = false;
+ }
+ }
}
public String toString() {
StringBuffer buf = new StringBuffer("CompilerOptions:"); //$NON-NLS-1$
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 beef97c36..1f8a5ad76 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
@@ -47,22 +47,21 @@ public class ImplicitNullAnnotationVerifier {
// can be 'this', but is never a MethodVerifier (to avoid infinite recursion).
ImplicitNullAnnotationVerifier buddyImplicitNullAnnotationsVerifier;
private boolean inheritNullAnnotations;
- private LookupEnvironment environment;
+ protected LookupEnvironment environment;
-//{ObjectTeams: added 2nd arg:
- public ImplicitNullAnnotationVerifier(boolean inheritNullAnnotations, LookupEnvironment environment) {
- this.environment = environment;
-// SH}
+
+ public ImplicitNullAnnotationVerifier(LookupEnvironment environment, boolean inheritNullAnnotations) {
this.buddyImplicitNullAnnotationsVerifier = this;
this.inheritNullAnnotations = inheritNullAnnotations;
+ this.environment = environment;
}
// for sub-classes:
-//{ObjectTeams: added 2nd arg:
- ImplicitNullAnnotationVerifier(CompilerOptions options, LookupEnvironment environment) {
- this.buddyImplicitNullAnnotationsVerifier = new ImplicitNullAnnotationVerifier(options.inheritNullAnnotations, environment);
-// SH}
+ ImplicitNullAnnotationVerifier(LookupEnvironment environment) {
+ CompilerOptions options = environment.globalOptions;
+ this.buddyImplicitNullAnnotationsVerifier = new ImplicitNullAnnotationVerifier(environment, options.inheritNullAnnotations);
this.inheritNullAnnotations = options.inheritNullAnnotations;
+ this.environment = environment;
}
/**
@@ -176,7 +175,7 @@ public class ImplicitNullAnnotationVerifier {
MethodBinding currentMethod = ifcMethods[i];
if (currentMethod.isStatic())
continue;
- if (areParametersEqual(original, currentMethod.original())) {
+ if (doesMethodOverride(original, currentMethod)) {
result.add(currentMethod);
return; // at most one method is overridden from any supertype
}
@@ -220,7 +219,6 @@ public class ImplicitNullAnnotationVerifier {
long currentBits = currentMethod.tagBits;
long currentNullnessBits = currentBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable);
- LookupEnvironment environment = scope.environment();
boolean shouldInherit = this.inheritNullAnnotations;
// return type:
@@ -257,7 +255,7 @@ public class ImplicitNullAnnotationVerifier {
{
if (srcMethod != null) {
scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod,
- environment.getNonNullAnnotationName());
+ this.environment.getNonNullAnnotationName());
} else {
scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod);
return;
@@ -319,9 +317,9 @@ public class ImplicitNullAnnotationVerifier {
if (shouldComplain) {
char[][] annotationName;
if (inheritedNonNullNess == Boolean.TRUE) {
- annotationName = environment.getNonNullAnnotationName();
+ annotationName = this.environment.getNonNullAnnotationName();
} else {
- annotationName = environment.getNullableAnnotationName();
+ annotationName = this.environment.getNullableAnnotationName();
}
if (inheritedNonNullNess != Boolean.TRUE // super parameter is not restricted to @NonNull
&& currentNonNullNess == Boolean.TRUE) // current parameter is restricted to @NonNull
@@ -331,7 +329,7 @@ public class ImplicitNullAnnotationVerifier {
scope.problemReporter().illegalRedefinitionToNonNullParameter(
currentArgument,
inheritedMethod.declaringClass,
- (inheritedNonNullNess == null) ? null : environment.getNullableAnnotationName());
+ (inheritedNonNullNess == null) ? null : this.environment.getNullableAnnotationName());
} else {
scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod);
}
@@ -512,4 +510,156 @@ public class ImplicitNullAnnotationVerifier {
return false;
}
// SH}
+ public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
+ return couldMethodOverride(method, inheritedMethod) && areMethodsCompatible(method, inheritedMethod);
+ }
+
+ protected boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
+ if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
+ return false;
+ if (method == inheritedMethod || method.isStatic() || inheritedMethod.isStatic())
+//{ObjectTeams: treat static pair of methods in role ifc/class as overriding:
+ if (!staticRoleMethodImpl(method, inheritedMethod))
+// SH}
+ return false;
+ if (inheritedMethod.isPrivate())
+ return false;
+ if (inheritedMethod.isDefault() && method.declaringClass.getPackage() != inheritedMethod.declaringClass.getPackage())
+ return false;
+ if (!method.isPublic()) { // inheritedMethod is either public or protected & method is less than public
+ if (inheritedMethod.isPublic())
+ return false;
+ if (inheritedMethod.isProtected() && !method.isProtected())
+ return false;
+ }
+ return true;
+ }
+
+//{ObjectTeams: is method the static implementation of a role ifc's abstract static?
+ private boolean staticRoleMethodImpl(MethodBinding method, MethodBinding inheritedMethod)
+ {
+ if (inheritedMethod.declaringClass.isSynthInterface())
+ return method.isStatic() && inheritedMethod.isStatic();
+ return false;
+ }
+// SH}
+
+ protected boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
+ // use the original methods to test compatibility, but do not check visibility, etc
+ one = one.original();
+ two = one.findOriginalInheritedMethod(two);
+
+ if (two == null)
+ return false; // method's declaringClass does not inherit from inheritedMethod's
+
+ return isParameterSubsignature(one, two);
+ }
+
+ protected boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
+ MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method);
+ return substitute != null && isSubstituteParameterSubsignature(method, substitute);
+ }
+
+ protected MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
+ if (inheritedMethod == null) return null;
+ //{ObjectTeams: use source-level params in case of enhanced callin methods:
+ /* orig:
+ if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
+ :giro */
+ if (currentMethod.getSourceParamLength() != inheritedMethod.getSourceParamLength()) return null; // no match
+ // SH}
+
+ // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
+ if (currentMethod.declaringClass instanceof BinaryTypeBinding)
+ ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
+ if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
+ ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);
+
+ TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables;
+ int inheritedLength = inheritedTypeVariables.length;
+ if (inheritedLength == 0) return inheritedMethod; // no substitution needed
+ TypeVariableBinding[] typeVariables = currentMethod.typeVariables;
+ int length = typeVariables.length;
+ if (length == 0)
+ return inheritedMethod.asRawMethod(this.environment);
+ if (length != inheritedLength)
+ return inheritedMethod; // no match JLS 8.4.2
+
+ // interface I { <T> void foo(T t); }
+ // class X implements I { public <T extends I> void foo(T t) {} }
+ // for the above case, we do not want to answer the substitute method since its not a match
+ TypeVariableBinding[] arguments = new TypeVariableBinding[length];
+ System.arraycopy(typeVariables, 0, arguments, 0, length);
+ ParameterizedGenericMethodBinding substitute =
+ this.environment.createParameterizedGenericMethod(inheritedMethod, arguments);
+ for (int i = 0; i < inheritedLength; i++) {
+ TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i];
+ TypeVariableBinding typeVariable = arguments[i];
+ if (typeVariable.firstBound == inheritedTypeVariable.firstBound) {
+ if (typeVariable.firstBound == null)
+ continue; // both are null
+ } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) {
+ if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass())
+ return inheritedMethod; // not a match
+ }
+ if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass)
+ return inheritedMethod; // not a match
+ int interfaceLength = inheritedTypeVariable.superInterfaces.length;
+ ReferenceBinding[] interfaces = typeVariable.superInterfaces;
+ if (interfaceLength != interfaces.length)
+ return inheritedMethod; // not a match
+ next : for (int j = 0; j < interfaceLength; j++) {
+ TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]);
+ for (int k = 0; k < interfaceLength; k++)
+ if (superType == interfaces[k])
+ continue next;
+ return inheritedMethod; // not a match
+ }
+ }
+ return substitute;
+ }
+
+ protected boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) {
+ if (!areParametersEqual(method, substituteMethod)) {
+ // method can still override substituteMethod in cases like :
+ // <U extends Number> void c(U u) {}
+ // @Override void c(Number n) {}
+ // but method cannot have a "generic-enabled" parameter type
+ if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod))
+ return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method);
+
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836
+ if (method.declaringClass.isRawType() && substituteMethod.declaringClass.isRawType())
+ if (method.hasSubstitutedParameters() && substituteMethod.hasSubstitutedParameters())
+ return areMethodsCompatible(method, substituteMethod);
+
+ return false;
+ }
+
+ if (substituteMethod instanceof ParameterizedGenericMethodBinding) {
+ if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
+ return !((ParameterizedGenericMethodBinding) substituteMethod).isRaw;
+ // since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does
+ return !hasGenericParameter(method);
+ }
+
+ // if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod()
+ return method.typeVariables == Binding.NO_TYPE_VARIABLES;
+ }
+
+ boolean hasGenericParameter(MethodBinding method) {
+ if (method.genericSignature() == null) return false;
+
+ // may be only the return type that is generic, need to check parameters
+ TypeBinding[] params = method.parameters;
+ for (int i = 0, l = params.length; i < l; i++) {
+ TypeBinding param = params[i].leafComponentType();
+ if (param instanceof ReferenceBinding) {
+ int modifiers = ((ReferenceBinding) param).modifiers;
+ if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 2614134e7..f42704780 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -15,6 +15,7 @@
* bug 395681 - [compiler] Improve simulation of javac6 behavior from bug 317719 after fixing bug 388795
* bug 406928 - computation of inherited methods seems damaged (affecting @Overrides)
* bug 409473 - [compiler] JDT cannot compile against JRE 1.8
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -68,7 +69,6 @@ public abstract class MethodVerifier extends ImplicitNullAnnotationVerifier {
SourceTypeBinding type;
HashtableOfObject inheritedMethods;
HashtableOfObject currentMethods;
- LookupEnvironment environment;
private boolean allowCompatibleReturnTypes;
/*
Binding creation is responsible for reporting all problems with types:
@@ -88,9 +88,7 @@ Binding creation is responsible for reporting all problems with types:
- defining an interface as a local type (local types can only be classes)
*/
MethodVerifier(LookupEnvironment environment) {
-//{ObjectTeams: added 2nd arg:
- super(environment.globalOptions, environment);
-// SH}
+ super(environment);
this.type = null; // Initialized with the public method verify(SourceTypeBinding)
this.inheritedMethods = null;
this.currentMethods = null;
@@ -99,9 +97,6 @@ MethodVerifier(LookupEnvironment environment) {
environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5
&& environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5;
}
-boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
- return isParameterSubsignature(one, two) && areReturnTypesCompatible(one, two);
-}
boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
//{ObjectTeams: consider enhanced callin signatures:
/* orig:
@@ -852,68 +847,6 @@ void computeMethods() {
}
}
-MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
- if (inheritedMethod == null) return null;
- if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
-//{ObjectTeams: copied from MethodVerifier15 and guarded with own condition:
- if ( (currentMethod.declaringClass.isRole() && inheritedMethod.declaringClass.isRole())
- || (currentMethod.declaringClass.isTeam() && inheritedMethod.declaringClass.isTeam()))
- {
- // orig 15:
- // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
- if (currentMethod.declaringClass instanceof BinaryTypeBinding)
- ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
- if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
- ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);
- // :giro
- }
-//SH}
- return inheritedMethod;
-}
-
-boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
- if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
- return false;
- if (method == inheritedMethod || method.isStatic() || inheritedMethod.isStatic())
-//{ObjectTeams: treat static pair of methods in role ifc/class as overriding:
- if (!staticRoleMethodImpl(method, inheritedMethod))
-// SH}
- return false;
- if (inheritedMethod.isPrivate())
- return false;
- if (inheritedMethod.isDefault() && method.declaringClass.getPackage() != inheritedMethod.declaringClass.getPackage())
- return false;
- if (!method.isPublic()) { // inheritedMethod is either public or protected & method is less than public
- if (inheritedMethod.isPublic())
- return false;
- if (inheritedMethod.isProtected() && !method.isProtected())
- return false;
- }
- return true;
-}
-//{ObjectTeams: is method the static implementation of a role ifc's abstract static?
-private boolean staticRoleMethodImpl(MethodBinding method, MethodBinding inheritedMethod)
-{
- if (inheritedMethod.declaringClass.isSynthInterface())
- return method.isStatic() && inheritedMethod.isStatic();
- return false;
-}
-// SH}
-// Answer whether the method overrides the inheritedMethod
-// Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass
-// See isMethodSubsignature() for parameter comparisons
-public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
- if (!couldMethodOverride(method, inheritedMethod))
- return false;
-
- inheritedMethod = inheritedMethod.original();
- TypeBinding match = method.declaringClass.findSuperTypeOriginatingFrom(inheritedMethod.declaringClass);
- if (!(match instanceof ReferenceBinding))
- return false; // method's declaringClass does not inherit from inheritedMethod's
-
- return isParameterSubsignature(method, inheritedMethod);
-}
-
SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
return null; // noop in 1.4
}
@@ -1020,10 +953,6 @@ public boolean isMethodSubsignature(MethodBinding method, MethodBinding inherite
&& isParameterSubsignature(method, inheritedMethod);
}
-boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
- return areParametersEqual(method, inheritedMethod);
-}
-
boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
do {
if (testClass == superclass) return true;
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 4e70de288..2993e65be 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
@@ -18,6 +18,7 @@
* bug 395681 - [compiler] Improve simulation of javac6 behavior from bug 317719 after fixing bug 388795
* bug 409473 - [compiler] JDT cannot compile against JRE 1.8
* Bug 410325 - [1.7][compiler] Generified method override different between javac and eclipse compiler
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -48,16 +49,6 @@ class MethodVerifier15 extends MethodVerifier {
MethodVerifier15(LookupEnvironment environment) {
super(environment);
}
-boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
- // use the original methods to test compatibility, but do not check visibility, etc
- one = one.original();
- two = one.findOriginalInheritedMethod(two);
-
- if (two == null)
- return false; // method's declaringClass does not inherit from inheritedMethod's
-
- return isParameterSubsignature(one, two);
-}
boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
//{ObjectTeams: consider enhanced callin signatures:
/* orig:
@@ -379,7 +370,7 @@ void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclara
if (currentMethod.declaringClass != this.type
&& (currentMethod.tagBits & TagBits.IsNullnessKnown) == 0)
{
- this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, this.type.scope);
+ this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, scope);
}
super.checkNullSpecInheritance(currentMethod, srcMethod, hasNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
}
@@ -790,69 +781,6 @@ void checkTypeVariableMethods(TypeParameter typeParameter) {
}
}
}
-MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
- if (inheritedMethod == null) return null;
-//{ObjectTeams: use source-level params in case of enhanced callin methods:
-/* orig:
- if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
- :giro */
- if (currentMethod.getSourceParamLength() != inheritedMethod.getSourceParamLength()) return null; // no match
-// SH}
-
- // due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
- if (currentMethod.declaringClass instanceof BinaryTypeBinding)
- ((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
- if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
- ((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);
-
- TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables;
- int inheritedLength = inheritedTypeVariables.length;
- if (inheritedLength == 0) return inheritedMethod; // no substitution needed
- TypeVariableBinding[] typeVariables = currentMethod.typeVariables;
- int length = typeVariables.length;
- if (length == 0)
- return inheritedMethod.asRawMethod(this.environment);
- if (length != inheritedLength)
- return inheritedMethod; // no match JLS 8.4.2
-
- // interface I { <T> void foo(T t); }
- // class X implements I { public <T extends I> void foo(T t) {} }
- // for the above case, we do not want to answer the substitute method since its not a match
- TypeBinding[] arguments = new TypeBinding[length];
- System.arraycopy(typeVariables, 0, arguments, 0, length);
- ParameterizedGenericMethodBinding substitute =
- this.environment.createParameterizedGenericMethod(inheritedMethod, arguments);
- for (int i = 0; i < inheritedLength; i++) {
- TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i];
- TypeBinding argument = arguments[i];
- if (argument instanceof TypeVariableBinding) {
- TypeVariableBinding typeVariable = (TypeVariableBinding) argument;
- if (typeVariable.firstBound == inheritedTypeVariable.firstBound) {
- if (typeVariable.firstBound == null)
- continue; // both are null
- } else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) {
- if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass())
- return inheritedMethod; // not a match
- }
- if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass)
- return inheritedMethod; // not a match
- int interfaceLength = inheritedTypeVariable.superInterfaces.length;
- ReferenceBinding[] interfaces = typeVariable.superInterfaces;
- if (interfaceLength != interfaces.length)
- return inheritedMethod; // not a match
- next : for (int j = 0; j < interfaceLength; j++) {
- TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]);
- for (int k = 0; k < interfaceLength; k++)
- if (superType == interfaces[k])
- continue next;
- return inheritedMethod; // not a match
- }
- } else if (inheritedTypeVariable.boundCheck(substitute, argument, this.type.scope) != TypeConstants.OK) {
- return inheritedMethod;
- }
- }
- return substitute;
-}
boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) {
if (!inherited.areParameterErasuresEqual(otherInherited))
return false;
@@ -913,9 +841,6 @@ boolean detectNameClash(MethodBinding current, MethodBinding inherited, boolean
if (severity == ProblemSeverities.Warning) return false;
return true;
}
-public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
- return couldMethodOverride(method, inheritedMethod) && areMethodsCompatible(method, inheritedMethod);
-}
boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) {
// one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod()
return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding);
@@ -989,21 +914,6 @@ SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBin
}
return copy;
}
-boolean hasGenericParameter(MethodBinding method) {
- if (method.genericSignature() == null) return false;
-
- // may be only the return type that is generic, need to check parameters
- TypeBinding[] params = method.parameters;
- for (int i = 0, l = params.length; i < l; i++) {
- TypeBinding param = params[i].leafComponentType();
- if (param instanceof ReferenceBinding) {
- int modifiers = ((ReferenceBinding) param).modifiers;
- if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
- return true;
- }
- }
- return false;
-}
boolean isAcceptableReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
// called when currentMethod's return type is compatible with inheritedMethod's return type
@@ -1049,39 +959,6 @@ public boolean isMethodSubsignature(MethodBinding method, MethodBinding inherite
MethodBinding inheritedOriginal = method.findOriginalInheritedMethod(inheritedMethod);
return isParameterSubsignature(method, inheritedOriginal == null ? inheritedMethod : inheritedOriginal);
}
-boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
- MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method);
- return substitute != null && isSubstituteParameterSubsignature(method, substitute);
-}
-// if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send
-// if it does not then a name clash error is likely
-boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) {
- if (!areParametersEqual(method, substituteMethod)) {
- // method can still override substituteMethod in cases like :
- // <U extends Number> void c(U u) {}
- // @Override void c(Number n) {}
- // but method cannot have a "generic-enabled" parameter type
- if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod))
- return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method);
-
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836
- if (method.declaringClass.isRawType() && substituteMethod.declaringClass.isRawType())
- if (method.hasSubstitutedParameters() && substituteMethod.hasSubstitutedParameters())
- return areMethodsCompatible(method, substituteMethod);
-
- return false;
- }
-
- if (substituteMethod instanceof ParameterizedGenericMethodBinding) {
- if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
- return !((ParameterizedGenericMethodBinding) substituteMethod).isRaw;
- // since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does
- return !hasGenericParameter(method);
- }
-
- // if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod()
- return method.typeVariables == Binding.NO_TYPE_VARIABLES;
-}
boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
// called when currentMethod's return type is NOT compatible with inheritedMethod's return type
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 f9f60d045..134d27da9 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
@@ -970,6 +970,12 @@ public void computeId() {
return;
}
break;
+ case 7 :
+ if (!CharOperation.equals(TypeConstants.JDT, this.compoundName[2]) || !CharOperation.equals(TypeConstants.TYPEBINDING, this.compoundName[6]))
+ return;
+ if (CharOperation.equals(TypeConstants.ORG_ECLIPSE_JDT_INTERNAL_COMPILER_LOOKUP_TYPEBINDING, this.compoundName))
+ this.typeBits |= TypeIds.BitUninternedType;
+ break;
}
}
@@ -1339,8 +1345,6 @@ boolean hasNonNullDefault() {
public final boolean hasRestrictedAccess() {
return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
}
-/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
-abstract public boolean hasTypeBit(int bit);
//{ObjectTeams: support asymmetric comparison. // FIXME(SH): is this needed or is super-impl smart enough??
@Override
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 16f12924e..f6499edb2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -23,6 +23,7 @@
* bug 388281 - [compiler][null] inheritance of null annotations as an option
* bug 331649 - [compiler][null] consider null annotations for fields
* bug 380896 - [compiler][null] Enum constants not recognised as being NonNull.
+ * Bug 418235 - [compiler][null] Unreported nullness error when using generic
* Till Brychcy - Contributions for
* bug 415269 - NonNullByDefault is not always inherited to nested classes
*******************************************************************************/
@@ -2403,9 +2404,8 @@ private void createArgumentBindings(MethodBinding method, CompilerOptions compil
methodDecl.createArgumentBindings();
// add implicit annotations (inherited(?) & default):
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
-//{ObjectTeams: added 2nd ctor arg:
- new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations, this.scope.environment()).checkImplicitNullAnnotations(method, methodDecl, true, this.scope);
-// SH}
+ new ImplicitNullAnnotationVerifier(this.scope.environment(), compilerOptions.inheritNullAnnotations)
+ .checkImplicitNullAnnotations(method, methodDecl, true, this.scope);
}
}
}
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 f5f61ef73..32e2ca5ca 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
@@ -1294,4 +1294,8 @@ public DependentTypeBinding asPlainDependentType() {
return null; // is not a dependent type
}
// SH}
+/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
+public boolean hasTypeBit(int bit) {
+ return false;
+}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index 6c801d9a3..b708a579b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -95,7 +95,12 @@ public interface TypeConstants {
char[] LANG3 = "lang3".toCharArray(); //$NON-NLS-1$
char[] COM = "com".toCharArray(); //$NON-NLS-1$
char[] GOOGLE = "google".toCharArray(); //$NON-NLS-1$
-
+ char[] JDT = "jdt".toCharArray(); //$NON-NLS-1$
+ char[] INTERNAL = "internal".toCharArray(); //$NON-NLS-1$
+ char[] COMPILER = "compiler".toCharArray(); //$NON-NLS-1$
+ char[] LOOKUP = "lookup".toCharArray(); //$NON-NLS-1$
+ char[] TYPEBINDING = "TypeBinding".toCharArray(); //$NON-NLS-1$
+
// Constant compound names
char[][] JAVA_LANG = {JAVA, LANG};
char[][] JAVA_IO = {JAVA, IO};
@@ -272,6 +277,7 @@ public interface TypeConstants {
char[] VALIDATE_CLASS = "Validate".toCharArray(); //$NON-NLS-1$
char[][] ORG_APACHE_COMMONS_LANG_VALIDATE = new char[][] { ORG, APACHE, COMMONS, LANG, VALIDATE_CLASS };
char[][] ORG_APACHE_COMMONS_LANG3_VALIDATE = new char[][] { ORG, APACHE, COMMONS, LANG3, VALIDATE_CLASS };
+ char[][] ORG_ECLIPSE_JDT_INTERNAL_COMPILER_LOOKUP_TYPEBINDING = new char[][] { ORG, ECLIPSE, JDT, INTERNAL, COMPILER, LOOKUP, TYPEBINDING };
// ... methods:
char[] IS_TRUE = "isTrue".toCharArray(); //$NON-NLS-1$
char[] NOT_NULL = "notNull".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index 5703e17c1..e19710ace 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -231,8 +231,9 @@ public interface TypeIds {
*/
final int BitResourceFreeCloseable = 8;
+ final int BitUninternedType = 16;
/**
* Set of type bits that should be inherited by any sub types.
*/
- final int InheritableBits = BitAutoCloseable | BitCloseable;
+ final int InheritableBits = BitAutoCloseable | BitCloseable | BitUninternedType;
}
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 048c40680..ee856293f 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
@@ -13121,4 +13121,32 @@ public void missingNonNullByDefaultAnnotation(TypeDeclaration type) {
compUnitDecl.currentPackage.sourceEnd);
}
}
+public void uninternedIdentityComparison(EqualExpression expr, TypeBinding lhs, TypeBinding rhs) {
+
+ char [] lhsName = lhs.sourceName();
+ char [] rhsName = rhs.sourceName();
+
+ if (CharOperation.equals(lhsName, "VoidTypeBinding".toCharArray()) //$NON-NLS-1$
+ || CharOperation.equals(lhsName, "NullTypeBinding".toCharArray()) //$NON-NLS-1$
+ || CharOperation.equals(lhsName, "ProblemReferenceBinding".toCharArray())) //$NON-NLS-1$
+ return;
+
+ if (CharOperation.equals(rhsName, "VoidTypeBinding".toCharArray()) //$NON-NLS-1$
+ || CharOperation.equals(rhsName, "NullTypeBinding".toCharArray()) //$NON-NLS-1$
+ || CharOperation.equals(rhsName, "ProblemReferenceBinding".toCharArray())) //$NON-NLS-1$
+ return;
+
+ this.handle(
+ IProblem.UninternedIdentityComparison,
+ new String[] {
+ new String(lhs.readableName()),
+ new String(rhs.readableName())
+ },
+ new String[] {
+ new String(lhs.shortReadableName()),
+ new String(rhs.shortReadableName())
+ },
+ expr.sourceStart,
+ expr.sourceEnd);
+}
}
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 92cdd61de..22d0da4f1 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
@@ -45,12 +45,12 @@
23 = Illegal enclosing instance specification for type {0}
24 = Cannot define static initializer in inner type {0}
25 = Cannot refer to a non-final variable {0} inside an inner class defined in a different method
-26 = The member interface {0} can only be defined inside a top-level class or interface
+26 = The member interface {0} can only be defined inside a top-level class or interface or in a static context
27 = Cannot use an expression of the type {0} as a valid enclosing instance
28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation
29 = An anonymous class cannot subclass the final class {0}
-30 = The member annotation {0} can only be defined inside a top-level class or interface
-31 = The member enum {0} can only be defined inside a top-level class or interface
+30 = The member annotation {0} can only be defined inside a top-level class or interface or in a static context
+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}
@@ -396,6 +396,7 @@
440 = 'assert' should not be used as an identifier, since it is a reserved keyword from source level 1.4 on
441 = 'enum' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on
442 = Enum constants cannot be surrounded by parenthesis
+443 = The uninterned types {0} and {1} should not be compared using ==/!= operators.
450 = {0}{1}

Back to the top