Skip to content

Commit 21cf78f

Browse files
committed
Lazily resolve whether variable is unique
1 parent 0b57920 commit 21cf78f

File tree

4 files changed

+54
-95
lines changed

4 files changed

+54
-95
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java

Lines changed: 10 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.eclipse.core.runtime.ILog;
2828
import org.eclipse.jdt.core.IJavaProject;
2929
import org.eclipse.jdt.core.WorkingCopyOwner;
30-
import org.eclipse.jdt.internal.codeassist.DOMCompletionUtil;
3130
import org.eclipse.jdt.internal.javac.dom.JavacAnnotationBinding;
3231
import org.eclipse.jdt.internal.javac.dom.JavacErrorMethodBinding;
3332
import org.eclipse.jdt.internal.javac.dom.JavacErrorTypeBinding;
@@ -342,11 +341,11 @@ public JavacTypeVariableBinding getTypeVariableBinding(TypeVar typeVar) {
342341
}
343342
//
344343
private Map<String, JavacVariableBinding> variableBindings = new HashMap<>();
345-
public JavacVariableBinding getVariableBinding(VarSymbol varSymbol, boolean isUnique) {
344+
public JavacVariableBinding getVariableBinding(VarSymbol varSymbol) {
346345
if (varSymbol == null) {
347346
return null;
348347
}
349-
JavacVariableBinding newInstance = new JavacVariableBinding(varSymbol, JavacBindingResolver.this, isUnique) { };
348+
JavacVariableBinding newInstance = new JavacVariableBinding(varSymbol, JavacBindingResolver.this) { };
350349
String k = newInstance.getKey();
351350
if( k != null ) {
352351
variableBindings.putIfAbsent(k, newInstance);
@@ -397,15 +396,7 @@ public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Ty
397396
return getMethodBinding(methodType, other, null, false);
398397
}
399398
} else if (owner instanceof final VarSymbol other) {
400-
if (JavacBindingResolver.this.symbolToDeclaration != null) {
401-
ASTNode ownerDecl = JavacBindingResolver.this.symbolToDeclaration.get(owner.owner);
402-
MethodDeclaration methodDecl = (MethodDeclaration) DOMCompletionUtil.findParent(ownerDecl, new int[] { ASTNode.METHOD_DECLARATION });
403-
if (methodDecl != null) {
404-
boolean isUnique = calculateIsUnique(methodDecl, other.name.toString());
405-
return getVariableBinding(other, isUnique);
406-
}
407-
return getVariableBinding(other, true);
408-
}
399+
return getVariableBinding(other);
409400
}
410401
return null;
411402
}
@@ -776,7 +767,7 @@ IVariableBinding resolveField(FieldAccess fieldAccess) {
776767
resolve();
777768
JCTree javacElement = this.converter.domToJavac.get(fieldAccess);
778769
if (javacElement instanceof JCFieldAccess javacFieldAccess && javacFieldAccess.sym instanceof VarSymbol varSymbol) {
779-
return this.bindings.getVariableBinding(varSymbol, true);
770+
return this.bindings.getVariableBinding(varSymbol);
780771
}
781772
return null;
782773
}
@@ -786,7 +777,7 @@ IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
786777
resolve();
787778
JCTree javacElement = this.converter.domToJavac.get(fieldAccess);
788779
if (javacElement instanceof JCFieldAccess javacFieldAccess && javacFieldAccess.sym instanceof VarSymbol varSymbol) {
789-
return this.bindings.getVariableBinding(varSymbol, true);
780+
return this.bindings.getVariableBinding(varSymbol);
790781
}
791782
return null;
792783
}
@@ -1253,7 +1244,7 @@ IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
12531244
if (this.converter.domToJavac.get(enumConstant) instanceof JCVariableDecl decl) {
12541245
// the decl.type can be null when there are syntax errors
12551246
if ((decl.type != null && !decl.type.isErroneous()) || this.isRecoveringBindings()) {
1256-
return this.bindings.getVariableBinding(decl.sym, true);
1247+
return this.bindings.getVariableBinding(decl.sym);
12571248
}
12581249
}
12591250
return null;
@@ -1262,69 +1253,17 @@ IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
12621253
@Override
12631254
IVariableBinding resolveVariable(VariableDeclaration variable) {
12641255
resolve();
1265-
boolean isUnique = calculateIsUnique(variable);
12661256
if (this.converter.domToJavac.get(variable) instanceof JCVariableDecl decl) {
12671257
// the decl.type can be null when there are syntax errors
12681258
if ((decl.type != null && !decl.type.isErroneous()) || this.isRecoveringBindings()) {
12691259
if (decl.name != Names.instance(this.context).error) { // cannot recover if name is error
1270-
return this.bindings.getVariableBinding(decl.sym, isUnique);
1260+
return this.bindings.getVariableBinding(decl.sym);
12711261
}
12721262
}
12731263
}
12741264
return null;
12751265
}
12761266

