Skip to content

Commit 5e97012

Browse files
SONARJAVA-5513 Update rule metadata (#5145)
Co-authored-by: romainbrenguier <[email protected]>
1 parent 0541e93 commit 5e97012

File tree

12 files changed

+135
-27
lines changed

12 files changed

+135
-27
lines changed

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1186.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ <h2>Why is this an issue?</h2>
1010
<h3>Exceptions</h3>
1111
<p>This does not raise an issue in the following cases:</p>
1212
<ul>
13+
<li> Methods with a comment to explain why they are empty </li>
1314
<li> Non-public default (no-argument) constructors </li>
1415
<li> Public default (no-argument) constructors when there are other constructors in the class </li>
1516
<li> Empty methods in abstract classes </li>
@@ -22,6 +23,7 @@ <h3>Exceptions</h3>
2223
}
2324
</pre>
2425
<h2>How to fix it</h2>
26+
<p>To fix this issue, either make the method do something, throw an exception, or add a comment to explain why it is empty.</p>
2527
<h3>Code examples</h3>
2628
<h4>Noncompliant code example</h4>
2729
<pre data-diff-id="1" data-diff-type="noncompliant">

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1481.html

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,100 @@ <h3>What is the potential impact?</h3>
1919
<p>In summary, unused local variables can make your code less readable, more confusing, and harder to maintain, and they can potentially lead to bugs
2020
or inefficient memory use. Therefore, it is best to remove them.</p>
2121
<h2>How to fix it</h2>
22-
<p>The fix for this issue is straightforward. Once you ensure the unused variable is not part of an incomplete implementation leading to bugs, you
23-
just need to remove it.</p>
22+
<p>The fix for this issue is straightforward. Once you ensure the unused variable is not part of an incomplete implementation, you just need to remove
23+
it.</p>
24+
<p>Java 22 introduces the unnamed variable pattern <code>_</code>. When a variable declared within a pattern match, an enhanced for loop, or a try
25+
with resource is unused, you should replace its name with the unnamed variable pattern to clearly indicate the intent not to use the variable.</p>
2426
<h3>Code examples</h3>
2527
<h4>Noncompliant code example</h4>
2628
<pre data-diff-id="1" data-diff-type="noncompliant">
2729
public int numberOfMinutes(int hours) {
28-
int seconds = 0; // Noncompliant - seconds is unused
30+
int seconds = 0; // Noncompliant: "seconds" is unused
2931
return hours * 60;
3032
}
3133
</pre>
34+
<pre data-diff-id="2" data-diff-type="noncompliant">
35+
public String name(Person p) {
36+
return switch (p) {
37+
case User(String name, int age) -&gt; name; // Noncompliant: "age" is unused replace it with the unnamed variable pattern (starting from Java 22)
38+
default -&gt; throw new IllegalArgumentException();
39+
};
40+
}
41+
</pre>
42+
<pre data-diff-id="3" data-diff-type="noncompliant">
43+
public String type(Person p) {
44+
return switch (p) {
45+
case User user -&gt; "user"; // Noncompliant: "user" is unused replace it with the unnamed variable pattern (starting from Java 22)
46+
default -&gt; throw new IllegalArgumentException();
47+
};
48+
}
49+
</pre>
50+
<pre data-diff-id="4" data-diff-type="noncompliant">
51+
public int age(Person p) {
52+
if (p instanceof User(String name, int age)) { // Noncompliant: "name" is unused replace it with the unnamed variable pattern (starting from Java 22)
53+
return age;
54+
}
55+
}
56+
</pre>
57+
<pre data-diff-id="5" data-diff-type="noncompliant">
58+
public static int count(int[] elements) {
59+
int count = 0;
60+
for (var el : elements) { // Noncompliant: "el" is unused replace it with the unnamed variable pattern (starting from Java 22)
61+
count++;
62+
}
63+
return count;
64+
}
65+
</pre>
66+
<pre data-diff-id="6" data-diff-type="noncompliant">
67+
public void foo() {
68+
try (var file = Files.createTempFile(directory, "temp", ".txt")) { // Noncompliant: "file" is unused replace it with the unnamed variable pattern (starting from Java 22)
69+
System.out.println("file created");
70+
}
71+
}
72+
</pre>
3273
<h4>Compliant solution</h4>
3374
<pre data-diff-id="1" data-diff-type="compliant">
3475
public int numberOfMinutes(int hours) {
3576
return hours * 60;
3677
}
3778
</pre>
79+
<pre data-diff-id="2" data-diff-type="compliant">
80+
public String name(Person p) {
81+
return switch (p) {
82+
case User(String name, _) -&gt; name; // Compliant
83+
default -&gt; throw new IllegalArgumentException();
84+
};
85+
}
86+
</pre>
87+
<pre data-diff-id="3" data-diff-type="compliant">
88+
public String type(Person p) {
89+
return switch (p) {
90+
case User _ -&gt; "user"; // Compliant
91+
default -&gt; throw new IllegalArgumentException();
92+
};
93+
}
94+
</pre>
95+
<pre data-diff-id="4" data-diff-type="compliant">
96+
public int age(Person p) {
97+
if (p instanceof User(String _, int age)) { // Compliant
98+
return age;
99+
}
100+
}
101+
</pre>
102+
<pre data-diff-id="5" data-diff-type="compliant">
103+
public static int count(int[] elements) {
104+
int count = 0;
105+
for (var _ : elements) { // Compliant
106+
count++;
107+
}
108+
return count;
109+
}
110+
</pre>
111+
<pre data-diff-id="6" data-diff-type="compliant">
112+
public void foo() {
113+
try (var _ = Files.createTempFile(directory, "temp", ".txt")) { // Compliant
114+
System.out.println("file created");
115+
}
116+
}
117+
</pre>
38118

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1481.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"constantCost": "5min"
1414
},
1515
"tags": [
16+
"java22",
1617
"unused"
1718
],
1819
"defaultSeverity": "Minor",

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2384.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ <h2>Why is this an issue?</h2>
44
<p>Instead use an unmodifiable <code>Collection</code> (via <code>Collections.unmodifiableCollection</code>,
55
<code>Collections.unmodifiableList</code>, …​) or make a copy of the mutable object, and store or return the copy instead.</p>
66
<p>This rule checks that private arrays, collections and Dates are not stored or returned directly.</p>
7+
<h3>Exceptions</h3>
8+
<p>The rule violation is not reported for mutable values stored in private methods if no non-private methods directly passes a mutable parameter to
9+
them.</p>
710
<h3>Noncompliant code example</h3>
811
<pre>
912
class A {
@@ -44,6 +47,10 @@ <h3>Compliant solution</h3>
4447
return strings.clone();
4548
}
4649

