Skip to content

Commit 0871ea2

Browse files
authored
Enhance unused local to unname variable (#1791)
* Enhance unused to unnamed var quick fix to support try with resources and for loops - modify RenameUnusedVariableFixCore to add new method that will check if rename to unnamed variable is available and add logic for try with resources and enhanced for loops - modify UnusedCodeCleanUpCore and UnusedCodeFixCore to use new method to check whether we can rename to unnamed variable - add new tests to QuickFixTest22 - fixes #1762
1 parent fcf7f0e commit 0871ea2

File tree

5 files changed

+188
-47
lines changed

5 files changed

+188
-47
lines changed

org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/RenameUnusedVariableCleanUpCore.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,11 @@
2626
import org.eclipse.jdt.core.JavaCore;
2727
import org.eclipse.jdt.core.compiler.IProblem;
2828
import org.eclipse.jdt.core.dom.CompilationUnit;
29-
import org.eclipse.jdt.core.dom.Pattern;
3029
import org.eclipse.jdt.core.dom.SimpleName;
31-
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
3230

3331
import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
3432
import org.eclipse.jdt.internal.corext.fix.RenameUnusedVariableFixCore;
3533
import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore;
36-
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
3734

3835
import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
3936
import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
@@ -150,9 +147,7 @@ public int computeNumberOfFixes(CompilationUnit compilationUnit) {
150147
if (id == IProblem.LocalVariableIsNeverUsed) {
151148
ProblemLocation location= new ProblemLocation(problem);
152149
SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, location);
153-
if (JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject()) &&
154-
name.getParent() instanceof SingleVariableDeclaration nameParent &&
155-
nameParent.getParent() instanceof Pattern) {
150+
if (RenameUnusedVariableFixCore.canRenameToUnnamedVariable(compilationUnit, name)) {
156151
result++;
157152
}
158153
} else if (id == IProblem.LambdaParameterIsNeverUsed) {

org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/UnusedCodeCleanUpCore.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@
2626
import org.eclipse.jdt.core.JavaCore;
2727
import org.eclipse.jdt.core.compiler.IProblem;
2828
import org.eclipse.jdt.core.dom.CompilationUnit;
29-
import org.eclipse.jdt.core.dom.Pattern;
3029
import org.eclipse.jdt.core.dom.SimpleName;
31-
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
3230

3331
import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
32+
import org.eclipse.jdt.internal.corext.fix.RenameUnusedVariableFixCore;
3433
import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore;
35-
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
3634

3735
import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
3836
import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
@@ -277,9 +275,7 @@ public int computeNumberOfFixes(CompilationUnit compilationUnit) {
277275
if (id == IProblem.LocalVariableIsNeverUsed) {
278276
ProblemLocation location= new ProblemLocation(problem);
279277
SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, location);
280-
if (!JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject()) ||
281-
!(name.getParent() instanceof SingleVariableDeclaration nameParent) ||
282-
!(nameParent.getParent() instanceof Pattern)) {
278+
if (!RenameUnusedVariableFixCore.canRenameToUnnamedVariable(compilationUnit, name)) {
283279
result++;
284280
}
285281
}

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/RenameUnusedVariableFixCore.java

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,19 @@
2828
import org.eclipse.jdt.core.dom.ASTNode;
2929
import org.eclipse.jdt.core.dom.CompilationUnit;
3030
import org.eclipse.jdt.core.dom.EnhancedForStatement;
31+
import org.eclipse.jdt.core.dom.ForStatement;
3132
import org.eclipse.jdt.core.dom.IBinding;
3233
import org.eclipse.jdt.core.dom.IVariableBinding;
3334
import org.eclipse.jdt.core.dom.LambdaExpression;
3435
import org.eclipse.jdt.core.dom.MethodDeclaration;
3536
import org.eclipse.jdt.core.dom.Pattern;
3637
import org.eclipse.jdt.core.dom.SimpleName;
3738
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
39+
import org.eclipse.jdt.core.dom.TryStatement;
40+
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
3841
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
3942
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
4043

41-
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
4244
import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
4345
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
4446

@@ -78,15 +80,10 @@ public static RenameUnusedVariableFixCore createRenameToUnnamedFix(CompilationUn
7880
if (name != null) {
7981
IBinding binding= name.resolveBinding();
8082
if (binding != null) {
81-
if (JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject())) {
82-
if (name.getParent() instanceof SingleVariableDeclaration parent &&
83-
parent.getParent() instanceof Pattern ||
84-
name.getParent() instanceof VariableDeclarationFragment parent2 &&
85-
parent2.getParent() instanceof LambdaExpression) {
86-
String label= FixMessages.UnusedCodeFix_RenameToUnnamedVariable_description;
87-
RenameToUnnamedVariableOperation operation= new RenameToUnnamedVariableOperation(name);
88-
return new RenameUnusedVariableFixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] { operation }, getCleanUpOptions());
89-
}
83+
if (canRenameToUnnamedVariable(compilationUnit, name)) {
84+
String label= FixMessages.UnusedCodeFix_RenameToUnnamedVariable_description;
85+
RenameToUnnamedVariableOperation operation= new RenameToUnnamedVariableOperation(name);
86+
return new RenameUnusedVariableFixCore(label, compilationUnit, new CompilationUnitRewriteOperation[] { operation }, getCleanUpOptions());
9087
}
9188
}
9289
}
@@ -131,16 +128,8 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble
131128
if (name != null) {
132129
IBinding binding= name.resolveBinding();
133130
if (binding instanceof IVariableBinding) {
134-
VariableDeclarationFragment parent= ASTNodes.getParent(name, VariableDeclarationFragment.class);
135-
if (parent == null || id == IProblem.LambdaParameterIsNeverUsed) {
136-
if (JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject())) {
137-
if (name.getParent() instanceof SingleVariableDeclaration nameParent &&
138-
nameParent.getParent() instanceof Pattern ||
139-
name.getParent() instanceof VariableDeclarationFragment varFragment &&
140-
varFragment.getParent() instanceof LambdaExpression) {
141-
result.add(new RenameToUnnamedVariableOperation(name));
142-
}
143-
}
131+
if (canRenameToUnnamedVariable(compilationUnit, name)) {
132+
result.add(new RenameToUnnamedVariableOperation(name));
144133
}
145134
}
146135
}
@@ -153,8 +142,23 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble
153142
return new RenameUnusedVariableFixCore(FixMessages.UnusedCodeFix_change_name, compilationUnit, result.toArray(new CompilationUnitRewriteOperation[result.size()]));
154143
}
155144

