Skip to content

Commit de6bdc9

Browse files
authored
Add new quick fix for unused pattern variable / unused lambda variable (#1747)
* Add new quick fix for unused pattern variable / unused lambda variable - add new logic to LocalCorrectionsSubProcessor to do a rename to unnamed variable when Java >= 22 and we have an unused pattern variable or lambda variable - add check for lambda variable not used into QuickProcessor and have it call the same method in LocalCorrectionSubProcessor - add new RenameUnusedVariableCleanUpCore and RenameUnusedVariableFixCore classes to deal with the errors and to allow multifix - add new QuickFixTest22 to QuickFixTestSuite - fixes #1701
1 parent 348433b commit de6bdc9

File tree

16 files changed

+716
-18
lines changed

16 files changed

+716
-18
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
* Red Hat Inc. - copied and modified from UnusedCodeCleanUpCore
14+
*******************************************************************************/
15+
package org.eclipse.jdt.internal.ui.fix;
16+
17+
18+
import java.util.ArrayList;
19+
import java.util.Hashtable;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
import org.eclipse.core.runtime.CoreException;
24+
25+
import org.eclipse.jdt.core.ICompilationUnit;
26+
import org.eclipse.jdt.core.JavaCore;
27+
import org.eclipse.jdt.core.compiler.IProblem;
28+
import org.eclipse.jdt.core.dom.CompilationUnit;
29+
import org.eclipse.jdt.core.dom.Pattern;
30+
import org.eclipse.jdt.core.dom.SimpleName;
31+
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
32+
33+
import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
34+
import org.eclipse.jdt.internal.corext.fix.RenameUnusedVariableFixCore;
35+
import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore;
36+
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
37+
38+
import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
39+
import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
40+
import org.eclipse.jdt.ui.text.java.IProblemLocation;
41+
42+
import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation;
43+
44+
/**
45+
* Create fixes which can remove unused code
46+
* see org.eclipse.jdt.internal.corext.fix.UnusedCodeFix
47+
*/
48+
public class RenameUnusedVariableCleanUpCore extends AbstractMultiFix {
49+
50+
public RenameUnusedVariableCleanUpCore(Map<String, String> options) {
51+
super(options);
52+
}
53+
54+
public RenameUnusedVariableCleanUpCore() {
55+
super();
56+
}
57+
58+
@Override
59+
public CleanUpRequirements getRequirements() {
60+
boolean requireAST= requireAST();
61+
Map<String, String> requiredOptions= requireAST ? getRequiredOptions() : null;
62+
return new CleanUpRequirements(requireAST, false, false, requiredOptions);
63+
}
64+
65+
private boolean requireAST() {
66+
return isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES);
67+
}
68+
69+
@Override
70+
public ICleanUpFix createFix(CompilationUnit compilationUnit) throws CoreException {
71+
return RenameUnusedVariableFixCore.createCleanUp(compilationUnit,
72+
isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES));
73+
}
74+
75+
@Override
76+
public ICleanUpFix createFix(CompilationUnit compilationUnit, IProblemLocation[] problems) throws CoreException {
77+
return RenameUnusedVariableFixCore.createCleanUp(compilationUnit, problems,
78+
isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES));
79+
}
80+
81+
public Map<String, String> getRequiredOptions() {
82+
Map<String, String> result= new Hashtable<>();
83+
84+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
85+
result.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.WARNING);
86+
result.put(JavaCore.COMPILER_PB_UNUSED_LAMBDA_PARAMETER, JavaCore.WARNING);
87+
}
88+
89+
return result;
90+
}
91+
92+
@Override
93+
public String[] getStepDescriptions() {
94+
List<String> result= new ArrayList<>();
95+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES))
96+
result.add(MultiFixMessages.UnusedCodeMultiFix_RemoveUnusedVariable_description);
97+
return result.toArray(new String[0]);
98+
}
99+
100+
@Override
101+
public String getPreview() {
102+
StringBuilder buf= new StringBuilder();
103+
104+
buf.append(" public void bar() {\n"); //$NON-NLS-1$
105+
if (!isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
106+
String code= """
107+
record R(int i, long l) {}
108+
109+
R r = new R(1, 1);
110+
switch (r) {
111+
case R(_, long l) -> {}
112+
case R r2 -> {}
113+
}
114+
"""; //$NON-NLS-1$
115+
buf.append(code);
116+
} else {
117+
String code= """
118+
record R(int i, long l) {}
119+
120+
R r = new R(1, 1);
121+
switch (r) {
122+
case R(_, _) -> {}
123+
case R _ -> {}
124+
}
125+
"""; //$NON-NLS-1$
126+
buf.append(code);
127+
}
128+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
129+
buf.append("\n"); //$NON-NLS-1$
130+
}
131+
132+
return buf.toString();
133+
}
134+
135+
@Override
136+
public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem) {
137+
if (UnusedCodeFixCore.isUnusedMember(problem) || UnusedCodeFixCore.isUnusedLambdaParameter(problem))
138+
return isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES);
139+
140+
return false;
141+
}
142+
143+
@Override
144+
public int computeNumberOfFixes(CompilationUnit compilationUnit) {
145+
int result= 0;
146+
IProblem[] problems= compilationUnit.getProblems();
147+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
148+
for (IProblem problem : problems) {
149+
int id= problem.getID();
150+
if (id == IProblem.LocalVariableIsNeverUsed) {
151+
ProblemLocation location= new ProblemLocation(problem);
152+
SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, location);
153+
if (JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject()) &&
154+
name.getParent() instanceof SingleVariableDeclaration nameParent &&
155+
nameParent.getParent() instanceof Pattern) {
156+
result++;
157+
}
158+
} else if (id == IProblem.LambdaParameterIsNeverUsed) {
159+
++result;
160+
}
161+
}
162+
}
163+
return result;
164+
}
165+
}

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2019, 2023 IBM Corporation and others.
2+
* Copyright (c) 2019, 2024 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -26,14 +26,20 @@
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;
30+
import org.eclipse.jdt.core.dom.SimpleName;
31+
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
2932

