2727import org .eclipse .core .runtime .ILog ;
2828import org .eclipse .jdt .core .IJavaProject ;
2929import org .eclipse .jdt .core .WorkingCopyOwner ;
30+ import org .eclipse .jdt .internal .codeassist .DOMCompletionUtil ;
3031import org .eclipse .jdt .internal .javac .dom .JavacAnnotationBinding ;
3132import org .eclipse .jdt .internal .javac .dom .JavacErrorMethodBinding ;
3233import org .eclipse .jdt .internal .javac .dom .JavacLambdaBinding ;
4647import com .sun .tools .javac .api .JavacTaskImpl ;
4748import com .sun .tools .javac .api .JavacTrees ;
4849import com .sun .tools .javac .code .Attribute ;
49- import com .sun .tools .javac .code .Symbol ;
50- import com .sun .tools .javac .code .Symtab ;
51- import com .sun .tools .javac .code .TypeTag ;
52- import com .sun .tools .javac .code .Types ;
5350import com .sun .tools .javac .code .Attribute .Compound ;
51+ import com .sun .tools .javac .code .Symbol ;
5452import com .sun .tools .javac .code .Symbol .ClassSymbol ;
5553import com .sun .tools .javac .code .Symbol .MethodSymbol ;
5654import com .sun .tools .javac .code .Symbol .ModuleSymbol ;
5957import com .sun .tools .javac .code .Symbol .TypeSymbol ;
6058import com .sun .tools .javac .code .Symbol .TypeVariableSymbol ;
6159import com .sun .tools .javac .code .Symbol .VarSymbol ;
60+ import com .sun .tools .javac .code .Symtab ;
6261import com .sun .tools .javac .code .Type .ArrayType ;
6362import com .sun .tools .javac .code .Type .ClassType ;
6463import com .sun .tools .javac .code .Type .ErrorType ;
7069import com .sun .tools .javac .code .Type .ModuleType ;
7170import com .sun .tools .javac .code .Type .PackageType ;
7271import com .sun .tools .javac .code .Type .TypeVar ;
72+ import com .sun .tools .javac .code .TypeTag ;
73+ import com .sun .tools .javac .code .Types ;
7374import com .sun .tools .javac .tree .JCTree ;
74- import com .sun .tools .javac .tree .TreeInfo ;
7575import com .sun .tools .javac .tree .JCTree .JCAnnotatedType ;
7676import com .sun .tools .javac .tree .JCTree .JCAnnotation ;
7777import com .sun .tools .javac .tree .JCTree .JCArrayTypeTree ;
9696import com .sun .tools .javac .tree .JCTree .JCTypeParameter ;
9797import com .sun .tools .javac .tree .JCTree .JCVariableDecl ;
9898import com .sun .tools .javac .tree .JCTree .JCWildcard ;
99+ import com .sun .tools .javac .tree .TreeInfo ;
99100import com .sun .tools .javac .util .Context ;
100101import com .sun .tools .javac .util .Names ;
101102
@@ -331,11 +332,11 @@ public JavacTypeVariableBinding getTypeVariableBinding(TypeVar typeVar) {
331332 }
332333 //
333334 private Map <String , JavacVariableBinding > variableBindings = new HashMap <>();
334- public JavacVariableBinding getVariableBinding (VarSymbol varSymbol ) {
335+ public JavacVariableBinding getVariableBinding (VarSymbol varSymbol , boolean isUnique ) {
335336 if (varSymbol == null ) {
336337 return null ;
337338 }
338- JavacVariableBinding newInstance = new JavacVariableBinding (varSymbol , JavacBindingResolver .this ) { };
339+ JavacVariableBinding newInstance = new JavacVariableBinding (varSymbol , JavacBindingResolver .this , isUnique ) { };
339340 String k = newInstance .getKey ();
340341 if ( k != null ) {
341342 variableBindings .putIfAbsent (k , newInstance );
@@ -386,7 +387,15 @@ public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Ty
386387 return getMethodBinding (methodType , other , null , false );
387388 }
388389 } else if (owner instanceof final VarSymbol other ) {
389- return getVariableBinding (other );
390+ if (JavacBindingResolver .this .symbolToDeclaration != null ) {
391+ ASTNode ownerDecl = JavacBindingResolver .this .symbolToDeclaration .get (owner .owner );
392+ MethodDeclaration methodDecl = (MethodDeclaration ) DOMCompletionUtil .findParent (ownerDecl , new int [] { ASTNode .METHOD_DECLARATION });
393+ if (methodDecl != null ) {
394+ boolean isUnique = calculateIsUnique (methodDecl , other .name .toString ());
395+ return getVariableBinding (other , isUnique );
396+ }
397+ return getVariableBinding (other , true );
398+ }
390399 }
391400 return null ;
392401 }
@@ -743,7 +752,7 @@ IVariableBinding resolveField(FieldAccess fieldAccess) {
743752 resolve ();
744753 JCTree javacElement = this .converter .domToJavac .get (fieldAccess );
745754 if (javacElement instanceof JCFieldAccess javacFieldAccess && javacFieldAccess .sym instanceof VarSymbol varSymbol ) {
746- return this .bindings .getVariableBinding (varSymbol );
755+ return this .bindings .getVariableBinding (varSymbol , true );
747756 }
748757 return null ;
749758 }
@@ -753,7 +762,7 @@ IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
753762 resolve ();
754763 JCTree javacElement = this .converter .domToJavac .get (fieldAccess );
755764 if (javacElement instanceof JCFieldAccess javacFieldAccess && javacFieldAccess .sym instanceof VarSymbol varSymbol ) {
756- return this .bindings .getVariableBinding (varSymbol );
765+ return this .bindings .getVariableBinding (varSymbol , true );
757766 }
758767 return null ;
759768 }
@@ -1214,7 +1223,7 @@ IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
12141223 if (this .converter .domToJavac .get (enumConstant ) instanceof JCVariableDecl decl ) {
12151224 // the decl.type can be null when there are syntax errors
12161225 if ((decl .type != null && !decl .type .isErroneous ()) || this .isRecoveringBindings ()) {
1217- return this .bindings .getVariableBinding (decl .sym );
1226+ return this .bindings .getVariableBinding (decl .sym , true );
12181227 }
12191228 }
12201229 return null ;
@@ -1223,17 +1232,69 @@ IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
12231232 @ Override
12241233 IVariableBinding resolveVariable (VariableDeclaration variable ) {
12251234 resolve ();
1235+ boolean isUnique = calculateIsUnique (variable );
12261236 if (this .converter .domToJavac .get (variable ) instanceof JCVariableDecl decl ) {
12271237 // the decl.type can be null when there are syntax errors
12281238 if ((decl .type != null && !decl .type .isErroneous ()) || this .isRecoveringBindings ()) {
12291239 if (decl .name != Names .instance (this .context ).error ) { // cannot recover if name is error
1230- return this .bindings .getVariableBinding (decl .sym );
1240+ return this .bindings .getVariableBinding (decl .sym , isUnique );
12311241 }
12321242 }
12331243 }
12341244 return null ;
12351245 }
12361246
1247+ public static boolean calculateIsUnique (VariableDeclaration variable ) {
1248+ MethodDeclaration parentMethod = (MethodDeclaration )DOMCompletionUtil .findParent (variable , new int [] { ASTNode .METHOD_DECLARATION });
1249+ if (parentMethod == null ) {
1250+ return true ;
1251+ }
1252+ final String variableName = variable .getName ().toString ();
1253+ class UniquenessVisitor extends ASTVisitor {
1254+ boolean isUnique = true ;
1255+ @ Override
1256+ public boolean visit (VariableDeclarationFragment node ) {
1257+ if (node != variable && variableName .equals (node .getName ().toString ())) {
1258+ isUnique = false ;
1259+ }
1260+ return super .visit (node );
1261+ }
1262+ @ Override
1263+ public boolean visit (SingleVariableDeclaration node ) {
1264+ if (node != variable && variableName .equals (node .getName ().toString ())) {
1265+ isUnique = false ;
1266+ }
1267+ return super .visit (node );
1268+ }
1269+ }
1270+ UniquenessVisitor uniquenessVisitor = new UniquenessVisitor ();
1271+ parentMethod .accept (uniquenessVisitor );
1272+ return uniquenessVisitor .isUnique ;
1273+ }
1274+
1275+ public static boolean calculateIsUnique (MethodDeclaration methodDecl , String name ) {
1276+ class UniquenessVisitor extends ASTVisitor {
1277+ int count = 0 ;
1278+ @ Override
1279+ public boolean visit (VariableDeclarationFragment node ) {
1280+ if (name .equals (node .getName ().toString ())) {
1281+ this .count ++;
1282+ }
1283+ return super .visit (node );
1284+ }
1285+ @ Override
1286+ public boolean visit (SingleVariableDeclaration node ) {
1287+ if (name .equals (node .getName ().toString ())) {
1288+ this .count ++;
1289+ }
1290+ return super .visit (node );
1291+ }
1292+ }
1293+ UniquenessVisitor uniquenessVisitor = new UniquenessVisitor ();
1294+ methodDecl .accept (uniquenessVisitor );
1295+ return uniquenessVisitor .count <= 1 ;
1296+ }
1297+
12371298 @ Override
12381299 public IPackageBinding resolvePackage (PackageDeclaration decl ) {
12391300 resolve ();
@@ -1480,7 +1541,7 @@ public Object getValueFromAttribute(Attribute attribute) {
14801541 } else if (attribute instanceof Attribute .Class clazz ) {
14811542 return this .bindings .getTypeBinding (clazz .classType );
14821543 } else if (attribute instanceof Attribute .Enum enumm ) {
1483- return this .bindings .getVariableBinding (enumm .value );
1544+ return this .bindings .getVariableBinding (enumm .value , true );
14841545 } else if (attribute instanceof Attribute .Array array ) {
14851546 return Stream .of (array .values ) //
14861547 .map (nestedAttr -> {
@@ -1489,7 +1550,7 @@ public Object getValueFromAttribute(Attribute attribute) {
14891550 } else if (nestedAttr instanceof Attribute .Class clazz ) {
14901551 return this .bindings .getTypeBinding (clazz .classType );
14911552 } else if (nestedAttr instanceof Attribute .Enum enumerable ) {
1492- return this .bindings .getVariableBinding (enumerable .value );
1553+ return this .bindings .getVariableBinding (enumerable .value , true );
14931554 }
14941555 throw new IllegalArgumentException ("Unexpected attribute type: " + nestedAttr .getClass ().getCanonicalName ());
14951556 }) //
0 commit comments