Skip to content

Commit e923b04

Browse files
SONARJAVA-5492 stop to raise issues inside record pattern as no fix exists before Java 22
1 parent 8a8c986 commit e923b04

5 files changed

Lines changed: 378 additions & 28 deletions

File tree

java-checks-test-sources/default/src/main/java/checks/unused/UnusedLocalVariableCheck.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,15 +273,15 @@ record Circle() implements Shape {}
273273

274274
static void switchOnSealedClass(Shape shape) {
275275
switch (shape) {
276-
case Box unused -> { } // compliant
276+
case Box unused -> { } // Noncompliant
277277
case Circle circle -> circle.toString();
278278
}
279279
}
280280

281281
static void switchWithTypePattern(Object o) {
282282
switch (o) {
283283
case Number used -> used.longValue();
284-
case Shape unused -> { } // compliant
284+
case Shape unused -> { } // Noncompliant
285285
default -> System.out.println();
286286
}
287287
}
@@ -290,12 +290,18 @@ record MyRecord(int x, int y) { }
290290

291291
static void switchRecordGuardedPattern(Object o) {
292292
switch(o) {
293-
case MyRecord(int x, int y) when x > 42 -> { } // Compliant
294-
case MyRecord(int x, int y) when y < 42 -> { } // Compliant
293+
case MyRecord(int x, int y) when x > 42 -> { } // Noncompliant
294+
// ^
295+
// fix@qfswitch1 {{Replace unused local variable with _}}
296+
// edit@qfswitch2 [[sc=28;ec=33]]{{var _}}
297+
case MyRecord(int x, int y) when y < 42 -> { } // Noncompliant
298+
// ^
299+
// fix@qfswitch2 {{Replace unused local variable with _}}
300+
// edit@qfswitch2 [[sc=21;ec=26]]{{var _}}
295301
case MyRecord m when m.x > 42 -> { }
296-
case MyRecord m when o.toString().length() > 42 -> { } // Compliant
297-
case MyRecord(int x, int y) -> { } // Compliant
298-
case MyRecord m -> { } // Compliant
302+
case MyRecord m when o.toString().length() > 42 -> { } // Noncompliant
303+
case MyRecord(int x, _) -> { } // Noncompliant
304+
case MyRecord m -> { } // Noncompliant
299305
case Object object -> {
300306
object.toString();
301307
var x = 42; // Noncompliant
@@ -314,6 +320,10 @@ record BallHolder<T extends Ball>(T ball) { }
314320
record Point(int x, int y) { }
315321
record ColoredPoint(Point p, String color) { }
316322

323+
sealed interface Tree {}
324+
record Node(Tree left, Tree right) implements Tree {}
325+
record Leaf() implements Tree {}
326+
317327
void unnamedVariablesUseCases(Queue<Ball> queue, BallHolder<? extends Ball> ballHolder, ColoredPoint coloredPoint) {
318328
int total = 0;
319329
int _ = 1 + 1;
@@ -383,5 +393,16 @@ void unnamedVariablesUseCases(Queue<Ball> queue, BallHolder<? extends Ball> ball
383393
if(coloredPoint instanceof ColoredPoint(Point(_, int y), _)) { // Compliant
384394
System.out.println("Point (_:" + y + ") with color not important");
385395
}
396+
397+
if(coloredPoint instanceof ColoredPoint(Point(int x, _), _)) { // Noncompliant
398+
}
399+
}
400+
void RecordPatternUnusedVars(Tree tree){
401+
if(tree instanceof Node(Leaf l, _)) { // Noncompliant
402+
}
403+
if(tree instanceof Node(Node(Leaf l, _), _)) { // Noncompliant
404+
}
405+
if(tree instanceof Node(Node(Leaf l1, _), Node(_, _))) { // Noncompliant
406+
}
386407
}
387408
}
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
package checks.unused;
2+
3+
import java.util.function.BinaryOperator;
4+
import java.util.function.UnaryOperator;
5+
import java.util.stream.Stream;
6+
7+
class UnusedLocalVariableCheck_java17 {
8+
9+
int unusedField;
10+
11+
{
12+
int unused = 42; // Noncompliant
13+
int used = 23; // Compliant
14+
System.out.println(used);
15+
}
16+
17+
static {
18+
int unused = 42; // Noncompliant
19+
int used = 23; // Compliant
20+
System.out.println(used);
21+
}
22+
23+
private UnusedLocalVariableCheck_java17(int unusedParameter) { // Compliant
24+
int unused = 42; // Noncompliant
25+
int used = 23; // Compliant
26+
System.out.println(used);
27+
}
28+
29+
public void f(int unusedParameter, Object o) {
30+
int unusedLocalVariable; // Noncompliant {{Remove this unused "unusedLocalVariable" local variable.}}
31+
// ^^^^^^^^^^^^^^^^^^^
32+
33+
int usedLocalVariable = 42;
34+
System.out.println(usedLocalVariable);
35+
36+
try {
37+
} catch (Exception e) {
38+
}
39+
40+
try (Stream foo = Stream.of()) { // Compliant
41+
}
42+
43+
44+
for (int i = 0; condition(); i++) { // Noncompliant
45+
}
46+
47+
for (int j = 0; j < 10; j++) {
48+
}
49+
50+
try (Stream foo2 = Stream.of()) {
51+
int x = 42; // Noncompliant
52+
foo2.findFirst();
53+
}
54+
55+
int notReadLocalVariable = 0; // Noncompliant
56+
notReadLocalVariable = 1;
57+
notReadLocalVariable += 1;
58+
notReadLocalVariable++;
59+
(notReadLocalVariable)++;
60+
61+
int readLocalVariable = 0;
62+
notReadLocalVariable = readLocalVariable++;
63+
64+
int readLocalVariable2 = 0;
65+
int unreadLocalVariable2 = 1; // Noncompliant
66+
unreadLocalVariable2 = readLocalVariable2;
67+
68+
java.util.stream.Stream<Object> s = Stream.of();
69+
s.map(v -> "");
70+
71+
try (Stream foo3 = Stream.of()) {
72+
foo3.findFirst();
73+
}
74+
try (Stream foo3 = Stream.of()) {
75+
foo3.findFirst();
76+
}
77+
78+
if (o instanceof String usedPatternVar) {
79+
System.out.println(usedPatternVar);
80+
}
81+
82+
if (o instanceof String unusedPatternVar) { // Noncompliant {{Remove this unused "unusedPatternVar" local variable.}}
83+
// ^^^^^^^^^^^^^^^^
84+
85+
}
86+
}
87+
88+
private boolean condition() {
89+
return false;
90+
}
91+
92+
public BinaryOperator<UnaryOperator<Object>> foo() {
93+
return (a, b) -> input -> {
94+
Object o = a.apply(input); // Compliant, lambda expression correctly handled
95+
o.toString();
96+
return o;
97+
};
98+
}
99+
100+
class QuickFixes {
101+
private void doSomething(Object parameter) {
102+
int unusedAndAlone; // Noncompliant [[quickfixes=qfzero]]
103+
// ^^^^^^^^^^^^^^
104+
// fix@qfzero {{Remove unused local variable}}
105+
// edit@qfzero [[sc=7;ec=26]]{{}}
106+
int unusedFirst = 42, used = 1; // Noncompliant [[quickfixes=qf0]]
107+
// ^^^^^^^^^^^
108+
// fix@qf0 {{Remove unused local variable}}
109+
// edit@qf0 [[sc=11;ec=29]]{{}}
110+
111+
int first = 0, unusedSecond, third = 1; // Noncompliant [[quickfixes=qf1]]
112+
// ^^^^^^^^^^^^
113+
// fix@qf1 {{Remove unused local variable}}
114+
// edit@qf1 [[sc=22;ec=36]]{{}}
115+
116+
int alpha = 0, beta = 1, unusedThird; // Noncompliant [[quickfixes=qf2]]
117+
// ^^^^^^^^^^^
118+
// fix@qf2 {{Remove unused local variable}}
119+
// edit@qf2 [[sc=30;ec=43]]{{}}
120+
121+
int initializedButNotRead = used + first + third + alpha + beta; // Noncompliant [[quickfixes=qf3]]
122+
// ^^^^^^^^^^^^^^^^^^^^^
123+
// fix@qf3 {{Remove unused local variable}}
124+
// edit@qf3 [[sc=7;ec=71]]{{}}
125+
126+
// Noncompliant@+1 [[quickfixes=qf4]]
127+
String unitializedAndUnused;
128+
// ^^^^^^^^^^^^^^^^^^^^
129+
// fix@qf4 {{Remove unused local variable}}
130+
// edit@qf4 [[sl=+0;sc=7;ec=35]]{{}}
131+
132+
if (parameter instanceof String unusedMatch) { // Noncompliant [[quickfixes=qf5]]
133+
// ^^^^^^^^^^^
134+
// fix@qf5 {{Remove unused local variable}}
135+
// edit@qf5 [[sc=39;ec=50]]{{}}
136+
}
137+
138+
for (int i, j = 0; j < 10; j++) { // Noncompliant [[quickfixes=qf6]]
139+
// ^
140+
// fix@qf6 {{Remove unused local variable}}
141+
// edit@qf6 [[sc=16;ec=18]] {{}}
142+
System.out.println(j);
143+
}
144+
for (int i = 0, j; i < 10; i++) { // Noncompliant [[quickfixes=qf7]]
145+
// ^
146+
// fix@qf7 {{Remove unused local variable}}
147+
// edit@qf7 [[sc=21;ec=24]] {{}}
148+
System.out.println(i);
149+
}
150+
151+
for (int i = 0; condition(); ) { // Noncompliant [[quickfixes=qf8]]
152+
// ^
153+
// fix@qf8 {{Remove unused local variable}}
154+
// edit@qf8 [[sc=12;ec=21]] {{}}
155+
}
156+
157+
final String unusedFinalAlone = "Hello"; // Noncompliant [[sc=20;ec=36;quickfixes=qf9]]
158+
// fix@qf9 {{Remove unused local variable}}
159+
// edit@qf9 [[sc=7;ec=47]] {{}}
160+
161+
final String unusedFinalFirst, usedFinalLast = "Bye!"; // Noncompliant [[sc=20;ec=36;quickfixes=qf10]]
162+
// fix@qf10 {{Remove unused local variable}}
163+
// edit@qf10 [[sc=20;ec=38]] {{}}
164+
System.out.println(usedFinalLast);
165+
166+
final String usedFinalFirst = "Hello!", unusedFinalLast; // Noncompliant [[quickfixes=qf11]]
167+
// ^^^^^^^^^^^^^^^
168+
// fix@qf11 {{Remove unused local variable}}
169+
// edit@qf11 [[sc=45;ec=62]] {{}}
170+
System.out.println(usedFinalFirst);
171+
172+
var unusedInferredAlone = 42; // Noncompliant [[quickfixes=qf12]]
173+
// ^^^^^^^^^^^^^^^^^^^
174+
// fix@qf12 {{Remove unused local variable}}
175+
// edit@qf12 [[sc=7;ec=36]] {{}}
176+
}
177+
178+
{
179+
int unusedAndAlone; // Noncompliant [[quickfixes=qfzero1]]
180+
// ^^^^^^^^^^^^^^
181+
// fix@qfzero1 {{Remove unused local variable}}
182+
// edit@qfzero1 [[sc=7;ec=26]]{{}}
183+
int unusedFirst = 42, used = 1; // Noncompliant [[quickfixes=qf01]]
184+
// ^^^^^^^^^^^
185+
// fix@qf01 {{Remove unused local variable}}
186+
// edit@qf01 [[sc=11;ec=29]]{{}}
187+
188+
int first = 0, unusedSecond, third = 1; // Noncompliant [[quickfixes=qf111]]
189+
// ^^^^^^^^^^^^
190+
// fix@qf111 {{Remove unused local variable}}
191+
// edit@qf111 [[sc=22;ec=36]]{{}}
192+
193+
int alpha = 0, beta = 1, unusedThird; // Noncompliant [[quickfixes=qf21]]
194+
// ^^^^^^^^^^^
195+
// fix@qf21 {{Remove unused local variable}}
196+
// edit@qf21 [[sc=30;ec=43]]{{}}
197+
198+
int initializedButNotRead = used + first + third + alpha + beta; // Noncompliant [[quickfixes=qf31]]
199+
// ^^^^^^^^^^^^^^^^^^^^^
200+
// fix@qf31 {{Remove unused local variable}}
201+
// edit@qf31 [[sc=7;ec=71]]{{}}
202+
203+
// Noncompliant@+1 [[quickfixes=qf41]]
204+
String unitializedAndUnused;
205+
// ^^^^^^^^^^^^^^^^^^^^
206+
// fix@qf41 {{Remove unused local variable}}
207+
// edit@qf41 [[sl=+0;sc=7;ec=35]]{{}}
208+
}
209+
210+
static {
211+
int unusedAndAlone; // Noncompliant [[quickfixes=qfzero2]]
212+
// ^^^^^^^^^^^^^^
213+
// fix@qfzero2 {{Remove unused local variable}}
214+
// edit@qfzero2 [[sc=7;ec=26]]{{}}
215+
int unusedFirst = 42, used = 1; // Noncompliant [[quickfixes=qf02]]
216+
// ^^^^^^^^^^^
217+
// fix@qf02 {{Remove unused local variable}}
218+
// edit@qf02 [[sc=11;ec=29]]{{}}
219+
220+
int first = 0, unusedSecond, third = 1; // Noncompliant [[quickfixes=qf122]]
221+
// ^^^^^^^^^^^^
222+
// fix@qf122 {{Remove unused local variable}}
223+
// edit@qf122 [[sc=22;ec=36]]{{}}
224+
225+
int alpha = 0, beta = 1, unusedThird; // Noncompliant [[quickfixes=qf22]]
226+
// ^^^^^^^^^^^
227+
// fix@qf22 {{Remove unused local variable}}
228+
// edit@qf22 [[sc=30;ec=43]]{{}}
229+
230+
int initializedButNotRead = used + first + third + alpha + beta; // Noncompliant [[quickfixes=qf32]]
231+
// ^^^^^^^^^^^^^^^^^^^^^
232+
// fix@qf32 {{Remove unused local variable}}
233+
// edit@qf32 [[sc=7;ec=71]]{{}}
234+
235+
// Noncompliant@+1 [[quickfixes=qf42]]
236+
String unitializedAndUnused;
237+
// ^^^^^^^^^^^^^^^^^^^^
238+
// fix@qf42 {{Remove unused local variable}}
239+
// edit@qf42 [[sl=+0;sc=7;ec=35]]{{}}
240+
}
241+
242+
private void doNotOfferQuickFixes() {
243+
int unusedButIncremented = 0; // Noncompliant [[quickfixes=!]]
244+
// ^^^^^^^^^^^^^^^^^^^^
245+
unusedButIncremented++;
246+
247+
for (int counter = 0; condition(); counter++) { // Noncompliant [[quickfixes=!]]
248+
// ^^^^^^^
249+
}
250+
}
251+
}
252+
}

java-checks-test-sources/default/src/main/java/checks/unused/UnusedLocalVariableCheck_java22.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,46 @@ public static void tryWithResources() {
3737
} catch (Exception e) {
3838
}
3939
}
40+
41+
sealed interface Shape permits Box, Circle {}
42+
record Box() implements Shape { }
43+
record Circle() implements Shape {}
44+
45+
static void switchOnSealedClass(Shape shape) {
46+
switch (shape) {
47+
case Box unused -> { } // Noncompliant
48+
case Circle circle -> circle.toString();
49+
}
50+
}
51+
52+
static void switchWithTypePattern(Object o) {
53+
switch (o) {
54+
case Number used -> used.longValue();
55+
case Shape unused -> { } // Noncompliant
56+
default -> System.out.println();
57+
}
58+
}
59+
60+
record MyRecord(int x, int y) { }
61+
62+
static void switchRecordGuardedPattern(Object o) {
63+
switch(o) {
64+
case MyRecord(int x, int y) -> { } // Noncompliant 2
65+
case MyRecord m -> { } // Noncompliant
66+
default -> {}
67+
}
68+
}
69+
70+
sealed interface Tree {}
71+
record Node(Tree left, Tree right) implements Tree {}
72+
record Leaf() implements Tree {}
73+
74+
void RecordPatternUnusedVars(Tree tree){
75+
if(tree instanceof Node(Leaf l, Leaf r)) { // Noncompliant 2
76+
}
77+
if(tree instanceof Node(Node(Leaf l, Leaf r), Leaf k)) { // Noncompliant 3
78+
}
79+
if(tree instanceof Node(Node(Leaf l1, Leaf r1), Node(Leaf l2, Leaf r2))) { // Noncompliant 4
80+
}
81+
}
4082
}

0 commit comments

Comments
 (0)