1277-
public static boolean calculateIsUnique(VariableDeclaration variable) {
1278-
MethodDeclaration parentMethod = (MethodDeclaration)DOMCompletionUtil.findParent(variable, new int[] { ASTNode.METHOD_DECLARATION });
1279-
if (parentMethod == null) {
1280-
return true;
1281-
}
1282-
final String variableName = variable.getName().toString();
1283-
class UniquenessVisitor extends ASTVisitor {
1284-
boolean isUnique = true;
1285-
@Override
1286-
public boolean visit(VariableDeclarationFragment node) {
1287-
if (node != variable && variableName.equals(node.getName().toString())) {
1288-
isUnique = false;
1289-
}
1290-
return super.visit(node);
1291-
}
1292-
@Override
1293-
public boolean visit(SingleVariableDeclaration node) {
1294-
if (node != variable && variableName.equals(node.getName().toString())) {
1295-
isUnique = false;
1296-
}
1297-
return super.visit(node);
1298-
}
1299-
}
1300-
UniquenessVisitor uniquenessVisitor = new UniquenessVisitor();
1301-
parentMethod.accept(uniquenessVisitor);
1302-
return uniquenessVisitor.isUnique;
1303-
}
1304-
1305-
public static boolean calculateIsUnique(MethodDeclaration methodDecl, String name) {
1306-
class UniquenessVisitor extends ASTVisitor {
1307-
int count = 0;
1308-
@Override
1309-
public boolean visit(VariableDeclarationFragment node) {
1310-
if (name.equals(node.getName().toString())) {
1311-
this.count++;
1312-
}
1313-
return super.visit(node);
1314-
}
1315-
@Override
1316-
public boolean visit(SingleVariableDeclaration node) {
1317-
if (name.equals(node.getName().toString())) {
1318-
this.count++;
1319-
}
1320-
return super.visit(node);
1321-
}
1322-
}
1323-
UniquenessVisitor uniquenessVisitor = new UniquenessVisitor();
1324-
methodDecl.accept(uniquenessVisitor);
1325-
return uniquenessVisitor.count <= 1;
1326-
}
1327-
13281267
@Override
13291268
public IPackageBinding resolvePackage(PackageDeclaration decl) {
13301269
resolve();
@@ -1571,7 +1510,7 @@ public Object getValueFromAttribute(Attribute attribute) {
15711510
} else if (attribute instanceof Attribute.Class clazz) {
15721511
return this.bindings.getTypeBinding(clazz.classType);
15731512
} else if (attribute instanceof Attribute.Enum enumm) {
1574-
return this.bindings.getVariableBinding(enumm.value, true);
1513+
return this.bindings.getVariableBinding(enumm.value);
15751514
} else if (attribute instanceof Attribute.Array array) {
15761515
return Stream.of(array.values) //
15771516
.map(nestedAttr -> {
@@ -1580,11 +1519,10 @@ public Object getValueFromAttribute(Attribute attribute) {
15801519
} else if (nestedAttr instanceof Attribute.Class clazz) {
15811520
return this.bindings.getTypeBinding(clazz.classType);
15821521
} else if (nestedAttr instanceof Attribute.Enum enumerable) {
1583-
return this.bindings.getVariableBinding(enumerable.value, true);
1522+
return this.bindings.getVariableBinding(enumerable.value);
15841523
}
15851524
throw new IllegalArgumentException("Unexpected attribute type: " + nestedAttr.getClass().getCanonicalName());
1586-
}) //
1587-
.toArray(Object[]::new);
1525+
}).toArray(Object[]::new);
15881526
}
15891527
throw new IllegalArgumentException("Unexpected attribute type: " + attribute.getClass().getCanonicalName());
15901528
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacMethodBinding.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,11 @@
3131
import org.eclipse.jdt.core.dom.ITypeBinding;
3232
import org.eclipse.jdt.core.dom.IVariableBinding;
3333
import org.eclipse.jdt.core.dom.JavacBindingResolver;
34-
import org.eclipse.jdt.core.dom.LambdaExpression;
3534
import org.eclipse.jdt.core.dom.MethodDeclaration;
3635
import org.eclipse.jdt.core.dom.Modifier;
3736
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
3837
import org.eclipse.jdt.core.dom.TypeParameter;
3938
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
40-
import org.eclipse.jdt.internal.codeassist.DOMCompletionUtil;
4139
import org.eclipse.jdt.internal.core.BinaryMethod;
4240
import org.eclipse.jdt.internal.core.JavaElement;
4341
import org.eclipse.jdt.internal.core.Member;
@@ -688,16 +686,8 @@ public IVariableBinding[] getSyntheticOuterLocals() {
688686
if (!this.methodSymbol.isLambdaMethod()) {
689687
return new IVariableBinding[0];
690688
}
691-
LambdaExpression lambdaExpression = (LambdaExpression) this.resolver.symbolToDeclaration.get(this.methodSymbol);
692-
MethodDeclaration methodDeclaration = (MethodDeclaration) DOMCompletionUtil.findParent(lambdaExpression, new int[] { ASTNode.METHOD_DECLARATION });
693689
return this.methodSymbol.capturedLocals.stream() //
694-
.map(varSymbol -> {
695-
boolean isUnique = true;
696-
if (methodDeclaration != null) {
697-
isUnique = JavacBindingResolver.calculateIsUnique(methodDeclaration, getName());
698-
}
699-
return this.resolver.bindings.getVariableBinding(varSymbol, isUnique);
700-
}) //
690+
.map(varSymbol -> this.resolver.bindings.getVariableBinding(varSymbol))
701691
.toArray(IVariableBinding[]::new);
702692
}
703693

