Skip to content

Commit 2fa5d7f

Browse files
committed
Fix/ignore major + minor code smells reported by SonarCloud
1 parent 22e6b7d commit 2fa5d7f

File tree

99 files changed

+595
-416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+595
-416
lines changed

google_checks.xml

-8
Original file line numberDiff line numberDiff line change
@@ -321,19 +321,11 @@
321321
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
322322
</module>
323323
<module name="JavadocMethod">
324-
<property name="accessModifiers" value="public"/>
325324
<property name="allowMissingParamTags" value="true"/>
326325
<property name="allowMissingReturnTag" value="true"/>
327326
<property name="allowedAnnotations" value="Override, Test"/>
328327
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
329328
</module>
330-
<module name="MissingJavadocMethod">
331-
<property name="scope" value="public"/>
332-
<property name="minLineCount" value="2"/>
333-
<property name="allowedAnnotations" value="Override, Test"/>
334-
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF,
335-
COMPACT_CTOR_DEF"/>
336-
</module>
337329
<module name="MissingJavadocType">
338330
<property name="scope" value="protected"/>
339331
<property name="tokens"

pom.xml

+11-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<google-java-format.version>1.15.0</google-java-format.version>
2222
<jacoco.version>0.8.8</jacoco.version>
2323
<spotbugs.version>4.7.1.0</spotbugs.version>
24+
<spotbugs-annotations.version>4.7.1</spotbugs-annotations.version>
2425
<findsecbugs.version>1.12.0</findsecbugs.version>
2526
<pmd-plugin.version>3.17.0</pmd-plugin.version>
2627
<pmd.version>6.47.0</pmd.version>
@@ -37,16 +38,24 @@
3738
<sonar.java.checkstyle.reportPaths>./target/checkstyle-result.xml</sonar.java.checkstyle.reportPaths>
3839
<sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
3940

40-
<!-- Exclude "Cognitive Complexity of methods should not be too high" from "method" package -->
41-
<sonar.issue.ignore.multicriteria>e1</sonar.issue.ignore.multicriteria>
41+
<sonar.issue.ignore.multicriteria>e1,e2</sonar.issue.ignore.multicriteria>
42+
<!-- Ignore "Cognitive Complexity of methods should not be too high" warnings in "method" package -->
4243
<sonar.issue.ignore.multicriteria.e1.ruleKey>java:S3776</sonar.issue.ignore.multicriteria.e1.ruleKey>
4344
<sonar.issue.ignore.multicriteria.e1.resourceKey>**/eu/happycoders/sort/method/**/*.*</sonar.issue.ignore.multicriteria.e1.resourceKey>
45+
<!-- Ignore "Weak Cryptography" warnings - we're just sorting random numbers -->
46+
<sonar.issue.ignore.multicriteria.e2.ruleKey>java:S2245</sonar.issue.ignore.multicriteria.e2.ruleKey>
47+
<sonar.issue.ignore.multicriteria.e2.resourceKey>**/*.*</sonar.issue.ignore.multicriteria.e2.resourceKey>
4448

4549
<!-- Exclude "method" package from duplicate check -->
4650
<sonar.cpd.exclusions>**/eu/happycoders/sort/method/**/*.*</sonar.cpd.exclusions>
4751
</properties>
4852

4953
<dependencies>
54+
<dependency>
55+
<groupId>com.github.spotbugs</groupId>
56+
<artifactId>spotbugs-annotations</artifactId>
57+
<version>${spotbugs-annotations.version}</version>
58+
</dependency>
5059
<dependency>
5160
<scope>test</scope>
5261
<groupId>org.junit.jupiter</groupId>

ruleset.xml

+10-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<rule ref="category/java/bestpractices.xml">
1111
<exclude name="AvoidReassigningParameters"/> <!-- In Java, this is OK, IMO -->
1212
<exclude name="SwitchStmtsShouldHaveDefault"/><!-- PMD doesn't recognize Java's new switch statements -->
13+
<exclude name="UseVarargs"/> <!-- PMD would suggest varargs wherever we pass an array to be sorted -->
1314
</rule>
1415

1516
<rule ref="category/java/codestyle.xml">
@@ -21,6 +22,8 @@
2122
<exclude name="OnlyOneReturn"/> <!-- This rule might have made sense decades ago when methods where hundreds of lines long -->
2223
<exclude name="ShortClassName"/> <!-- Wouldn't allow class names like "User" -->
2324
<exclude name="ShortMethodName"/> <!-- Wouldn't allow method names like "of" -->
25+
<exclude name="ShortVariable"/> <!-- This is usually a valid check; however, in the search algorithms, we often use variables "i" and "j"Wouldn't allow method names like "of" -->
26+
<exclude name="CallSuperInConstructor"/> <!-- IMO, this would be noise -->
2427
</rule>
2528

