Skip to content

Commit 9c2779b

Browse files
committed
SONARJAVA-572 Reduce severity, ignore enum constant and handle members having same visibility but different types
1 parent f5efc08 commit 9c2779b

4 files changed

Lines changed: 92 additions & 72 deletions

File tree

its/ruling/src/test/resources/expected/squid-S1845.json

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424
'project:com/sun/corba/se/impl/naming/cosnaming/BindingIteratorImpl.java':[
2525
178,
2626
],
27-
'project:com/sun/corba/se/impl/oa/poa/AOMEntry.java':[
28-
245,
29-
246,
30-
],
3127
'project:com/sun/jmx/snmp/IPAcl/Parser.java':[
3228
168,
3329
232,
@@ -56,11 +52,8 @@
5652
42,
5753
50,
5854
],
59-
'project:com/sun/org/apache/xerces/internal/dom/NamedNodeMapImpl.java':[
60-
418,
61-
422,
62-
426,
63-
430,
55+
'project:com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java':[
56+
183,
6457
],
6558
'project:com/sun/org/apache/xerces/internal/dom/events/EventImpl.java':[
6659
43,
@@ -134,12 +127,16 @@
134127
1996,
135128
2036,
136129
],
130+
'project:java/awt/GridBagLayoutInfo.java':[
131+
84,
132+
],
137133
'project:java/awt/MediaTracker.java':[
138134
883,
139135
884,
140136
],
141137
'project:java/awt/SentEvent.java':[
142138
45,
139+
48,
143140
],
144141
'project:java/awt/SequencedEvent.java':[
145142
49,
@@ -156,14 +153,21 @@
156153
'project:java/io/Console.java':[
157154
373,
158155
],
159-
'project:java/io/StreamTokenizer.java':[
160-
775,
161-
],
162-
'project:java/lang/invoke/FilterOneArgument.java':[
163-
53,
164-
],
165-
'project:java/lang/invoke/MethodHandleImpl.java':[
166-
251,
156+
'project:java/io/ObjectInputStream.java':[
157+
3426,
158+
],
159+
'project:java/lang/invoke/ToGeneric.java':[
160+
374,
161+
375,
162+
376,
163+
378,
164+
380,
165+
809,
166+
860,
167+
894,
168+
932,
169+
974,
170+
1020,
167171
],
168172
'project:java/math/MutableBigInteger.java':[
169173
1187,
@@ -172,25 +176,20 @@
172176
712,
173177
713,
174178
],
175-
'project:java/security/Signature.java':[
176-
551,
177-
587,
178-
621,
179-
657,
180-
],
181-
'project:java/util/Formatter.java':[
182-
4264,
179+
'project:java/util/HashMap.java':[
180+
1050,
183181
],
184182
'project:java/util/Hashtable.java':[
185-
1007,
186183
1008,
187184
],
188-
'project:java/util/concurrent/ThreadPoolExecutor.java':[
189-
379,
190-
1953,
185+
'project:java/util/LinkedHashMap.java':[
186+
388,
187+
],
188+
'project:java/util/concurrent/ConcurrentHashMap.java':[
189+
1285,
191190
],
192-
'project:java/util/prefs/Base64.java':[
193-
214,
191+
'project:java/util/regex/Pattern.java':[
192+
1696,
194193
],
195194
'project:javax/management/Query.java':[
196195
168,
@@ -201,41 +200,34 @@
201200
536,
202201
554,
203202
],
204-
'project:javax/management/remote/rmi/RMIConnectionImpl.java':[
205-
1705,
206-
],
207-
'project:javax/management/remote/rmi/RMIConnector.java':[
208-
2466,
209-
],
210203
'project:javax/sql/RowSet.java':[
211204
107,
212205
2182,
213206
],
214207
'project:javax/sql/rowset/BaseRowSet.java':[
215208
4504,
216209
],
210+
'project:javax/swing/JProgressBar.java':[
211+
153,
212+
],
217213
'project:javax/swing/JScrollPane.java':[
218214
204,
219215
],
220216
'project:javax/swing/ScrollPaneLayout.java':[
221217
69,
222218
],
223-
'project:javax/swing/plaf/basic/BasicPopupMenuUI.java':[
224-
623,
225-
],
226-
'project:javax/swing/plaf/basic/BasicTreeUI.java':[
227-
4276,
228-
4289,
229-
4294,
230-
],
231219
'project:javax/swing/plaf/synth/SynthComboBoxUI.java':[
232220
539,
233221
],
234222
'project:javax/swing/text/html/HTML.java':[
235223
379,
236224
],
225+
'project:javax/swing/text/html/HTMLDocument.java':[
226+
1795,
227+
],
237228
'project:javax/swing/text/html/HTMLEditorKit.java':[
238229
636,
230+
1818,
239231
],
240232
'project:javax/swing/text/html/parser/AttributeList.java':[
241233
49,
@@ -249,10 +241,6 @@
249241
'project:javax/swing/text/html/parser/Entity.java':[
250242
45,
251243
],
252-
'project:javax/swing/text/html/parser/Parser.java':[
253-
394,
254-
445,
255-
],
256244
'project:javax/xml/datatype/XMLGregorianCalendar.java':[
257245
1052,
258246
],

java-checks/src/main/java/org/sonar/java/checks/MembersDifferOnlyByCapitalizationCheck.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
key = "S1845",
4545
name = "Methods and field names should not be the same or differ only by capitalization",
4646
tags = {"confusing"},
47-
priority = Priority.CRITICAL)
47+
priority = Priority.MAJOR)
4848
@ActivatedByDefault
4949
@SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.UNDERSTANDABILITY)
5050
@SqaleConstantRemediation("10min")
@@ -99,7 +99,7 @@ private static boolean isOverriding(Symbol symbol) {
9999

100100
private static boolean isInvalidMember(Symbol currentMember, Symbol knownMember) {
101101
if (!isOverriding(currentMember)) {
102-
return !sameName(currentMember, knownMember) || (differentTypes(currentMember, knownMember) && bothPublic(currentMember, knownMember));
102+
return differentTypes(currentMember, knownMember) ? sameVisibilityNotPrivate(currentMember, knownMember) : !sameName(currentMember, knownMember);
103103
}
104104
return false;
105105
}
@@ -108,6 +108,18 @@ private static boolean isValidIssueLocation(Symbol currentMember, Symbol knownMe
108108
return !sameOwner(currentMember, knownMember) || isOverriding(knownMember) || getDeclarationLine(currentMember) > getDeclarationLine(knownMember);
109109
}
110110

111+
private static boolean sameVisibilityNotPrivate(Symbol s1, Symbol s2) {
112+
return bothPublic(s1, s2) || bothProtected(s1, s2) || bothPackageVisibility(s1, s2);
113+
}
114+
115+
private static boolean bothPackageVisibility(Symbol s1, Symbol s2) {
116+
return s1.isPackageVisibility() && s2.isPackageVisibility();
117+
}
118+
119+
private static boolean bothProtected(Symbol s1, Symbol s2) {
120+
return s1.isProtected() && s2.isProtected();
121+
}
122+
111123
private static boolean bothPublic(Symbol s1, Symbol s2) {
112124
return s1.isPublic() && s2.isPublic();
113125
}
@@ -172,19 +184,19 @@ private static List<Symbol> retrieveMembers(Symbol.TypeSymbol classSymbol) {
172184
private static List<Symbol> extractMembers(Symbol.TypeSymbol classSymbol, boolean ignorePrivate) {
173185
List<Symbol> results = Lists.newLinkedList();
174186
for (Symbol symbol : classSymbol.memberSymbols()) {
175-
if ((variableButNotThisNorSuper(symbol) || methodButNotConstructor(symbol)) && !(symbol.isPrivate() && ignorePrivate)) {
187+
if ((isVariableToExtract(symbol) || isMethodToExtract(symbol)) && !(symbol.isPrivate() && ignorePrivate)) {
176188
results.add(symbol);
177189
}
178190
}
179191
return results;
180192
}
181193

182-
private static boolean variableButNotThisNorSuper(Symbol symbol) {
194+
private static boolean isVariableToExtract(Symbol symbol) {
183195
String name = symbol.name();
184-
return symbol.isVariableSymbol() && !"this".equals(name) && !"super".equals(name);
196+
return !symbol.isEnum() && symbol.isVariableSymbol() && !"this".equals(name) && !"super".equals(name);
185197
}
186198

187-
private static boolean methodButNotConstructor(Symbol symbol) {
199+
private static boolean isMethodToExtract(Symbol symbol) {
188200
return symbol.isMethodSymbol() && !"<init>".equals(symbol.name());
189201
}
190202
}

java-checks/src/main/resources/org/sonar/l10n/java/rules/squid/S1845.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
<p>Looking at the set of methods in a class, including superclass methods, and finding two methods or fields that differ only by capitalization is confusing to users of the class. It is similarly confusing to have a method and a field which differ only in capitalization or a method and a field with exactly the same name.</p>
1+
<p>Looking at the set of methods in a class, including superclass methods, and finding two methods or fields that differ only by capitalization is confusing to users of the class. It is similarly confusing to have a method and a field which differ only in capitalization or a method and a field with exactly the same name and visibility.</p>
22
<p>In the case of methods, it may have been a mistake on the part of the original developer, who intended to override a superclass method, but instead added a new method with nearly the same name.</p>
33
<p>Otherwise, this situation simply indicates poor naming. Method names should be action-oriented, and thus contain a verb, which is unlikely in the case where both a method and a member have the same name (with or without capitalization differences). However, renaming a public method could be disruptive to callers. Therefore renaming the member is the recommended action.</p>
44
<h2>Noncompliant Code Example</h2>
55

66
<pre>
77
public class Car{
88

9-
private DriveTrain drive;
9+
public DriveTrain drive;
1010

1111
public void tearDown(){...}
1212

@@ -26,11 +26,11 @@ <h2>Compliant Solution</h2>
2626
<pre>
2727
public class Car{
2828

29-
private DriveTrain driveTrain;
29+
private DriveTrain drive;
3030

3131
public void tearDown(){...}
3232

33-
public void drive() {...} // field was renamed
33+
public void drive() {...} // field visibility reduced
3434
}
3535

3636
public class MyCar extends Car{

java-checks/src/test/files/checks/MembersDifferOnlyByCapitalizationCheck.java

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,10 @@ public void myOtherMethoD() {} // Noncompliant {{Rename method "myOtherMethoD" t
1919
private static void gUl() {} // Noncompliant {{Rename method "gUl" to prevent any misunderstanding/clash with method "gul" defined on line 20.}}
2020
public void gul() {} // Compliant
2121

22-
public int tmp0;
23-
public void tmp0() {} // Noncompliant {{Rename method "tmp0" to prevent any misunderstanding/clash with field "tmp0" defined on line 22.}}
24-
25-
private int tmp1;
26-
private void tmp1() {} // Compliant
27-
28-
private int tmp2;
29-
public void tmp2() {}; // Compliant
30-
31-
public int tmp3;
32-
private void tmp3() {}; // Compliant
33-
3422
private boolean qix;
3523

3624
public Object myField; // Noncompliant
37-
public void myField();
25+
public void myField(); // Compliant, as it overrides the parent interface method
3826

3927
public A() {}
4028
class MyInnerClass {}
@@ -61,3 +49,35 @@ public void myMethoD() {} // Noncompliant {{Rename method "myMethoD" to prevent
6149

6250
public void fOo(int i) {} // Noncompliant
6351
}
52+
53+
class Visibility {
54+
public int tmp0;
55+
private void tmp0() {}
56+
public void tmp0(int i) {} // Noncompliant {{Rename method "tmp0" to prevent any misunderstanding/clash with field "tmp0" defined on line 54.}}
57+
protected void tmp0(long l) {}
58+
void tmp0(short s) {}
59+
60+
private int tmp1;
61+
private void tmp1() {} // Compliant - private members having same name are ignored
62+
public void tmp1(int i) {}
63+
protected void tmp1(long l) {}
64+
void tmp1(short s) {}
65+
66+
int tmp2;
67+
private void tmp2() {}
68+
public void tmp1(int i) {}
69+
protected void tmp1(long l) {}
70+
void tmp2(short s) {} // Noncompliant {{Rename method "tmp2" to prevent any misunderstanding/clash with field "tmp2" defined on line 66.}}
71+
72+
protected int tmp3;
73+
private void tmp3() {}
74+
public void tmp3(int i) {}
75+
protected void tmp3(long l) {} // Noncompliant {{Rename method "tmp3" to prevent any misunderstanding/clash with field "tmp3" defined on line 72.}}
76+
void tmp3(short s) {}
77+
}
78+
79+
public enum MyEnum {
80+
FOO;
81+
82+
public void foo() {} // Compliant
83+
}

0 commit comments

Comments
 (0)