3033
import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
3134
import org.eclipse.jdt.internal.corext.fix.UnusedCodeFixCore;
35+
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
3236

3337
import org.eclipse.jdt.ui.cleanup.CleanUpRequirements;
3438
import org.eclipse.jdt.ui.cleanup.ICleanUpFix;
3539
import org.eclipse.jdt.ui.text.java.IProblemLocation;
3640

41+
import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation;
42+
3743
/**
3844
* Create fixes which can remove unused code
3945
* see org.eclipse.jdt.internal.corext.fix.UnusedCodeFix
@@ -111,8 +117,9 @@ public Map<String, String> getRequiredOptions() {
111117
isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_TYPES)))
112118
result.put(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER, JavaCore.WARNING);
113119

114-
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES))
120+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
115121
result.put(JavaCore.COMPILER_PB_UNUSED_LOCAL, JavaCore.WARNING);
122+
}
116123

117124
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS)) {
118125
result.put(JavaCore.COMPILER_PB_UNUSED_PARAMETER, JavaCore.WARNING);
@@ -174,7 +181,7 @@ public String getPreview() {
174181
public void zoz() {
175182
zozo();
176183
}
177-
184+
178185
private void zozo() {
179186
System.out.println("");
180187
};
@@ -186,7 +193,7 @@ private void zozo() {
186193
public void zoz() {
187194
zozo(34);
188195
}
189-
196+
190197
private void zozo(int k) {
191198
System.out.println("");
192199
};
@@ -230,7 +237,7 @@ public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem
230237
if (UnusedCodeFixCore.isUnusedImport(problem))
231238
return isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS);
232239

233-
if (UnusedCodeFixCore.isUnusedMember(problem))
240+
if (UnusedCodeFixCore.isUnusedMember(problem) || UnusedCodeFixCore.isUnusedLambdaParameter(problem))
234241
return isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS) && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_METHODS) ||
235242
isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS) && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_CONSTRUCTORS) ||
236243
isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS) && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_TYPES) ||
@@ -264,8 +271,20 @@ public int computeNumberOfFixes(CompilationUnit compilationUnit) {
264271
result+= getNumberOfProblems(problems, IProblem.UnusedPrivateType);
265272
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_MEMBERS) && isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_PRIVATE_FELDS))
266273
result+= getNumberOfProblems(problems, IProblem.UnusedPrivateField);
267-
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES))
268-
result+= getNumberOfProblems(problems, IProblem.LocalVariableIsNeverUsed);
274+
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_LOCAL_VARIABLES)) {
275+
for (IProblem problem : problems) {
276+
int id= problem.getID();
277+
if (id == IProblem.LocalVariableIsNeverUsed) {
278+
ProblemLocation location= new ProblemLocation(problem);
279+
SimpleName name= UnusedCodeFixCore.getUnusedName(compilationUnit, location);
280+
if (!JavaModelUtil.is22OrHigher(compilationUnit.getJavaElement().getJavaProject()) ||
281+
!(name.getParent() instanceof SingleVariableDeclaration nameParent) ||
282+
!(nameParent.getParent() instanceof Pattern)) {
283+
result++;
284+
}
285+
}
286+
}
287+
}
269288
if (isEnabled(CleanUpConstants.REMOVE_UNUSED_CODE_METHOD_PARAMETERS))
270289
result+= getNumberOfProblems(problems, IProblem.ArgumentIsNeverUsed);
271290
return result;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2023 IBM Corporation and others.
2+
* Copyright (c) 2000, 2024 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -91,6 +91,7 @@ private FixMessages() {
9191
public static String UnusedCodeFix_RemoveUnusedField_description;
9292
public static String UnusedCodeFix_RemoveUnusedVariabl_description;
9393
public static String UnusedCodeFix_RemoveUnnecessaryArrayCreation_description;
94+
public static String UnusedCodeFix_RenameToUnnamedVariable_description;
9495

9596
public static String Java50Fix_AddMissingAnnotation_description;
9697
public static String Java50Fix_AddDeprecated_description;

org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2005, 2019 IBM Corporation and others.
2+
# Copyright (c) 2005, 2024 IBM Corporation and others.
33
#
44
# This program and the accompanying materials
55
# are made available under the terms of the Eclipse Public License 2.0
@@ -53,6 +53,7 @@ UnusedCodeFix_change_name=Remove unused code
5353
UnusedCodeFix_RemoveImport_description=Remove unused import
5454
UnusedCodeFix_RemoveParameter_description=Remove unused parameter ''{0}''
5555
UnusedCodeFix_RemoveUnnecessaryArrayCreation_description=Remove unnecessary array creation
56+
UnusedCodeFix_RenameToUnnamedVariable_description=Rename to unnamed variable
5657

5758
Java50Fix_AddMissingAnnotation_description=Add missing {0} annotation
5859
Java50Fix_SerialVersion_default_description=Add default serial version ID

0 commit comments

Comments
 (0)