50+
private void setStringsInternal(String [] strings) {
51+
this.strings = strings;
52+
}
53+
4754
public void setStrings(String [] strings) {
4855
this.strings = strings.clone();
4956
}

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S3753.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ <h2>Why is this an issue?</h2>
77
<h3>Noncompliant code example</h3>
88
<pre>
99
@Controller
10-
@SessionAttributes("hello") // Noncompliant; this doesn't get cleaned up
10+
@SessionAttributes("hello") // Noncompliant: this doesn't get cleaned up
1111
public class HelloWorld {
1212

1313
@RequestMapping("/greet", method = GET)

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S4682.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<h2>Why is this an issue?</h2>
2-
<p>By definition, primitive types are not Objects and so they can’t be <code>null</code>. Adding <code>@CheckForNull</code> or <code>@Nullable</code>
3-
on primitive types adds confusion and is useless.</p>
2+
<p>By definition, primitive types are not Objects and so they cannot be <code>null</code>. Adding <code>@CheckForNull</code> or <code>@Nullable</code>
3+
on primitive types is redundant and may lead to misunderstandings.</p>
44
<p>This rule raises an issue when <code>@CheckForNull</code> or <code>@Nullable</code> is set on a method returning a primitive type: byte, short,
55
int, long, float, double, boolean, char.</p>
66
<h3>Noncompliant code example</h3>

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6818.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<h2>Why is this an issue?</h2>
22
<p><code>@Autowired</code> is an annotation in the Spring Framework for automatic dependency injection. It tells Spring to automatically provide the
33
required dependencies (such as other beans or components) to a class’s fields, methods, or constructors, allowing for easier and more flexible
4-
management of dependencies in a Spring application. In other words, it’s a way to wire up and inject dependencies into Spring components
4+
management of dependencies in a Spring application. In other words, it is a way to wire up and inject dependencies into Spring components
55
automatically, reducing the need for manual configuration and enhancing modularity and maintainability.</p>
66
<p>In any bean class, only one constructor is permitted to declare <code>@Autowired</code> with the <code>required</code> attribute set to true. This
77
signifies the constructor to be automatically wired when used as a Spring bean. Consequently, when the required attribute remains at its default value

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6829.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ <h2>Why is this an issue?</h2>
66
maintain.</p>
77
<h3>What is the potential impact?</h3>
88
<ul>
9-
<li> <strong>Incorrect Instantiation</strong>: the wrong constructor is selected for instantiation, leading to a bean not being correctly
9+
<li> <strong>incorrect instantiation</strong>: the wrong constructor is selected for instantiation, leading to a bean not being correctly
1010
initialized. </li>
11-
<li> <strong>Unsatisfied Dependency Exception</strong>: the constructor selected by Spring requires beans that are not available in the Spring
11+
<li> <strong>unsatisfied dependency exception</strong>: the constructor selected by Spring requires beans that are not available in the Spring
1212
context. </li>
13-
<li> <strong>Non-Deterministic Behavior</strong>: the constructor selected by Spring can vary, based on the number of dependencies that can be
13+
<li> <strong>non-deterministic behavior</strong>: the constructor selected by Spring can vary, based on the number of dependencies that can be
1414
satisfied at runtime, leading to unpredictable application behavior. </li>
15-
<li> <strong>Maintainability Issues</strong>: adding more constructors in the future could lead to further confusion and potential bugs. </li>
15+
<li> <strong>maintainability issues</strong>: adding more constructors in the future could lead to further confusion and potential bugs. </li>
1616
</ul>
1717
<h2>How to fix it</h2>
1818
<p>Use the <code>@Autowired</code> annotation to specify which constructor to use for auto-wiring.</p>
1919
<h3>Code examples</h3>
2020
<h4>Noncompliant code example</h4>
2121
<pre data-diff-id="1" data-diff-type="noncompliant">
2222
@Component
23-
public class ExampleClass { // Noncompliant, multiple constructors present and no @Autowired annotation to specify which one to use
23+
public class ExampleClass { // Noncompliant: multiple constructors present and no @Autowired annotation to specify which one to use
2424

2525
private final DependencyClass1 dependency1;
2626

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S6838.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ <h4>Noncompliant code example</h4>
3737
@Bean
3838
@Scope("prototype")
3939
public PrototypeBean prototypeBean() {
40-
return new PrototypeBean(singletonBean()); // Noncompliant, the singletonBean is created every time a prototypeBean is created
40+
return new PrototypeBean(singletonBean()); // Noncompliant: a "singletonBean" is created every time a prototypeBean is created
4141
}
4242

4343
class SingletonBean {
Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
1-
<p>This rule reports syntax errors in Spring Expression Language (SpEL) expressions.</p>
1+
<p>This rule reports syntax errors in Spring Expression Language (<code>SpEL</code>) expressions and property placeholders. It verifies that every
2+
<code>SpEL</code> expression and property placeholder is properly closed and that the content of each expression or placeholder is syntactically
3+
correct.</p>
24
<h2>Why is this an issue?</h2>
3-
<p>SpEL is used in Spring annotations and is parsed by the Spring framework, not by the Java compiler. This means that invalid SpEL expressions are
4-
not detected during Java compile time. They will cause exceptions during runtime instead, or even fail silently with the expression string interpreted
5-
as a simple string literal by Spring.</p>
5+
<p>Only the Spring framework, not the Java compiler, parses <code>SpEL</code> expression inside Spring annotations. This means that the Java compiler
6+
does not detect invalid <code>SpEL</code> expressions during compile time. They will cause exceptions during runtime instead, or even fail silently
7+
when Spring interprets the expression as a simple string literal.</p>
68
<h3>Exceptions</h3>
7-
<p>This rule does report syntactical errors in SpEL expressions but does not consider semantic errors, such as unknown identifiers or incompatible
8-
operand data types.</p>
9+
<p>This rule reports syntactical errors in <code>SpEL</code> expressions but does not consider semantic errors, such as unknown identifiers or
10+
incompatible operand data types.</p>
911
<h2>How to fix it</h2>
1012
<p>Correct the syntax error in the SpEL expression.</p>
1113
<h3>Code examples</h3>
1214
<h4>Noncompliant code example</h4>
1315
<pre data-diff-id="1" data-diff-type="noncompliant">
14-
@Value("#{systemProperties['user.region'}") // Noncompliant, unclosed "["
16+
@Value("#{systemProperties['user.region'}") // Noncompliant: unclosed "["
1517
private String region;
1618
</pre>
1719
<pre data-diff-id="2" data-diff-type="noncompliant">
18-
@Value("#{'${listOfValues}' split(',')}") // Noncompliant, missing operator
20+
@Value("#{'${listOfValues}' split(',')}") // Noncompliant: missing operator
1921
private List&lt;String&gt; valuesList;
2022
</pre>
2123
<pre data-diff-id="3" data-diff-type="noncompliant">
22-
@Value("#{T(java.lang.Math).random() * 64h}") // Noncompliant, invalid number
24+
@Value("#{T(java.lang.Math).random() * 64h}") // Noncompliant: invalid number
2325
private Double randPercent;
2426
</pre>
2527
<pre data-diff-id="4" data-diff-type="noncompliant">
26-
@Query("SELECT u FROM User u WHERE u.status = :#{#status+}") // Noncompliant, missing operand for "+"
28+
@Query("SELECT u FROM User u WHERE u.status = :#{#status+}") // Noncompliant: missing operand for "+"
2729
List&lt;User&gt; findUsersByStatus(@Param("status") String status);
2830
</pre>
31+
<pre data-diff-id="5" data-diff-type="noncompliant">
32+
@Value("${myapp.!prop}") // Noncompliant: property key contains an exclamation mark "!"
33+
private String myProperty;
34+
</pre>
35+
<pre data-diff-id="6" data-diff-type="noncompliant">
36+
@Value("${my.property:#{1**1}}") // Noncompliant: invalid SpEL expression "1**1"
37+
private Integer myValue;
38+
</pre>
2939
<h4>Compliant solution</h4>
3040
<pre data-diff-id="1" data-diff-type="compliant">
3141
@Value("#{systemProperties['user.region']}") // Compliant
@@ -43,10 +53,18 @@ <h4>Compliant solution</h4>
4353
@Query("SELECT u FROM User u WHERE u.status = :#{#status+42}") // Compliant
4454
List&lt;User&gt; findUsersByStatus(@Param("status") String status);
4555
</pre>
56+
<pre data-diff-id="5" data-diff-type="compliant">
57+
@Value("${myapp.prop}") // Compliant
58+
private String myProperty;
59+
</pre>
60+
<pre data-diff-id="6" data-diff-type="compliant">
61+
@Value("${my.property:#{1*1}}") // Compliant
62+
private Integer myValue;
63+
</pre>
4664
<h2>Resources</h2>
4765
<h3>Documentation</h3>
4866
<ul>
49-
<li> <a href="https://docs.spring.io/spring-framework/reference/core/expressions.html">Spring Framework - Spring Expression Language (SpEL)</a>
50-
</li>
67+
<li> Spring Framework Documentation - <a href="https://docs.spring.io/spring-framework/reference/core/expressions.html">Spring Expression Language
68+
(SpEL)</a> </li>
5169
</ul>
5270

0 commit comments

Comments
 (0)