2629
<rule ref="category/java/codestyle.xml/ClassNamingConventions">
@@ -37,6 +40,9 @@
3740

3841
<rule ref="category/java/design.xml">
3942
<exclude name="LawOfDemeter"/> <!-- We don't want to apply this law -->
43+
<exclude name="CognitiveComplexity"/> <!-- This is usually a valid check; however, search algorithms *are* complex (we could make the code easier by extracting several methods, but I prefer to have it as close to the actual algorithm description as possible) -->
44+
<exclude name="CyclomaticComplexity"/> <!-- This is usually a valid check; however, search algorithms *are* complex (we could make the code easier by extracting several methods, but I prefer to have it as close to the actual algorithm description as possible) -->
45+
<exclude name="NPathComplexity"/> <!-- This is usually a valid check; however, search algorithms *are* complex (we could make the code easier by extracting several methods, but I prefer to have it as close to the actual algorithm description as possible) -->
4046
</rule>
4147

4248
<rule ref="category/java/documentation.xml">
@@ -50,11 +56,13 @@
5056

5157
<rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition">
5258
<properties>
53-
<property name="ignoreMagicNumbers" value="-1,0,1" /><!-- Default is only -1 and 0; add 1 -->
59+
<property name="ignoreMagicNumbers" value="-1,0,1,2" /><!-- Default is only -1 and 0; add 1, 2 -->
5460
</properties>
5561
</rule>
5662

57-
<rule ref="category/java/multithreading.xml"/>
63+
<rule ref="category/java/multithreading.xml">
64+
<exclude name="DoNotUseThreads"/> <!-- This warning is for Java EE applications -->
65+
</rule>
5866

5967
<rule ref="category/java/performance.xml"/>
6068

src/main/java/eu/happycoders/sort/CountOperations.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import eu.happycoders.sort.method.SortAlgorithm;
55
import eu.happycoders.sort.utils.ArrayUtils;
66
import java.util.Locale;
7-
import java.util.function.Function;
7+
import java.util.function.IntFunction;
88