156-
public static boolean isFormalParameterInEnhancedForStatement(SimpleName name) {
157-
return name.getParent() instanceof SingleVariableDeclaration && name.getParent().getLocationInParent() == EnhancedForStatement.PARAMETER_PROPERTY;
145+
public static boolean canRenameToUnnamedVariable(CompilationUnit compilationUnit, SimpleName name) {
146+
if (JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject())) {
147+
if (name.getParent() instanceof SingleVariableDeclaration nameParent) {
148+
if (nameParent.getParent() instanceof Pattern || nameParent.getParent() instanceof EnhancedForStatement) {
149+
return true;
150+
}
151+
} else if (name.getParent() instanceof VariableDeclarationFragment varFragment) {
152+
if (varFragment.getParent() instanceof LambdaExpression) {
153+
return true;
154+
} else if (varFragment.getParent() instanceof VariableDeclarationExpression varFragmentParent) {
155+
if (varFragmentParent.getParent() instanceof TryStatement || varFragmentParent.getParent() instanceof ForStatement) {
156+
return true;
157+
}
158+
}
159+
}
160+
}
161+
return false;
158162
}
159163

160164
public static SimpleName getUnusedName(CompilationUnit compilationUnit, IProblemLocation problem) {

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/UnusedCodeFixCore.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
import org.eclipse.jdt.core.dom.Modifier;
6666
import org.eclipse.jdt.core.dom.NodeFinder;
6767
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
68-
import org.eclipse.jdt.core.dom.Pattern;
6968
import org.eclipse.jdt.core.dom.PostfixExpression;
7069
import org.eclipse.jdt.core.dom.PrefixExpression;
7170
import org.eclipse.jdt.core.dom.QualifiedName;
@@ -90,7 +89,6 @@
9089
import org.eclipse.jdt.internal.corext.dom.ReplaceRewrite;
9190
import org.eclipse.jdt.internal.corext.dom.StatementRewrite;
9291
import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
93-
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
9492
import org.eclipse.jdt.internal.corext.util.Messages;
9593

9694
import org.eclipse.jdt.ui.cleanup.CleanUpOptions;
@@ -930,7 +928,7 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble
930928

931929
if ((removeUnusedLocalVariables && id == IProblem.LocalVariableIsNeverUsed) || (removeUnusedPrivateFields && id == IProblem.UnusedPrivateField)) {
932930
SimpleName name= getUnusedName(compilationUnit, problem);
933-
if (name != null) {
931+
if (name != null && !RenameUnusedVariableFixCore.canRenameToUnnamedVariable(compilationUnit, name)) {
934932
IBinding binding= name.resolveBinding();
935933
if (binding instanceof IVariableBinding && !isFormalParameterInEnhancedForStatement(name) && (!((IVariableBinding) binding).isField() || isSideEffectFree(name, compilationUnit))) {
936934
VariableDeclarationFragment parent= ASTNodes.getParent(name, VariableDeclarationFragment.class);
@@ -941,16 +939,7 @@ public static ICleanUpFix createCleanUp(CompilationUnit compilationUnit, IProble
941939
}
942940
variableDeclarations.get(varDecl).add(name);
943941
} else {
944-
if (id == IProblem.LocalVariableIsNeverUsed) {
945-
SimpleName nameNode= UnusedCodeFixCore.getUnusedName(compilationUnit, problem);
946-
if (!JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject()) ||
947-
!(nameNode.getParent() instanceof SingleVariableDeclaration nameParent) ||
948-
!(nameParent.getParent() instanceof Pattern)) {
949-
result.add(new RemoveUnusedMemberOperation(new SimpleName[] { name }, false));
950-
}
951-
} else {
952-
result.add(new RemoveUnusedMemberOperation(new SimpleName[] { name }, false));
953-
}
942+
result.add(new RemoveUnusedMemberOperation(new SimpleName[] { name }, false));
954943
}
955944
}
956945
}

org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest22.java

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,161 @@ case R(_, long _) -> {}
173173
assertEqualString(preview1, expected1);
174174
}
175175

