Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2014-11-11 20:35:54 +0000
committerStephan Herrmann2014-11-11 20:35:54 +0000
commit4194d1760530eb281a099ab365ea7dcb0dfadf22 (patch)
treebf9e6ead15f6b3e81738eef1ebb0f77c8b86d66e /org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast
parent5cb0427a4624e351329b5f2b51a3d36b82b7d595 (diff)
downloadorg.eclipse.objectteams-4194d1760530eb281a099ab365ea7dcb0dfadf22.tar.gz
org.eclipse.objectteams-4194d1760530eb281a099ab365ea7dcb0dfadf22.tar.xz
org.eclipse.objectteams-4194d1760530eb281a099ab365ea7dcb0dfadf22.zip
(right before bug 437444)
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast')
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java67
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java7
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java41
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java46
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java35
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java62
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java37
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java58
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java6
15 files changed, 227 insertions, 160 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 1449ff1b1..362aeeadb 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
@@ -565,6 +565,11 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
return false;
}
+ public boolean isQualifiedSuper() {
+
+ return false;
+ }
+
public boolean isThis() {
return false;
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 fa9b241f7..e378b439f 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
@@ -110,6 +110,8 @@ public class AllocationExpression extends Expression implements Invocation {
// hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
private SimpleLookupTable/*<PMB,IC18>*/ inferenceContexts;
protected InnerInferenceHelper innerInferenceHelper;
+ public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+ public boolean argumentsHaveErrors;
/** Record to keep state between different parts of resolution. */
ResolutionState suspendedResolutionState;
@@ -119,7 +121,6 @@ public class AllocationExpression extends Expression implements Invocation {
boolean diamondNeedsDeferring;
boolean argsContainCast;
boolean cannotInferDiamond; // request the an error be reported in due time
- TypeBinding[] argumentTypes;
boolean hasReportedError;
ResolutionState(BlockScope scope, boolean isDiamond, boolean diamonNeedsDeferring,
@@ -129,7 +130,6 @@ public class AllocationExpression extends Expression implements Invocation {
this.isDiamond = isDiamond;
this.diamondNeedsDeferring = diamonNeedsDeferring;
this.argsContainCast = argsContainCast;
- this.argumentTypes = argumentTypes;
}
}
@@ -167,7 +167,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
}
this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
- }
+ }
analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
}
@@ -468,14 +468,14 @@ public TypeBinding resolveType(BlockScope scope) {
// resolve type arguments (for generic constructor call)
if (this.typeArguments != null) {
int length = this.typeArguments.length;
- boolean argHasError = sourceLevel < ClassFileConstants.JDK1_5;
+ this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
this.genericTypeArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
TypeReference typeReference = this.typeArguments[i];
if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
- argHasError = true;
+ this.argumentsHaveErrors = true;
}
- if (argHasError && typeReference instanceof Wildcard) {
+ if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
scope.problemReporter().illegalUsageOfWildcard(typeReference);
}
}
@@ -483,7 +483,7 @@ public TypeBinding resolveType(BlockScope scope) {
scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
return null;
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
if (this.arguments != null) { // still attempt to resolve arguments
for (int i = 0, max = this.arguments.length; i < max; i++) {
this.arguments[i].resolveType(scope);
@@ -495,11 +495,10 @@ public TypeBinding resolveType(BlockScope scope) {
// buffering the arguments' types
boolean argsContainCast = false;
- TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
if (this.arguments != null) {
- boolean argHasError = false;
+ this.argumentsHaveErrors = false;
int length = this.arguments.length;
- argumentTypes = new TypeBinding[length];
+ this.argumentTypes = new TypeBinding[length];
for (int i = 0; i < length; i++) {
Expression argument = this.arguments[i];
if (argument instanceof CastExpression) {
@@ -509,25 +508,25 @@ public TypeBinding resolveType(BlockScope scope) {
argument.setExpressionContext(INVOCATION_CONTEXT);
//{ObjectTeams: generated arguments can be pre-resolved indeed:
if (argument.resolvedType != null && argument.isGenerated()) {
- argumentTypes[i] = argument.resolvedType;
- if (argumentTypes[i] == null)
- argHasError = true;
+ this.argumentTypes[i] = argument.resolvedType;
+ if (this.argumentTypes[i] == null)
+ this.argumentsHaveErrors = true;
} else {
// orig:
if (this.arguments[i].resolvedType != null)
scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this); //$NON-NLS-1$
- if ((argumentTypes[i] = argument.resolveType(scope)) == null) {
- argHasError = true;
+ if ((this.argumentTypes[i] = argument.resolveType(scope)) == null) {
+ this.argumentsHaveErrors = true;
}
// :giro
}
// SH}
- if (sourceLevel >= ClassFileConstants.JDK1_8 && argument.isPolyExpression()) {
+ if (sourceLevel >= ClassFileConstants.JDK1_8 && (argument.isPolyExpression() || ((argument instanceof Invocation) && ((Invocation) argument).usesInference()))) {
if (this.innerInferenceHelper == null)
this.innerInferenceHelper = new InnerInferenceHelper();
}
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
not return the partially resolved type.
@@ -539,7 +538,7 @@ public TypeBinding resolveType(BlockScope scope) {
// record a best guess, for clients who need hint about possible constructor match
TypeBinding[] pseudoArgs = new TypeBinding[length];
for (int i = length; --i >= 0;) {
- pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+ pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i]; // replace args with errors with null type
}
this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
@@ -571,7 +570,7 @@ public TypeBinding resolveType(BlockScope scope) {
scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
return this.resolvedType;
}
- ResolutionState state = new ResolutionState(scope, isDiamond, diamondNeedsDeferring, argsContainCast, argumentTypes);
+ ResolutionState state = new ResolutionState(scope, isDiamond, diamondNeedsDeferring, argsContainCast, this.argumentTypes);
if (diamondNeedsDeferring) {
this.suspendedResolutionState = state; // resolving to be continued later (via binding(TypeBinding targetType)).
return new PolyTypeBinding(this);
@@ -587,7 +586,7 @@ boolean resolvePart2(ResolutionState state) {
// TODO: all information persisted during this method may need to be stored per targetType?
if (state.isDiamond) {
ReferenceBinding genericType = ((ParameterizedTypeBinding) this.resolvedType).genericType();
- TypeBinding [] inferredTypes = inferElidedTypes((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), state.argumentTypes, state.scope);
+ TypeBinding [] inferredTypes = inferElidedTypes((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), this.argumentTypes, state.scope);
if (inferredTypes == null) {
if (!state.diamondNeedsDeferring) {
state.scope.problemReporter().cannotInferElidedTypes(this);
@@ -608,7 +607,7 @@ boolean resolvePart2(ResolutionState state) {
// ensure allocation type has methods:
Dependencies.ensureBindingState(receiverType, ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS);
// SH}
- this.binding = findConstructorBinding(state.scope, this, receiverType, state.argumentTypes);
+ this.binding = findConstructorBinding(state.scope, this, receiverType, this.argumentTypes);
//:giro
} finally {
AnchorMapping.removeCurrentMapping(anchorMapping);
@@ -625,7 +624,7 @@ TypeBinding resolvePart3(ResolutionState state) {
if (state.cannotInferDiamond) {
state.scope.problemReporter().cannotInferElidedTypes(this);
return this.resolvedType = null;
- }
+ }
ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
if (!this.binding.isValidBinding()) {
//{ObjectTeams: baseclass decapsulation?
@@ -664,20 +663,20 @@ TypeBinding resolvePart3(ResolutionState state) {
}
if (isMethodUseDeprecated(this.binding, state.scope, true)) {
state.scope.problemReporter().deprecatedMethod(this.binding, this);
- }
- if (checkInvocationArguments(state.scope, null, allocationType, this.binding, this.arguments, state.argumentTypes, state.argsContainCast, this)) {
+ }
+ if (checkInvocationArguments(state.scope, null, allocationType, this.binding, this.arguments, this.argumentTypes, state.argsContainCast, this)) {
this.bits |= ASTNode.Unchecked;
}
if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
state.scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
}
if (!state.isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
- checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), state.argumentTypes, state.scope);
+ checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, this.resolvedType.enclosingType(), this.argumentTypes, state.scope);
}
CompilerOptions compilerOptions = state.scope.compilerOptions();
if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
new ImplicitNullAnnotationVerifier(state.scope.environment(), compilerOptions.inheritNullAnnotations)
- .checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, state.scope);
+ .checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, state.scope);
}
recordExceptionsForEnclosingLambda(state.scope, this.binding.thrownExceptions);
//{ObjectTeams: may need to wrap the resolved type
@@ -732,13 +731,13 @@ void checkIllegalNullAnnotation(BlockScope scope, TypeBinding allocationType) {
}
}
-public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTyps, final BlockScope scope) {
/* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
to the types elided in the <>.
*/
- MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTypes, this);
+ MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTyps, this);
if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
this.inferredReturnType = genericFactory.inferredReturnType;
@@ -748,9 +747,9 @@ public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding allocationType, R
// refresh argumentTypes from updated bindings in arguments:
// (this shouldn't be strictly necessary, as FunctionExpression.isCompatibleWith() should give the same result,
// but it's probably be a good idea to avoid the necessity to call isCompatibleWith() in the first place).
- for (int i = 0; i < argumentTypes.length; i++) {
- if (argumentTypes[i] instanceof PolyTypeBinding)
- argumentTypes[i] = this.arguments[i].resolvedType;
+ for (int i = 0; i < argumentTyps.length; i++) {
+ if (argumentTyps[i] instanceof PolyTypeBinding)
+ argumentTyps[i] = this.arguments[i].resolvedType;
}
}
return ((ParameterizedTypeBinding)factory.returnType).arguments;
@@ -758,12 +757,12 @@ public TypeBinding[] inferElidedTypes(ParameterizedTypeBinding allocationType, R
return null;
}
-public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTyps, final BlockScope scope) {
if ((scope.problemReporter().computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
if (allocationType.arguments == null) return; // raw binding
if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
if (this.type == null) return;
- if (argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
+ if (argumentTyps == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
// check the case when no ctor takes no params and inference uses the expected type directly
@@ -785,7 +784,7 @@ public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType,
// checking for redundant type parameters must fake a diamond,
// so we infer the same results as we would get with a diamond in source code:
this.type.bits |= IsDiamond;
- inferredTypes = inferElidedTypes(allocationType, enclosingType, argumentTypes, scope);
+ inferredTypes = inferElidedTypes(allocationType, enclosingType, argumentTyps, scope);
} finally {
// reset effects of inference
this.type.bits = previousBits;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index 54b6c6661..bcb140544 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -228,7 +228,7 @@ public TypeBinding resolveType(BlockScope scope) {
this.expression.setExpressionContext(ASSIGNMENT_CONTEXT);
this.expression.setExpectedType(lhsType); // needed in case of generic method invocation
if (lhsType != null) {
- this.resolvedType = lhsType.capture(scope, this.sourceEnd);
+ this.resolvedType = lhsType.capture(scope, this.lhs.sourceEnd); // make it unique, `this' shares source end with 'this.expression'.
}
LocalVariableBinding localVariableBinding = this.lhs.localVariableBinding();
if (localVariableBinding != null && (localVariableBinding.isCatchParameter() || localVariableBinding.isParameter())) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
index df65187ff..3a5783171 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -39,12 +39,7 @@ public class Block extends Statement {
public int explicitDeclarations;
// the number of explicit declaration , used to create scope
public BlockScope scope;
- public boolean lambdaBody;
-public Block(int explicitDeclarations, boolean lambdaBody) {
- this.explicitDeclarations = explicitDeclarations;
- this.lambdaBody = lambdaBody;
-}
public Block(int explicitDeclarations) {
this.explicitDeclarations = explicitDeclarations;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index 55efa4eb8..c5f85a88a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -374,8 +374,9 @@ private static void checkAlternateBinding(BlockScope scope, Expression receiver,
public int sourceEnd() { return 0; }
public TypeBinding invocationTargetType() { return invocationSite.invocationTargetType(); }
public boolean receiverIsImplicitThis() { return invocationSite.receiverIsImplicitThis();}
- public InferenceContext18 freshInferenceContext(Scope someScope) { return null; /* suppress inference */ }
+ public InferenceContext18 freshInferenceContext(Scope someScope) { return invocationSite.freshInferenceContext(someScope); }
public ExpressionContext getExpressionContext() { return invocationSite.getExpressionContext(); }
+ public boolean isQualifiedSuper() { return invocationSite.isQualifiedSuper(); }
};
MethodBinding bindingIfNoCast;
if (binding.isConstructor()) {
@@ -421,7 +422,8 @@ public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding ex
castType = ((WeakenedTypeBinding)castType).getStrongType();
// SH}
if (TypeBinding.equalsEquals(match, castType)) {
- if (!isNarrowing && TypeBinding.equalsEquals(match, this.resolvedType.leafComponentType())) { // do not tag as unnecessary when recursing through upper bounds
+ if (!isNarrowing && TypeBinding.equalsEquals(match, this.resolvedType.leafComponentType()) // do not tag as unnecessary when recursing through upper bounds
+ && !(expressionType.isParameterizedType() && expressionType.isProvablyDistinct(castType))) {
tagAsUnnecessaryCast(scope, castType);
}
return true;
@@ -736,7 +738,7 @@ public TypeBinding resolveType(BlockScope scope) {
this.bits |= ASTNode.DisableUnnecessaryCastCheck; // disable further secondary diagnosis
}
}
- this.resolvedType = castType.capture(scope, this.sourceEnd);
+ this.resolvedType = castType.capture(scope, this.type.sourceEnd); // make it unique, a cast expression shares source end with the expression.
if (exprContainCast) {
checkNeedForCastCast(scope, this);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index f5b3c1d7a..a7552681d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -509,7 +509,7 @@ public class ExplicitConstructorCall extends Statement implements Invocation {
argumentTypes[i] = argument.resolvedType;
}
// SH}
- if (sourceLevel >= ClassFileConstants.JDK1_8 && argument.isPolyExpression()) {
+ if (sourceLevel >= ClassFileConstants.JDK1_8 && (argument.isPolyExpression() || ((argument instanceof Invocation) && ((Invocation) argument).usesInference()))) {
if (this.innerInferenceHelper == null)
this.innerInferenceHelper = new InnerInferenceHelper();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index affb2effb..67fb64226 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.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
@@ -542,6 +542,11 @@ public boolean isSuperAccess() {
return this.receiver.isSuper();
}
+@Override
+public boolean isQualifiedSuper() {
+ return this.receiver.isQualifiedSuper();
+}
+
public boolean isTypeAccess() {
return this.receiver != null && this.receiver.isTypeReference();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
index 005fcc8c9..903f4443b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
@@ -4,7 +4,6 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- * $Id: JavadocAllocationExpression.java 19873 2009-04-13 16:51:05Z stephan $
*
* Contributors:
* IBM Corporation - initial API and implementation
@@ -53,26 +52,26 @@ public class JavadocAllocationExpression extends AllocationExpression {
}
// buffering the arguments' types
- TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+ this.argumentTypes = Binding.NO_PARAMETERS;
boolean hasTypeVarArgs = false;
if (this.arguments != null) {
- boolean argHasError = false;
+ this.argumentsHaveErrors = false;
int length = this.arguments.length;
- argumentTypes = new TypeBinding[length];
+ this.argumentTypes = new TypeBinding[length];
for (int i = 0; i < length; i++) {
Expression argument = this.arguments[i];
if (scope.kind == Scope.CLASS_SCOPE) {
- argumentTypes[i] = argument.resolveType((ClassScope)scope);
+ this.argumentTypes[i] = argument.resolveType((ClassScope)scope);
} else {
- argumentTypes[i] = argument.resolveType((BlockScope)scope);
+ this.argumentTypes[i] = argument.resolveType((BlockScope)scope);
}
- if (argumentTypes[i] == null) {
- argHasError = true;
+ if (this.argumentTypes[i] == null) {
+ this.argumentsHaveErrors = true;
} else if (!hasTypeVarArgs) {
- hasTypeVarArgs = argumentTypes[i].isTypeVariable();
+ hasTypeVarArgs = this.argumentTypes[i].isTypeVariable();
}
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
return null;
}
}
@@ -88,13 +87,13 @@ public class JavadocAllocationExpression extends AllocationExpression {
}
ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
- this.binding = scope.getConstructor(allocationType, argumentTypes, this);
+ this.binding = scope.getConstructor(allocationType, this.argumentTypes, this);
if (!this.binding.isValidBinding()) {
ReferenceBinding enclosingTypeBinding = allocationType;
MethodBinding contructorBinding = this.binding;
while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
enclosingTypeBinding = enclosingTypeBinding.enclosingType();
- contructorBinding = scope.getConstructor(enclosingTypeBinding, argumentTypes, this);
+ contructorBinding = scope.getConstructor(enclosingTypeBinding, this.argumentTypes, this);
}
if (contructorBinding.isValidBinding()) {
this.binding = contructorBinding;
@@ -103,7 +102,7 @@ public class JavadocAllocationExpression extends AllocationExpression {
if (!this.binding.isValidBinding()) {
// First try to search a method instead
//{ObjectTeams: don't use beautified name.
- MethodBinding methodBinding = scope.getMethod(this.resolvedType, this.resolvedType.internalName(), argumentTypes, this);
+ MethodBinding methodBinding = scope.getMethod(this.resolvedType, this.resolvedType.internalName(), this.argumentTypes, this);
// SH}
if (methodBinding.isValidBinding()) {
this.binding = methodBinding;
@@ -115,22 +114,22 @@ public class JavadocAllocationExpression extends AllocationExpression {
}
return this.resolvedType;
} else if (this.binding.isVarargs()) {
- int length = argumentTypes.length;
- if (!(this.binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+ int length = this.argumentTypes.length;
+ if (!(this.binding.parameters.length == length && this.argumentTypes[length-1].isArrayType())) {
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
}
} else if (hasTypeVarArgs) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
} else if (this.binding instanceof ParameterizedMethodBinding) {
ParameterizedMethodBinding paramMethodBinding = (ParameterizedMethodBinding) this.binding;
if (paramMethodBinding.hasSubstitutedParameters()) {
- int length = argumentTypes.length;
+ int length = this.argumentTypes.length;
for (int i=0; i<length; i++) {
- if (TypeBinding.notEquals(paramMethodBinding.parameters[i], argumentTypes[i]) &&
- TypeBinding.notEquals(paramMethodBinding.parameters[i].erasure(), argumentTypes[i].erasure())) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+ if (TypeBinding.notEquals(paramMethodBinding.parameters[i], this.argumentTypes[i]) &&
+ TypeBinding.notEquals(paramMethodBinding.parameters[i].erasure(), this.argumentTypes[i].erasure())) {
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
break;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
index ef5ed425e..ec65a8edc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -4,7 +4,6 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- * $Id: JavadocMessageSend.java 23405 2010-02-03 17:02:18Z stephan $
*
* Contributors:
* IBM Corporation - initial API and implementation
@@ -61,26 +60,25 @@ public class JavadocMessageSend extends MessageSend {
// will check for null after args are resolved
- TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
boolean hasArgsTypeVar = false;
if (this.arguments != null) {
- boolean argHasError = false; // typeChecks all arguments
+ this.argumentsHaveErrors = false; // typeChecks all arguments
int length = this.arguments.length;
- argumentTypes = new TypeBinding[length];
+ this.argumentTypes = new TypeBinding[length];
for (int i = 0; i < length; i++){
Expression argument = this.arguments[i];
if (scope.kind == Scope.CLASS_SCOPE) {
- argumentTypes[i] = argument.resolveType((ClassScope)scope);
+ this.argumentTypes[i] = argument.resolveType((ClassScope)scope);
} else {
- argumentTypes[i] = argument.resolveType((BlockScope)scope);
+ this.argumentTypes[i] = argument.resolveType((BlockScope)scope);
}
- if (argumentTypes[i] == null) {
- argHasError = true;
+ if (this.argumentTypes[i] == null) {
+ this.argumentsHaveErrors = true;
} else if (!hasArgsTypeVar) {
- hasArgsTypeVar = argumentTypes[i].isTypeVariable();
+ hasArgsTypeVar = this.argumentTypes[i].isTypeVariable();
}
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
return null;
}
}
@@ -97,15 +95,15 @@ public class JavadocMessageSend extends MessageSend {
// base type cannot receive any message
if (this.actualReceiverType.isBaseType()) {
- scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
+ scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, this.argumentTypes, scope.getDeclarationModifiers());
return null;
}
// {ObjectTeams:
AnchorMapping anchorMapping = null;
try {
- anchorMapping = beforeMethodLookup(argumentTypes, scope);
+ anchorMapping = beforeMethodLookup(this.argumentTypes, scope);
// jwl}
- this.binding = scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+ this.binding = scope.getMethod(this.actualReceiverType, this.selector, this.argumentTypes, this);
// {ObjectTeams:
} finally {
// added by haebor according to MessageSend.resolveType(BlockScope)
@@ -120,7 +118,7 @@ public class JavadocMessageSend extends MessageSend {
MethodBinding methodBinding = this.binding;
while (!methodBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
enclosingTypeBinding = enclosingTypeBinding.enclosingType();
- methodBinding = scope.getMethod(enclosingTypeBinding, this.selector, argumentTypes, this);
+ methodBinding = scope.getMethod(enclosingTypeBinding, this.selector, this.argumentTypes, this);
}
if (methodBinding.isValidBinding()) {
this.binding = methodBinding;
@@ -129,12 +127,12 @@ public class JavadocMessageSend extends MessageSend {
enclosingTypeBinding = this.actualReceiverType;
MethodBinding contructorBinding = this.binding;
if (!contructorBinding.isValidBinding() && CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
- contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
+ contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, this.argumentTypes, this);
}
while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
enclosingTypeBinding = enclosingTypeBinding.enclosingType();
if (CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
- contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
+ contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, this.argumentTypes, this);
}
}
if (contructorBinding.isValidBinding()) {
@@ -164,7 +162,7 @@ public class JavadocMessageSend extends MessageSend {
if (this.actualReceiverType instanceof ReferenceBinding) {
this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
} else {
- scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
+ scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, this.argumentTypes, scope.getDeclarationModifiers());
return null;
}
}
@@ -176,19 +174,19 @@ public class JavadocMessageSend extends MessageSend {
}
return this.resolvedType = this.binding == null ? null : this.binding.returnType;
} else if (hasArgsTypeVar) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
} else if (this.binding.isVarargs()) {
- int length = argumentTypes.length;
- if (!(this.binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+ int length = this.argumentTypes.length;
+ if (!(this.binding.parameters.length == length && this.argumentTypes[length-1].isArrayType())) {
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
}
} else {
- int length = argumentTypes.length;
+ int length = this.argumentTypes.length;
for (int i=0; i<length; i++) {
- if (TypeBinding.notEquals(this.binding.parameters[i].erasure(), argumentTypes[i].erasure())) {
- MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+ if (TypeBinding.notEquals(this.binding.parameters[i].erasure(), this.argumentTypes[i].erasure())) {
+ MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, this.argumentTypes, ProblemReasons.NotFound);
scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
break;
}
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 a23c17fc0..a7dd51aa5 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
@@ -107,6 +107,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
private boolean shapeAnalysisComplete = false;
boolean returnsValue;
public boolean isSerializable;
+ private boolean requiresGenericSignature;
boolean returnsVoid;
public LambdaExpression original = this;
public SyntheticArgumentBinding[] outerLocalVariables = NO_SYNTHETIC_ARGUMENTS;
@@ -119,15 +120,20 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
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);
+ private static final Block NO_BODY = new Block(0);
- public LambdaExpression(CompilationResult compilationResult, boolean assistNode) {
+ public LambdaExpression(CompilationResult compilationResult, boolean assistNode, boolean requiresGenericSignature) {
super(compilationResult);
this.assistNode = assistNode;
+ this.requiresGenericSignature = requiresGenericSignature;
setArguments(NO_ARGUMENTS);
setBody(NO_BODY);
}
-
+
+ public LambdaExpression(CompilationResult compilationResult, boolean assistNode) {
+ this(compilationResult, assistNode, false);
+ }
+
public void setArguments(Argument [] arguments) {
this.arguments = arguments != null ? arguments : ASTNode.NO_ARGUMENTS;
this.argumentTypes = new TypeBinding[arguments != null ? arguments.length : 0];
@@ -172,6 +178,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
this.binding.modifiers |= ClassFileConstants.AccStatic;
}
SourceTypeBinding sourceType = currentScope.enclosingSourceType();
+ boolean firstSpill = !(this.binding instanceof SyntheticMethodBinding);
this.binding = sourceType.addSyntheticMethod(this);
int pc = codeStream.position;
StringBuffer signature = new StringBuffer();
@@ -182,7 +189,7 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
}
for (int i = 0, length = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length; i < length; i++) {
SyntheticArgumentBinding syntheticArgument = this.outerLocalVariables[i];
- if (this.shouldCaptureInstance) {
+ if (this.shouldCaptureInstance && firstSpill) { // finally block handling results in extra spills, avoid side effect.
syntheticArgument.resolvedPosition++;
}
signature.append(syntheticArgument.type.signature());
@@ -336,7 +343,11 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
this.resolvedType = null; // continue to type check.
}
}
-
+ if (this.requiresGenericSignature) {
+ 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;
@@ -372,6 +383,8 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if ((exception.tagBits & TagBits.HasMissingType) != 0) {
this.binding.tagBits |= TagBits.HasMissingType;
}
+ if (this.requiresGenericSignature)
+ this.binding.modifiers |= (exception.modifiers & ExtraCompilerModifiers.AccGenericSignature);
}
TypeBinding returnType = this.binding.returnType;
@@ -379,6 +392,11 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if ((returnType.tagBits & TagBits.HasMissingType) != 0) {
this.binding.tagBits |= TagBits.HasMissingType;
}
+ if (this.requiresGenericSignature) {
+ 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) {
@@ -414,6 +432,9 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
this.scope.problemReporter().missingTypeInLambda(this, this.binding);
}
+ if (this.shouldCaptureInstance && this.scope.isConstructorCall) {
+ this.scope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this);
+ }
return this.resolvedType;
}
@@ -733,12 +754,14 @@ public class LambdaExpression extends FunctionalExpression implements ReferenceC
if (this.body instanceof Block) {
if (this.returnsVoid) {
this.shapeAnalysisComplete = true;
+ break shapeAnalysis;
}
} else {
- final Expression expressionBody = (Expression) this.body;
+ final Expression expressionBody = (Expression) copy.body;
this.voidCompatible = this.assistNode ? true : expressionBody.statementExpression();
this.valueCompatible = expressionBody.resolvedType != TypeBinding.VOID;
this.shapeAnalysisComplete = true;
+ break shapeAnalysis;
}
// Do not proceed with data/control flow analysis if resolve encountered errors.
if (this.hasIgnoredMandatoryErrors || enclosingScopesHaveErrors()) {
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 d363c0dcf..75db50709 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
@@ -193,6 +193,11 @@ public class MessageSend extends Expression implements Invocation {
// hold on to this context from invocation applicability inference until invocation type inference (per method candidate):
private SimpleLookupTable/*<PGMB,InferenceContext18>*/ inferenceContexts;
protected InnerInferenceHelper innerInferenceHelper;
+ private boolean receiverIsType;
+ protected boolean argsContainCast;
+ public TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+ public boolean argumentsHaveErrors;
+
//{ObjectTeams:
private boolean isDecapsulation = false;
@@ -802,7 +807,7 @@ public TypeBinding resolveType(BlockScope scope) {
this.constant = Constant.NotAConstant;
long sourceLevel = scope.compilerOptions().sourceLevel;
- boolean receiverCast = false, argsContainCast = false;
+ boolean receiverCast = false;
if (this.receiver instanceof CastExpression) {
this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
receiverCast = true;
@@ -818,10 +823,10 @@ public TypeBinding resolveType(BlockScope scope) {
// :giro
}
/*orig:
- boolean receiverIsType = this.receiver instanceof NameReference && (((NameReference) this.receiver).bits & Binding.TYPE) != 0;
+ this.receiverIsType = this.receiver instanceof NameReference && (((NameReference) this.receiver).bits & Binding.TYPE) != 0;
*/
// don't only expect NameReference, BaseReference can be static, too.
- boolean receiverIsType = ( (this.receiver instanceof NameReference)
+ this.receiverIsType = ( (this.receiver instanceof NameReference)
|| (this.receiver instanceof BaseReference))
&& (this.receiver.bits & Binding.TYPE) != 0
|| (this.receiver instanceof TypeReference); // happens in generated AST
@@ -835,18 +840,18 @@ public TypeBinding resolveType(BlockScope scope) {
// resolve type arguments (for generic constructor call)
if (this.typeArguments != null) {
int length = this.typeArguments.length;
- boolean argHasError = sourceLevel < ClassFileConstants.JDK1_5; // typeChecks all arguments
+ this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5; // typeChecks all arguments
this.genericTypeArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
TypeReference typeReference = this.typeArguments[i];
if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
- argHasError = true;
+ this.argumentsHaveErrors = true;
}
- if (argHasError && typeReference instanceof Wildcard) {
+ if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
scope.problemReporter().illegalUsageOfWildcard(typeReference);
}
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
if (this.arguments != null) { // still attempt to resolve arguments
for (int i = 0, max = this.arguments.length; i < max; i++) {
this.arguments[i].resolveType(scope);
@@ -856,11 +861,10 @@ public TypeBinding resolveType(BlockScope scope) {
}
}
// will check for null after args are resolved
- TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
if (this.arguments != null) {
- boolean argHasError = false; // typeChecks all arguments
+ this.argumentsHaveErrors = false; // typeChecks all arguments
int length = this.arguments.length;
- argumentTypes = new TypeBinding[length];
+ this.argumentTypes = new TypeBinding[length];
for (int i = 0; i < length; i++){
Expression argument = this.arguments[i];
//{ObjectTeams: keep pre-resolved binding inside generated code:
@@ -870,16 +874,16 @@ public TypeBinding resolveType(BlockScope scope) {
scope.problemReporter().genericInferenceError("Argument was unexpectedly found resolved", this); //$NON-NLS-1$
if (argument instanceof CastExpression) {
argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
- argsContainCast = true;
+ this.argsContainCast = true;
}
argument.setExpressionContext(INVOCATION_CONTEXT);
//{ObjectTeams: arguments might already be resolved, see e.g. CastExpression.createRoleCheck
if (argument.resolvedType != null) {
- argumentTypes[i] = argument.resolvedType;
+ this.argumentTypes[i] = argument.resolvedType;
} else {
// orig:
- if ((argumentTypes[i] = argument.resolveType(scope)) == null){
- argHasError = true;
+ if ((this.argumentTypes[i] = argument.resolveType(scope)) == null){
+ this.argumentsHaveErrors = true;
}
// :giro
}
@@ -892,12 +896,12 @@ public TypeBinding resolveType(BlockScope scope) {
}
}
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
if (this.actualReceiverType instanceof ReferenceBinding) {
// record a best guess, for clients who need hint about possible method match
TypeBinding[] pseudoArgs = new TypeBinding[length];
for (int i = length; --i >= 0;)
- pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+ pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i]; // replace args with errors with null type
this.binding =
this.receiver.isImplicitThis()
? scope.getImplicitMethod(this.selector, pseudoArgs, this)
@@ -933,7 +937,7 @@ public TypeBinding resolveType(BlockScope scope) {
}
// base type cannot receive any message
if (this.actualReceiverType.isBaseType()) {
- scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+ scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, this.argumentTypes);
return null;
}
//{ObjectTeams: revert receiver weakening & setup anchorMapping:
@@ -974,7 +978,7 @@ public TypeBinding resolveType(BlockScope scope) {
this.selector=IOTConstants._OT_GETBASE;
// orig:
- findMethodBinding(scope, argumentTypes);
+ findMethodBinding(scope);
// :giro
if (this.binding == null)
@@ -1043,7 +1047,7 @@ public TypeBinding resolveType(BlockScope scope) {
if (this.actualReceiverType instanceof ReferenceBinding) {
this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
} else {
- scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+ scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, this.argumentTypes);
return null;
}
}
@@ -1161,7 +1165,7 @@ public TypeBinding resolveType(BlockScope scope) {
}
if (!this.binding.isStatic()) {
// the "receiver" must not be a type
- if (receiverIsType) {
+ if (this.receiverIsType) {
scope.problemReporter().mustUseAStaticMethod(this, this.binding);
if (this.actualReceiverType.isRawType()
&& (this.receiver.bits & ASTNode.IgnoreRawTypeCheck) == 0
@@ -1180,14 +1184,14 @@ public TypeBinding resolveType(BlockScope scope) {
}
} else {
// static message invoked through receiver? legal but unoptimal (optional warning).
- if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || receiverIsType)) {
+ if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || this.receiverIsType)) {
scope.problemReporter().nonStaticAccessToStaticMethod(this, this.binding);
}
if (!this.receiver.isImplicitThis() && TypeBinding.notEquals(this.binding.declaringClass, this.actualReceiverType)) {
scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
}
}
- if (checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+ if (checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, this.argumentTypes, this.argsContainCast, this)) {
this.bits |= ASTNode.Unchecked;
}
@@ -1277,7 +1281,7 @@ public TypeBinding resolveType(BlockScope scope) {
}
if (this.receiver.isSuper() && this.actualReceiverType.isInterface()) {
// 15.12.3 (Java 8)
- scope.checkAppropriateMethodAgainstSupers(this.selector, this.binding, argumentTypes, this);
+ scope.checkAppropriateMethodAgainstSupers(this.selector, this.binding, this.argumentTypes, this);
}
if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
@@ -1293,11 +1297,11 @@ public TypeBinding resolveType(BlockScope scope) {
* after applicability checking (18.5.1) to include more information into the final
* invocation type inference (18.5.2).
*/
-protected void findMethodBinding(BlockScope scope, TypeBinding[] argumentTypes) {
+protected void findMethodBinding(BlockScope scope) {
this.binding = this.receiver.isImplicitThis()
- ? scope.getImplicitMethod(this.selector, argumentTypes, this)
- : scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
- resolvePolyExpressionArguments(this, this.binding, argumentTypes, scope);
+ ? scope.getImplicitMethod(this.selector, this.argumentTypes, this)
+ : scope.getMethod(this.actualReceiverType, this.selector, this.argumentTypes, this);
+ resolvePolyExpressionArguments(this, this.binding, this.argumentTypes, scope);
/* There are embedded assumptions in the JLS8 type inference scheme that a successful solution of the type equations results in an
applicable method. This appears to be a tenuous assumption, at least one not made by the JLS7 engine or the reference compiler and
@@ -1673,4 +1677,8 @@ public InnerInferenceHelper innerInferenceHelper() {
public InferenceContext18 freshInferenceContext(Scope scope) {
return new InferenceContext18(scope, this.arguments, this);
}
+@Override
+public boolean isQualifiedSuper() {
+ return this.receiver.isQualifiedSuper();
+}
}
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 9e7c2a074..bc0a6d7f6 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
@@ -18,9 +18,6 @@
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
* bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
* bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
- * Bug 416267 - NPE in QualifiedAllocationExpression.resolveType
- * Andy Clement - Contributions for
- * Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
* bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
* Bug 415850 - [1.8] Ensure RunJDTCoreTests can cope with null annotations enabled
* Bug 392238 - [1.8][compiler][null] Detect semantically invalid null type annotations
@@ -458,14 +455,14 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
if (this.typeArguments != null) {
int length = this.typeArguments.length;
- boolean argHasError = sourceLevel < ClassFileConstants.JDK1_5;
+ this.argumentsHaveErrors = sourceLevel < ClassFileConstants.JDK1_5;
this.genericTypeArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
TypeReference typeReference = this.typeArguments[i];
if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
- argHasError = true;
+ this.argumentsHaveErrors = true;
}
- if (argHasError && typeReference instanceof Wildcard) {
+ if (this.argumentsHaveErrors && typeReference instanceof Wildcard) {
scope.problemReporter().illegalUsageOfWildcard(typeReference);
}
}
@@ -473,7 +470,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
return null;
}
- if (argHasError) {
+ if (this.argumentsHaveErrors) {
if (this.arguments != null) { // still attempt to resolve arguments
for (int i = 0, max = this.arguments.length; i < max; i++) {
this.arguments[i].resolveType(scope);
@@ -484,10 +481,10 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
}
// will check for null after args are resolved
- TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+ this.argumentTypes = Binding.NO_PARAMETERS;
if (this.arguments != null) {
int length = this.arguments.length;
- argumentTypes = new TypeBinding[length];
+ this.argumentTypes = new TypeBinding[length];
for (int i = 0; i < length; i++) {
Expression argument = this.arguments[i];
if (argument instanceof CastExpression) {
@@ -495,10 +492,10 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
argsContainCast = true;
}
argument.setExpressionContext(INVOCATION_CONTEXT);
- if ((argumentTypes[i] = argument.resolveType(scope)) == null){
+ if ((this.argumentTypes[i] = argument.resolveType(scope)) == null){
hasError = true;
}
- if (sourceLevel >= ClassFileConstants.JDK1_8 && argument.isPolyExpression()) {
+ if (sourceLevel >= ClassFileConstants.JDK1_8 && (argument.isPolyExpression() || (argument instanceof Invocation && ((Invocation)argument).usesInference()))) {
if (this.innerInferenceHelper == null)
this.innerInferenceHelper = new InnerInferenceHelper();
}
@@ -525,7 +522,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
int length = this.arguments == null ? 0 : this.arguments.length;
TypeBinding[] pseudoArgs = new TypeBinding[length];
for (int i = length; --i >= 0;) {
- pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+ pseudoArgs[i] = this.argumentTypes[i] == null ? TypeBinding.NULL : this.argumentTypes[i]; // replace args with errors with null type
}
this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this, false);
if (this.binding != null && !this.binding.isValidBinding()) {
@@ -561,7 +558,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
return this.resolvedType = receiverType;
}
if (isDiamond) {
- TypeBinding [] inferredTypes = inferElidedTypes((ParameterizedTypeBinding) receiverType, receiverType.enclosingType(), argumentTypes, scope);
+ TypeBinding [] inferredTypes = inferElidedTypes((ParameterizedTypeBinding) receiverType, receiverType.enclosingType(), this.argumentTypes, scope);
if (inferredTypes == null) {
scope.problemReporter().cannotInferElidedTypes(this);
return this.resolvedType = null;
@@ -578,7 +575,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
null, this.arguments, scope);
try {
// orig:
- this.binding = findConstructorBinding(scope, this, allocationType, argumentTypes);
+ this.binding = findConstructorBinding(scope, this, allocationType, this.argumentTypes);
// :giro
} finally {
AnchorMapping.removeCurrentMapping(anchorMapping);
@@ -589,7 +586,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
if (isMethodUseDeprecated(this.binding, scope, true)) {
scope.problemReporter().deprecatedMethod(this.binding, this);
}
- if (checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+ if (checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, this.argumentTypes, argsContainCast, this)) {
this.bits |= ASTNode.Unchecked;
}
if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
@@ -614,8 +611,8 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
}
} else {
// orig:
- scope.problemReporter().invalidConstructor(this, this.binding);
- return this.resolvedType = receiverType;
+ scope.problemReporter().invalidConstructor(this, this.binding);
+ return this.resolvedType = receiverType;
// :giro
}
// SH}
@@ -624,7 +621,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
scope.problemReporter().missingTypeInConstructor(this, this.binding);
}
if (!isDiamond && receiverType.isParameterizedTypeWithActualArguments()) {
- checkTypeArgumentRedundancy((ParameterizedTypeBinding)receiverType, receiverType.enclosingType(), argumentTypes , scope);
+ checkTypeArgumentRedundancy((ParameterizedTypeBinding)receiverType, receiverType.enclosingType(), this.argumentTypes , scope);
}
// The enclosing instance must be compatible with the innermost enclosing type
ReferenceBinding expectedType = this.binding.declaringClass.enclosingType();
@@ -670,7 +667,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
if ((this.resolvedType.tagBits & TagBits.HierarchyHasProblems) != 0) {
return null; // stop secondary errors
}
- MethodBinding inheritedBinding = findConstructorBinding(scope, this, anonymousSuperclass, argumentTypes);
+ MethodBinding inheritedBinding = findConstructorBinding(scope, this, anonymousSuperclass, this.argumentTypes);
if (!inheritedBinding.isValidBinding()) {
if (inheritedBinding.declaringClass == null) {
@@ -698,7 +695,7 @@ public static abstract class AbstractQualifiedAllocationExpression extends Alloc
this.enclosingInstance.computeConversion(scope, targetEnclosing, enclosingInstanceType);
}
if (this.arguments != null) {
- if (checkInvocationArguments(scope, null, anonymousSuperclass, inheritedBinding, this.arguments, argumentTypes, argsContainCast, this)) {
+ if (checkInvocationArguments(scope, null, anonymousSuperclass, inheritedBinding, this.arguments, this.argumentTypes, argsContainCast, this)) {
this.bits |= ASTNode.Unchecked;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
index 46472760c..43761941a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.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
@@ -27,6 +27,10 @@ public boolean isSuper() {
return true;
}
+public boolean isQualifiedSuper() {
+ return true;
+}
+
public boolean isThis() {
return false;
}
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 310c53d91..e9465f353 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
@@ -56,10 +56,12 @@ import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -116,7 +118,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
int argc = this.descriptor.parameters.length;
- LambdaExpression implicitLambda = new LambdaExpression(this.compilationResult, false);
+ LambdaExpression implicitLambda = new LambdaExpression(this.compilationResult, false, (this.binding.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0);
Argument [] arguments = new Argument[argc];
for (int i = 0; i < argc; i++)
arguments[i] = new Argument(("arg" + i).toCharArray(), 0, null, 0, true); //$NON-NLS-1$
@@ -409,10 +411,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.resolvedType = null; // nope, no useful type found
// Convert parameters into argument expressions for look up.
- TypeBinding[] descriptorParameters = this.descriptor != null && this.descriptor.parameters != null && this.descriptor.parameters.length > 0 ?
- new TypeBinding[this.descriptor.parameters.length] : Binding.NO_PARAMETERS;
- for (int i = 0, length = descriptorParameters.length; i < length; i++)
- descriptorParameters[i] = this.descriptor.parameters[i].capture(scope, this.sourceEnd);
+ TypeBinding[] descriptorParameters = descriptorParametersAsArgumentExpressions();
if (lhsType.isBaseType()) {
scope.problemReporter().errorNoMethodFor(this.lhs, lhsType, this.selector, descriptorParameters);
@@ -440,8 +439,19 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
// handle the special case of array construction first.
this.receiverType = lhsType;
+
+ this.haveReceiver = true;
+ if (this.lhs instanceof NameReference) {
+ if ((this.lhs.bits & ASTNode.RestrictiveFlagMASK) == Binding.TYPE) {
+ this.haveReceiver = false;
+ }
+ } else if (this.lhs instanceof TypeReference) {
+ this.haveReceiver = false;
+ }
+
if (!this.haveReceiver && !this.lhs.isSuper() && !this.isArrayConstructorReference())
this.receiverType = lhsType.capture(scope, this.sourceEnd);
+
final int parametersLength = descriptorParameters.length;
if (isConstructorReference() && lhsType.isArrayType()) {
final TypeBinding leafComponentType = lhsType.leafComponentType();
@@ -457,18 +467,15 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
scope.problemReporter().constructedArrayIncompatible(this, lhsType, this.descriptor.returnType);
return this.resolvedType = null;
}
+
+ if (this.typeArguments != null) {
+ scope.problemReporter().invalidTypeArguments(this.typeArguments);
+ return this.resolvedType = null;
+ }
+
this.binding = this.exactMethodBinding = scope.getExactConstructor(lhsType, this);
return this.resolvedType;
}
-
- this.haveReceiver = true;
- if (this.lhs instanceof NameReference) {
- if ((this.lhs.bits & ASTNode.RestrictiveFlagMASK) == Binding.TYPE) {
- this.haveReceiver = false;
- }
- } else if (this.lhs instanceof TypeReference) {
- this.haveReceiver = false;
- }
/* For Reference expressions unlike other call sites, we always have a receiver _type_ since LHS of :: cannot be empty.
LHS's resolved type == actual receiver type. All code below only when a valid descriptor is available.
@@ -666,6 +673,25 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.resolvedType; // Phew !
}
+ private TypeBinding[] descriptorParametersAsArgumentExpressions() {
+
+ if (this.descriptor == null || this.descriptor.parameters == null || this.descriptor.parameters.length == 0)
+ return Binding.NO_PARAMETERS;
+
+ /* 15.13.1, " ... method reference is treated as if it were an invocation with argument expressions of types P1, ..., Pn;"
+ This implies/requires wildcard capture. This creates interesting complications, we can't just take the descriptor parameters
+ and apply captures - where a single wildcard type got "fanned out" and propagated into multiple locations through type variable
+ substitutions, we will end up creating distinct captures defeating the very idea of capture. We need to first capture and then
+ fan out. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=432759.
+ */
+ if (this.expectedType.isParameterizedType()) {
+ ParameterizedTypeBinding type = (ParameterizedTypeBinding) this.expectedType;
+ MethodBinding method = type.getSingleAbstractMethod(this.enclosingScope, true, this.sourceEnd);
+ return method.parameters;
+ }
+ return this.descriptor.parameters;
+ }
+
/** During inference: Try to find an applicable method binding without causing undesired side-effects. */
public MethodBinding findCompileTimeMethodTargeting(TypeBinding targetType, Scope scope) {
MethodBinding targetMethod = internalResolveTentatively(targetType, scope);
@@ -681,6 +707,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
MethodBinding previousBinding = this.binding;
MethodBinding previousDescriptor = this.descriptor;
TypeBinding previousResolvedType = this.resolvedType;
+ TypeBinding previousExpectedType = this.expectedType;
try {
setExpressionContext(INVOCATION_CONTEXT);
setExpectedType(targetType);
@@ -695,7 +722,7 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
this.descriptor = previousDescriptor;
this.resolvedType = previousResolvedType;
setExpressionContext(previousContext);
- this.expectedType = null; // don't call setExpectedType(null), would NPE
+ this.expectedType = previousExpectedType;
this.trialResolution = false;
}
}
@@ -823,7 +850,6 @@ public class ReferenceExpression extends FunctionalExpression implements Invocat
return this.resolvedType.isCompatibleWith(left, scope);
}
// 15.13.2
- left = left.uncapture(this.enclosingScope);
final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope, true);
if (sam == null || !sam.isValidBinding())
return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
index b6ef490d1..a0386ff99 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -65,6 +65,12 @@ public class SingleTypeReference extends TypeReference {
if (typeVariable.declaringElement instanceof SourceTypeBinding) {
scope.tagAsAccessingEnclosingInstanceStateOf((ReferenceBinding) typeVariable.declaringElement, true /* type variable access */);
}
+ } else if (this.resolvedType instanceof LocalTypeBinding) {
+ LocalTypeBinding localType = (LocalTypeBinding) this.resolvedType;
+ MethodScope methodScope = scope.methodScope();
+ if (methodScope != null && !methodScope.isStatic) {
+ methodScope.tagAsAccessingEnclosingInstanceStateOf(localType, false /* ! type variable access */);
+ }
}
if (scope.kind == Scope.CLASS_SCOPE && this.resolvedType.isValidBinding())

Back to the top