99
/**
1010
* Measures the performance of all sorting algorithms for various input sizes.
@@ -43,7 +43,7 @@ private void countOps(
4343
SortAlgorithm algorithm,
4444
boolean sorted,
4545
String inputOrder,
46-
Function<Integer, int[]> arraySupplier) {
46+
IntFunction<int[]> arraySupplier) {
4747
System.out.printf("%n--- %s (order: %s) ---%n", algorithm.getName(), inputOrder);
4848

4949
// Sort until sorting takes more than MAX_SORTING_TIME_SECS
@@ -74,7 +74,7 @@ private void countOps(
7474

7575
private Counters countOps(SortAlgorithm algorithm, int[] elements) {
7676
Counters counters = new Counters();
77-
algorithm.sort(elements, counters);
77+
algorithm.sortWithCounters(elements, counters);
7878
return counters;
7979
}
8080
}

src/main/java/eu/happycoders/sort/UltimateTest.java

+26-26
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.HashMap;
2222
import java.util.Locale;
2323
import java.util.Map;
24-
import java.util.function.Function;
24+
import java.util.function.IntFunction;
2525

2626
/**
2727
* Measures the performance of all sorting algorithms for various input sizes.
@@ -31,29 +31,28 @@
3131
@SuppressWarnings({"PMD.SystemPrintln", "java:S106"})
3232
public class UltimateTest {
3333

34-
static final SortAlgorithm[] ALGORITHMS =
35-
new SortAlgorithm[] {
36-
new InsertionSort(),
37-
new SelectionSort(),
38-
new BubbleSortOpt1(),
39-
40-
// Quicksort
41-
new QuicksortVariant1(PivotStrategy.RIGHT),
42-
new QuicksortVariant1(PivotStrategy.MIDDLE),
43-
new QuicksortVariant1(PivotStrategy.MEDIAN3),
44-
new QuicksortImproved(48, new QuicksortVariant1(PivotStrategy.MIDDLE)),
45-
new DualPivotQuicksort(DualPivotQuicksort.PivotStrategy.THIRDS),
46-
new DualPivotQuicksortImproved(64, DualPivotQuicksort.PivotStrategy.THIRDS),
47-
new MergeSort(),
48-
49-
// Heapsort
50-
new Heapsort(),
51-
new BottomUpHeapsort(),
52-
new HeapsortSlowComparisons(),
53-
new BottomUpHeapsortSlowComparisons(),
54-
new CountingSort(),
55-
new JavaArraysSort()
56-
};
34+
static final SortAlgorithm[] ALGORITHMS = {
35+
new InsertionSort(),
36+
new SelectionSort(),
37+
new BubbleSortOpt1(),
38+
39+
// Quicksort
40+
new QuicksortVariant1(PivotStrategy.RIGHT),
41+
new QuicksortVariant1(PivotStrategy.MIDDLE),
42+
new QuicksortVariant1(PivotStrategy.MEDIAN3),
43+
new QuicksortImproved(48, new QuicksortVariant1(PivotStrategy.MIDDLE)),
44+
new DualPivotQuicksort(DualPivotQuicksort.PivotStrategy.THIRDS),
45+
new DualPivotQuicksortImproved(64, DualPivotQuicksort.PivotStrategy.THIRDS),
46+
new MergeSort(),
47+
48+
// Heapsort
49+
new Heapsort(),
50+
new BottomUpHeapsort(),
51+
new HeapsortSlowComparisons(),
52+
new BottomUpHeapsortSlowComparisons(),
53+
new CountingSort(),
54+
new JavaArraysSort()
55+
};
5756

5857
private static final int WARM_UPS = 2;
5958

@@ -65,6 +64,7 @@ public class UltimateTest {
6564

6665
private static final boolean TEST_SORTED_INPUT = true;
6766

67+
@SuppressWarnings("PMD.UseConcurrentHashMap") // Not accessed concurrently
6868
private final Map<String, Scorecard> scorecards = new HashMap<>();
6969

7070
public static void main(String[] args) {
@@ -108,7 +108,7 @@ private void test(SortAlgorithm algorithm, boolean warmingUp) {
108108
private void test(
109109
SortAlgorithm algorithm,
110110
InputOrder inputOrder,
111-
Function<Integer, int[]> arraySupplier,
111+
IntFunction<int[]> arraySupplier,
112112
boolean warmingUp) {
113113
System.out.printf("%n--- %s (order: %s) ---%n", algorithm.getName(), inputOrder);
114114

@@ -199,7 +199,7 @@ boolean isSorted() {
199199

200200
@Override
201201
public String toString() {
202-
return name().toLowerCase();
202+
return name().toLowerCase(Locale.US);
203203
}
204204
}
205205
}

src/main/java/eu/happycoders/sort/comparisons/CompareImprovedDualPivotQuicksort.java

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public static void main(String[] args) {
2020
new CompareImprovedDualPivotQuicksort().run();
2121
}
2222

23+
@SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
2324
private void run() {
2425
List<SortAlgorithm> algorithms = new ArrayList<>();
2526
algorithms.add(new DualPivotQuicksort(DualPivotQuicksort.PivotStrategy.THIRDS));

src/main/java/eu/happycoders/sort/comparisons/CompareImprovedQuicksort.java

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public static void main(String[] args) {
2323
new CompareImprovedQuicksort().run();
2424
}
2525

26+
@SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
2627
private void run() {
2728
List<SortAlgorithm> algorithms = new ArrayList<>();
2829
algorithms.add(new QuicksortVariant1(PivotStrategy.MIDDLE));

src/main/java/eu/happycoders/sort/comparisons/CompareMergeSorts.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ public static void main(String[] args) {
1919
}
2020

2121
private void run() {
22-
SortAlgorithm[] algorithms =
23-
new SortAlgorithm[] {new MergeSort(), new MergeSort2(), new MergeSort3()};
22+
SortAlgorithm[] algorithms = {new MergeSort(), new MergeSort2(), new MergeSort3()};
2423

2524
runTest(algorithms, SIZE);
2625
}

src/main/java/eu/happycoders/sort/comparisons/DirectComparison.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ public class DirectComparison {
1919
private static final int ITERATIONS = 100;
2020
private static final int PRINT_RESULTS_ALL_X_ITERATIONS = 10;
2121

22+
@SuppressWarnings("PMD.UseConcurrentHashMap") // Not accessed concurrently
2223
private final Map<String, Scorecard> scorecards = new HashMap<>();
2324

2425
private int longestNameLength;
2526

26-
public void runTest(SortAlgorithm[] algorithms, int size) {
27+
void runTest(SortAlgorithm[] algorithms, int size) {
2728
longestNameLength = Scorecard.findLongestAlgorithmName(algorithms);
2829

2930
int numAlgorithms = algorithms.length;
@@ -78,11 +79,9 @@ private long measure(SortAlgorithm sortAlgorithm, int[] elements) {
7879
long time = System.nanoTime();
7980
sortAlgorithm.sort(elements);
8081
time = System.nanoTime() - time;
81-
System.out.printf(
82-
Locale.US,
83-
" %-" + longestNameLength + "s -> time = %,10.3f ms",
84-
sortAlgorithm.getName(),
85-
(time / 1_000_000.0));
82+
83+
String format = " %-" + longestNameLength + "s -> time = %,10.3f ms";
84+
System.out.printf(Locale.US, format, sortAlgorithm.getName(), time / 1_000_000.0);
8685

8786
// Validate that's sorted (and make sure the sorting wasn't optimized away!)
8887
if (!ArrayUtils.isSorted(elements)) {

src/main/java/eu/happycoders/sort/method/Counters.java

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package eu.happycoders.sort.method;
22

3+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
34
import java.util.Locale;
45

56
/**
67
* Counter for sort operations.
78
*
89
* @author <a href="[email protected]">Sven Woltmann</a>
910
*/
11+
@SuppressWarnings("PMD.TooManyMethods") // That's OK for this simple counter class
1012
public class Counters {
1113

1214
private long iterations;
@@ -21,42 +23,42 @@ public void incIterations() {
2123
iterations++;
2224
}
2325

24-
public void addIterations(int x) {
25-
iterations += x;
26+
public void addIterations(int increment) {
27+
iterations += increment;
2628
}
2729

2830
public void incComparisons() {
2931
comparisons++;
3032
}
3133

32-
public void addComparisons(int x) {
33-
comparisons += x;
34+
public void addComparisons(int increment) {
35+
comparisons += increment;
3436
}
3537

3638
public void incReads() {
3739
reads++;
3840
}
3941

40-
public void addReads(int x) {
41-
reads += x;
42+
public void addReads(int increment) {
43+
reads += increment;
4244
}
4345

4446
public void incWrites() {
4547
writes++;
4648
}
4749

48-
public void addWrites(int x) {
49-
writes += x;
50+
public void addWrites(int increment) {
51+
writes += increment;
5052
}
5153

5254
public void incReadsAndWrites() {
5355
reads++;
5456
writes++;
5557
}
5658

57-
public void addReadsAndWrites(int x) {
58-
reads += x;
59-
writes += x;
59+
public void addReadsAndWrites(int increment) {
60+
reads += increment;
61+
writes += increment;
6062
}
6163

6264
public void incLocalVariableAssignments() {
@@ -69,8 +71,9 @@ public void incLocalVariableAssignments() {
6971
*
7072
* <p>Not thread-safe!
7173
*
72-
* @return
74+
* @return the second set of counters
7375
*/
76+
@SuppressFBWarnings("EI_EXPOSE_REP") // We're intentionally exposing the "phase2" object
7477
public Counters getPhase2() {
7578
if (phase2 == null) {
7679
phase2 = new Counters();

src/main/java/eu/happycoders/sort/method/InsertionSort.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*
66
* @author <a href="[email protected]">Sven Woltmann</a>
77
*/
8+
// We don't want to use System.arraycopy - we want to demonstrate how the algorithm works
9+
@SuppressWarnings("PMD.AvoidArrayLoops")
810
public class InsertionSort implements SortAlgorithm {
911

1012
@Override
@@ -27,11 +29,11 @@ public void sort(int[] elements, int fromIndex, int toIndex) {
2729
}
2830

2931
@Override
30-
public void sort(int[] elements, Counters counters) {
31-
sort(elements, 0, elements.length, counters);
32+
public void sortWithCounters(int[] elements, Counters counters) {
33+
sortWithCounters(elements, 0, elements.length, counters);
3234
}
3335

34-
public void sort(int[] elements, int fromIndex, int toIndex, Counters counters) {
36+
public void sortWithCounters(int[] elements, int fromIndex, int toIndex, Counters counters) {
3537
for (int i = fromIndex + 1; i < toIndex; i++) {
3638
counters.incIterations();
3739

@@ -44,12 +46,14 @@ public void sort(int[] elements, int fromIndex, int toIndex, Counters counters)
4446
counters.incIterations();
4547

4648
counters.incComparisons();
47-
if (!(number < elements[j - 1])) break;
48-
49-
elements[j] = elements[j - 1];
50-
counters.incReads();
51-
counters.incWrites();
52-
j--;
49+
if (number < elements[j - 1]) {
50+
elements[j] = elements[j - 1];
51+
counters.incReads();
52+
counters.incWrites();
53+
j--;
54+
} else {
55+
break;
56+
}
5357
}
5458
elements[j] = number;
5559
counters.incWrites();

0 commit comments

Comments
 (0)