@@ -746,4 +736,5 @@ protected String modifiersAsString() {
746736
}
747737
return res;
748738
}
739+
749740
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@
5454
import org.eclipse.jdt.core.dom.ITypeBinding;
5555
import org.eclipse.jdt.core.dom.IVariableBinding;
5656
import org.eclipse.jdt.core.dom.JavacBindingResolver;
57-
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
5857
import org.eclipse.jdt.core.dom.MethodDeclaration;
5958
import org.eclipse.jdt.core.dom.Modifier;
6059
import org.eclipse.jdt.core.dom.RecordDeclaration;
6160
import org.eclipse.jdt.core.dom.TypeDeclaration;
61+
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
6262
import org.eclipse.jdt.internal.codeassist.KeyUtils;
6363
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
6464
import org.eclipse.jdt.internal.core.BinaryType;
@@ -70,10 +70,13 @@
7070
import com.sun.tools.javac.code.Attribute;
7171
import com.sun.tools.javac.code.Flags;
7272
import com.sun.tools.javac.code.Kinds;
73+
import com.sun.tools.javac.code.Symbol;
74+
import com.sun.tools.javac.code.Type;
75+
import com.sun.tools.javac.code.TypeTag;
76+
import com.sun.tools.javac.code.Types;
7377
import com.sun.tools.javac.code.Kinds.Kind;
7478
import com.sun.tools.javac.code.Kinds.KindSelector;
7579
import com.sun.tools.javac.code.Scope.LookupKind;
76-
import com.sun.tools.javac.code.Symbol;
7780
import com.sun.tools.javac.code.Symbol.ClassSymbol;
7881
import com.sun.tools.javac.code.Symbol.CompletionFailure;
7982
import com.sun.tools.javac.code.Symbol.MethodSymbol;
@@ -82,7 +85,6 @@
8285
import com.sun.tools.javac.code.Symbol.TypeSymbol;
8386
import com.sun.tools.javac.code.Symbol.TypeVariableSymbol;
8487
import com.sun.tools.javac.code.Symbol.VarSymbol;
85-
import com.sun.tools.javac.code.Type;
8688
import com.sun.tools.javac.code.Type.ArrayType;
8789
import com.sun.tools.javac.code.Type.ClassType;
8890
import com.sun.tools.javac.code.Type.ErrorType;
@@ -92,8 +94,6 @@
9294
import com.sun.tools.javac.code.Type.MethodType;
9395
import com.sun.tools.javac.code.Type.TypeVar;
9496
import com.sun.tools.javac.code.Type.WildcardType;
95-
import com.sun.tools.javac.code.TypeTag;
96-
import com.sun.tools.javac.code.Types;
9797
import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
9898
import com.sun.tools.javac.util.Name;
9999
import com.sun.tools.javac.util.Names;
@@ -686,7 +686,7 @@ public IVariableBinding[] getDeclaredFields() {
686686
.filter(VarSymbol.class::isInstance)
687687
.map(VarSymbol.class::cast)
688688
.filter(sym -> sym.name != this.names.error)
689-
.map(varSym -> this.resolver.bindings.getVariableBinding(varSym, true))
689+
.map(varSym -> this.resolver.bindings.getVariableBinding(varSym))
690690
.filter(Objects::nonNull)
691691
.toArray(IVariableBinding[]::new);
692692
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacVariableBinding.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@
2121
import org.eclipse.jdt.core.JavaModelException;
2222
import org.eclipse.jdt.core.Signature;
2323
import org.eclipse.jdt.core.dom.ASTNode;
24+
import org.eclipse.jdt.core.dom.ASTVisitor;
2425
import org.eclipse.jdt.core.dom.FieldDeclaration;
2526
import org.eclipse.jdt.core.dom.IAnnotationBinding;
2627
import org.eclipse.jdt.core.dom.IBinding;
2728
import org.eclipse.jdt.core.dom.IMethodBinding;
2829
import org.eclipse.jdt.core.dom.ITypeBinding;
2930
import org.eclipse.jdt.core.dom.IVariableBinding;
3031
import org.eclipse.jdt.core.dom.JavacBindingResolver;
31-
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
3232
import org.eclipse.jdt.core.dom.LambdaExpression;
33+
import org.eclipse.jdt.core.dom.MethodDeclaration;
3334
import org.eclipse.jdt.core.dom.Modifier;
3435
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
3536
import org.eclipse.jdt.core.dom.VariableDeclaration;
3637
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
3738
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
3839
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
40+
import org.eclipse.jdt.core.dom.JavacBindingResolver.BindingKeyException;
41+
import org.eclipse.jdt.internal.codeassist.DOMCompletionUtil;
3942
import org.eclipse.jdt.internal.core.BinaryMember;
4043
import org.eclipse.jdt.internal.core.DOMToModelPopulator;
4144
import org.eclipse.jdt.internal.core.JavaElement;
@@ -49,24 +52,22 @@
4952
import com.sun.tools.javac.code.Flags;
5053
import com.sun.tools.javac.code.Kinds;
5154
import com.sun.tools.javac.code.Symbol;
55+
import com.sun.tools.javac.code.Type;
5256
import com.sun.tools.javac.code.Symbol.ClassSymbol;
5357
import com.sun.tools.javac.code.Symbol.MethodSymbol;
5458
import com.sun.tools.javac.code.Symbol.TypeSymbol;
5559
import com.sun.tools.javac.code.Symbol.VarSymbol;
56-
import com.sun.tools.javac.code.Type;
5760

5861
public abstract class JavacVariableBinding implements IVariableBinding {
5962

6063
public final VarSymbol variableSymbol;
6164
private final JavacBindingResolver resolver;
62-
private final boolean isUnique;
6365
private IJavaElement javaElement;
6466
private String key;
6567

66-
public JavacVariableBinding(VarSymbol sym, JavacBindingResolver resolver, boolean isUnique) {
68+
public JavacVariableBinding(VarSymbol sym, JavacBindingResolver resolver) {
6769
this.variableSymbol = sym;
6870
this.resolver = resolver;
69-
this.isUnique = isUnique;
7071
}
7172

7273
@Override
@@ -214,7 +215,7 @@ private String getKeyImpl() throws BindingKeyException {
214215
Type.MethodType toUse = methodSymbol.type instanceof Type.MethodType methodType ? methodType : null;
215216
JavacMethodBinding.getKey(builder, methodSymbol, toUse, null, true, this.resolver);
216217
// no need to get it right, just get it right enough
217-
if (!isUnique) {
218+
if (!isUnique()) {
218219
builder.append(this.variableSymbol.pos);
219220
}
220221
builder.append("#");
@@ -226,6 +227,35 @@ private String getKeyImpl() throws BindingKeyException {
226227
throw new UnsupportedOperationException("unhandled `Symbol` subclass " + this.variableSymbol.owner.getClass().toString());
227228
}
228229

230+
private boolean isUnique() {
231+
ASTNode variable = this.resolver.findDeclaringNode(this);
232+
MethodDeclaration parentMethod = (MethodDeclaration)DOMCompletionUtil.findParent(variable, new int[] { ASTNode.METHOD_DECLARATION });
233+
if (parentMethod == null) {
234+
return true;
235+
}
236+
final String variableName = getName().toString();
237+
class UniquenessVisitor extends ASTVisitor {
238+
boolean isUnique = true;
239+
@Override
240+
public boolean visit(VariableDeclarationFragment node) {
241+
if (node != variable && variableName.equals(node.getName().toString())) {
242+
isUnique = false;
243+
}
244+
return super.visit(node);
245+
}
246+
@Override
247+
public boolean visit(SingleVariableDeclaration node) {
248+
if (node != variable && variableName.equals(node.getName().toString())) {
249+
isUnique = false;
250+
}
251+
return super.visit(node);
252+
}
253+
}
254+
UniquenessVisitor uniquenessVisitor = new UniquenessVisitor();
255+
parentMethod.accept(uniquenessVisitor);
256+
return uniquenessVisitor.isUnique;
257+
}
258+
229259
@Override
230260
public boolean isEqualTo(IBinding binding) {
231261
return binding instanceof JavacVariableBinding other && //

0 commit comments

Comments
 (0)