Skip to content

Commit 2602169

Browse files
authored
Merge pull request #9041 from lahodaj/java-hints-local-class
Better handling of local class when creating local variable-like elements.
2 parents bde8174 + 398d864 commit 2602169

File tree

13 files changed

+228
-24
lines changed

13 files changed

+228
-24
lines changed

java/java.hints/src/org/netbeans/modules/java/hints/errors/ChangeType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public List<Fix> run(CompilationInfo info,
168168
return null;
169169
}
170170
//anonymous class?
171-
expressionType[0] = org.netbeans.modules.java.hints.errors.Utilities.convertIfAnonymous(expressionType[0]);
171+
expressionType[0] = org.netbeans.modules.java.hints.errors.Utilities.convertIfAnonymous(expressionType[0], true);
172172

173173
result.add(new ChangeTypeFix(info, treePath,
174174
((VariableTree) leaf[0]).getName().toString(),

java/java.hints/src/org/netbeans/modules/java/hints/errors/ChangeTypeFix.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ protected void performRewrite(TransformationContext ctx) throws Exception {
6161
ChangeType.computeType(working, position, tm, expressionType, leaf);
6262

6363
//anonymous class?
64-
expressionType[0] = Utilities.convertIfAnonymous(expressionType[0]);
64+
expressionType[0] = Utilities.convertIfAnonymous(expressionType[0], true);
6565

6666
if (leaf[0] instanceof VariableTree) {
6767
VariableTree oldVariableTree = ((VariableTree)leaf[0]);

java/java.hints/src/org/netbeans/modules/java/hints/errors/CreateElement.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ private static List<Fix> analyzeImpl(CompilationInfo info, String diagnosticKey,
358358
if (!ErrorFixesFakeHint.enabled(info.getFileObject(), FixKind.CREATE_LOCAL_VARIABLE)) {
359359
fixTypes.remove(ElementKind.LOCAL_VARIABLE);
360360
}
361+
TypeMirror localType;
361362
final TypeMirror type;
362363

363364
if (types != null && !types.isEmpty()) {
@@ -376,13 +377,15 @@ private static List<Fix> analyzeImpl(CompilationInfo info, String diagnosticKey,
376377
i++;
377378
}
378379
//XXX: should reasonably consider all the found type candidates, not only the one:
379-
type = types.get(0);
380+
localType = Utilities.convertIfAnonymous(types.get(0), true);
381+
type = Utilities.convertIfAnonymous(types.get(0), false);
380382

381383
if (superType[0] == null) {
382384
// the type must be already un-captured.
383385
superType[0] = type;
384386
}
385387
} else {
388+
localType = null;
386389
type = null;
387390
}
388391

@@ -500,11 +503,11 @@ private static List<Fix> analyzeImpl(CompilationInfo info, String diagnosticKey,
500503
if (ee != null && fixTypes.contains(ElementKind.PARAMETER) && !Utilities.isMethodHeaderInsideGuardedBlock(info, (MethodTree) firstMethod.getLeaf()))
501504
result.add(new AddParameterOrLocalFix(info, type, simpleName, ElementKind.PARAMETER, identifierPos).toEditorFix());
502505
if ((firstMethod != null || firstInitializer != null || firstLambda != null) && fixTypes.contains(ElementKind.LOCAL_VARIABLE) && ErrorFixesFakeHint.enabled(ErrorFixesFakeHint.FixKind.CREATE_LOCAL_VARIABLE))
503-
result.add(new AddParameterOrLocalFix(info, type, simpleName, ElementKind.LOCAL_VARIABLE, identifierPos).toEditorFix());
506+
result.add(new AddParameterOrLocalFix(info, localType, simpleName, ElementKind.LOCAL_VARIABLE, identifierPos).toEditorFix());
504507
if (fixTypes.contains(ElementKind.RESOURCE_VARIABLE))
505-
result.add(new AddParameterOrLocalFix(info, type, simpleName, ElementKind.RESOURCE_VARIABLE, identifierPos).toEditorFix());
508+
result.add(new AddParameterOrLocalFix(info, localType, simpleName, ElementKind.RESOURCE_VARIABLE, identifierPos).toEditorFix());
506509
if (fixTypes.contains(ElementKind.OTHER))
507-
result.add(new AddParameterOrLocalFix(info, type, simpleName, ElementKind.OTHER, identifierPos).toEditorFix());
510+
result.add(new AddParameterOrLocalFix(info, localType, simpleName, ElementKind.OTHER, identifierPos).toEditorFix());
508511
}
509512

510513
return result;

java/java.hints/src/org/netbeans/modules/java/hints/errors/CreateElementUtilities.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,6 @@ private static List<? extends TypeMirror> computeAssignment(Set<ElementKind> typ
390390
type = info.getTrees().getTypeMirror(new TreePath(parent, at.getExpression()));
391391

392392
if (type != null) {
393-
//anonymous class?
394-
type = org.netbeans.modules.java.hints.errors.Utilities.convertIfAnonymous(type);
395-
396393
if (type.getKind() == TypeKind.EXECUTABLE) {
397394
//TODO: does not actualy work, attempt to solve situations like:
398395
//t = Collections.emptyList()

java/java.hints/src/org/netbeans/modules/java/hints/errors/Utilities.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,13 +656,13 @@ public static <T extends Tree> T copyComments(WorkingCopy wc, Tree from, T to, b
656656
*
657657
* @return typemirror of supertype/iface, initial tm if not anonymous
658658
*/
659-
public static TypeMirror convertIfAnonymous(TypeMirror tm) {
659+
public static TypeMirror convertIfAnonymous(TypeMirror tm, boolean keepLocal) {
660660
//anonymous class?
661661
Set<ElementKind> fm = EnumSet.of(ElementKind.METHOD, ElementKind.FIELD);
662662
if (tm instanceof DeclaredType) {
663663
Element el = ((DeclaredType) tm).asElement();
664664
//XXX: the null check is needed for lambda type, not covered by test:
665-
if (el != null && (el.getSimpleName().length() == 0 || fm.contains(el.getEnclosingElement().getKind()))) {
665+
if (el != null && (el.getSimpleName().length() == 0 || (!keepLocal && fm.contains(el.getEnclosingElement().getKind())))) {
666666
List<? extends TypeMirror> interfaces = ((TypeElement) el).getInterfaces();
667667
if (interfaces.isEmpty()) {
668668
tm = ((TypeElement) el).getSuperclass();
@@ -1156,7 +1156,7 @@ public static MethodArguments resolveArguments(CompilationInfo info, TreePath in
11561156
TypeMirror tm = info.getTrees().getTypeMirror(argPath);
11571157

11581158
//anonymous class?
1159-
tm = Utilities.convertIfAnonymous(tm);
1159+
tm = Utilities.convertIfAnonymous(tm, false);
11601160

11611161
if (tm == null || tm.getKind() == TypeKind.NONE || containsErrorsRecursively(tm)) {
11621162
return null;

java/java.hints/src/org/netbeans/modules/java/hints/introduce/InstanceRefFinder.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ public class InstanceRefFinder extends ErrorAwareTreePathScanner {
6767
* Immediate enclosing element
6868
*/
6969
private Element enclosingElement;
70-
private TreePath enclosingElementPath;
7170
private TypeElement enclosingType;
7271

7372
private Set<TypeElement> superReferences = Collections.<TypeElement>emptySet();
@@ -135,8 +134,7 @@ private void findEnclosingElement() {
135134
case INTERFACE:
136135
case RECORD:
137136
case NEW_CLASS:
138-
enclosingElementPath = path;
139-
enclosingElement = ci.getTrees().getElement(enclosingElementPath);
137+
enclosingElement = ci.getTrees().getElement(path);
140138
if (enclosingElement == null) {
141139
return;
142140
}
@@ -152,9 +150,6 @@ private void findEnclosingElement() {
152150
}
153151

154152
private void addLocalReference(TypeElement el) {
155-
if (this.enclosingElement != el.getEnclosingElement()) {
156-
return;
157-
}
158153
if (localReferences.isEmpty()) {
159154
localReferences = new HashSet<TypeElement>();
160155
}

java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceExpressionBasedMethodFix.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public void run(ResultIterator resultIterator) throws Exception {
233233
if (expression == null || returnType == null) {
234234
return; //TODO...
235235
}
236-
returnType = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(copy, returnType));
236+
returnType = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(copy, returnType), false);
237237
final TreeMaker make = copy.getTreeMaker();
238238
Tree returnTypeTree = make.Type(returnType);
239239
copy.tag(returnTypeTree, TYPE_TAG);

java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceFieldFix.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public void run(ResultIterator resultIterator) throws Exception {
284284
if (tm == null) {
285285
return; //TODO...
286286
}
287-
tm = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(parameter, tm));
287+
tm = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(parameter, tm), false);
288288
TreePath pathToClass = findTargetClass(parameter, resolved);
289289
if (pathToClass == null) {
290290
return; //TODO...

java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceHint.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ private static void addExpressionFixes(CompilationInfo info, int start, int end,
236236
TreePath method = TreeUtils.findMethod(resolved);
237237
boolean variableRewrite = resolved.getLeaf().getKind() == Kind.VARIABLE;
238238
TreePath value = !variableRewrite ? resolved : new TreePath(resolved, ((VariableTree) resolved.getLeaf()).getInitializer());
239+
boolean hasNonLocalRefs = hasNonLocalRefs(info, value);
239240
boolean isVariable = TreeUtils.findStatement(resolved) != null && method != null && !variableRewrite;
240241
Set<TreePath> duplicatesForVariable = isVariable ? SourceUtils.computeDuplicates(info, resolved, method, cancel) : null;
241242
Set<TreePath> duplicatesForConstant = /*isConstant ? */SourceUtils.computeDuplicates(info, resolved, new TreePath(info.getCompilationUnit()), cancel);// : null;
@@ -252,7 +253,7 @@ private static void addExpressionFixes(CompilationInfo info, int start, int end,
252253
Fix constant = IntroduceConstantFix.createConstant(resolved, info, value, guessedName, duplicatesForConstant.size() + 1, end, variableRewrite, cancel);
253254

254255

255-
Fix parameter = isVariable ? new IntroduceParameterFix(h) : null;
256+
Fix parameter = isVariable && !hasNonLocalRefs ? new IntroduceParameterFix(h) : null;
256257
IntroduceFieldFix field = null;
257258
IntroduceFixBase methodFix = null;
258259

@@ -320,7 +321,7 @@ private static void addExpressionFixes(CompilationInfo info, int start, int end,
320321
}
321322
}
322323

323-
if (!error186980) {
324+
if (!error186980 && !hasNonLocalRefs) {
324325
Set<TypeMirror> exceptions = new HashSet<TypeMirror>(info.getTreeUtilities().getUncaughtExceptions(resolved));
325326

326327
Set<TypeMirrorHandle> exceptionHandles = new HashSet<TypeMirrorHandle>();
@@ -341,7 +342,7 @@ private static void addExpressionFixes(CompilationInfo info, int start, int end,
341342
if (viableTargets != null && !viableTargets.isEmpty()) {
342343
TypeMirror returnType =
343344
Utilities.convertIfAnonymous(Utilities.resolveCapturedType(info,
344-
resolveType(info, resolved)));
345+
resolveType(info, resolved)), false);
345346
if (Utilities.isValidType(returnType)) {
346347
methodFix = new IntroduceExpressionBasedMethodFix(info.getSnapshot().getSource(), h, params, TypeMirrorHandle.create(returnType),
347348
exceptionHandles, duplicatesCount, typeVars, end, viableTargets);
@@ -380,6 +381,12 @@ private static void addExpressionFixes(CompilationInfo info, int start, int end,
380381
}
381382
}
382383

384+
private static boolean hasNonLocalRefs(final CompilationInfo info, TreePath path) {
385+
InstanceRefFinder finder = new InstanceRefFinder(info, path);
386+
finder.process();
387+
return finder.containsLocalReferences();
388+
}
389+
383390
public static List<ErrorDescription> computeError(CompilationInfo info, int start, int end, Map<IntroduceKind, Fix> fixesMap, Map<IntroduceKind, String> errorMessage, AtomicBoolean cancel) {
384391
List<ErrorDescription> hints = new LinkedList<ErrorDescription>();
385392
List<Fix> fixes = new LinkedList<Fix>();

java/java.hints/src/org/netbeans/modules/java/hints/introduce/IntroduceVariableFix.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public void run(ResultIterator resultIterator) throws Exception {
169169
if (tm == null) {
170170
return; //TODO...
171171
}
172-
tm = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(parameter, tm));
172+
tm = Utilities.convertIfAnonymous(Utilities.resolveTypeForDeclaration(parameter, tm), true);
173173
if (!Utilities.isValidType(tm)) {
174174
return; // TODO...
175175
}

0 commit comments

Comments
 (0)