176+
@Test
177+
public void testRenameToUnnamedProposal3() throws Exception {
178+
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
179+
fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
180+
JavaProjectHelper.set22CompilerOptions(fJProject1);
181+
182+
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
183+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
184+
185+
String test= """
186+
package test;
187+
188+
public class Unused {
189+
190+
public static void main(String[] args) {
191+
for (String arg : args) {
192+
System.out.println("abc");
193+
}
194+
}
195+
}
196+
""";
197+
198+
ICompilationUnit cu= pack1.createCompilationUnit("Unused.java", test, false, null);
199+
200+
CompilationUnit astRoot= getASTRoot(cu);
201+
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
202+
assertCorrectLabels(proposals);
203+
204+
CUCorrectionProposal proposal1= (CUCorrectionProposal) proposals.get(0);
205+
String preview1= getPreviewContent(proposal1);
206+
207+
String expected1= """
208+
package test;
209+
210+
public class Unused {
211+
212+
public static void main(String[] args) {
213+
for (String _ : args) {
214+
System.out.println("abc");
215+
}
216+
}
217+
}
218+
""";
219+
220+
assertEqualString(preview1, expected1);
221+
}
222+
223+
@Test
224+
public void testRenameToUnnamedProposal4() throws Exception {
225+
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
226+
fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
227+
JavaProjectHelper.set22CompilerOptions(fJProject1);
228+
229+
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
230+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
231+
232+
String test= """
233+
package test;
234+
import java.io.FileInputStream;
235+
236+
public class Unused {
237+
238+
public static void main(String[] args) {
239+
try (FileInputStream x = new FileInputStream("a.b")) {
240+
System.out.println("abc");
241+
} catch (Exception e) {
242+
}
243+
}
244+
}
245+
""";
246+
247+
ICompilationUnit cu= pack1.createCompilationUnit("Unused.java", test, false, null);
248+
249+
CompilationUnit astRoot= getASTRoot(cu);
250+
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
251+
assertCorrectLabels(proposals);
252+
253+
CUCorrectionProposal proposal1= (CUCorrectionProposal) proposals.get(0);
254+
String preview1= getPreviewContent(proposal1);
255+
256+
String expected1= """
257+
package test;
258+
import java.io.FileInputStream;
259+
260+
public class Unused {
261+
262+
public static void main(String[] args) {
263+
try (FileInputStream _ = new FileInputStream("a.b")) {
264+
System.out.println("abc");
265+
} catch (Exception e) {
266+
}
267+
}
268+
}
269+
""";
270+
271+
assertEqualString(preview1, expected1);
272+
}
273+
274+
@Test
275+
public void testRenameToUnnamedProposal5() throws Exception {
276+
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
277+
fJProject1.setRawClasspath(projectsetup.getDefaultClasspath(), null);
278+
JavaProjectHelper.set22CompilerOptions(fJProject1);
279+
280+
fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
281+
IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null);
282+
283+
String test= """
284+
package test;
285+
286+
public class Unused {
287+
288+
private static int x = 1;
289+
290+
private static int sideEffect() {
291+
return ++x;
292+
}
293+
294+
public static void main(String[] args) {
295+
for (int i = 0, se = sideEffect(); i < 9; ++i) {
296+
System.out.println("abc");
297+
}
298+
}
299+
}
300+
""";
301+
302+
ICompilationUnit cu= pack1.createCompilationUnit("Unused.java", test, false, null);
303+
304+
CompilationUnit astRoot= getASTRoot(cu);
305+
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu, astRoot, 1);
306+
assertCorrectLabels(proposals);
307+
308+
CUCorrectionProposal proposal1= (CUCorrectionProposal) proposals.get(0);
309+
String preview1= getPreviewContent(proposal1);
310+
311+
String expected1= """
312+
package test;
313+
314+
public class Unused {
315+
316+
private static int x = 1;
317+
318+
private static int sideEffect() {
319+
return ++x;
320+
}
321+
322+
public static void main(String[] args) {
323+
for (int i = 0, _ = sideEffect(); i < 9; ++i) {
324+
System.out.println("abc");
325+
}
326+
}
327+
}
328+
""";
329+
330+
assertEqualString(preview1, expected1);
331+
}
332+
176333
}

0 commit comments

Comments
 (0)