From 90fa36e9f8be8524076514fa20cc09d9c8694d8b Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Tue, 18 Jun 2024 16:54:01 +0200 Subject: [PATCH 01/26] SONARJAVA-5049 Add CheckListGenerator --- sonar-java-plugin/pom.xml | 67 ++++++- .../plugins/java/CheckListGenerator.java | 188 ++++++++++++++++++ 2 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java diff --git a/sonar-java-plugin/pom.xml b/sonar-java-plugin/pom.xml index c1274754b0f..97433736c43 100644 --- a/sonar-java-plugin/pom.xml +++ b/sonar-java-plugin/pom.xml @@ -129,10 +129,75 @@ ${project.version} test + + commons-io + commons-io + 2.16.1 + + + + org.codehaus.mojo + exec-maven-plugin + 3.2.0 + + + process-classes + + java + + + org.sonar.plugins.java.CheckListGenerator + compile + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.5.0 + + + process-classes + + add-source + + + + ${project.build.directory}/generated-sources + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + process-classes + + + compile + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + prepare-package + + + + + org.sonarsource.sonar-packaging-maven-plugin sonar-packaging-maven-plugin @@ -164,7 +229,7 @@ - 20000000 + 30000000 18500000 ${project.build.directory}/${project.build.finalName}.jar diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java new file mode 100644 index 00000000000..9c22e911885 --- /dev/null +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -0,0 +1,188 @@ +/* + * SonarQube Java + * Copyright (C) 2012-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.plugins.java; + +import com.google.gson.Gson; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.FileFilterUtils; +import org.sonar.check.Rule; + +public class CheckListGenerator { + + private static class Metadata { + String scope; + } + + private static final String CLASS_NAME = "GeneratedCheckList"; + + public static void main(String[] args) throws IOException { + + var filter = FileFilterUtils.suffixFileFilter("Check.java"); + var files = FileUtils.listFiles(new File("java-checks/src/main/java/org/sonar/java/checks"), filter, FileFilterUtils.trueFileFilter()); + + var modifiedFiles = files.stream() + .map(File::toString) + .map(file -> file.replace("java-checks/src/main/java/", "")) + .map(file -> file.replace(".java", "")) + .map(file -> file.replace("/", ".")) + .toList(); + + var classes = modifiedFiles.stream() + .map(file -> { + try { + return Class.forName(file); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Can not find the class for name " + file, e); + } + }) + .toList(); + + var filteredClasses = classes.stream() + .filter(c -> !Modifier.isAbstract(c.getModifiers())) + .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) + .toList(); + + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + + filteredClasses.forEach(c -> { + Rule ruleAnnotation = c.getAnnotationsByType(Rule.class)[0]; + String key = ruleAnnotation.key(); + String fileName = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/" + key + ".json"; + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new IllegalStateException("Could not find rule file " + fileName, e); + } + Metadata metadata = new Gson().fromJson(br, Metadata.class); + + switch (metadata.scope) { + case "All" -> allClasses.add(c); + case "Main" -> mainClasses.add(c); + case "Tests" -> testClasses.add(c); + default -> throw new IllegalStateException("Unknown scope " + metadata.scope + " for class " + c.getName()); + } + }); + + String importChecks = filteredClasses.stream() + .map(c -> c.getPackageName() + "." + c.getSimpleName()) + .map(c -> "import " + c + ";") + .collect(Collectors.joining("\n")); + + String collectMainChecks = mainClasses.stream() + .map(c -> c.getSimpleName() + ".class") + .collect(Collectors.joining(", \n ")); + + String collectTestChecks = testClasses.stream() + .map(c -> c.getSimpleName() + ".class") + .collect(Collectors.joining(", \n ")); + + String collectAllChecks = allClasses.stream() + .map(c -> c.getSimpleName() + ".class") + .collect(Collectors.joining(", \n ")); + + try { + Path path = Path.of("sonar-java-plugin/target/generated-sources/" + CLASS_NAME + ".java"); + Files.writeString(path, """ + package org.sonar.plugins.java; + + import java.util.Arrays; + import java.util.Comparator; + import java.util.List; + import java.util.Set; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import org.sonar.plugins.java.api.JavaCheck; + + ${importChecks} + + public final class ${className} { + + public static final String REPOSITORY_KEY = "java"; + + private static final List> JAVA_MAIN_CHECKS = Arrays.asList( + ${mainClasses}); + + private static final List> JAVA_TEST_CHECKS = Arrays.asList( + ${testClasses}); + + private static final List> JAVA_MAIN_AND_TEST_CHECKS = Arrays.asList( + ${allClasses}); + + private static final List> ALL_CHECKS = Stream.of(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS) + .flatMap(List::stream) + .sorted(Comparator.comparing(Class::getSimpleName)) + .collect(Collectors.toList()); + + private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of(); + + private GeneratedCheckList() { + } + + public static List> getChecks() { + return ALL_CHECKS; + } + + public static List> getJavaChecks() { + return sortedJoin(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS); + } + + public static List> getJavaTestChecks() { + return sortedJoin(JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS); + } + + public static Set> getJavaChecksNotWorkingForAutoScan() { + return JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN; + } + + @SafeVarargs + private static List> sortedJoin(List>... lists) { + return Arrays.stream(lists) + .flatMap(List::stream) + .sorted(Comparator.comparing(Class::getSimpleName)) + .toList(); + } + } + """ + .replace("${importChecks}", importChecks) + .replace("${className}", CLASS_NAME) + .replace("${mainClasses}", collectMainChecks) + .replace("${testClasses}", collectTestChecks) + .replace("${allClasses}", collectAllChecks)); + + } catch (IOException e) { + throw new IOException("Failed to generate class", e); + } + } + +} From 3275b5de57977914e424c693e648f42ec374805a Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Tue, 18 Jun 2024 17:24:18 +0200 Subject: [PATCH 02/26] Revert maxSize --- sonar-java-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-java-plugin/pom.xml b/sonar-java-plugin/pom.xml index 97433736c43..4b6976bda7a 100644 --- a/sonar-java-plugin/pom.xml +++ b/sonar-java-plugin/pom.xml @@ -229,7 +229,7 @@ - 30000000 + 20000000 18500000 ${project.build.directory}/${project.build.finalName}.jar From 2406170a60ea98cd0c1eebcfb5c0d4bda9f83a9f Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Tue, 18 Jun 2024 18:02:23 +0200 Subject: [PATCH 03/26] Separate writing to a file to a method --- .../plugins/java/CheckListGenerator.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java index 9c22e911885..2cf060fc8ec 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -37,13 +37,9 @@ public class CheckListGenerator { - private static class Metadata { - String scope; - } - private static final String CLASS_NAME = "GeneratedCheckList"; - public static void main(String[] args) throws IOException { + public static void main(String[] args) { var filter = FileFilterUtils.suffixFileFilter("Check.java"); var files = FileUtils.listFiles(new File("java-checks/src/main/java/org/sonar/java/checks"), filter, FileFilterUtils.trueFileFilter()); @@ -94,25 +90,27 @@ public static void main(String[] args) throws IOException { } }); - String importChecks = filteredClasses.stream() + var importChecks = filteredClasses.stream() .map(c -> c.getPackageName() + "." + c.getSimpleName()) .map(c -> "import " + c + ";") .collect(Collectors.joining("\n")); - String collectMainChecks = mainClasses.stream() - .map(c -> c.getSimpleName() + ".class") - .collect(Collectors.joining(", \n ")); - - String collectTestChecks = testClasses.stream() - .map(c -> c.getSimpleName() + ".class") - .collect(Collectors.joining(", \n ")); + try { + writeToFile(importChecks, collectChecks(mainClasses), collectChecks(testClasses), collectChecks(allClasses)); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } - String collectAllChecks = allClasses.stream() + private static String collectChecks(List> allClasses) { + return allClasses.stream() .map(c -> c.getSimpleName() + ".class") .collect(Collectors.joining(", \n ")); + } + private static void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks) throws IOException { try { - Path path = Path.of("sonar-java-plugin/target/generated-sources/" + CLASS_NAME + ".java"); + var path = Path.of("sonar-java-plugin/target/generated-sources/" + CLASS_NAME + ".java"); Files.writeString(path, """ package org.sonar.plugins.java; @@ -185,4 +183,8 @@ private static List> sortedJoin(List Date: Tue, 18 Jun 2024 18:07:04 +0200 Subject: [PATCH 04/26] Separate check files search and filtering to a method --- .../plugins/java/CheckListGenerator.java | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java index 2cf060fc8ec..ebacfe88c1e 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -41,30 +41,7 @@ public class CheckListGenerator { public static void main(String[] args) { - var filter = FileFilterUtils.suffixFileFilter("Check.java"); - var files = FileUtils.listFiles(new File("java-checks/src/main/java/org/sonar/java/checks"), filter, FileFilterUtils.trueFileFilter()); - - var modifiedFiles = files.stream() - .map(File::toString) - .map(file -> file.replace("java-checks/src/main/java/", "")) - .map(file -> file.replace(".java", "")) - .map(file -> file.replace("/", ".")) - .toList(); - - var classes = modifiedFiles.stream() - .map(file -> { - try { - return Class.forName(file); - } catch (ClassNotFoundException e) { - throw new IllegalStateException("Can not find the class for name " + file, e); - } - }) - .toList(); - - var filteredClasses = classes.stream() - .filter(c -> !Modifier.isAbstract(c.getModifiers())) - .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) - .toList(); + var filteredClasses = getCheckClasses(); List> mainClasses = new ArrayList<>(); List> testClasses = new ArrayList<>(); @@ -102,6 +79,33 @@ public static void main(String[] args) { } } + private static List> getCheckClasses() { + var filter = FileFilterUtils.suffixFileFilter("Check.java"); + var files = FileUtils.listFiles(new File("java-checks/src/main/java/org/sonar/java/checks"), filter, FileFilterUtils.trueFileFilter()); + + var modifiedFiles = files.stream() + .map(File::toString) + .map(file -> file.replace("java-checks/src/main/java/", "")) + .map(file -> file.replace(".java", "")) + .map(file -> file.replace("/", ".")) + .toList(); + + var classes = modifiedFiles.stream() + .map(file -> { + try { + return Class.forName(file); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Can not find the class for name " + file, e); + } + }) + .toList(); + + return classes.stream() + .filter(c -> !Modifier.isAbstract(c.getModifiers())) + .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) + .toList(); + } + private static String collectChecks(List> allClasses) { return allClasses.stream() .map(c -> c.getSimpleName() + ".class") From feebe50b6a375d27424b8157c5a70a405d0a99bd Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Wed, 19 Jun 2024 14:43:06 +0200 Subject: [PATCH 05/26] Remove commons io library --- sonar-java-plugin/pom.xml | 5 ---- .../plugins/java/CheckListGenerator.java | 23 +++++++++---------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/sonar-java-plugin/pom.xml b/sonar-java-plugin/pom.xml index 4b6976bda7a..43013117b8c 100644 --- a/sonar-java-plugin/pom.xml +++ b/sonar-java-plugin/pom.xml @@ -129,11 +129,6 @@ ${project.version} test - - commons-io - commons-io - 2.16.1 - diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java index ebacfe88c1e..467919318a3 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -21,7 +21,6 @@ import com.google.gson.Gson; import java.io.BufferedReader; -import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Modifier; @@ -31,8 +30,6 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.FileFilterUtils; import org.sonar.check.Rule; public class CheckListGenerator { @@ -80,15 +77,17 @@ public static void main(String[] args) { } private static List> getCheckClasses() { - var filter = FileFilterUtils.suffixFileFilter("Check.java"); - var files = FileUtils.listFiles(new File("java-checks/src/main/java/org/sonar/java/checks"), filter, FileFilterUtils.trueFileFilter()); - - var modifiedFiles = files.stream() - .map(File::toString) - .map(file -> file.replace("java-checks/src/main/java/", "")) - .map(file -> file.replace(".java", "")) - .map(file -> file.replace("/", ".")) - .toList(); + List modifiedFiles; + try (var stream = Files.walk(Path.of("java-checks/src/main/java/org/sonar/java/checks"))) { + modifiedFiles = stream.map(Path::toString) + .filter(file -> file.endsWith("Check.java")) + .map(file -> file.replace("java-checks/src/main/java/", "")) + .map(file -> file.replace(".java", "")) + .map(file -> file.replace("/", ".")) + .toList(); + } catch (IOException e) { + throw new IllegalStateException(e); + } var classes = modifiedFiles.stream() .map(file -> { From 9e5cb7c6cd2d8be7448e1af61d4cba33cc780561 Mon Sep 17 00:00:00 2001 From: Leonardo Pilastri Date: Wed, 19 Jun 2024 14:53:59 +0200 Subject: [PATCH 06/26] Fix windows file separator --- .../java/org/sonar/plugins/java/CheckListGenerator.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java index 467919318a3..c2ac674df0b 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -21,6 +21,7 @@ import com.google.gson.Gson; import java.io.BufferedReader; +import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Modifier; @@ -78,12 +79,12 @@ public static void main(String[] args) { private static List> getCheckClasses() { List modifiedFiles; - try (var stream = Files.walk(Path.of("java-checks/src/main/java/org/sonar/java/checks"))) { - modifiedFiles = stream.map(Path::toString) + var relativePath = Path.of("java-checks/src/main/java"); + try (var stream = Files.walk(relativePath.resolve("org/sonar/java/checks"))) { + modifiedFiles = stream.map(p -> relativePath.relativize(p).toString()) .filter(file -> file.endsWith("Check.java")) - .map(file -> file.replace("java-checks/src/main/java/", "")) .map(file -> file.replace(".java", "")) - .map(file -> file.replace("/", ".")) + .map(file -> file.replace(File.separator, ".")) .toList(); } catch (IOException e) { throw new IllegalStateException(e); From f731fe58f87116030c6676c8088ac91adc7e0024 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Wed, 19 Jun 2024 16:38:46 +0200 Subject: [PATCH 07/26] Update some field names --- .../plugins/java/CheckListGenerator.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java index c2ac674df0b..03a192f0b34 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java @@ -38,34 +38,32 @@ public class CheckListGenerator { private static final String CLASS_NAME = "GeneratedCheckList"; public static void main(String[] args) { - - var filteredClasses = getCheckClasses(); + var checks = getCheckClasses(); List> mainClasses = new ArrayList<>(); List> testClasses = new ArrayList<>(); List> allClasses = new ArrayList<>(); - filteredClasses.forEach(c -> { - Rule ruleAnnotation = c.getAnnotationsByType(Rule.class)[0]; - String key = ruleAnnotation.key(); - String fileName = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/" + key + ".json"; + checks.forEach(check -> { + var ruleKey = check.getAnnotation(Rule.class).key(); + var fileName = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/" + ruleKey + ".json"; BufferedReader br = null; try { br = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8)); } catch (IOException e) { throw new IllegalStateException("Could not find rule file " + fileName, e); } - Metadata metadata = new Gson().fromJson(br, Metadata.class); + var metadata = new Gson().fromJson(br, Metadata.class); switch (metadata.scope) { - case "All" -> allClasses.add(c); - case "Main" -> mainClasses.add(c); - case "Tests" -> testClasses.add(c); - default -> throw new IllegalStateException("Unknown scope " + metadata.scope + " for class " + c.getName()); + case "All" -> allClasses.add(check); + case "Main" -> mainClasses.add(check); + case "Tests" -> testClasses.add(check); + default -> throw new IllegalStateException("Unknown scope " + metadata.scope + " for class " + check.getName()); } }); - var importChecks = filteredClasses.stream() + var importChecks = checks.stream() .map(c -> c.getPackageName() + "." + c.getSimpleName()) .map(c -> "import " + c + ";") .collect(Collectors.joining("\n")); @@ -73,7 +71,7 @@ public static void main(String[] args) { try { writeToFile(importChecks, collectChecks(mainClasses), collectChecks(testClasses), collectChecks(allClasses)); } catch (IOException e) { - throw new IllegalStateException(e); + throw new IllegalStateException("Unable to write checks to the file.", e); } } From 387dc3a74b2ea1d332e42819b8407f2934846154 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 15:35:36 +0200 Subject: [PATCH 08/26] Move CheckList generation to java-frontend. Replace usages of CheckList with GeneratedCheckList. --- java-checks/pom.xml | 59 ++++++++++++++++++ .../org/sonar}/java/CheckListGenerator.java | 54 +++++++++++++++-- sonar-java-plugin/pom.xml | 60 ------------------- .../plugins/java/JavaRulesDefinition.java | 9 +-- .../org/sonar/plugins/java/JavaSensor.java | 16 ++--- .../plugins/java/JavaSonarWayProfile.java | 4 +- .../plugins/java/JavaRulesDefinitionTest.java | 5 +- .../sonar/plugins/java/JavaSensorTest.java | 5 +- .../org/sonar/plugins/java/SanityTest.java | 5 +- 9 files changed, 133 insertions(+), 84 deletions(-) rename {sonar-java-plugin/src/main/java/org/sonar/plugins => java-checks/src/main/java/org/sonar}/java/CheckListGenerator.java (72%) diff --git a/java-checks/pom.xml b/java-checks/pom.xml index f91d0737981..e422efdd359 100644 --- a/java-checks/pom.xml +++ b/java-checks/pom.xml @@ -97,6 +97,65 @@ + + + org.codehaus.mojo + exec-maven-plugin + 3.2.0 + + + process-classes + + java + + + org.sonar.java.CheckListGenerator + compile + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.5.0 + + + process-classes + + add-source + + + + ${project.build.directory}/generated-sources + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + process-classes + + + compile + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + process-classes + + + + de.thetaphi forbiddenapis diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java b/java-checks/src/main/java/org/sonar/java/CheckListGenerator.java similarity index 72% rename from sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java rename to java-checks/src/main/java/org/sonar/java/CheckListGenerator.java index 03a192f0b34..aae3becdb65 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckListGenerator.java +++ b/java-checks/src/main/java/org/sonar/java/CheckListGenerator.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.plugins.java; +package org.sonar.java; import com.google.gson.Gson; import java.io.BufferedReader; @@ -112,9 +112,9 @@ private static String collectChecks(List> allClasses) { private static void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks) throws IOException { try { - var path = Path.of("sonar-java-plugin/target/generated-sources/" + CLASS_NAME + ".java"); + var path = Path.of("java-checks/target/generated-sources/" + CLASS_NAME + ".java"); Files.writeString(path, """ - package org.sonar.plugins.java; + package org.sonar.java; import java.util.Arrays; import java.util.Comparator; @@ -144,7 +144,53 @@ public final class ${className} { .sorted(Comparator.comparing(Class::getSimpleName)) .collect(Collectors.toList()); - private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of(); + private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of( + // Symbolic executions rules are not in this list because they are dynamically excluded + // Rules relying on correct setup of jdk.home + CallToDeprecatedCodeMarkedForRemovalCheck.class, + CallToDeprecatedMethodCheck.class, + // Rules relying on correct setup of java version + AbstractClassNoFieldShouldBeInterfaceCheck.class, + AnonymousClassShouldBeLambdaCheck.class, + CombineCatchCheck.class, + DateAndTimesCheck.class, + DateUtilsTruncateCheck.class, + DiamondOperatorCheck.class, + InsecureCreateTempFileCheck.class, + JdbcDriverExplicitLoadingCheck.class, + LambdaOptionalParenthesisCheck.class, + LambdaSingleExpressionCheck.class, + RepeatAnnotationCheck.class, + ReplaceGuavaWithJavaCheck.class, + ReplaceLambdaByMethodRefCheck.class, + SwitchInsteadOfIfSequenceCheck.class, + ThreadLocalWithInitialCheck.class, + TryWithResourcesCheck.class, + ValueBasedObjectUsedForLockCheck.class, + // Rules with a high deviation (>3%) + AccessibilityChangeCheck.class, + CipherBlockChainingCheck.class, + ClassNamedLikeExceptionCheck.class, + ClassWithOnlyStaticMethodsInstantiationCheck.class, + CollectionInappropriateCallsCheck.class, + DeadStoreCheck.class, + EqualsArgumentTypeCheck.class, + EqualsNotOverridenWithCompareToCheck.class, + EqualsOverridenWithHashCodeCheck.class, + ForLoopVariableTypeCheck.class, + JWTWithStrongCipherCheck.class, + MethodNamedEqualsCheck.class, + NioFileDeleteCheck.class, + PrivateFieldUsedLocallyCheck.class, + SillyEqualsCheck.class, + StandardCharsetsConstantsCheck.class, + ThreadLocalCleanupCheck.class, + ThreadOverridesRunCheck.class, + UnusedPrivateClassCheck.class, + UnusedPrivateFieldCheck.class, + VerifiedServerHostnamesCheck.class, + VolatileNonPrimitiveFieldCheck.class, + WeakSSLContextCheck.class); private GeneratedCheckList() { } diff --git a/sonar-java-plugin/pom.xml b/sonar-java-plugin/pom.xml index 43013117b8c..c1274754b0f 100644 --- a/sonar-java-plugin/pom.xml +++ b/sonar-java-plugin/pom.xml @@ -133,66 +133,6 @@ - - - org.codehaus.mojo - exec-maven-plugin - 3.2.0 - - - process-classes - - java - - - org.sonar.plugins.java.CheckListGenerator - compile - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - process-classes - - add-source - - - - ${project.build.directory}/generated-sources - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - process-classes - - - compile - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - prepare-package - - - - - org.sonarsource.sonar-packaging-maven-plugin sonar-packaging-maven-plugin diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaRulesDefinition.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaRulesDefinition.java index 87121f85bc1..a0ff11c3881 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaRulesDefinition.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaRulesDefinition.java @@ -25,6 +25,7 @@ import org.sonar.api.SonarRuntime; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.AnnotationUtils; +import org.sonar.java.GeneratedCheckList; import org.sonar.java.annotations.VisibleForTesting; import org.sonar.plugins.java.api.CheckRegistrar; import org.sonarsource.analyzer.commons.RuleMetadataLoader; @@ -65,11 +66,11 @@ public JavaRulesDefinition(SonarRuntime sonarRuntime, CheckRegistrar[] checkRegi @Override public void define(Context context) { NewRepository repository = context - .createRepository(CheckList.REPOSITORY_KEY, Java.KEY) + .createRepository(GeneratedCheckList.REPOSITORY_KEY, Java.KEY) .setName("SonarAnalyzer"); RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, JavaSonarWayProfile.SONAR_WAY_PATH, sonarRuntime); - ruleMetadataLoader.addRulesByAnnotatedClass(repository, CheckList.getChecks()); + ruleMetadataLoader.addRulesByAnnotatedClass(repository, GeneratedCheckList.getChecks()); TEMPLATE_RULE_KEY.stream() .map(repository::rule) @@ -78,13 +79,13 @@ public void define(Context context) { INTERNAL_KEYS.forEach((ruleKey, internalKey) -> repository.rule(ruleKey).setInternalKey(internalKey)); // for all the rules without explicit deprecated key already declared, register them with "squid:key" - CheckList.getChecks().stream() + GeneratedCheckList.getChecks().stream() .filter(rule -> !deprecatesRules(rule)) .map(JavaRulesDefinition::ruleKey) .map(repository::rule) .forEach(rule -> rule.addDeprecatedRuleKey("squid", rule.key())); - for(CheckRegistrar registrar : checkRegistrars){ + for (CheckRegistrar registrar : checkRegistrars) { registrar.customRulesDefinition(context, repository); } diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java index 88b759914c2..55618c27be0 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java @@ -40,6 +40,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.issue.NoSonarFilter; import org.sonar.api.rule.RuleKey; +import org.sonar.java.GeneratedCheckList; import org.sonar.java.JavaFrontend; import org.sonar.java.Measurer; import org.sonar.java.SonarComponents; @@ -74,13 +75,13 @@ public class JavaSensor implements Sensor { private final PostAnalysisIssueFilter postAnalysisIssueFilter; public JavaSensor(SonarComponents sonarComponents, FileSystem fs, JavaResourceLocator javaResourceLocator, - Configuration settings, NoSonarFilter noSonarFilter, PostAnalysisIssueFilter postAnalysisIssueFilter) { + Configuration settings, NoSonarFilter noSonarFilter, PostAnalysisIssueFilter postAnalysisIssueFilter) { this(sonarComponents, fs, javaResourceLocator, settings, noSonarFilter, postAnalysisIssueFilter, null); } public JavaSensor(SonarComponents sonarComponents, FileSystem fs, JavaResourceLocator javaResourceLocator, - Configuration settings, NoSonarFilter noSonarFilter, - PostAnalysisIssueFilter postAnalysisIssueFilter, @Nullable Jasper jasper) { + Configuration settings, NoSonarFilter noSonarFilter, + PostAnalysisIssueFilter postAnalysisIssueFilter, @Nullable Jasper jasper) { this.noSonarFilter = noSonarFilter; this.sonarComponents = sonarComponents; this.fs = fs; @@ -88,8 +89,8 @@ public JavaSensor(SonarComponents sonarComponents, FileSystem fs, JavaResourceLo this.settings = settings; this.postAnalysisIssueFilter = postAnalysisIssueFilter; this.jasper = jasper; - this.sonarComponents.registerMainChecks(CheckList.REPOSITORY_KEY, CheckList.getJavaChecks()); - this.sonarComponents.registerTestChecks(CheckList.REPOSITORY_KEY, CheckList.getJavaTestChecks()); + this.sonarComponents.registerMainChecks(GeneratedCheckList.REPOSITORY_KEY, GeneratedCheckList.getJavaChecks()); + this.sonarComponents.registerTestChecks(GeneratedCheckList.REPOSITORY_KEY, GeneratedCheckList.getJavaTestChecks()); } @Override @@ -117,8 +118,8 @@ private UnaryOperator> createCheckFilter(boolean isAutoScanCheck if (isAutoScanCheckFiltering) { Set autoScanCompatibleRules = new HashSet<>(JavaSonarWayProfile.sonarJavaSonarWayRuleKeys()); - CheckList.getJavaChecksNotWorkingForAutoScan().stream() - .map(checkClass -> RuleKey.of(CheckList.REPOSITORY_KEY, getRuleKey(checkClass))) + GeneratedCheckList.getJavaChecksNotWorkingForAutoScan().stream() + .map(checkClass -> RuleKey.of(GeneratedCheckList.REPOSITORY_KEY, getRuleKey(checkClass))) .forEach(autoScanCompatibleRules::remove); autoScanCompatibleRules.addAll(sonarComponents.getAdditionalAutoScanCompatibleRuleKeys()); @@ -144,7 +145,6 @@ private static PerformanceMeasure.Duration createPerformanceMeasureReport(Sensor .start("JavaSensor"); } - private Collection runJasper(SensorContext context) { if (sonarComponents.isAutoScan()) { // for security reasons, do not run jasper to generate code in autoscan mode diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java index e18039c6e6b..c9808b1353f 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSonarWayProfile.java @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.rule.RuleKey; import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; +import org.sonar.java.GeneratedCheckList; import org.sonar.java.annotations.VisibleForTesting; import org.sonar.plugins.java.api.ProfileRegistrar; import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader; @@ -40,7 +41,6 @@ @SonarLintSide public class JavaSonarWayProfile implements BuiltInQualityProfilesDefinition { - private static final Logger LOG = LoggerFactory.getLogger(JavaSonarWayProfile.class); static final String SECURITY_RULES_CLASS_NAME = "com.sonar.plugins.security.api.JavaRules"; @@ -93,7 +93,7 @@ public void define(Context context) { static Set sonarJavaSonarWayRuleKeys() { return BuiltInQualityProfileJsonLoader.loadActiveKeysFromJsonProfile(SONAR_WAY_PATH).stream() - .map(rule -> RuleKey.of(CheckList.REPOSITORY_KEY, rule)) + .map(rule -> RuleKey.of(GeneratedCheckList.REPOSITORY_KEY, rule)) .collect(Collectors.toSet()); } diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaRulesDefinitionTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaRulesDefinitionTest.java index b8b65686f42..ce7010a0565 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaRulesDefinitionTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaRulesDefinitionTest.java @@ -32,6 +32,7 @@ import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.Version; +import org.sonar.java.GeneratedCheckList; import org.sonar.plugins.java.api.CheckRegistrar; import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKeys; @@ -56,7 +57,7 @@ void test_creation_of_rules() { assertThat(repository.name()).isEqualTo("Sonar"); assertThat(repository.language()).isEqualTo("java"); - assertThat(repository.rules()).hasSize(CheckList.getChecks().size()); + assertThat(repository.rules()).hasSize(GeneratedCheckList.getChecks().size()); RulesDefinition.Rule unusedLabelRule = repository.rule("S1065"); assertThat(unusedLabelRule).isNotNull(); @@ -91,7 +92,7 @@ void rules_definition_should_be_locale_independent() { assertThat(repository.name()).isEqualTo("Sonar"); assertThat(repository.language()).isEqualTo("java"); - assertThat(repository.rules()).hasSize(CheckList.getChecks().size()); + assertThat(repository.rules()).hasSize(GeneratedCheckList.getChecks().size()); Locale.setDefault(defaultLocale); } diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaSensorTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaSensorTest.java index 85594d669c0..a4fea765a49 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaSensorTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaSensorTest.java @@ -58,6 +58,7 @@ import org.sonar.api.utils.AnnotationUtils; import org.sonar.api.utils.Version; import org.sonar.java.DefaultJavaResourceLocator; +import org.sonar.java.GeneratedCheckList; import org.sonar.java.SonarComponents; import org.sonar.java.checks.naming.BadMethodNameCheck; import org.sonar.java.classpath.ClasspathForMain; @@ -133,7 +134,7 @@ private void testIssueCreation(InputFile.Type onType, int expectedIssues) throws jss.execute(context); // argument 121 refers to the comment on line #121 in this file, each time this file changes, this argument should be updated - verify(noSonarFilter, times(1)).noSonarInFile(fs.inputFiles().iterator().next(), Collections.singleton(120)); + verify(noSonarFilter, times(1)).noSonarInFile(fs.inputFiles().iterator().next(), Collections.singleton(121)); verify(sonarComponents, times(expectedIssues)).reportIssue(any(AnalyzerMessage.class)); settings.setProperty(JavaVersion.SOURCE_VERSION, "wrongFormat"); @@ -430,7 +431,7 @@ private SensorContextTester analyzeTwoFilesWithIssues(MapSettings settings) thro ActiveRulesBuilder activeRulesBuilder = new ActiveRulesBuilder(); - CheckList.getChecks().stream() + GeneratedCheckList.getChecks().stream() .map(check -> AnnotationUtils.getAnnotation(check, org.sonar.check.Rule.class).key()) .map(key -> new NewActiveRule.Builder().setRuleKey(RuleKey.of("java", key)).build()) .forEach(activeRulesBuilder::addRule); diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/SanityTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/SanityTest.java index cc89c33d2ed..70b99d80282 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/SanityTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/SanityTest.java @@ -50,6 +50,7 @@ import org.sonar.api.utils.AnnotationUtils; import org.sonar.api.utils.Version; import org.sonar.java.AnalysisProgress; +import org.sonar.java.GeneratedCheckList; import org.sonar.java.SonarComponents; import org.sonar.java.ast.JavaAstScanner; import org.sonar.java.checks.verifier.FilesUtils; @@ -191,8 +192,8 @@ private static String processExceptions(List exceptions) { private static List getJavaCheckInstances() { List> checkClasses = new ArrayList<>(); - checkClasses.addAll(CheckList.getJavaChecks()); - checkClasses.addAll(CheckList.getJavaTestChecks()); + checkClasses.addAll(GeneratedCheckList.getJavaChecks()); + checkClasses.addAll(GeneratedCheckList.getJavaTestChecks()); List javaChecks = new ArrayList<>(); for (Class checkClass : checkClasses) { From 22b60ebdc27008a1c6565920414c37f55533cadc Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 16:49:56 +0200 Subject: [PATCH 09/26] Try moving checkList generator to separate module. We need both Checks and AWS Checks compiled to generate list and to use it in Plugin module. --- check-list/pom.xml | 112 ++++++++++++++++++ .../org/sonar/java/CheckListGenerator.java | 14 ++- java-checks/pom.xml | 59 --------- pom.xml | 1 + sonar-java-plugin/pom.xml | 5 + 5 files changed, 129 insertions(+), 62 deletions(-) create mode 100644 check-list/pom.xml rename {java-checks => check-list}/src/main/java/org/sonar/java/CheckListGenerator.java (93%) diff --git a/check-list/pom.xml b/check-list/pom.xml new file mode 100644 index 00000000000..6e00d722a4e --- /dev/null +++ b/check-list/pom.xml @@ -0,0 +1,112 @@ + + + 4.0.0 + + + org.sonarsource.java + java + 8.1.0-SNAPSHOT + + + check-list + + SonarQube Java :: Check List + + + + 21 + 21 + UTF-8 + + + + + org.sonarsource.api.plugin + sonar-plugin-api + provided + + + org.slf4j + slf4j-api + provided + + + ${project.groupId} + java-checks + ${project.version} + + + ${project.groupId} + java-checks-aws + ${project.version} + + + com.google.code.gson + gson + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.2.0 + + + process-classes + + java + + + org.sonar.java.CheckListGenerator + compile + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.5.0 + + + process-classes + + add-source + + + + ${project.build.directory}/generated-sources + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + process-classes + + + compile + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + process-classes + + + + + + diff --git a/java-checks/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java similarity index 93% rename from java-checks/src/main/java/org/sonar/java/CheckListGenerator.java rename to check-list/src/main/java/org/sonar/java/CheckListGenerator.java index aae3becdb65..6502443c805 100644 --- a/java-checks/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.sonar.check.Rule; public class CheckListGenerator { @@ -78,8 +79,15 @@ public static void main(String[] args) { private static List> getCheckClasses() { List modifiedFiles; var relativePath = Path.of("java-checks/src/main/java"); - try (var stream = Files.walk(relativePath.resolve("org/sonar/java/checks"))) { - modifiedFiles = stream.map(p -> relativePath.relativize(p).toString()) + var awsRelativePath = Path.of("java-checks-aws/src/main/java"); + try (var stream = Stream.concat(Files.walk(relativePath.resolve("org/sonar/java/checks")), Files.walk(awsRelativePath.resolve("org/sonar/java/checks")))) { + modifiedFiles = stream.map(p -> { + if (p.startsWith(awsRelativePath)) { + return awsRelativePath.relativize(p).toString(); + } else { + return relativePath.relativize(p).toString(); + } + }) .filter(file -> file.endsWith("Check.java")) .map(file -> file.replace(".java", "")) .map(file -> file.replace(File.separator, ".")) @@ -112,7 +120,7 @@ private static String collectChecks(List> allClasses) { private static void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks) throws IOException { try { - var path = Path.of("java-checks/target/generated-sources/" + CLASS_NAME + ".java"); + var path = Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"); Files.writeString(path, """ package org.sonar.java; diff --git a/java-checks/pom.xml b/java-checks/pom.xml index e422efdd359..f91d0737981 100644 --- a/java-checks/pom.xml +++ b/java-checks/pom.xml @@ -97,65 +97,6 @@ - - - org.codehaus.mojo - exec-maven-plugin - 3.2.0 - - - process-classes - - java - - - org.sonar.java.CheckListGenerator - compile - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - process-classes - - add-source - - - - ${project.build.directory}/generated-sources - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - process-classes - - - compile - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - process-classes - - - - de.thetaphi forbiddenapis diff --git a/pom.xml b/pom.xml index be71904b003..0bc3f2d4973 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ java-checks-testkit java-checks java-checks-aws + check-list external-reports sonar-java-plugin java-surefire diff --git a/sonar-java-plugin/pom.xml b/sonar-java-plugin/pom.xml index c1274754b0f..28e9a0654cb 100644 --- a/sonar-java-plugin/pom.xml +++ b/sonar-java-plugin/pom.xml @@ -46,6 +46,11 @@ java-checks-aws ${project.version} + + ${project.groupId} + check-list + ${project.version} + ${project.groupId} external-reports From 88720d6603f91799e118d782589a5fd7c64b32de Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 17:04:43 +0200 Subject: [PATCH 10/26] Build before sanity tests and autoscan --- .cirrus.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.cirrus.yml b/.cirrus.yml index 6064bf93e99..65435298982 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -181,6 +181,7 @@ sanity_task: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER - mvn clean compile --projects java-checks-test-sources --also-make-dependents + - mvn clean install -DskipTests=true - mvn verify -f sonar-java-plugin/pom.xml -Psanity -Dtest=SanityTest cleanup_before_cache_script: cleanup_maven_repository @@ -261,6 +262,7 @@ autoscan_task: autoscan_script: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER + - JAVA_HOME="${JAVA_21_HOME}" mvn clean install -DskipTests=true - JAVA_HOME="${JAVA_21_HOME}" mvn clean compile --projects java-checks-test-sources --also-make-dependents - cd its/autoscan - mvn clean package --batch-mode --errors --show-version --activate-profiles it-autoscan -Dsonar.runtimeVersion=LATEST_RELEASE[10.3] -Dmaven.test.redirectTestOutputToFile=false -Dparallel=methods -DuseUnlimitedThreads=true From 8a24b2b3683a2306a6f8ede412a638c3eab6e295 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 17:27:28 +0200 Subject: [PATCH 11/26] Try fixing autocan and sanity --- .cirrus.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 65435298982..0546cdf4a65 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -180,8 +180,8 @@ sanity_task: sanity_script: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER - - mvn clean compile --projects java-checks-test-sources --also-make-dependents - - mvn clean install -DskipTests=true + - mvn clean install -Dmaven.test.skip=true + - mvn compile --projects java-checks-test-sources --also-make-dependents - mvn verify -f sonar-java-plugin/pom.xml -Psanity -Dtest=SanityTest cleanup_before_cache_script: cleanup_maven_repository @@ -262,8 +262,8 @@ autoscan_task: autoscan_script: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER - - JAVA_HOME="${JAVA_21_HOME}" mvn clean install -DskipTests=true - - JAVA_HOME="${JAVA_21_HOME}" mvn clean compile --projects java-checks-test-sources --also-make-dependents + - JAVA_HOME="${JAVA_21_HOME}" mvn clean install -Dmaven.test.skip=true + - JAVA_HOME="${JAVA_21_HOME}" mvn compile --projects java-checks-test-sources --also-make-dependents - cd its/autoscan - mvn clean package --batch-mode --errors --show-version --activate-profiles it-autoscan -Dsonar.runtimeVersion=LATEST_RELEASE[10.3] -Dmaven.test.redirectTestOutputToFile=false -Dparallel=methods -DuseUnlimitedThreads=true cleanup_before_cache_script: cleanup_maven_repository From 03326993c37f1a520cc2323fc7b59887f6d4f137 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 20:46:19 +0200 Subject: [PATCH 12/26] Update gson version to be compatible with records. --- check-list/pom.xml | 19 ++++++++++++------- .../org/sonar/java/CheckListGenerator.java | 7 +++---- pom.xml | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/check-list/pom.xml b/check-list/pom.xml index 6e00d722a4e..25e29d9d5f2 100644 --- a/check-list/pom.xml +++ b/check-list/pom.xml @@ -13,13 +13,7 @@ check-list SonarQube Java :: Check List - - - - 21 - 21 - UTF-8 - + 2024 @@ -46,6 +40,17 @@ com.google.code.gson gson + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + diff --git a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java index 6502443c805..bcbdd9a1c05 100644 --- a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -1,6 +1,6 @@ /* * SonarQube Java - * Copyright (C) 2012-2024 SonarSource SA + * Copyright (C) 2024-2024 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or @@ -48,7 +48,7 @@ public static void main(String[] args) { checks.forEach(check -> { var ruleKey = check.getAnnotation(Rule.class).key(); var fileName = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/" + ruleKey + ".json"; - BufferedReader br = null; + BufferedReader br; try { br = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8)); } catch (IOException e) { @@ -239,8 +239,7 @@ private static List> sortedJoin(List com.google.code.gson gson - 2.8.9 + 2.11.0 compile From 86ac8a91bc2dec9816c0536aba026f71fbfcc538 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 20:47:56 +0200 Subject: [PATCH 13/26] Add GeneratedCheckListTest --- .../plugins/java/GeneratedCheckListTest.java | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java new file mode 100644 index 00000000000..ef6837ff8a4 --- /dev/null +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java @@ -0,0 +1,223 @@ +/* + * SonarQube Java + * Copyright (C) 2012-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.plugins.java; + +import com.google.gson.Gson; +import java.io.File; +import java.io.FileReader; +import java.lang.reflect.Constructor; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.sonar.api.internal.apachecommons.io.FileUtils; +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; +import org.sonar.api.utils.AnnotationUtils; +import org.sonar.check.Rule; +import org.sonar.java.GeneratedCheckList; +import org.sonar.plugins.java.api.JavaCheck; +import org.sonarsource.analyzer.commons.collections.SetUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Fail.fail; + +class GeneratedCheckListTest { + + private static final String ARTIFICIAL_DESCRIPTION = "-1"; + + private final Gson gson = new Gson(); + + private static final Set BLACK_LIST = SetUtils.immutableSetOf( + "AbstractXPathBasedCheck.java", + "AbstractWebXmlXPathBasedCheck.java", + "AbstractRegexCheck.java"); + + /** + * Enforces that each check declared in list. + */ + @Test + void count() { + int count = 0; + List files = getCheckFiles(); + for (File file : files) { + if (file.getName().endsWith("Check.java") && !BLACK_LIST.contains(file.getName())) { + count++; + } + } + assertThat(GeneratedCheckList.getChecks()).hasSize(count); + } + + private static List getCheckFiles() { + List files = (List) FileUtils.listFiles(new File("../java-checks/src/main/java/org/sonar/java/checks/"), new String[] {"java"}, true); + files.addAll(FileUtils.listFiles(new File("../java-checks-aws/src/main/java/org/sonar/java/checks/"), new String[] {"java"}, true)); + return files; + } + + @Test + void min_check_count() { + assertThat(GeneratedCheckList.getJavaChecks()).hasSizeGreaterThan(500); + assertThat(GeneratedCheckList.getJavaTestChecks()).hasSizeGreaterThan(40); + assertThat(GeneratedCheckList.getJavaChecksNotWorkingForAutoScan()).hasSizeGreaterThan(40); + assertThat(GeneratedCheckList.getChecks()).hasSizeGreaterThan(600); + } + + private static class CustomRulesDefinition implements RulesDefinition { + + @Override + public void define(Context context) { + String language = "java"; + NewRepository repository = context + .createRepository(GeneratedCheckList.REPOSITORY_KEY, language) + .setName("SonarQube"); + + List> checks = GeneratedCheckList.getChecks(); + new RulesDefinitionAnnotationLoader().load(repository, checks.toArray(new Class[checks.size()])); + + for (NewRule rule : repository.rules()) { + try { + rule.setName("Artificial Name (set via JSON files, no need to test it)"); + rule.setMarkdownDescription(ARTIFICIAL_DESCRIPTION); + } catch (IllegalStateException e) { + // it means that the html description was already set in Rule annotation + fail("Description of " + rule.key() + " should be in separate file"); + } + } + repository.done(); + } + } + + /** + * Enforces that each check has test, name and description. + */ + @Test + void test() throws MalformedURLException { + Map keyMap = new HashMap<>(); + for (Class cls : GeneratedCheckList.getChecks()) { + String testName = '/' + cls.getName().replace('.', '/') + "Test.java"; + List checkModules = List.of("java-checks", "java-checks-aws"); + + String simpleName = cls.getSimpleName(); + // Handle legacy keys. + Rule ruleAnnotation = AnnotationUtils.getAnnotation(cls, Rule.class); + keyMap.put(ruleAnnotation.key(), ruleAnnotation.key()); + assertThat(checkModules.stream() + .anyMatch(module -> Files.exists(Path.of("../", module, "src/test/java", testName)))) + .overridingErrorMessage("No test for " + simpleName) + .isTrue(); + } + + Set keys = new HashSet<>(); + Set names = new HashSet<>(); + CustomRulesDefinition definition = new CustomRulesDefinition(); + RulesDefinition.Context context = new RulesDefinition.Context(); + definition.define(context); + List rules = context.repository(GeneratedCheckList.REPOSITORY_KEY).rules(); + + for (RulesDefinition.Rule rule : rules) { + assertThat(keys).as("Duplicate key " + rule.key()).doesNotContain(rule.key()); + keys.add(rule.key()); + names.add(rule.name()); + assertThat(getClass().getResource("/org/sonar/l10n/java/rules/" + GeneratedCheckList.REPOSITORY_KEY + "/" + keyMap.get(rule.key()) + ".html")) + .overridingErrorMessage("No description for " + rule.key() + " " + keyMap.get(rule.key())) + .isNotNull(); + assertThat(getClass().getResource("/org/sonar/l10n/java/rules/" + GeneratedCheckList.REPOSITORY_KEY + "/" + keyMap.get(rule.key()) + ".json")) + .overridingErrorMessage("No json metadata file for " + rule.key() + " " + keyMap.get(rule.key())) + .isNotNull(); + + assertThat(rule.htmlDescription()).isNull(); + assertThat(rule.markdownDescription()).isEqualTo(ARTIFICIAL_DESCRIPTION); + + for (RulesDefinition.Param param : rule.params()) { + assertThat(param.description()).overridingErrorMessage(rule.key() + " missing description for param " + param.key()).isNotEmpty(); + } + } + } + + @Test + void enforce_CheckList_registration() { + List files = getCheckFiles(); + List> checks = GeneratedCheckList.getChecks(); + files.stream() + .filter(file -> file.getName().endsWith("Check.java")) + .filter(file -> !file.getName().startsWith("Abstract")) + .map(File::getAbsolutePath) + .map(f -> f.replace(File.separatorChar, '.')) + .map(f -> f.substring(f.indexOf("org.sonar.java.checks"), f.length() - 5)) + .forEach(className -> { + try { + Class aClass = Class.forName(className); + assertThat(checks).as(className + " is not declared in CheckList").contains(aClass); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + }); + } + + @Test + void rules_targeting_tests_should_have_tests_tag() throws Exception { + Set> testChecks = new HashSet<>(GeneratedCheckList.getJavaTestChecks()); + Set> mainChecks = new HashSet<>(GeneratedCheckList.getJavaChecks()); + + for (Class cls : GeneratedCheckList.getChecks()) { + String key = AnnotationUtils.getAnnotation(cls, Rule.class).key(); + URL metadataURL = getClass().getResource("/org/sonar/l10n/java/rules/" + CheckList.REPOSITORY_KEY + "/" + key + ".json"); + File metadataFile = new File(metadataURL.toURI()); + assertThat(metadataFile).exists(); + try (FileReader jsonReader = new FileReader(metadataFile)) { + DummyMetatada metadata = gson.fromJson(jsonReader, DummyMetatada.class); + + if (!"deprecated".equals(metadata.status)) { + // deprecated rules usually have no tags + if ((testChecks.contains(cls) && !mainChecks.contains(cls)) || "S3414".equals(key)) { + assertThat(metadata.tags) + .as("Rule " + key + " is targeting tests sources and should contain the 'tests' tag.") + .contains("tests"); + } else { + assertThat(metadata.tags) + .as("Rule " + key + " is targeting main sources and should not contain the 'tests' tag.") + .doesNotContain("tests"); + } + } + } + } + } + + private static class DummyMetatada { + // ignore all the other fields + String[] tags; + String status; + } + + @Test + void private_constructor() throws Exception { + Constructor constructor = GeneratedCheckList.class.getDeclaredConstructor(); + assertThat(constructor.isAccessible()).isFalse(); + constructor.setAccessible(true); + constructor.newInstance(); + } + +} From 4c7fc94ee2431709cf1567ecfbe67da598bce27d Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Thu, 20 Jun 2024 23:09:42 +0200 Subject: [PATCH 14/26] Add tests for CheckListGenerator --- .../org/sonar/java/CheckListGenerator.java | 358 +++++++++--------- .../org/sonar/java/checks/ExampleCheck.java | 3 + .../sonar/java/CheckListGeneratorTest.java | 147 +++++++ 3 files changed, 331 insertions(+), 177 deletions(-) create mode 100644 check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java create mode 100644 check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java diff --git a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java index bcbdd9a1c05..f0f663facf2 100644 --- a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -22,8 +22,8 @@ import com.google.gson.Gson; import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; +import java.io.Reader; import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -35,211 +35,215 @@ import org.sonar.check.Rule; public class CheckListGenerator { - private static final String CLASS_NAME = "GeneratedCheckList"; + private static final String RULES_PATH = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"; + private final Gson gson; - public static void main(String[] args) { - var checks = getCheckClasses(); - - List> mainClasses = new ArrayList<>(); - List> testClasses = new ArrayList<>(); - List> allClasses = new ArrayList<>(); - - checks.forEach(check -> { - var ruleKey = check.getAnnotation(Rule.class).key(); - var fileName = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/" + ruleKey + ".json"; - BufferedReader br; - try { - br = new BufferedReader(new FileReader(fileName, StandardCharsets.UTF_8)); - } catch (IOException e) { - throw new IllegalStateException("Could not find rule file " + fileName, e); - } - var metadata = new Gson().fromJson(br, Metadata.class); - - switch (metadata.scope) { - case "All" -> allClasses.add(check); - case "Main" -> mainClasses.add(check); - case "Tests" -> testClasses.add(check); - default -> throw new IllegalStateException("Unknown scope " + metadata.scope + " for class " + check.getName()); - } - }); - - var importChecks = checks.stream() - .map(c -> c.getPackageName() + "." + c.getSimpleName()) - .map(c -> "import " + c + ";") - .collect(Collectors.joining("\n")); - - try { - writeToFile(importChecks, collectChecks(mainClasses), collectChecks(testClasses), collectChecks(allClasses)); - } catch (IOException e) { - throw new IllegalStateException("Unable to write checks to the file.", e); - } + public CheckListGenerator(Gson gson) { + this.gson = gson; } - private static List> getCheckClasses() { - List modifiedFiles; + public static void main(String[] args) { + var generator = new CheckListGenerator(new Gson()); var relativePath = Path.of("java-checks/src/main/java"); var awsRelativePath = Path.of("java-checks-aws/src/main/java"); - try (var stream = Stream.concat(Files.walk(relativePath.resolve("org/sonar/java/checks")), Files.walk(awsRelativePath.resolve("org/sonar/java/checks")))) { - modifiedFiles = stream.map(p -> { - if (p.startsWith(awsRelativePath)) { - return awsRelativePath.relativize(p).toString(); - } else { - return relativePath.relativize(p).toString(); - } - }) + var checks = generator.getCheckClasses(relativePath, awsRelativePath); + var path = Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"); + generator.generateCheckListFile(checks, path, RULES_PATH); + } + + public List> getCheckClasses(Path directory, Path awsDirectory) { + var modifiedFiles = getModifiedFiles(directory, awsDirectory); + return modifiedFiles.stream() + .map(CheckListGenerator::getClassByName) + .filter(c -> !Modifier.isAbstract(c.getModifiers())) + .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) + .toList(); + } + + private static List getModifiedFiles(Path relativePath, Path awsRelativePath) { + try (Stream stream = Stream.concat(Files.walk(relativePath.resolve("org/sonar/java/checks")), Files.walk(awsRelativePath.resolve("org/sonar/java/checks")))) { + return stream + .map(p -> p.startsWith(awsRelativePath) ? awsRelativePath.relativize(p).toString() : relativePath.relativize(p).toString()) .filter(file -> file.endsWith("Check.java")) - .map(file -> file.replace(".java", "")) - .map(file -> file.replace(File.separator, ".")) + .map(file -> file.replace(".java", "").replace(File.separator, ".")) .toList(); } catch (IOException e) { - throw new IllegalStateException(e); + throw new IllegalStateException(e.getMessage()); } + } - var classes = modifiedFiles.stream() - .map(file -> { - try { - return Class.forName(file); - } catch (ClassNotFoundException e) { - throw new IllegalStateException("Can not find the class for name " + file, e); - } - }) - .toList(); + private static Class getClassByName(String className) { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Cannot find the class for name " + className, e); + } + } - return classes.stream() - .filter(c -> !Modifier.isAbstract(c.getModifiers())) - .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) - .toList(); + public String getRuleKey(Class check) { + return check.getAnnotation(Rule.class).key(); + } + + public Metadata getMetadata(Reader reader) { + return gson.fromJson(reader, Metadata.class); + } + + public String generateImportStatements(List> checks) { + return checks.stream() + .map(c -> "import " + c.getPackageName() + "." + c.getSimpleName() + ";") + .collect(Collectors.joining("\n")); } - private static String collectChecks(List> allClasses) { - return allClasses.stream() + public String collectChecks(List> classes) { + return classes.stream() .map(c -> c.getSimpleName() + ".class") .collect(Collectors.joining(", \n ")); } - private static void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks) throws IOException { + public void generateCheckListFile(List> checks, Path path, String rulesPath) { + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + checks.forEach(check -> { + String ruleKey = getRuleKey(check); + String fileName = rulesPath + ruleKey + ".json"; + try (BufferedReader reader = Files.newBufferedReader(Path.of(fileName), StandardCharsets.UTF_8)) { + Metadata metadata = getMetadata(reader); + switch (metadata.scope) { + case "All" -> allClasses.add(check); + case "Main" -> mainClasses.add(check); + case "Tests" -> testClasses.add(check); + default -> throw new IllegalStateException("Unknown scope " + metadata.scope + " for class " + check.getName()); + } + } catch (IOException e) { + throw new IllegalStateException("Could not find rule file " + fileName, e); + } + }); + String importChecks = generateImportStatements(checks); try { - var path = Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"); - Files.writeString(path, """ - package org.sonar.java; - - import java.util.Arrays; - import java.util.Comparator; - import java.util.List; - import java.util.Set; - import java.util.stream.Collectors; - import java.util.stream.Stream; - import org.sonar.plugins.java.api.JavaCheck; - - ${importChecks} + writeToFile(importChecks, collectChecks(mainClasses), collectChecks(testClasses), collectChecks(allClasses), path); + } catch (IOException e) { + throw new IllegalStateException("Unable to write checks to the file.", e); + } + } - public final class ${className} { + public void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks, Path path) throws IOException { + String content = """ + package org.sonar.java; + + import java.util.Arrays; + import java.util.Comparator; + import java.util.List; + import java.util.Set; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import org.sonar.plugins.java.api.JavaCheck; + + ${importChecks} + + public final class ${className} { + + public static final String REPOSITORY_KEY = "java"; + + private static final List> JAVA_MAIN_CHECKS = Arrays.asList( + ${mainClasses}); + + private static final List> JAVA_TEST_CHECKS = Arrays.asList( + ${testClasses}); + + private static final List> JAVA_MAIN_AND_TEST_CHECKS = Arrays.asList( + ${allClasses}); + + private static final List> ALL_CHECKS = Stream.of(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS) + .flatMap(List::stream) + .sorted(Comparator.comparing(Class::getSimpleName)) + .collect(Collectors.toList()); + + private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of( + // Symbolic executions rules are not in this list because they are dynamically excluded + // Rules relying on correct setup of jdk.home + CallToDeprecatedCodeMarkedForRemovalCheck.class, + CallToDeprecatedMethodCheck.class, + // Rules relying on correct setup of java version + AbstractClassNoFieldShouldBeInterfaceCheck.class, + AnonymousClassShouldBeLambdaCheck.class, + CombineCatchCheck.class, + DateAndTimesCheck.class, + DateUtilsTruncateCheck.class, + DiamondOperatorCheck.class, + InsecureCreateTempFileCheck.class, + JdbcDriverExplicitLoadingCheck.class, + LambdaOptionalParenthesisCheck.class, + LambdaSingleExpressionCheck.class, + RepeatAnnotationCheck.class, + ReplaceGuavaWithJavaCheck.class, + ReplaceLambdaByMethodRefCheck.class, + SwitchInsteadOfIfSequenceCheck.class, + ThreadLocalWithInitialCheck.class, + TryWithResourcesCheck.class, + ValueBasedObjectUsedForLockCheck.class, + // Rules with a high deviation (>3%) + AccessibilityChangeCheck.class, + CipherBlockChainingCheck.class, + ClassNamedLikeExceptionCheck.class, + ClassWithOnlyStaticMethodsInstantiationCheck.class, + CollectionInappropriateCallsCheck.class, + DeadStoreCheck.class, + EqualsArgumentTypeCheck.class, + EqualsNotOverridenWithCompareToCheck.class, + EqualsOverridenWithHashCodeCheck.class, + ForLoopVariableTypeCheck.class, + JWTWithStrongCipherCheck.class, + MethodNamedEqualsCheck.class, + NioFileDeleteCheck.class, + PrivateFieldUsedLocallyCheck.class, + SillyEqualsCheck.class, + StandardCharsetsConstantsCheck.class, + ThreadLocalCleanupCheck.class, + ThreadOverridesRunCheck.class, + UnusedPrivateClassCheck.class, + UnusedPrivateFieldCheck.class, + VerifiedServerHostnamesCheck.class, + VolatileNonPrimitiveFieldCheck.class, + WeakSSLContextCheck.class); + + private GeneratedCheckList() { + } - public static final String REPOSITORY_KEY = "java"; + public static List> getChecks() { + return ALL_CHECKS; + } - private static final List> JAVA_MAIN_CHECKS = Arrays.asList( - ${mainClasses}); + public static List> getJavaChecks() { + return sortedJoin(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS); + } - private static final List> JAVA_TEST_CHECKS = Arrays.asList( - ${testClasses}); + public static List> getJavaTestChecks() { + return sortedJoin(JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS); + } - private static final List> JAVA_MAIN_AND_TEST_CHECKS = Arrays.asList( - ${allClasses}); + public static Set> getJavaChecksNotWorkingForAutoScan() { + return JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN; + } - private static final List> ALL_CHECKS = Stream.of(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS) + @SafeVarargs + private static List> sortedJoin(List>... lists) { + return Arrays.stream(lists) .flatMap(List::stream) .sorted(Comparator.comparing(Class::getSimpleName)) - .collect(Collectors.toList()); - - private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of( - // Symbolic executions rules are not in this list because they are dynamically excluded - // Rules relying on correct setup of jdk.home - CallToDeprecatedCodeMarkedForRemovalCheck.class, - CallToDeprecatedMethodCheck.class, - // Rules relying on correct setup of java version - AbstractClassNoFieldShouldBeInterfaceCheck.class, - AnonymousClassShouldBeLambdaCheck.class, - CombineCatchCheck.class, - DateAndTimesCheck.class, - DateUtilsTruncateCheck.class, - DiamondOperatorCheck.class, - InsecureCreateTempFileCheck.class, - JdbcDriverExplicitLoadingCheck.class, - LambdaOptionalParenthesisCheck.class, - LambdaSingleExpressionCheck.class, - RepeatAnnotationCheck.class, - ReplaceGuavaWithJavaCheck.class, - ReplaceLambdaByMethodRefCheck.class, - SwitchInsteadOfIfSequenceCheck.class, - ThreadLocalWithInitialCheck.class, - TryWithResourcesCheck.class, - ValueBasedObjectUsedForLockCheck.class, - // Rules with a high deviation (>3%) - AccessibilityChangeCheck.class, - CipherBlockChainingCheck.class, - ClassNamedLikeExceptionCheck.class, - ClassWithOnlyStaticMethodsInstantiationCheck.class, - CollectionInappropriateCallsCheck.class, - DeadStoreCheck.class, - EqualsArgumentTypeCheck.class, - EqualsNotOverridenWithCompareToCheck.class, - EqualsOverridenWithHashCodeCheck.class, - ForLoopVariableTypeCheck.class, - JWTWithStrongCipherCheck.class, - MethodNamedEqualsCheck.class, - NioFileDeleteCheck.class, - PrivateFieldUsedLocallyCheck.class, - SillyEqualsCheck.class, - StandardCharsetsConstantsCheck.class, - ThreadLocalCleanupCheck.class, - ThreadOverridesRunCheck.class, - UnusedPrivateClassCheck.class, - UnusedPrivateFieldCheck.class, - VerifiedServerHostnamesCheck.class, - VolatileNonPrimitiveFieldCheck.class, - WeakSSLContextCheck.class); - - private GeneratedCheckList() { - } - - public static List> getChecks() { - return ALL_CHECKS; - } - - public static List> getJavaChecks() { - return sortedJoin(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS); - } - - public static List> getJavaTestChecks() { - return sortedJoin(JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS); - } - - public static Set> getJavaChecksNotWorkingForAutoScan() { - return JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN; - } - - @SafeVarargs - private static List> sortedJoin(List>... lists) { - return Arrays.stream(lists) - .flatMap(List::stream) - .sorted(Comparator.comparing(Class::getSimpleName)) - .toList(); - } + .toList(); } - """ - .replace("${importChecks}", importChecks) - .replace("${className}", CLASS_NAME) - .replace("${mainClasses}", collectMainChecks) - .replace("${testClasses}", collectTestChecks) - .replace("${allClasses}", collectAllChecks)); - - } catch (IOException e) { - throw new IOException("Failed to generate class", e); - } + } + """ + .replace("${importChecks}", importChecks) + .replace("${className}", CLASS_NAME) + .replace("${mainClasses}", collectMainChecks) + .replace("${testClasses}", collectTestChecks) + .replace("${allClasses}", collectAllChecks); + Files.writeString(path, content); } - private record Metadata(String scope) { + public record Metadata(String scope) { } - } diff --git a/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java b/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java new file mode 100644 index 00000000000..141af87cc85 --- /dev/null +++ b/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java @@ -0,0 +1,3 @@ +@Rule(key = "exampleKey") +class ExampleCheck implements JavaCheck { +} diff --git a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java new file mode 100644 index 00000000000..0a4b9adf1eb --- /dev/null +++ b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java @@ -0,0 +1,147 @@ +/* + * SonarQube Java + * Copyright (C) 2024-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.java; + +import com.google.gson.Gson; +import java.io.IOException; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.sonar.check.Rule; +import org.sonar.plugins.java.api.JavaCheck; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CheckListGeneratorTest { + private CheckListGenerator generator; + private final String directory = System.getProperty("user.dir").replace("check-list", ""); + + @BeforeEach + public void setUp() { + Gson gson = new Gson(); + generator = new CheckListGenerator(gson); + } + + @Test + void test_Main() { + assertThrows(IllegalStateException.class, () -> CheckListGenerator.main(new String[] {})); + } + + @Test + void testGetCheckClasses_and_generateCheckListFile() throws IOException { + Path relativePath = Path.of(directory, "java-checks/src/main/java"); + Path awsRelativePath = Path.of(directory, "java-checks-aws/src/main/java"); + var classes = generator.getCheckClasses(relativePath, awsRelativePath); + assertNotNull(classes); + assertFalse(classes.isEmpty()); + assertTrue(classes.stream().allMatch(c -> c.isAnnotationPresent(Rule.class))); + + Path tempFile = Files.createTempFile("testGeneratedCheckList", ".java"); + generator.generateCheckListFile(classes, tempFile, directory + "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"); + } + + @Test + void testGetCheckClasses_fail() { + Path relativePath = Path.of("java-checks/src/main/java"); + Path awsRelativePath = Path.of(directory, "java-checks-aws/src/main/java"); + assertThrows(IllegalStateException.class, () -> generator.getCheckClasses(relativePath, awsRelativePath)); + } + + @Test + void testGetCheckClasses_fail_getClassByName() { + Path relativePath = Path.of(directory, "check-list/src/test/files"); + Path awsRelativePath = Path.of(directory, "java-checks-aws/src/main/java"); + assertThrows(IllegalStateException.class, () -> generator.getCheckClasses(relativePath, awsRelativePath), "Cannot find the class for name org.sonar.java.checks.ExampleCheck"); + } + + @Test + void testGetRuleKey() { + @Rule(key = "exampleKey") + class ExampleCheck implements JavaCheck { + } + String ruleKey = generator.getRuleKey(ExampleCheck.class); + assertEquals("exampleKey", ruleKey); + } + + @Test + void testGetMetadata() { + String json = "{\"scope\":\"Main\"}"; + CheckListGenerator.Metadata metadata = generator.getMetadata(new StringReader(json)); + assertNotNull(metadata); + assertEquals("Main", metadata.scope()); + } + + @Test + void testGenerateImportStatements() { + @Rule(key = "exampleKey") + class ExampleCheck1 implements JavaCheck { + } + @Rule(key = "exampleKey2") + class ExampleCheck2 implements JavaCheck { + } + List> checks = List.of(ExampleCheck1.class, ExampleCheck2.class); + String importStatements = generator.generateImportStatements(checks); + assertTrue(importStatements.contains("import org.sonar.java.ExampleCheck1;")); + assertTrue(importStatements.contains("import org.sonar.java.ExampleCheck2;")); + } + + @Test + void testCollectChecks() { + @Rule(key = "exampleKey") + class ExampleCheck1 implements JavaCheck { + } + @Rule(key = "exampleKey2") + class ExampleCheck2 implements JavaCheck { + } + List> classes = List.of(ExampleCheck1.class, ExampleCheck2.class); + String checks = generator.collectChecks(classes); + assertTrue(checks.contains("ExampleCheck1.class")); + assertTrue(checks.contains("ExampleCheck2.class")); + } + + @Test + void testWriteToFile() throws IOException { + Path tempFile = Files.createTempFile("testGeneratedCheckList", ".java"); + generator.writeToFile( + "importStatements", + "collectMainChecks", + "collectTestChecks", + "collectAllChecks", tempFile); + assertTrue(Files.exists(tempFile)); + String content = Files.readString(tempFile); + assertNotNull(content); + assertTrue(content.contains("GeneratedCheckList")); + assertTrue(content.contains("importStatements")); + Files.deleteIfExists(tempFile); + } + + @Test + void generateTest() { + + } + +} From 093a35c941f60e168a3bcd3c0483b7070c1d003a Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 09:27:06 +0200 Subject: [PATCH 15/26] Add tests for CheckListGenerator --- .../org/sonar/java/CheckListGenerator.java | 75 ++++++++++++------- .../sonar/java/CheckListGeneratorTest.java | 60 +++++++++++---- 2 files changed, 95 insertions(+), 40 deletions(-) diff --git a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java index f0f663facf2..bff7fcc6946 100644 --- a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -36,20 +36,45 @@ public class CheckListGenerator { private static final String CLASS_NAME = "GeneratedCheckList"; - private static final String RULES_PATH = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"; + public static final String RULES_PATH = "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"; private final Gson gson; - public CheckListGenerator(Gson gson) { + final Path relativePath; + final Path awsRelativePath; + Path pathToWriteList; + final String rulesPath; + + public CheckListGenerator(Gson gson, Path relativePath, Path awsRelativePath, Path pathToWriteList, String rulesPath) { this.gson = gson; + this.relativePath = relativePath; + this.awsRelativePath = awsRelativePath; + this.pathToWriteList = pathToWriteList; + this.rulesPath = rulesPath; } public static void main(String[] args) { - var generator = new CheckListGenerator(new Gson()); - var relativePath = Path.of("java-checks/src/main/java"); - var awsRelativePath = Path.of("java-checks-aws/src/main/java"); - var checks = generator.getCheckClasses(relativePath, awsRelativePath); - var path = Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"); - generator.generateCheckListFile(checks, path, RULES_PATH); + var generator = new CheckListGenerator(new Gson(), + Path.of("java-checks/src/main/java"), + Path.of("java-checks-aws/src/main/java"), + Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"), + RULES_PATH); + generateCheckList(generator); + } + + public static void generateCheckList(CheckListGenerator generator) { + var checks = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); + + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + generator.generateCheckListClasses(checks, mainClasses, testClasses, allClasses, generator.rulesPath); + String main = generator.collectChecks(mainClasses); + String test = generator.collectChecks(testClasses); + String all = generator.collectChecks(allClasses); + + String importChecks = generateImportStatements(checks); + + generator.writeToFile(importChecks, main, test, all, generator.pathToWriteList); } public List> getCheckClasses(Path directory, Path awsDirectory) { @@ -89,7 +114,7 @@ public Metadata getMetadata(Reader reader) { return gson.fromJson(reader, Metadata.class); } - public String generateImportStatements(List> checks) { + public static String generateImportStatements(List> checks) { return checks.stream() .map(c -> "import " + c.getPackageName() + "." + c.getSimpleName() + ";") .collect(Collectors.joining("\n")); @@ -101,10 +126,7 @@ public String collectChecks(List> classes) { .collect(Collectors.joining(", \n ")); } - public void generateCheckListFile(List> checks, Path path, String rulesPath) { - List> mainClasses = new ArrayList<>(); - List> testClasses = new ArrayList<>(); - List> allClasses = new ArrayList<>(); + public void generateCheckListClasses(List> checks, List> mainClasses, List> testClasses, List> allClasses, String rulesPath) { checks.forEach(check -> { String ruleKey = getRuleKey(check); String fileName = rulesPath + ruleKey + ".json"; @@ -120,15 +142,9 @@ public void generateCheckListFile(List> checks, Path path, St throw new IllegalStateException("Could not find rule file " + fileName, e); } }); - String importChecks = generateImportStatements(checks); - try { - writeToFile(importChecks, collectChecks(mainClasses), collectChecks(testClasses), collectChecks(allClasses), path); - } catch (IOException e) { - throw new IllegalStateException("Unable to write checks to the file.", e); - } } - public void writeToFile(String importChecks, String collectMainChecks, String collectTestChecks, String collectAllChecks, Path path) throws IOException { + public void writeToFile(String importChecks, String mainChecks, String testChecks, String allChecks, Path path) { String content = """ package org.sonar.java; @@ -147,13 +163,13 @@ public final class ${className} { public static final String REPOSITORY_KEY = "java"; private static final List> JAVA_MAIN_CHECKS = Arrays.asList( - ${mainClasses}); + ${mainChecks}); private static final List> JAVA_TEST_CHECKS = Arrays.asList( - ${testClasses}); + ${testChecks}); private static final List> JAVA_MAIN_AND_TEST_CHECKS = Arrays.asList( - ${allClasses}); + ${allChecks}); private static final List> ALL_CHECKS = Stream.of(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS) .flatMap(List::stream) @@ -238,10 +254,15 @@ private static List> sortedJoin(List CheckListGenerator.generateCheckList(generator)); + } + + @Test + void testGetCheckClasses() { + var classes = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); assertNotNull(classes); assertFalse(classes.isEmpty()); assertTrue(classes.stream().allMatch(c -> c.isAnnotationPresent(Rule.class))); + } - Path tempFile = Files.createTempFile("testGeneratedCheckList", ".java"); - generator.generateCheckListFile(classes, tempFile, directory + "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"); + @Test + void testGenerateCheckList() { + var checks = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + generator.generateCheckListClasses(checks, mainClasses, testClasses, allClasses, directory + "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"); + assertTrue(Files.exists(generator.pathToWriteList)); + } + + @Test + void testGenerateCheckList_fail() { + @Rule(key = "exampleKey") + class ExampleCheck1 implements JavaCheck { + } + @Rule(key = "exampleKey2") + class ExampleCheck2 implements JavaCheck { + } + List> checks = List.of(ExampleCheck1.class, ExampleCheck2.class); + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + assertThrows(IllegalStateException.class, + () -> generator.generateCheckListClasses(checks, mainClasses, testClasses, allClasses, directory + "sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/"), + "Could not find rule file /Users/irina.batinic/Projects/sonar-java/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/exampleKey.json"); } @Test @@ -139,9 +178,4 @@ void testWriteToFile() throws IOException { Files.deleteIfExists(tempFile); } - @Test - void generateTest() { - - } - } From c3499032e912f3a8c4507210b8e1b243354bf96e Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 09:56:35 +0200 Subject: [PATCH 16/26] Updating gson version breaks build - 1 forbidden licenses used. Returning back to 2.8.9 --- .../src/main/java/org/sonar/java/CheckListGenerator.java | 3 ++- .../src/test/java/org/sonar/java/CheckListGeneratorTest.java | 2 +- pom.xml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java index bff7fcc6946..fa1ce551a4c 100644 --- a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -265,6 +265,7 @@ private static List> sortedJoin(List com.google.code.gson gson - 2.11.0 + 2.8.9 compile From 0b6c15d12abf15fa9bf6193c4ed0ec971a42a35f Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 10:43:46 +0200 Subject: [PATCH 17/26] Remove unnecessary test. Remove unnecessary exception from method signature. --- .../sonar/plugins/java/GeneratedCheckListTest.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java index ef6837ff8a4..b7a23a45e8e 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java @@ -22,8 +22,6 @@ import com.google.gson.Gson; import java.io.File; import java.io.FileReader; -import java.lang.reflect.Constructor; -import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; @@ -114,7 +112,7 @@ public void define(Context context) { * Enforces that each check has test, name and description. */ @Test - void test() throws MalformedURLException { + void test() { Map keyMap = new HashMap<>(); for (Class cls : GeneratedCheckList.getChecks()) { String testName = '/' + cls.getName().replace('.', '/') + "Test.java"; @@ -212,12 +210,4 @@ private static class DummyMetatada { String status; } - @Test - void private_constructor() throws Exception { - Constructor constructor = GeneratedCheckList.class.getDeclaredConstructor(); - assertThat(constructor.isAccessible()).isFalse(); - constructor.setAccessible(true); - constructor.newInstance(); - } - } From 2368659d0f105a938b34c19fa023827c7a4941d5 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 10:56:47 +0200 Subject: [PATCH 18/26] Add test for wrong metadata --- .../src/test/files/metadata/exampleKey.json | 3 +++ .../src/test/files/metadata/exampleKey2.json | 3 +++ .../org/sonar/java/checks/ExampleCheck.java | 2 ++ .../sonar/java/CheckListGeneratorTest.java | 19 ++++++++++++++++++- 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 check-list/src/test/files/metadata/exampleKey.json create mode 100644 check-list/src/test/files/metadata/exampleKey2.json diff --git a/check-list/src/test/files/metadata/exampleKey.json b/check-list/src/test/files/metadata/exampleKey.json new file mode 100644 index 00000000000..58fe01043dd --- /dev/null +++ b/check-list/src/test/files/metadata/exampleKey.json @@ -0,0 +1,3 @@ +{ + "scope": "Something" +} diff --git a/check-list/src/test/files/metadata/exampleKey2.json b/check-list/src/test/files/metadata/exampleKey2.json new file mode 100644 index 00000000000..9dbbef5a6c0 --- /dev/null +++ b/check-list/src/test/files/metadata/exampleKey2.json @@ -0,0 +1,3 @@ +{ + "scope": "All" +} diff --git a/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java b/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java index 141af87cc85..b77f016ff8e 100644 --- a/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java +++ b/check-list/src/test/files/org/sonar/java/checks/ExampleCheck.java @@ -1,3 +1,5 @@ +import org.sonar.check.Rule; + @Rule(key = "exampleKey") class ExampleCheck implements JavaCheck { } diff --git a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java index 4fedb7eef06..59973593f61 100644 --- a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java +++ b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java @@ -103,6 +103,23 @@ class ExampleCheck2 implements JavaCheck { "Could not find rule file /Users/irina.batinic/Projects/sonar-java/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/exampleKey.json"); } + @Test + void testGenerateCheckList_fail_wrong_metadata() { + @Rule(key = "exampleKey") + class ExampleCheck1 implements JavaCheck { + } + @Rule(key = "exampleKey2") + class ExampleCheck2 implements JavaCheck { + } + List> checks = List.of(ExampleCheck1.class, ExampleCheck2.class); + List> mainClasses = new ArrayList<>(); + List> testClasses = new ArrayList<>(); + List> allClasses = new ArrayList<>(); + assertThrows(IllegalStateException.class, + () -> generator.generateCheckListClasses(checks, mainClasses, testClasses, allClasses, directory + "check-list/src/test/files/metadata/"), + "Unknown scope Something for class class org.sonar.java.CheckListGeneratorTest$2ExampleCheck1"); + } + @Test void testGetCheckClasses_fail() { Path relativePath = Path.of("java-checks/src/main/java"); @@ -143,7 +160,7 @@ class ExampleCheck1 implements JavaCheck { class ExampleCheck2 implements JavaCheck { } List> checks = List.of(ExampleCheck1.class, ExampleCheck2.class); - String importStatements = generator.generateImportStatements(checks); + String importStatements = CheckListGenerator.generateImportStatements(checks); assertTrue(importStatements.contains("import org.sonar.java.ExampleCheck1;")); assertTrue(importStatements.contains("import org.sonar.java.ExampleCheck2;")); } From e37da21ff92fc21457ce7384a2a8e9c1f10e1a6c Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 14:31:21 +0200 Subject: [PATCH 19/26] Rename test method --- .../src/test/java/org/sonar/java/CheckListGeneratorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java index 59973593f61..cd05e120ce7 100644 --- a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java +++ b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java @@ -52,7 +52,7 @@ public void setUp() throws IOException { } @Test - void test_Main() { + void test_Main_throwsException_withDefaultProperties() { assertThrows(IllegalStateException.class, () -> CheckListGenerator.main(new String[] {})); } From 6e2041baf32771849d864cee7eab7bfaa034a3ed Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 14:37:22 +0200 Subject: [PATCH 20/26] Add test for writing to file --- .../java/org/sonar/java/CheckListGeneratorTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java index cd05e120ce7..7b0487af4f8 100644 --- a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java +++ b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java @@ -24,6 +24,7 @@ import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -195,4 +196,14 @@ void testWriteToFile() throws IOException { Files.deleteIfExists(tempFile); } + @Test + void test_writingToFile_ToInvalidPath_ThrowsException() { + Path invalidPath = Paths.get("/invalid/directory/test.txt"); + assertThrows(IllegalStateException.class, () -> generator.writeToFile( + "importStatements", + "collectMainChecks", + "collectTestChecks", + "collectAllChecks", invalidPath)); + } + } From c5995f0466d35b22606a33e0ec057a2eac81ac57 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 17:23:43 +0200 Subject: [PATCH 21/26] Changes after code review --- .../org/sonar/java/CheckListGenerator.java | 27 ++++++++++--------- .../sonar/java/CheckListGeneratorTest.java | 18 +++++++------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java index fa1ce551a4c..c02b61f4d85 100644 --- a/check-list/src/main/java/org/sonar/java/CheckListGenerator.java +++ b/check-list/src/main/java/org/sonar/java/CheckListGenerator.java @@ -58,40 +58,41 @@ public static void main(String[] args) { Path.of("java-checks-aws/src/main/java"), Path.of("check-list/target/generated-sources/" + CLASS_NAME + ".java"), RULES_PATH); - generateCheckList(generator); + generator.generateCheckList(); } - public static void generateCheckList(CheckListGenerator generator) { - var checks = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); + public void generateCheckList() { + var checks = getCheckClasses(); List> mainClasses = new ArrayList<>(); List> testClasses = new ArrayList<>(); List> allClasses = new ArrayList<>(); - generator.generateCheckListClasses(checks, mainClasses, testClasses, allClasses, generator.rulesPath); - String main = generator.collectChecks(mainClasses); - String test = generator.collectChecks(testClasses); - String all = generator.collectChecks(allClasses); + generateCheckListClasses(checks, mainClasses, testClasses, allClasses, rulesPath); + String main = collectChecks(mainClasses); + String test = collectChecks(testClasses); + String all = collectChecks(allClasses); String importChecks = generateImportStatements(checks); - generator.writeToFile(importChecks, main, test, all, generator.pathToWriteList); + writeToFile(importChecks, main, test, all, pathToWriteList); } - public List> getCheckClasses(Path directory, Path awsDirectory) { - var modifiedFiles = getModifiedFiles(directory, awsDirectory); - return modifiedFiles.stream() + public List> getCheckClasses() { + var checkFiles = getCheckFiles(); + return checkFiles.stream() .map(CheckListGenerator::getClassByName) .filter(c -> !Modifier.isAbstract(c.getModifiers())) .filter(c -> c.getAnnotationsByType(Rule.class).length != 0) .toList(); } - private static List getModifiedFiles(Path relativePath, Path awsRelativePath) { + private List getCheckFiles() { try (Stream stream = Stream.concat(Files.walk(relativePath.resolve("org/sonar/java/checks")), Files.walk(awsRelativePath.resolve("org/sonar/java/checks")))) { return stream .map(p -> p.startsWith(awsRelativePath) ? awsRelativePath.relativize(p).toString() : relativePath.relativize(p).toString()) .filter(file -> file.endsWith("Check.java")) .map(file -> file.replace(".java", "").replace(File.separator, ".")) + .sorted() .toList(); } catch (IOException e) { throw new IllegalStateException(e.getMessage()); @@ -110,7 +111,7 @@ public String getRuleKey(Class check) { return check.getAnnotation(Rule.class).key(); } - public Metadata getMetadata(Reader reader) { + protected Metadata getMetadata(Reader reader) { return gson.fromJson(reader, Metadata.class); } diff --git a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java index 7b0487af4f8..bccfb538d89 100644 --- a/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java +++ b/check-list/src/test/java/org/sonar/java/CheckListGeneratorTest.java @@ -59,19 +59,19 @@ void test_Main_throwsException_withDefaultProperties() { @Test void test_generateCheckList() { - CheckListGenerator.generateCheckList(generator); + generator.generateCheckList(); assertTrue(Files.exists(generator.pathToWriteList)); } @Test void test_generateCheckList_fail() { generator.pathToWriteList = null; - assertThrows(NullPointerException.class, () -> CheckListGenerator.generateCheckList(generator)); + assertThrows(NullPointerException.class, () -> generator.generateCheckList()); } @Test void testGetCheckClasses() { - var classes = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); + var classes = generator.getCheckClasses(); assertNotNull(classes); assertFalse(classes.isEmpty()); assertTrue(classes.stream().allMatch(c -> c.isAnnotationPresent(Rule.class))); @@ -79,7 +79,7 @@ void testGetCheckClasses() { @Test void testGenerateCheckList() { - var checks = generator.getCheckClasses(generator.relativePath, generator.awsRelativePath); + var checks = generator.getCheckClasses(); List> mainClasses = new ArrayList<>(); List> testClasses = new ArrayList<>(); List> allClasses = new ArrayList<>(); @@ -122,17 +122,19 @@ class ExampleCheck2 implements JavaCheck { } @Test - void testGetCheckClasses_fail() { + void testGetCheckClasses_fail() throws IOException { Path relativePath = Path.of("java-checks/src/main/java"); Path awsRelativePath = Path.of(directory, "java-checks-aws/src/main/java"); - assertThrows(IllegalStateException.class, () -> generator.getCheckClasses(relativePath, awsRelativePath)); + generator = new CheckListGenerator(new Gson(), relativePath, awsRelativePath, Files.createTempFile("testGeneratedCheckList", ".java"), directory + CheckListGenerator.RULES_PATH); + assertThrows(IllegalStateException.class, () -> generator.getCheckClasses()); } @Test - void testGetCheckClasses_fail_getClassByName() { + void testGetCheckClasses_fail_getClassByName() throws IOException { Path relativePath = Path.of(directory, "check-list/src/test/files"); Path awsRelativePath = Path.of(directory, "java-checks-aws/src/main/java"); - assertThrows(IllegalStateException.class, () -> generator.getCheckClasses(relativePath, awsRelativePath), "Cannot find the class for name org.sonar.java.checks.ExampleCheck"); + generator = new CheckListGenerator(new Gson(), relativePath, awsRelativePath, Files.createTempFile("testGeneratedCheckList", ".java"), directory + CheckListGenerator.RULES_PATH); + assertThrows(IllegalStateException.class, () -> generator.getCheckClasses(), "Cannot find the class for name org.sonar.java.checks.ExampleCheck"); } @Test From 231a86abc85af4537a8588f29bd1d59a56bac8f6 Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 17:54:52 +0200 Subject: [PATCH 22/26] Compiling explicitly just test sources --- .cirrus.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 0546cdf4a65..10bb0cfa65d 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -180,8 +180,9 @@ sanity_task: sanity_script: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER - - mvn clean install -Dmaven.test.skip=true - - mvn compile --projects java-checks-test-sources --also-make-dependents + - cd java-checks-test-sources + - mvn clean compile + - cd ../ - mvn verify -f sonar-java-plugin/pom.xml -Psanity -Dtest=SanityTest cleanup_before_cache_script: cleanup_maven_repository @@ -262,9 +263,9 @@ autoscan_task: autoscan_script: - source cirrus-env QA - source set_maven_build_version $BUILD_NUMBER - - JAVA_HOME="${JAVA_21_HOME}" mvn clean install -Dmaven.test.skip=true - - JAVA_HOME="${JAVA_21_HOME}" mvn compile --projects java-checks-test-sources --also-make-dependents - - cd its/autoscan + - cd java-checks-test-sources + - JAVA_HOME="${JAVA_21_HOME}" mvn clean compile + - cd ../its/autoscan - mvn clean package --batch-mode --errors --show-version --activate-profiles it-autoscan -Dsonar.runtimeVersion=LATEST_RELEASE[10.3] -Dmaven.test.redirectTestOutputToFile=false -Dparallel=methods -DuseUnlimitedThreads=true cleanup_before_cache_script: cleanup_maven_repository on_failure: From 7218164c03fa22ac54208b8e1f314f5d251ce3ec Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 18:19:11 +0200 Subject: [PATCH 23/26] Update readme for compiling test sources --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e536827d29d..cbeafb0ad27 100644 --- a/README.md +++ b/README.md @@ -162,10 +162,10 @@ Running this test can be broken down in 2 steps: Make sure that the `java-checks-tests-sources` module has been compiled (ie: the .class files in `java-checks-tests-sources/target/` are up to date). -In doubt, go the top-level of the project and run: +In doubt, go the [`java-checks-tests-sources`](java-checks-tests-sources) module and run: ```shell # Use java 21! -mvn clean compile --projects java-checks-test-sources --also-make-dependents +mvn clean compile ``` ##### Executing the autoscan test From 60c41dccf5540debf63558b9dc6337c33a112b2e Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Fri, 21 Jun 2024 19:08:17 +0200 Subject: [PATCH 24/26] Remove CheckList class --- .../org/sonar/plugins/java/CheckList.java | 1414 ----------------- .../org/sonar/plugins/java/CheckListTest.java | 220 --- .../plugins/java/GeneratedCheckListTest.java | 2 +- 3 files changed, 1 insertion(+), 1635 deletions(-) delete mode 100644 sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckList.java delete mode 100644 sonar-java-plugin/src/test/java/org/sonar/plugins/java/CheckListTest.java diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckList.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckList.java deleted file mode 100644 index b7584e62057..00000000000 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/CheckList.java +++ /dev/null @@ -1,1414 +0,0 @@ -/* - * SonarQube Java - * Copyright (C) 2012-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.java; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.sonar.java.checks.AbsOnNegativeCheck; -import org.sonar.java.checks.AbstractClassNoFieldShouldBeInterfaceCheck; -import org.sonar.java.checks.AbstractClassWithoutAbstractMethodCheck; -import org.sonar.java.checks.AccessibilityChangeCheck; -import org.sonar.java.checks.AccessibilityChangeOnRecordsCheck; -import org.sonar.java.checks.AllBranchesAreIdenticalCheck; -import org.sonar.java.checks.AnnotationDefaultArgumentCheck; -import org.sonar.java.checks.AnonymousClassShouldBeLambdaCheck; -import org.sonar.java.checks.AnonymousClassesTooBigCheck; -import org.sonar.java.checks.ArrayCopyLoopCheck; -import org.sonar.java.checks.ArrayDesignatorAfterTypeCheck; -import org.sonar.java.checks.ArrayDesignatorOnVariableCheck; -import org.sonar.java.checks.ArrayForVarArgCheck; -import org.sonar.java.checks.ArrayHashCodeAndToStringCheck; -import org.sonar.java.checks.ArraysAsListOfPrimitiveToStreamCheck; -import org.sonar.java.checks.AssertOnBooleanVariableCheck; -import org.sonar.java.checks.AssertionsInProductionCodeCheck; -import org.sonar.java.checks.AssertsOnParametersOfPublicMethodCheck; -import org.sonar.java.checks.AssignmentInSubExpressionCheck; -import org.sonar.java.checks.AtLeastOneConstructorCheck; -import org.sonar.java.checks.AvoidHighFrameratesOnMobileCheck; -import org.sonar.java.checks.BasicAuthCheck; -import org.sonar.java.checks.BatchSQLStatementsCheck; -import org.sonar.java.checks.BigDecimalDoubleConstructorCheck; -import org.sonar.java.checks.BlockingOperationsInVirtualThreadsCheck; -import org.sonar.java.checks.BluetoothLowPowerModeCheck; -import org.sonar.java.checks.BooleanInversionCheck; -import org.sonar.java.checks.BooleanLiteralCheck; -import org.sonar.java.checks.BooleanMethodReturnCheck; -import org.sonar.java.checks.BoxedBooleanExpressionsCheck; -import org.sonar.java.checks.CORSCheck; -import org.sonar.java.checks.CallOuterPrivateMethodCheck; -import org.sonar.java.checks.CallSuperMethodFromInnerClassCheck; -import org.sonar.java.checks.CallToDeprecatedCodeMarkedForRemovalCheck; -import org.sonar.java.checks.CallToDeprecatedMethodCheck; -import org.sonar.java.checks.CallToFileDeleteOnExitMethodCheck; -import org.sonar.java.checks.CaseInsensitiveComparisonCheck; -import org.sonar.java.checks.CastArithmeticOperandCheck; -import org.sonar.java.checks.CatchExceptionCheck; -import org.sonar.java.checks.CatchIllegalMonitorStateExceptionCheck; -import org.sonar.java.checks.CatchNPECheck; -import org.sonar.java.checks.CatchOfThrowableOrErrorCheck; -import org.sonar.java.checks.CatchRethrowingCheck; -import org.sonar.java.checks.CatchUsesExceptionWithContextCheck; -import org.sonar.java.checks.ChangeMethodContractCheck; -import org.sonar.java.checks.ChildClassShadowFieldCheck; -import org.sonar.java.checks.ClassComparedByNameCheck; -import org.sonar.java.checks.ClassFieldCountCheck; -import org.sonar.java.checks.ClassVariableVisibilityCheck; -import org.sonar.java.checks.ClassWithOnlyStaticMethodsInstantiationCheck; -import org.sonar.java.checks.ClassWithoutHashCodeInHashStructureCheck; -import org.sonar.java.checks.CloneMethodCallsSuperCloneCheck; -import org.sonar.java.checks.CloneOverrideCheck; -import org.sonar.java.checks.CloneableImplementingCloneCheck; -import org.sonar.java.checks.CognitiveComplexityMethodCheck; -import org.sonar.java.checks.CollapsibleIfCandidateCheck; -import org.sonar.java.checks.CollectInsteadOfForeachCheck; -import org.sonar.java.checks.CollectionCallingItselfCheck; -import org.sonar.java.checks.CollectionConstructorReferenceCheck; -import org.sonar.java.checks.CollectionImplementationReferencedCheck; -import org.sonar.java.checks.CollectionInappropriateCallsCheck; -import org.sonar.java.checks.CollectionIsEmptyCheck; -import org.sonar.java.checks.CollectionMethodsWithLinearComplexityCheck; -import org.sonar.java.checks.CollectionSizeAndArrayLengthCheck; -import org.sonar.java.checks.CollectionsEmptyConstantsCheck; -import org.sonar.java.checks.CollectorsToListCheck; -import org.sonar.java.checks.CombineCatchCheck; -import org.sonar.java.checks.CommentRegularExpressionCheck; -import org.sonar.java.checks.CommentedOutCodeLineCheck; -import org.sonar.java.checks.CompareObjectWithEqualsCheck; -import org.sonar.java.checks.CompareStringsBoxedTypesWithEqualsCheck; -import org.sonar.java.checks.CompareToNotOverloadedCheck; -import org.sonar.java.checks.CompareToResultTestCheck; -import org.sonar.java.checks.CompareToReturnValueCheck; -import org.sonar.java.checks.ConcatenationWithStringValueOfCheck; -import org.sonar.java.checks.ConditionalOnNewLineCheck; -import org.sonar.java.checks.ConfigurationBeanNamesCheck; -import org.sonar.java.checks.ConfusingOverloadCheck; -import org.sonar.java.checks.ConfusingVarargCheck; -import org.sonar.java.checks.ConstantMathCheck; -import org.sonar.java.checks.ConstantMethodCheck; -import org.sonar.java.checks.ConstantsShouldBeStaticFinalCheck; -import org.sonar.java.checks.ConstructorCallingOverridableCheck; -import org.sonar.java.checks.ConstructorInjectionCheck; -import org.sonar.java.checks.ControlCharacterInLiteralCheck; -import org.sonar.java.checks.CounterModeIVShouldNotBeReusedCheck; -import org.sonar.java.checks.CustomCryptographicAlgorithmCheck; -import org.sonar.java.checks.DanglingElseStatementsCheck; -import org.sonar.java.checks.DateAndTimesCheck; -import org.sonar.java.checks.DateFormatWeekYearCheck; -import org.sonar.java.checks.DateTimeFormatterMismatchCheck; -import org.sonar.java.checks.DateUtilsTruncateCheck; -import org.sonar.java.checks.DeadStoreCheck; -import org.sonar.java.checks.DefaultEncodingUsageCheck; -import org.sonar.java.checks.DefaultInitializedFieldCheck; -import org.sonar.java.checks.DefaultPackageCheck; -import org.sonar.java.checks.DeprecatedArgumentsCheck; -import org.sonar.java.checks.DeprecatedTagPresenceCheck; -import org.sonar.java.checks.DepthOfInheritanceTreeCheck; -import org.sonar.java.checks.DiamondOperatorCheck; -import org.sonar.java.checks.DisallowedClassCheck; -import org.sonar.java.checks.DisallowedConstructorCheck; -import org.sonar.java.checks.DisallowedMethodCheck; -import org.sonar.java.checks.DisallowedThreadGroupCheck; -import org.sonar.java.checks.DoubleBraceInitializationCheck; -import org.sonar.java.checks.DoubleCheckedLockingAssignmentCheck; -import org.sonar.java.checks.DoublePrefixOperatorCheck; -import org.sonar.java.checks.DuplicateConditionIfElseIfCheck; -import org.sonar.java.checks.DynamicClassLoadCheck; -import org.sonar.java.checks.EmptyBlockCheck; -import org.sonar.java.checks.EmptyClassCheck; -import org.sonar.java.checks.EmptyFileCheck; -import org.sonar.java.checks.EmptyMethodsCheck; -import org.sonar.java.checks.EmptyStatementUsageCheck; -import org.sonar.java.checks.EnumEqualCheck; -import org.sonar.java.checks.EnumMapCheck; -import org.sonar.java.checks.EnumMutableFieldCheck; -import org.sonar.java.checks.EnumSetCheck; -import org.sonar.java.checks.EqualsArgumentTypeCheck; -import org.sonar.java.checks.EqualsNotOverriddenInSubclassCheck; -import org.sonar.java.checks.EqualsNotOverridenWithCompareToCheck; -import org.sonar.java.checks.EqualsOnAtomicClassCheck; -import org.sonar.java.checks.EqualsOverridenWithHashCodeCheck; -import org.sonar.java.checks.EqualsParametersMarkedNonNullCheck; -import org.sonar.java.checks.ErrorClassExtendedCheck; -import org.sonar.java.checks.EscapedUnicodeCharactersCheck; -import org.sonar.java.checks.ExceptionsShouldBeImmutableCheck; -import org.sonar.java.checks.ExpressionComplexityCheck; -import org.sonar.java.checks.FieldModifierCheck; -import org.sonar.java.checks.FileHeaderCheck; -import org.sonar.java.checks.FilesExistsJDK8Check; -import org.sonar.java.checks.FinalClassCheck; -import org.sonar.java.checks.FinalizeFieldsSetCheck; -import org.sonar.java.checks.FixmeTagPresenceCheck; -import org.sonar.java.checks.FloatEqualityCheck; -import org.sonar.java.checks.ForLoopCounterChangedCheck; -import org.sonar.java.checks.ForLoopFalseConditionCheck; -import org.sonar.java.checks.ForLoopIncrementAndUpdateCheck; -import org.sonar.java.checks.ForLoopIncrementSignCheck; -import org.sonar.java.checks.ForLoopTerminationConditionCheck; -import org.sonar.java.checks.ForLoopUsedAsWhileLoopCheck; -import org.sonar.java.checks.ForLoopVariableTypeCheck; -import org.sonar.java.checks.GarbageCollectorCalledCheck; -import org.sonar.java.checks.GetClassLoaderCheck; -import org.sonar.java.checks.GetRequestedSessionIdCheck; -import org.sonar.java.checks.GettersSettersOnRightFieldCheck; -import org.sonar.java.checks.HardCodedPasswordCheck; -import org.sonar.java.checks.HardCodedSecretCheck; -import org.sonar.java.checks.HardcodedIpCheck; -import org.sonar.java.checks.HardcodedURICheck; -import org.sonar.java.checks.HasNextCallingNextCheck; -import org.sonar.java.checks.HiddenFieldCheck; -import org.sonar.java.checks.IdenticalCasesInSwitchCheck; -import org.sonar.java.checks.IdenticalOperandOnBinaryExpressionCheck; -import org.sonar.java.checks.IfElseIfStatementEndsWithElseCheck; -import org.sonar.java.checks.IgnoredOperationStatusCheck; -import org.sonar.java.checks.IgnoredReturnValueCheck; -import org.sonar.java.checks.IgnoredStreamReturnValueCheck; -import org.sonar.java.checks.ImmediateReverseBoxingCheck; -import org.sonar.java.checks.ImmediatelyReturnedVariableCheck; -import org.sonar.java.checks.ImplementsEnumerationCheck; -import org.sonar.java.checks.InappropriateRegexpCheck; -import org.sonar.java.checks.IncorrectOrderOfMembersCheck; -import org.sonar.java.checks.IncrementDecrementInSubExpressionCheck; -import org.sonar.java.checks.IndentationAfterConditionalCheck; -import org.sonar.java.checks.IndentationCheck; -import org.sonar.java.checks.IndexOfWithPositiveNumberCheck; -import org.sonar.java.checks.InnerClassOfNonSerializableCheck; -import org.sonar.java.checks.InnerClassOfSerializableCheck; -import org.sonar.java.checks.InnerClassTooManyLinesCheck; -import org.sonar.java.checks.InnerStaticClassesCheck; -import org.sonar.java.checks.InputStreamOverrideReadCheck; -import org.sonar.java.checks.InputStreamReadCheck; -import org.sonar.java.checks.InsecureCreateTempFileCheck; -import org.sonar.java.checks.InstanceOfPatternMatchingCheck; -import org.sonar.java.checks.InstanceofUsedOnExceptionCheck; -import org.sonar.java.checks.InterfaceAsConstantContainerCheck; -import org.sonar.java.checks.InterfaceOrSuperclassShadowingCheck; -import org.sonar.java.checks.InterruptedExceptionCheck; -import org.sonar.java.checks.InvalidDateValuesCheck; -import org.sonar.java.checks.IsInstanceMethodCheck; -import org.sonar.java.checks.IterableIteratorCheck; -import org.sonar.java.checks.IteratorNextExceptionCheck; -import org.sonar.java.checks.JacksonDeserializationCheck; -import org.sonar.java.checks.JdbcDriverExplicitLoadingCheck; -import org.sonar.java.checks.JpaEagerFetchTypeCheck; -import org.sonar.java.checks.KeySetInsteadOfEntrySetCheck; -import org.sonar.java.checks.KnownCapacityHashBasedCollectionCheck; -import org.sonar.java.checks.LabelsShouldNotBeUsedCheck; -import org.sonar.java.checks.LambdaOptionalParenthesisCheck; -import org.sonar.java.checks.LambdaSingleExpressionCheck; -import org.sonar.java.checks.LambdaTooBigCheck; -import org.sonar.java.checks.LambdaTypeParameterCheck; -import org.sonar.java.checks.LazyArgEvaluationCheck; -import org.sonar.java.checks.LeastSpecificTypeCheck; -import org.sonar.java.checks.LeftCurlyBraceEndLineCheck; -import org.sonar.java.checks.LeftCurlyBraceStartLineCheck; -import org.sonar.java.checks.LoggedRethrownExceptionsCheck; -import org.sonar.java.checks.LoggerClassCheck; -import org.sonar.java.checks.LoggersDeclarationCheck; -import org.sonar.java.checks.LongBitsToDoubleOnIntCheck; -import org.sonar.java.checks.LoopExecutingAtMostOnceCheck; -import org.sonar.java.checks.LoopsOnSameSetCheck; -import org.sonar.java.checks.MagicNumberCheck; -import org.sonar.java.checks.MainMethodThrowsExceptionCheck; -import org.sonar.java.checks.MapKeyNotComparableCheck; -import org.sonar.java.checks.MathClampMethodsCheck; -import org.sonar.java.checks.MathClampRangeCheck; -import org.sonar.java.checks.MathOnFloatCheck; -import org.sonar.java.checks.MembersDifferOnlyByCapitalizationCheck; -import org.sonar.java.checks.MethodComplexityCheck; -import org.sonar.java.checks.MethodIdenticalImplementationsCheck; -import org.sonar.java.checks.MethodOnlyCallsSuperCheck; -import org.sonar.java.checks.MethodParametersOrderCheck; -import org.sonar.java.checks.MethodTooBigCheck; -import org.sonar.java.checks.MethodWithExcessiveReturnsCheck; -import org.sonar.java.checks.MismatchPackageDirectoryCheck; -import org.sonar.java.checks.MissingBeanValidationCheck; -import org.sonar.java.checks.MissingCurlyBracesCheck; -import org.sonar.java.checks.MissingDeprecatedCheck; -import org.sonar.java.checks.MissingNewLineAtEndOfFileCheck; -import org.sonar.java.checks.MissingOverridesInRecordWithArrayComponentCheck; -import org.sonar.java.checks.MissingPackageInfoCheck; -import org.sonar.java.checks.MissingPathVariableAnnotationCheck; -import org.sonar.java.checks.ModifiersOrderCheck; -import org.sonar.java.checks.ModulusEqualityCheck; -import org.sonar.java.checks.MultilineBlocksCurlyBracesCheck; -import org.sonar.java.checks.MutableMembersUsageCheck; -import org.sonar.java.checks.NPEThrowCheck; -import org.sonar.java.checks.NestedBlocksCheck; -import org.sonar.java.checks.NestedEnumStaticCheck; -import org.sonar.java.checks.NestedIfStatementsCheck; -import org.sonar.java.checks.NestedSwitchCheck; -import org.sonar.java.checks.NestedTernaryOperatorsCheck; -import org.sonar.java.checks.NestedTryCatchCheck; -import org.sonar.java.checks.NioFileDeleteCheck; -import org.sonar.java.checks.NoCheckstyleTagPresenceCheck; -import org.sonar.java.checks.NoPmdTagPresenceCheck; -import org.sonar.java.checks.NoSonarCheck; -import org.sonar.java.checks.NonShortCircuitLogicCheck; -import org.sonar.java.checks.NonStaticClassInitializerCheck; -import org.sonar.java.checks.NotifyCheck; -import org.sonar.java.checks.NullCheckWithInstanceofCheck; -import org.sonar.java.checks.NullReturnedOnComputeIfPresentOrAbsentCheck; -import org.sonar.java.checks.NullShouldNotBeUsedWithOptionalCheck; -import org.sonar.java.checks.OSCommandsPathCheck; -import org.sonar.java.checks.ObjectCreatedOnlyToCallGetClassCheck; -import org.sonar.java.checks.ObjectFinalizeCheck; -import org.sonar.java.checks.ObjectFinalizeOverloadedCheck; -import org.sonar.java.checks.ObjectFinalizeOverriddenCheck; -import org.sonar.java.checks.ObjectFinalizeOverridenCallsSuperFinalizeCheck; -import org.sonar.java.checks.ObjectFinalizeOverridenNotPublicCheck; -import org.sonar.java.checks.OctalValuesCheck; -import org.sonar.java.checks.OmitPermittedTypesCheck; -import org.sonar.java.checks.OneClassInterfacePerFileCheck; -import org.sonar.java.checks.OneDeclarationPerLineCheck; -import org.sonar.java.checks.OperatorPrecedenceCheck; -import org.sonar.java.checks.OptionalAsParameterCheck; -import org.sonar.java.checks.OutputStreamOverrideWriteCheck; -import org.sonar.java.checks.OverrideAnnotationCheck; -import org.sonar.java.checks.OverwrittenKeyCheck; -import org.sonar.java.checks.ParameterReassignedToCheck; -import org.sonar.java.checks.ParsingErrorCheck; -import org.sonar.java.checks.PatternMatchUsingIfCheck; -import org.sonar.java.checks.PopulateBeansCheck; -import org.sonar.java.checks.PredictableSeedCheck; -import org.sonar.java.checks.PreferStreamAnyMatchCheck; -import org.sonar.java.checks.PreparedStatementAndResultSetCheck; -import org.sonar.java.checks.PreparedStatementLoopInvariantCheck; -import org.sonar.java.checks.PrimitiveTypeBoxingWithToStringCheck; -import org.sonar.java.checks.PrimitiveWrappersInTernaryOperatorCheck; -import org.sonar.java.checks.PrimitivesMarkedNullableCheck; -import org.sonar.java.checks.PrintfFailCheck; -import org.sonar.java.checks.PrintfMisuseCheck; -import org.sonar.java.checks.PrivateFieldUsedLocallyCheck; -import org.sonar.java.checks.ProtectedMemberInFinalClassCheck; -import org.sonar.java.checks.PseudoRandomCheck; -import org.sonar.java.checks.PublicConstructorInAbstractClassCheck; -import org.sonar.java.checks.PublicStaticFieldShouldBeFinalCheck; -import org.sonar.java.checks.PublicStaticMutableMembersCheck; -import org.sonar.java.checks.QueryOnlyRequiredFieldsCheck; -import org.sonar.java.checks.RandomFloatToIntCheck; -import org.sonar.java.checks.RawByteBitwiseOperationsCheck; -import org.sonar.java.checks.RawExceptionCheck; -import org.sonar.java.checks.RawTypeCheck; -import org.sonar.java.checks.ReadObjectSynchronizedCheck; -import org.sonar.java.checks.RecordDuplicatedGetterCheck; -import org.sonar.java.checks.RecordInsteadOfClassCheck; -import org.sonar.java.checks.RecordPatternInsteadOfFieldAccessCheck; -import org.sonar.java.checks.RedundantAbstractMethodCheck; -import org.sonar.java.checks.RedundantCloseCheck; -import org.sonar.java.checks.RedundantJumpCheck; -import org.sonar.java.checks.RedundantModifierCheck; -import org.sonar.java.checks.RedundantRecordMethodsCheck; -import org.sonar.java.checks.RedundantStreamCollectCheck; -import org.sonar.java.checks.RedundantThrowsDeclarationCheck; -import org.sonar.java.checks.RedundantTypeCastCheck; -import org.sonar.java.checks.ReflectionOnNonRuntimeAnnotationCheck; -import org.sonar.java.checks.RegexPatternsNeedlesslyCheck; -import org.sonar.java.checks.ReleaseSensorsCheck; -import org.sonar.java.checks.RepeatAnnotationCheck; -import org.sonar.java.checks.ReplaceGuavaWithJavaCheck; -import org.sonar.java.checks.ReplaceLambdaByMethodRefCheck; -import org.sonar.java.checks.RestrictedIdentifiersUsageCheck; -import org.sonar.java.checks.ResultSetIsLastCheck; -import org.sonar.java.checks.ReturnEmptyArrayNotNullCheck; -import org.sonar.java.checks.ReturnInFinallyCheck; -import org.sonar.java.checks.ReturnOfBooleanExpressionsCheck; -import org.sonar.java.checks.ReuseRandomCheck; -import org.sonar.java.checks.ReverseSequencedCollectionCheck; -import org.sonar.java.checks.ReversedMethodSequencedCollectionCheck; -import org.sonar.java.checks.RightCurlyBraceDifferentLineAsNextBlockCheck; -import org.sonar.java.checks.RightCurlyBraceSameLineAsNextBlockCheck; -import org.sonar.java.checks.RightCurlyBraceStartLineCheck; -import org.sonar.java.checks.RunFinalizersCheck; -import org.sonar.java.checks.SQLInjectionCheck; -import org.sonar.java.checks.ScheduledThreadPoolExecutorZeroCheck; -import org.sonar.java.checks.SelectorMethodArgumentCheck; -import org.sonar.java.checks.SelfAssignementCheck; -import org.sonar.java.checks.ServletInstanceFieldCheck; -import org.sonar.java.checks.ServletMethodsExceptionsThrownCheck; -import org.sonar.java.checks.SeveralBreakOrContinuePerLoopCheck; -import org.sonar.java.checks.ShiftOnIntOrLongCheck; -import org.sonar.java.checks.SillyEqualsCheck; -import org.sonar.java.checks.SillyStringOperationsCheck; -import org.sonar.java.checks.SimpleClassNameCheck; -import org.sonar.java.checks.SimpleStringLiteralForSingleLineStringsCheck; -import org.sonar.java.checks.SingleIfInsteadOfPatternMatchGuardCheck; -import org.sonar.java.checks.SpecializedFunctionalInterfacesCheck; -import org.sonar.java.checks.StandardCharsetsConstantsCheck; -import org.sonar.java.checks.StandardFunctionalInterfaceCheck; -import org.sonar.java.checks.StaticFieldInitializationCheck; -import org.sonar.java.checks.StaticFieldUpateCheck; -import org.sonar.java.checks.StaticFieldUpdateInConstructorCheck; -import org.sonar.java.checks.StaticImportCountCheck; -import org.sonar.java.checks.StaticMemberAccessCheck; -import org.sonar.java.checks.StaticMembersAccessCheck; -import org.sonar.java.checks.StaticMethodCheck; -import org.sonar.java.checks.StaticMultithreadedUnsafeFieldsCheck; -import org.sonar.java.checks.StreamPeekCheck; -import org.sonar.java.checks.StringBufferAndBuilderWithCharCheck; -import org.sonar.java.checks.StringCallsBeyondBoundsCheck; -import org.sonar.java.checks.StringConcatToTextBlockCheck; -import org.sonar.java.checks.StringConcatenationInLoopCheck; -import org.sonar.java.checks.StringIndexOfRangesCheck; -import org.sonar.java.checks.StringLiteralDuplicatedCheck; -import org.sonar.java.checks.StringLiteralInsideEqualsCheck; -import org.sonar.java.checks.StringMethodsWithLocaleCheck; -import org.sonar.java.checks.StringOffsetMethodsCheck; -import org.sonar.java.checks.StringPrimitiveConstructorCheck; -import org.sonar.java.checks.StringToPrimitiveConversionCheck; -import org.sonar.java.checks.StringToStringCheck; -import org.sonar.java.checks.StrongCipherAlgorithmCheck; -import org.sonar.java.checks.SubClassStaticReferenceCheck; -import org.sonar.java.checks.SunPackagesUsedCheck; -import org.sonar.java.checks.SuppressWarningsCheck; -import org.sonar.java.checks.SuspiciousListRemoveCheck; -import org.sonar.java.checks.SwitchAtLeastThreeCasesCheck; -import org.sonar.java.checks.SwitchCaseTooBigCheck; -import org.sonar.java.checks.SwitchCaseWithoutBreakCheck; -import org.sonar.java.checks.SwitchCasesShouldBeCommaSeparatedCheck; -import org.sonar.java.checks.SwitchDefaultLastCaseCheck; -import org.sonar.java.checks.SwitchInsteadOfIfSequenceCheck; -import org.sonar.java.checks.SwitchLastCaseIsDefaultCheck; -import org.sonar.java.checks.SwitchRedundantKeywordCheck; -import org.sonar.java.checks.SwitchWithLabelsCheck; -import org.sonar.java.checks.SwitchWithTooManyCasesCheck; -import org.sonar.java.checks.SymmetricEqualsCheck; -import org.sonar.java.checks.SyncGetterAndSetterCheck; -import org.sonar.java.checks.SynchronizationOnStringOrBoxedCheck; -import org.sonar.java.checks.SynchronizedClassUsageCheck; -import org.sonar.java.checks.SynchronizedFieldAssignmentCheck; -import org.sonar.java.checks.SynchronizedLockCheck; -import org.sonar.java.checks.SynchronizedOverrideCheck; -import org.sonar.java.checks.SystemExitCalledCheck; -import org.sonar.java.checks.SystemOutOrErrUsageCheck; -import org.sonar.java.checks.TabCharacterCheck; -import org.sonar.java.checks.TernaryOperatorCheck; -import org.sonar.java.checks.TestsInSeparateFolderCheck; -import org.sonar.java.checks.TextBlockTabsAndSpacesCheck; -import org.sonar.java.checks.TextBlocksInComplexExpressionsCheck; -import org.sonar.java.checks.ThisExposedFromConstructorCheck; -import org.sonar.java.checks.ThreadAsRunnableArgumentCheck; -import org.sonar.java.checks.ThreadLocalCleanupCheck; -import org.sonar.java.checks.ThreadLocalWithInitialCheck; -import org.sonar.java.checks.ThreadOverridesRunCheck; -import org.sonar.java.checks.ThreadRunCheck; -import org.sonar.java.checks.ThreadSleepCheck; -import org.sonar.java.checks.ThreadStartedInConstructorCheck; -import org.sonar.java.checks.ThreadWaitCallCheck; -import org.sonar.java.checks.ThrowCheckedExceptionCheck; -import org.sonar.java.checks.ThrowsFromFinallyCheck; -import org.sonar.java.checks.ThrowsSeveralCheckedExceptionCheck; -import org.sonar.java.checks.ToArrayCheck; -import org.sonar.java.checks.ToStringReturningNullCheck; -import org.sonar.java.checks.ToStringUsingBoxingCheck; -import org.sonar.java.checks.TodoTagPresenceCheck; -import org.sonar.java.checks.TooLongLineCheck; -import org.sonar.java.checks.TooManyLinesOfCodeInFileCheck; -import org.sonar.java.checks.TooManyMethodsCheck; -import org.sonar.java.checks.TooManyParametersCheck; -import org.sonar.java.checks.TooManyStatementsPerLineCheck; -import org.sonar.java.checks.TrailingCommentCheck; -import org.sonar.java.checks.TransientFieldInNonSerializableCheck; -import org.sonar.java.checks.TryWithResourcesCheck; -import org.sonar.java.checks.TypeParametersShadowingCheck; -import org.sonar.java.checks.TypeUpperBoundNotFinalCheck; -import org.sonar.java.checks.URLHashCodeAndEqualsCheck; -import org.sonar.java.checks.UnderscoreMisplacedOnNumberCheck; -import org.sonar.java.checks.UnderscoreOnNumberCheck; -import org.sonar.java.checks.UndocumentedApiCheck; -import org.sonar.java.checks.UnnecessaryBitOperationCheck; -import org.sonar.java.checks.UnnecessaryEscapeSequencesInTextBlockCheck; -import org.sonar.java.checks.UnnecessarySemicolonCheck; -import org.sonar.java.checks.UnreachableCatchCheck; -import org.sonar.java.checks.UppercaseSuffixesCheck; -import org.sonar.java.checks.UseMotionSensorWithoutGyroscopeCheck; -import org.sonar.java.checks.UseSwitchExpressionCheck; -import org.sonar.java.checks.UselessExtendsCheck; -import org.sonar.java.checks.UselessImportCheck; -import org.sonar.java.checks.UselessIncrementCheck; -import org.sonar.java.checks.UselessPackageInfoCheck; -import org.sonar.java.checks.UselessParenthesesCheck; -import org.sonar.java.checks.UtilityClassWithPublicConstructorCheck; -import org.sonar.java.checks.ValueBasedObjectsShouldNotBeSerializedCheck; -import org.sonar.java.checks.VarArgCheck; -import org.sonar.java.checks.VarCanBeUsedCheck; -import org.sonar.java.checks.VariableDeclarationScopeCheck; -import org.sonar.java.checks.VirtualThreadNotSynchronizedCheck; -import org.sonar.java.checks.VirtualThreadUnsupportedMethodsCheck; -import org.sonar.java.checks.VisibleForTestingUsageCheck; -import org.sonar.java.checks.VolatileNonPrimitiveFieldCheck; -import org.sonar.java.checks.VolatileVariablesOperationsCheck; -import org.sonar.java.checks.WaitInSynchronizeCheck; -import org.sonar.java.checks.WaitInWhileLoopCheck; -import org.sonar.java.checks.WaitOnConditionCheck; -import org.sonar.java.checks.WeakSSLContextCheck; -import org.sonar.java.checks.WildcardImportsShouldNotBeUsedCheck; -import org.sonar.java.checks.WildcardReturnParameterTypeCheck; -import org.sonar.java.checks.WrongAssignmentOperatorCheck; -import org.sonar.java.checks.aws.AwsConsumerBuilderUsageCheck; -import org.sonar.java.checks.aws.AwsCredentialsShouldBeSetExplicitlyCheck; -import org.sonar.java.checks.aws.AwsLambdaSyncCallCheck; -import org.sonar.java.checks.aws.AwsLongTermAccessKeysCheck; -import org.sonar.java.checks.aws.AwsRegionSetterCheck; -import org.sonar.java.checks.aws.AwsRegionShouldBeSetExplicitlyCheck; -import org.sonar.java.checks.aws.AwsReusableResourcesInitializedOnceCheck; -import org.sonar.java.checks.design.BrainMethodCheck; -import org.sonar.java.checks.design.ClassCouplingCheck; -import org.sonar.java.checks.design.ClassImportCouplingCheck; -import org.sonar.java.checks.design.SingletonUsageCheck; -import org.sonar.java.checks.naming.BadAbstractClassNameCheck; -import org.sonar.java.checks.naming.BadClassNameCheck; -import org.sonar.java.checks.naming.BadConstantNameCheck; -import org.sonar.java.checks.naming.BadFieldNameCheck; -import org.sonar.java.checks.naming.BadFieldNameStaticNonFinalCheck; -import org.sonar.java.checks.naming.BadInterfaceNameCheck; -import org.sonar.java.checks.naming.BadLocalConstantNameCheck; -import org.sonar.java.checks.naming.BadLocalVariableNameCheck; -import org.sonar.java.checks.naming.BadMethodNameCheck; -import org.sonar.java.checks.naming.BadPackageNameCheck; -import org.sonar.java.checks.naming.BadTestClassNameCheck; -import org.sonar.java.checks.naming.BadTestMethodNameCheck; -import org.sonar.java.checks.naming.BadTypeParameterNameCheck; -import org.sonar.java.checks.naming.BooleanMethodNameCheck; -import org.sonar.java.checks.naming.ClassNamedLikeExceptionCheck; -import org.sonar.java.checks.naming.FieldNameMatchingTypeNameCheck; -import org.sonar.java.checks.naming.KeywordAsIdentifierCheck; -import org.sonar.java.checks.naming.MethodNameSameAsClassCheck; -import org.sonar.java.checks.naming.MethodNamedEqualsCheck; -import org.sonar.java.checks.naming.MethodNamedHashcodeOrEqualCheck; -import org.sonar.java.checks.regex.AnchorPrecedenceCheck; -import org.sonar.java.checks.regex.CanonEqFlagInRegexCheck; -import org.sonar.java.checks.regex.DuplicatesInCharacterClassCheck; -import org.sonar.java.checks.regex.EmptyLineRegexCheck; -import org.sonar.java.checks.regex.EmptyRegexGroupCheck; -import org.sonar.java.checks.regex.EmptyStringRepetitionCheck; -import org.sonar.java.checks.regex.EscapeSequenceControlCharacterCheck; -import org.sonar.java.checks.regex.GraphemeClustersInClassesCheck; -import org.sonar.java.checks.regex.ImpossibleBackReferenceCheck; -import org.sonar.java.checks.regex.ImpossibleBoundariesCheck; -import org.sonar.java.checks.regex.InvalidRegexCheck; -import org.sonar.java.checks.regex.MultipleWhitespaceCheck; -import org.sonar.java.checks.regex.PossessiveQuantifierContinuationCheck; -import org.sonar.java.checks.regex.RedosCheck; -import org.sonar.java.checks.regex.RedundantRegexAlternativesCheck; -import org.sonar.java.checks.regex.RegexComplexityCheck; -import org.sonar.java.checks.regex.RegexLookaheadCheck; -import org.sonar.java.checks.regex.RegexStackOverflowCheck; -import org.sonar.java.checks.regex.ReluctantQuantifierCheck; -import org.sonar.java.checks.regex.ReluctantQuantifierWithEmptyContinuationCheck; -import org.sonar.java.checks.regex.SingleCharCharacterClassCheck; -import org.sonar.java.checks.regex.SingleCharacterAlternationCheck; -import org.sonar.java.checks.regex.StringReplaceCheck; -import org.sonar.java.checks.regex.SuperfluousCurlyBraceCheck; -import org.sonar.java.checks.regex.UnicodeAwareCharClassesCheck; -import org.sonar.java.checks.regex.UnicodeCaseCheck; -import org.sonar.java.checks.regex.UnquantifiedNonCapturingGroupCheck; -import org.sonar.java.checks.regex.UnusedGroupNamesCheck; -import org.sonar.java.checks.regex.VerboseRegexCheck; -import org.sonar.java.checks.security.AndroidBiometricAuthWithoutCryptoCheck; -import org.sonar.java.checks.security.AndroidBroadcastingCheck; -import org.sonar.java.checks.security.AndroidExternalStorageCheck; -import org.sonar.java.checks.security.AndroidMobileDatabaseEncryptionKeysCheck; -import org.sonar.java.checks.security.AndroidNonAuthenticatedUsersCheck; -import org.sonar.java.checks.security.AndroidUnencryptedDatabaseCheck; -import org.sonar.java.checks.security.AndroidUnencryptedFilesCheck; -import org.sonar.java.checks.security.AuthorizationsStrongDecisionsCheck; -import org.sonar.java.checks.security.CipherBlockChainingCheck; -import org.sonar.java.checks.security.ClearTextProtocolCheck; -import org.sonar.java.checks.security.CookieHttpOnlyCheck; -import org.sonar.java.checks.security.CryptographicKeySizeCheck; -import org.sonar.java.checks.security.DataHashingCheck; -import org.sonar.java.checks.security.DebugFeatureEnabledCheck; -import org.sonar.java.checks.security.DisableAutoEscapingCheck; -import org.sonar.java.checks.security.DisclosingTechnologyFingerprintsCheck; -import org.sonar.java.checks.security.EmptyDatabasePasswordCheck; -import org.sonar.java.checks.security.EncryptionAlgorithmCheck; -import org.sonar.java.checks.security.ExcessiveContentRequestCheck; -import org.sonar.java.checks.security.FilePermissionsCheck; -import org.sonar.java.checks.security.HardCodedCredentialsShouldNotBeUsedCheck; -import org.sonar.java.checks.security.IntegerToHexStringCheck; -import org.sonar.java.checks.security.JWTWithStrongCipherCheck; -import org.sonar.java.checks.security.LDAPAuthenticatedConnectionCheck; -import org.sonar.java.checks.security.LDAPDeserializationCheck; -import org.sonar.java.checks.security.LogConfigurationCheck; -import org.sonar.java.checks.security.OpenSAML2AuthenticationBypassCheck; -import org.sonar.java.checks.security.PasswordEncoderCheck; -import org.sonar.java.checks.security.PubliclyWritableDirectoriesCheck; -import org.sonar.java.checks.security.ReceivingIntentsCheck; -import org.sonar.java.checks.security.SecureCookieCheck; -import org.sonar.java.checks.security.ServerCertificatesCheck; -import org.sonar.java.checks.security.UnpredictableSaltCheck; -import org.sonar.java.checks.security.UserEnumerationCheck; -import org.sonar.java.checks.security.VerifiedServerHostnamesCheck; -import org.sonar.java.checks.security.WebViewJavaScriptSupportCheck; -import org.sonar.java.checks.security.WebViewsFileAccessCheck; -import org.sonar.java.checks.security.XxeActiveMQCheck; -import org.sonar.java.checks.security.ZipEntryCheck; -import org.sonar.java.checks.serialization.BlindSerialVersionUidCheck; -import org.sonar.java.checks.serialization.CustomSerializationMethodCheck; -import org.sonar.java.checks.serialization.ExternalizableClassConstructorCheck; -import org.sonar.java.checks.serialization.NonSerializableWriteCheck; -import org.sonar.java.checks.serialization.PrivateReadResolveCheck; -import org.sonar.java.checks.serialization.RecordSerializationIgnoredMembersCheck; -import org.sonar.java.checks.serialization.SerialVersionUidCheck; -import org.sonar.java.checks.serialization.SerialVersionUidInRecordCheck; -import org.sonar.java.checks.serialization.SerializableComparatorCheck; -import org.sonar.java.checks.serialization.SerializableFieldInSerializableClassCheck; -import org.sonar.java.checks.serialization.SerializableObjectInSessionCheck; -import org.sonar.java.checks.serialization.SerializableSuperConstructorCheck; -import org.sonar.java.checks.spring.AsyncMethodsCalledViaThisCheck; -import org.sonar.java.checks.spring.AsyncMethodsOnConfigurationClassCheck; -import org.sonar.java.checks.spring.AsyncMethodsReturnTypeCheck; -import org.sonar.java.checks.spring.AutowiredOnConstructorWhenMultipleConstructorsCheck; -import org.sonar.java.checks.spring.AutowiredOnMultipleConstructorsCheck; -import org.sonar.java.checks.spring.AvoidQualifierOnBeanMethodsCheck; -import org.sonar.java.checks.spring.ControllerWithRestControllerReplacementCheck; -import org.sonar.java.checks.spring.ControllerWithSessionAttributesCheck; -import org.sonar.java.checks.spring.DirectBeanMethodInvocationWithoutProxyCheck; -import org.sonar.java.checks.spring.FieldDependencyInjectionCheck; -import org.sonar.java.checks.spring.ModelAttributeNamingConventionForSpELCheck; -import org.sonar.java.checks.spring.NonSingletonAutowiredInSingletonCheck; -import org.sonar.java.checks.spring.NullableInjectedFieldsHaveDefaultValueCheck; -import org.sonar.java.checks.spring.OptionalRestParametersShouldBeObjectsCheck; -import org.sonar.java.checks.spring.PersistentEntityUsedAsRequestParameterCheck; -import org.sonar.java.checks.spring.RequestMappingMethodPublicCheck; -import org.sonar.java.checks.spring.SpelExpressionCheck; -import org.sonar.java.checks.spring.SpringAntMatcherOrderCheck; -import org.sonar.java.checks.spring.SpringAutoConfigurationCheck; -import org.sonar.java.checks.spring.SpringBeanNamingConventionCheck; -import org.sonar.java.checks.spring.SpringBeansShouldBeAccessibleCheck; -import org.sonar.java.checks.spring.SpringComponentWithNonAutowiredMembersCheck; -import org.sonar.java.checks.spring.SpringComponentWithWrongScopeCheck; -import org.sonar.java.checks.spring.SpringComposedRequestMappingCheck; -import org.sonar.java.checks.spring.SpringConfigurationWithAutowiredFieldsCheck; -import org.sonar.java.checks.spring.SpringConstructorInjectionCheck; -import org.sonar.java.checks.spring.SpringIncompatibleTransactionalCheck; -import org.sonar.java.checks.spring.SpringRequestMappingMethodCheck; -import org.sonar.java.checks.spring.SpringScanDefaultPackageCheck; -import org.sonar.java.checks.spring.SpringSecurityDisableCSRFCheck; -import org.sonar.java.checks.spring.SpringSessionFixationCheck; -import org.sonar.java.checks.spring.StatusCodesOnResponseCheck; -import org.sonar.java.checks.spring.SuperfluousResponseBodyAnnotationCheck; -import org.sonar.java.checks.spring.TransactionalMethodVisibilityCheck; -import org.sonar.java.checks.spring.ValueAnnotationShouldInjectPropertyOrSpELCheck; -import org.sonar.java.checks.sustainability.AndroidExactAlarmCheck; -import org.sonar.java.checks.sustainability.AndroidFusedLocationProviderClientCheck; -import org.sonar.java.checks.synchronization.DoubleCheckedLockingCheck; -import org.sonar.java.checks.synchronization.SynchronizationOnGetClassCheck; -import org.sonar.java.checks.synchronization.TwoLocksWaitCheck; -import org.sonar.java.checks.synchronization.ValueBasedObjectUsedForLockCheck; -import org.sonar.java.checks.synchronization.WriteObjectTheOnlySynchronizedMethodCheck; -import org.sonar.java.checks.tests.AssertJApplyConfigurationCheck; -import org.sonar.java.checks.tests.AssertJAssertionsInConsumerCheck; -import org.sonar.java.checks.tests.AssertJChainSimplificationCheck; -import org.sonar.java.checks.tests.AssertJConsecutiveAssertionCheck; -import org.sonar.java.checks.tests.AssertJContextBeforeAssertionCheck; -import org.sonar.java.checks.tests.AssertJTestForEmptinessCheck; -import org.sonar.java.checks.tests.AssertThatThrownByAloneCheck; -import org.sonar.java.checks.tests.AssertTrueInsteadOfDedicatedAssertCheck; -import org.sonar.java.checks.tests.AssertionArgumentOrderCheck; -import org.sonar.java.checks.tests.AssertionCompareToSelfCheck; -import org.sonar.java.checks.tests.AssertionFailInCatchBlockCheck; -import org.sonar.java.checks.tests.AssertionInThreadRunCheck; -import org.sonar.java.checks.tests.AssertionInTryCatchCheck; -import org.sonar.java.checks.tests.AssertionTypesCheck; -import org.sonar.java.checks.tests.AssertionsCompletenessCheck; -import org.sonar.java.checks.tests.AssertionsInTestsCheck; -import org.sonar.java.checks.tests.AssertionsWithoutMessageCheck; -import org.sonar.java.checks.tests.BooleanOrNullLiteralInAssertionsCheck; -import org.sonar.java.checks.tests.CallSuperInTestCaseCheck; -import org.sonar.java.checks.tests.ExpectedExceptionCheck; -import org.sonar.java.checks.tests.IgnoredTestsCheck; -import org.sonar.java.checks.tests.JUnit45MethodAnnotationCheck; -import org.sonar.java.checks.tests.JUnit4AnnotationsCheck; -import org.sonar.java.checks.tests.JUnit5DefaultPackageClassAndMethodCheck; -import org.sonar.java.checks.tests.JUnit5SilentlyIgnoreClassAndMethodCheck; -import org.sonar.java.checks.tests.JUnitCompatibleAnnotationsCheck; -import org.sonar.java.checks.tests.JunitNestedAnnotationCheck; -import org.sonar.java.checks.tests.MockingAllMethodsCheck; -import org.sonar.java.checks.tests.MockitoAnnotatedObjectsShouldBeInitializedCheck; -import org.sonar.java.checks.tests.MockitoArgumentMatchersUsedOnAllParametersCheck; -import org.sonar.java.checks.tests.MockitoEqSimplificationCheck; -import org.sonar.java.checks.tests.NoTestInTestClassCheck; -import org.sonar.java.checks.tests.OneExpectedCheckedExceptionCheck; -import org.sonar.java.checks.tests.OneExpectedRuntimeExceptionCheck; -import org.sonar.java.checks.tests.ParameterizedTestCheck; -import org.sonar.java.checks.tests.RandomizedTestDataCheck; -import org.sonar.java.checks.tests.SpringAssertionsSimplificationCheck; -import org.sonar.java.checks.tests.TestAnnotationWithExpectedExceptionCheck; -import org.sonar.java.checks.tests.TestsStabilityCheck; -import org.sonar.java.checks.tests.ThreadSleepInTestsCheck; -import org.sonar.java.checks.tests.TooManyAssertionsCheck; -import org.sonar.java.checks.unused.UnusedLabelCheck; -import org.sonar.java.checks.unused.UnusedLocalVariableCheck; -import org.sonar.java.checks.unused.UnusedMethodParameterCheck; -import org.sonar.java.checks.unused.UnusedPrivateClassCheck; -import org.sonar.java.checks.unused.UnusedPrivateFieldCheck; -import org.sonar.java.checks.unused.UnusedPrivateMethodCheck; -import org.sonar.java.checks.unused.UnusedReturnedDataCheck; -import org.sonar.java.checks.unused.UnusedTestRuleCheck; -import org.sonar.java.checks.unused.UnusedThrowableCheck; -import org.sonar.java.checks.unused.UnusedTypeParameterCheck; -import org.sonar.plugins.java.api.JavaCheck; - -public final class CheckList { - - public static final String REPOSITORY_KEY = "java"; - - private static final List> JAVA_MAIN_CHECKS = Arrays.asList( - - // fast JavaFileScanner (not IssuableSubscriptionVisitor) ordered from the fastest to the slowest - LeftCurlyBraceEndLineCheck.class, - IndentationCheck.class, - IncorrectOrderOfMembersCheck.class, - MagicNumberCheck.class, - NestedIfStatementsCheck.class, - BadAbstractClassNameCheck.class, - RawExceptionCheck.class, - MissingPackageInfoCheck.class, - OperatorPrecedenceCheck.class, - RawTypeCheck.class, - - // IssuableSubscriptionVisitor rules ordered alphabetically - AbsOnNegativeCheck.class, - AbstractClassNoFieldShouldBeInterfaceCheck.class, - AbstractClassWithoutAbstractMethodCheck.class, - AccessibilityChangeCheck.class, - AccessibilityChangeOnRecordsCheck.class, - AllBranchesAreIdenticalCheck.class, - AnchorPrecedenceCheck.class, - AndroidBroadcastingCheck.class, - AndroidUnencryptedFilesCheck.class, - AndroidExactAlarmCheck.class, - AndroidFusedLocationProviderClientCheck.class, - AndroidExternalStorageCheck.class, - AndroidMobileDatabaseEncryptionKeysCheck.class, - AndroidNonAuthenticatedUsersCheck.class, - AnnotationDefaultArgumentCheck.class, - ArrayCopyLoopCheck.class, - ArrayDesignatorAfterTypeCheck.class, - ArrayForVarArgCheck.class, - ArrayHashCodeAndToStringCheck.class, - ArraysAsListOfPrimitiveToStreamCheck.class, - AssertOnBooleanVariableCheck.class, - AssertionsInProductionCodeCheck.class, - AssertsOnParametersOfPublicMethodCheck.class, - AsyncMethodsCalledViaThisCheck.class, - AsyncMethodsOnConfigurationClassCheck.class, - AsyncMethodsReturnTypeCheck.class, - AtLeastOneConstructorCheck.class, - AuthorizationsStrongDecisionsCheck.class, - AutowiredOnConstructorWhenMultipleConstructorsCheck.class, - AutowiredOnMultipleConstructorsCheck.class, - AvoidHighFrameratesOnMobileCheck.class, - AvoidQualifierOnBeanMethodsCheck.class, - AwsConsumerBuilderUsageCheck.class, - AwsCredentialsShouldBeSetExplicitlyCheck.class, - AwsLambdaSyncCallCheck.class, - AwsLongTermAccessKeysCheck.class, - AwsRegionSetterCheck.class, - AwsRegionShouldBeSetExplicitlyCheck.class, - AwsReusableResourcesInitializedOnceCheck.class, - BadLocalConstantNameCheck.class, - BadMethodNameCheck.class, - BasicAuthCheck.class, - BatchSQLStatementsCheck.class, - BigDecimalDoubleConstructorCheck.class, - AndroidBiometricAuthWithoutCryptoCheck.class, - BlindSerialVersionUidCheck.class, - BlockingOperationsInVirtualThreadsCheck.class, - BluetoothLowPowerModeCheck.class, - BooleanInversionCheck.class, - BooleanLiteralCheck.class, - BooleanMethodNameCheck.class, - BooleanMethodReturnCheck.class, - BrainMethodCheck.class, - ConfigurationBeanNamesCheck.class, - CORSCheck.class, - CallOuterPrivateMethodCheck.class, - CallSuperMethodFromInnerClassCheck.class, - CallToFileDeleteOnExitMethodCheck.class, - CanonEqFlagInRegexCheck.class, - CaseInsensitiveComparisonCheck.class, - CatchExceptionCheck.class, - CatchIllegalMonitorStateExceptionCheck.class, - CatchOfThrowableOrErrorCheck.class, - CatchRethrowingCheck.class, - ChangeMethodContractCheck.class, - CounterModeIVShouldNotBeReusedCheck.class, - ChildClassShadowFieldCheck.class, - CipherBlockChainingCheck.class, - ClassComparedByNameCheck.class, - ClassImportCouplingCheck.class, - ClassFieldCountCheck.class, - ClassNamedLikeExceptionCheck.class, - ClassWithOnlyStaticMethodsInstantiationCheck.class, - ClassWithoutHashCodeInHashStructureCheck.class, - ClearTextProtocolCheck.class, - CloneMethodCallsSuperCloneCheck.class, - CloneOverrideCheck.class, - CloneableImplementingCloneCheck.class, - CognitiveComplexityMethodCheck.class, - CollectInsteadOfForeachCheck.class, - CollectionCallingItselfCheck.class, - CollectionConstructorReferenceCheck.class, - CollectionInappropriateCallsCheck.class, - CollectionMethodsWithLinearComplexityCheck.class, - CollectionSizeAndArrayLengthCheck.class, - CombineCatchCheck.class, - CommentRegularExpressionCheck.class, - CompareToNotOverloadedCheck.class, - CompareToResultTestCheck.class, - CompareToReturnValueCheck.class, - ConditionalOnNewLineCheck.class, - ConfusingOverloadCheck.class, - ConfusingVarargCheck.class, - ConstantMathCheck.class, - ConstantMethodCheck.class, - ConstantsShouldBeStaticFinalCheck.class, - ConstructorCallingOverridableCheck.class, - ConstructorInjectionCheck.class, - ControlCharacterInLiteralCheck.class, - ControllerWithRestControllerReplacementCheck.class, - ControllerWithSessionAttributesCheck.class, - CookieHttpOnlyCheck.class, - HardCodedCredentialsShouldNotBeUsedCheck.class, - CryptographicKeySizeCheck.class, - CustomCryptographicAlgorithmCheck.class, - CustomSerializationMethodCheck.class, - DanglingElseStatementsCheck.class, - DataHashingCheck.class, - DateAndTimesCheck.class, - DateFormatWeekYearCheck.class, - DateTimeFormatterMismatchCheck.class, - DateUtilsTruncateCheck.class, - DebugFeatureEnabledCheck.class, - DeprecatedArgumentsCheck.class, - DefaultEncodingUsageCheck.class, - DefaultInitializedFieldCheck.class, - DeprecatedTagPresenceCheck.class, - DiamondOperatorCheck.class, - DirectBeanMethodInvocationWithoutProxyCheck.class, - DisableAutoEscapingCheck.class, - DisallowedConstructorCheck.class, - DisallowedMethodCheck.class, - DisclosingTechnologyFingerprintsCheck.class, - DoubleBraceInitializationCheck.class, - DoubleCheckedLockingAssignmentCheck.class, - DoubleCheckedLockingCheck.class, - DoublePrefixOperatorCheck.class, - DuplicatesInCharacterClassCheck.class, - DynamicClassLoadCheck.class, - EmptyClassCheck.class, - EmptyDatabasePasswordCheck.class, - EmptyLineRegexCheck.class, - EmptyRegexGroupCheck.class, - EmptyStringRepetitionCheck.class, - EncryptionAlgorithmCheck.class, - EnumEqualCheck.class, - EnumMutableFieldCheck.class, - EnumSetCheck.class, - EqualsArgumentTypeCheck.class, - EqualsNotOverriddenInSubclassCheck.class, - EqualsNotOverridenWithCompareToCheck.class, - EqualsOnAtomicClassCheck.class, - EqualsOverridenWithHashCodeCheck.class, - EqualsParametersMarkedNonNullCheck.class, - ErrorClassExtendedCheck.class, - EscapeSequenceControlCharacterCheck.class, - EscapedUnicodeCharactersCheck.class, - ExceptionsShouldBeImmutableCheck.class, - ExcessiveContentRequestCheck.class, - ExpressionComplexityCheck.class, - ExternalizableClassConstructorCheck.class, - FieldDependencyInjectionCheck.class, - FieldModifierCheck.class, - FileHeaderCheck.class, - FilePermissionsCheck.class, - FilesExistsJDK8Check.class, - FinalClassCheck.class, - FinalizeFieldsSetCheck.class, - FloatEqualityCheck.class, - ForLoopFalseConditionCheck.class, - ForLoopIncrementAndUpdateCheck.class, - ForLoopIncrementSignCheck.class, - ForLoopTerminationConditionCheck.class, - ForLoopUsedAsWhileLoopCheck.class, - ForLoopVariableTypeCheck.class, - GarbageCollectorCalledCheck.class, - GetClassLoaderCheck.class, - GetRequestedSessionIdCheck.class, - GettersSettersOnRightFieldCheck.class, - GraphemeClustersInClassesCheck.class, - HardCodedPasswordCheck.class, - HardCodedSecretCheck.class, - HardcodedURICheck.class, - HasNextCallingNextCheck.class, - IdenticalCasesInSwitchCheck.class, - IdenticalOperandOnBinaryExpressionCheck.class, - IfElseIfStatementEndsWithElseCheck.class, - IgnoredOperationStatusCheck.class, - IgnoredReturnValueCheck.class, - IgnoredStreamReturnValueCheck.class, - ImmediateReverseBoxingCheck.class, - ImplementsEnumerationCheck.class, - ImpossibleBackReferenceCheck.class, - ImpossibleBoundariesCheck.class, - InappropriateRegexpCheck.class, - IndexOfWithPositiveNumberCheck.class, - InnerClassOfNonSerializableCheck.class, - InnerClassOfSerializableCheck.class, - InnerClassTooManyLinesCheck.class, - InputStreamOverrideReadCheck.class, - InputStreamReadCheck.class, - InstanceOfPatternMatchingCheck.class, - InstanceofUsedOnExceptionCheck.class, - IntegerToHexStringCheck.class, - InterfaceAsConstantContainerCheck.class, - InterfaceOrSuperclassShadowingCheck.class, - InterruptedExceptionCheck.class, - InvalidDateValuesCheck.class, - InvalidRegexCheck.class, - IsInstanceMethodCheck.class, - IterableIteratorCheck.class, - IteratorNextExceptionCheck.class, - JacksonDeserializationCheck.class, - JdbcDriverExplicitLoadingCheck.class, - JpaEagerFetchTypeCheck.class, - JWTWithStrongCipherCheck.class, - KeySetInsteadOfEntrySetCheck.class, - KnownCapacityHashBasedCollectionCheck.class, - LDAPAuthenticatedConnectionCheck.class, - LDAPDeserializationCheck.class, - LabelsShouldNotBeUsedCheck.class, - LambdaSingleExpressionCheck.class, - LambdaTypeParameterCheck.class, - LeastSpecificTypeCheck.class, - LogConfigurationCheck.class, - LoggedRethrownExceptionsCheck.class, - LoggerClassCheck.class, - LongBitsToDoubleOnIntCheck.class, - LoopExecutingAtMostOnceCheck.class, - LoopsOnSameSetCheck.class, - MainMethodThrowsExceptionCheck.class, - MapKeyNotComparableCheck.class, - MathClampMethodsCheck.class, - MathClampRangeCheck.class, - MembersDifferOnlyByCapitalizationCheck.class, - MethodComplexityCheck.class, - MethodNamedEqualsCheck.class, - MethodNamedHashcodeOrEqualCheck.class, - MethodOnlyCallsSuperCheck.class, - MethodParametersOrderCheck.class, - MethodTooBigCheck.class, - MethodWithExcessiveReturnsCheck.class, - MissingBeanValidationCheck.class, - MissingCurlyBracesCheck.class, - MissingDeprecatedCheck.class, - MissingOverridesInRecordWithArrayComponentCheck.class, - ModelAttributeNamingConventionForSpELCheck.class, - ModulusEqualityCheck.class, - MultipleWhitespaceCheck.class, - NPEThrowCheck.class, - NestedEnumStaticCheck.class, - NestedSwitchCheck.class, - NestedTernaryOperatorsCheck.class, - NioFileDeleteCheck.class, - NoCheckstyleTagPresenceCheck.class, - NonSingletonAutowiredInSingletonCheck.class, - NoPmdTagPresenceCheck.class, - NoSonarCheck.class, - NonSerializableWriteCheck.class, - NonShortCircuitLogicCheck.class, - NonStaticClassInitializerCheck.class, - NotifyCheck.class, - NullableInjectedFieldsHaveDefaultValueCheck.class, - NullCheckWithInstanceofCheck.class, - NullReturnedOnComputeIfPresentOrAbsentCheck.class, - OSCommandsPathCheck.class, - ObjectCreatedOnlyToCallGetClassCheck.class, - ObjectFinalizeCheck.class, - ObjectFinalizeOverloadedCheck.class, - ObjectFinalizeOverridenCallsSuperFinalizeCheck.class, - ObjectFinalizeOverriddenCheck.class, - ObjectFinalizeOverridenNotPublicCheck.class, - OmitPermittedTypesCheck.class, - OneClassInterfacePerFileCheck.class, - OneDeclarationPerLineCheck.class, - OpenSAML2AuthenticationBypassCheck.class, - OptionalAsParameterCheck.class, - OptionalRestParametersShouldBeObjectsCheck.class, - OutputStreamOverrideWriteCheck.class, - OverwrittenKeyCheck.class, - PasswordEncoderCheck.class, - MissingPathVariableAnnotationCheck.class, - PatternMatchUsingIfCheck.class, - PersistentEntityUsedAsRequestParameterCheck.class, - PopulateBeansCheck.class, - PossessiveQuantifierContinuationCheck.class, - PredictableSeedCheck.class, - PreferStreamAnyMatchCheck.class, - PreparedStatementAndResultSetCheck.class, - PreparedStatementLoopInvariantCheck.class, - PrimitiveWrappersInTernaryOperatorCheck.class, - PrimitivesMarkedNullableCheck.class, - PrintfFailCheck.class, - PrivateFieldUsedLocallyCheck.class, - PrivateReadResolveCheck.class, - ProtectedMemberInFinalClassCheck.class, - PseudoRandomCheck.class, - PublicConstructorInAbstractClassCheck.class, - PublicStaticMutableMembersCheck.class, - PubliclyWritableDirectoriesCheck.class, - QueryOnlyRequiredFieldsCheck.class, - RandomFloatToIntCheck.class, - ReadObjectSynchronizedCheck.class, - ReceivingIntentsCheck.class, - RecordDuplicatedGetterCheck.class, - RecordInsteadOfClassCheck.class, - RecordPatternInsteadOfFieldAccessCheck.class, - RecordSerializationIgnoredMembersCheck.class, - RedosCheck.class, - RedundantAbstractMethodCheck.class, - RedundantCloseCheck.class, - RedundantJumpCheck.class, - RedundantModifierCheck.class, - RedundantRecordMethodsCheck.class, - RedundantRegexAlternativesCheck.class, - RedundantStreamCollectCheck.class, - RedundantTypeCastCheck.class, - ReflectionOnNonRuntimeAnnotationCheck.class, - RegexComplexityCheck.class, - RegexLookaheadCheck.class, - RegexPatternsNeedlesslyCheck.class, - RegexStackOverflowCheck.class, - ReleaseSensorsCheck.class, - ReluctantQuantifierCheck.class, - ReluctantQuantifierWithEmptyContinuationCheck.class, - ReplaceLambdaByMethodRefCheck.class, - RequestMappingMethodPublicCheck.class, - ResultSetIsLastCheck.class, - ReturnEmptyArrayNotNullCheck.class, - ReturnOfBooleanExpressionsCheck.class, - ReuseRandomCheck.class, - ReverseSequencedCollectionCheck.class, - ReversedMethodSequencedCollectionCheck.class, - RightCurlyBraceDifferentLineAsNextBlockCheck.class, - RightCurlyBraceSameLineAsNextBlockCheck.class, - RightCurlyBraceStartLineCheck.class, - RunFinalizersCheck.class, - SingleIfInsteadOfPatternMatchGuardCheck.class, - SQLInjectionCheck.class, - ScheduledThreadPoolExecutorZeroCheck.class, - SecureCookieCheck.class, - SelectorMethodArgumentCheck.class, - SelfAssignementCheck.class, - SerialVersionUidCheck.class, - SerializableComparatorCheck.class, - SerializableFieldInSerializableClassCheck.class, - SerializableObjectInSessionCheck.class, - SerializableSuperConstructorCheck.class, - SerialVersionUidInRecordCheck.class, - ServerCertificatesCheck.class, - ServletInstanceFieldCheck.class, - ServletMethodsExceptionsThrownCheck.class, - ShiftOnIntOrLongCheck.class, - StatusCodesOnResponseCheck.class, - StringIndexOfRangesCheck.class, - UnnecessaryBitOperationCheck.class, - SillyEqualsCheck.class, - SillyStringOperationsCheck.class, - SimpleClassNameCheck.class, - SimpleStringLiteralForSingleLineStringsCheck.class, - SingleCharacterAlternationCheck.class, - SingleCharCharacterClassCheck.class, - SingletonUsageCheck.class, - SpecializedFunctionalInterfacesCheck.class, - SpelExpressionCheck.class, - SpringAntMatcherOrderCheck.class, - SpringAutoConfigurationCheck.class, - SpringBeanNamingConventionCheck.class, - SpringBeansShouldBeAccessibleCheck.class, - SpringComponentWithNonAutowiredMembersCheck.class, - SpringComponentWithWrongScopeCheck.class, - SpringComposedRequestMappingCheck.class, - SpringConfigurationWithAutowiredFieldsCheck.class, - SpringConstructorInjectionCheck.class, - SpringIncompatibleTransactionalCheck.class, - SpringRequestMappingMethodCheck.class, - SpringScanDefaultPackageCheck.class, - SpringSecurityDisableCSRFCheck.class, - SpringSessionFixationCheck.class, - StandardCharsetsConstantsCheck.class, - StandardFunctionalInterfaceCheck.class, - StaticFieldInitializationCheck.class, - StaticFieldUpateCheck.class, - StaticFieldUpdateInConstructorCheck.class, - StaticImportCountCheck.class, - StaticMemberAccessCheck.class, - StaticMembersAccessCheck.class, - StaticMultithreadedUnsafeFieldsCheck.class, - StreamPeekCheck.class, - StringCallsBeyondBoundsCheck.class, - StringLiteralInsideEqualsCheck.class, - StringMethodsWithLocaleCheck.class, - StringOffsetMethodsCheck.class, - StringPrimitiveConstructorCheck.class, - StringReplaceCheck.class, - StringToPrimitiveConversionCheck.class, - StringToStringCheck.class, - StrongCipherAlgorithmCheck.class, - SubClassStaticReferenceCheck.class, - SuperfluousCurlyBraceCheck.class, - SuperfluousResponseBodyAnnotationCheck.class, - SuppressWarningsCheck.class, - SuspiciousListRemoveCheck.class, - SwitchCaseTooBigCheck.class, - SwitchDefaultLastCaseCheck.class, - SwitchInsteadOfIfSequenceCheck.class, - SwitchRedundantKeywordCheck.class, - SwitchWithLabelsCheck.class, - SwitchWithTooManyCasesCheck.class, - SymmetricEqualsCheck.class, - SyncGetterAndSetterCheck.class, - SynchronizationOnGetClassCheck.class, - SynchronizationOnStringOrBoxedCheck.class, - SynchronizedClassUsageCheck.class, - SynchronizedFieldAssignmentCheck.class, - SynchronizedLockCheck.class, - SynchronizedOverrideCheck.class, - SystemExitCalledCheck.class, - SystemOutOrErrUsageCheck.class, - TabCharacterCheck.class, - TernaryOperatorCheck.class, - TestsInSeparateFolderCheck.class, - TextBlockTabsAndSpacesCheck.class, - TextBlocksInComplexExpressionsCheck.class, - ThisExposedFromConstructorCheck.class, - ThreadAsRunnableArgumentCheck.class, - ThreadLocalCleanupCheck.class, - ThreadLocalWithInitialCheck.class, - ThreadOverridesRunCheck.class, - ThreadRunCheck.class, - ThreadSleepCheck.class, - ThreadStartedInConstructorCheck.class, - ThreadWaitCallCheck.class, - ThrowCheckedExceptionCheck.class, - ThrowsSeveralCheckedExceptionCheck.class, - ToArrayCheck.class, - ToStringReturningNullCheck.class, - ToStringUsingBoxingCheck.class, - TooLongLineCheck.class, - TooManyLinesOfCodeInFileCheck.class, - TooManyMethodsCheck.class, - TooManyParametersCheck.class, - TooManyStatementsPerLineCheck.class, - TrailingCommentCheck.class, - TransactionalMethodVisibilityCheck.class, - TransientFieldInNonSerializableCheck.class, - TryWithResourcesCheck.class, - TwoLocksWaitCheck.class, - TypeUpperBoundNotFinalCheck.class, - URLHashCodeAndEqualsCheck.class, - UnderscoreMisplacedOnNumberCheck.class, - UnderscoreOnNumberCheck.class, - AndroidUnencryptedDatabaseCheck.class, - UnicodeAwareCharClassesCheck.class, - UnicodeCaseCheck.class, - UnnecessaryEscapeSequencesInTextBlockCheck.class, - UnnecessarySemicolonCheck.class, - UnpredictableSaltCheck.class, - UnquantifiedNonCapturingGroupCheck.class, - UnreachableCatchCheck.class, - UnusedGroupNamesCheck.class, - UnusedLabelCheck.class, - UnusedPrivateClassCheck.class, - UnusedReturnedDataCheck.class, - UnusedThrowableCheck.class, - UnusedTypeParameterCheck.class, - UppercaseSuffixesCheck.class, - UseMotionSensorWithoutGyroscopeCheck.class, - UseSwitchExpressionCheck.class, - UselessExtendsCheck.class, - UselessIncrementCheck.class, - UserEnumerationCheck.class, - UtilityClassWithPublicConstructorCheck.class, - ValueAnnotationShouldInjectPropertyOrSpELCheck.class, - ValueBasedObjectUsedForLockCheck.class, - ValueBasedObjectsShouldNotBeSerializedCheck.class, - VarArgCheck.class, - VarCanBeUsedCheck.class, - VariableDeclarationScopeCheck.class, - VerboseRegexCheck.class, - VerifiedServerHostnamesCheck.class, - VirtualThreadNotSynchronizedCheck.class, - VirtualThreadUnsupportedMethodsCheck.class, - VisibleForTestingUsageCheck.class, - VolatileNonPrimitiveFieldCheck.class, - VolatileVariablesOperationsCheck.class, - WaitInSynchronizeCheck.class, - WaitInWhileLoopCheck.class, - WaitOnConditionCheck.class, - WeakSSLContextCheck.class, - WebViewJavaScriptSupportCheck.class, - WebViewsFileAccessCheck.class, - WildcardImportsShouldNotBeUsedCheck.class, - WildcardReturnParameterTypeCheck.class, - WriteObjectTheOnlySynchronizedMethodCheck.class, - WrongAssignmentOperatorCheck.class, - XxeActiveMQCheck.class, - ZipEntryCheck.class, - - // slow JavaFileScanner (not IssuableSubscriptionVisitor) ordered from the fastest to the slowest - IncrementDecrementInSubExpressionCheck.class, - StringLiteralDuplicatedCheck.class, - LoggersDeclarationCheck.class, - AssignmentInSubExpressionCheck.class, - SeveralBreakOrContinuePerLoopCheck.class, - ClassCouplingCheck.class, - AnonymousClassesTooBigCheck.class, - CatchUsesExceptionWithContextCheck.class, - ForLoopCounterChangedCheck.class, - MutableMembersUsageCheck.class, - LambdaTooBigCheck.class, - CollectionImplementationReferencedCheck.class, - NestedTryCatchCheck.class, - StaticMethodCheck.class, - AnonymousClassShouldBeLambdaCheck.class, - SwitchAtLeastThreeCasesCheck.class, - DepthOfInheritanceTreeCheck.class, - CatchNPECheck.class, - CollectionIsEmptyCheck.class, - CompareObjectWithEqualsCheck.class, - StringConcatenationInLoopCheck.class, - DisallowedThreadGroupCheck.class, - ClassVariableVisibilityCheck.class, - PublicStaticFieldShouldBeFinalCheck.class, - UndocumentedApiCheck.class, - BadClassNameCheck.class, - LazyArgEvaluationCheck.class, - BoxedBooleanExpressionsCheck.class, - ThrowsFromFinallyCheck.class, - TypeParametersShadowingCheck.class, - ParsingErrorCheck.class, - NullShouldNotBeUsedWithOptionalCheck.class, - ReturnInFinallyCheck.class, - CollectionsEmptyConstantsCheck.class, - CompareStringsBoxedTypesWithEqualsCheck.class, - FieldNameMatchingTypeNameCheck.class, - SunPackagesUsedCheck.class, - ConcatenationWithStringValueOfCheck.class, - EmptyFileCheck.class, - MissingNewLineAtEndOfFileCheck.class, - InnerStaticClassesCheck.class, - MathOnFloatCheck.class, - CastArithmeticOperandCheck.class, - NestedBlocksCheck.class, - HardcodedIpCheck.class, - UselessPackageInfoCheck.class, - BadPackageNameCheck.class, - RepeatAnnotationCheck.class, - OctalValuesCheck.class, - DuplicateConditionIfElseIfCheck.class, - IndentationAfterConditionalCheck.class, - RawByteBitwiseOperationsCheck.class, - StringBufferAndBuilderWithCharCheck.class, - InsecureCreateTempFileCheck.class, - KeywordAsIdentifierCheck.class, - MultilineBlocksCurlyBracesCheck.class, - PrimitiveTypeBoxingWithToStringCheck.class, - EnumMapCheck.class, - LeftCurlyBraceStartLineCheck.class, - DisallowedClassCheck.class, - ParameterReassignedToCheck.class); - - private static final List> JAVA_TEST_CHECKS = Arrays.asList( - // Rule classes are listed alphabetically - AssertionArgumentOrderCheck.class, - AssertionCompareToSelfCheck.class, - AssertionFailInCatchBlockCheck.class, - AssertionInThreadRunCheck.class, - AssertionInTryCatchCheck.class, - AssertionsCompletenessCheck.class, - AssertionsInTestsCheck.class, - AssertionTypesCheck.class, - AssertionsWithoutMessageCheck.class, - AssertJApplyConfigurationCheck.class, - AssertJAssertionsInConsumerCheck.class, - AssertJChainSimplificationCheck.class, - AssertJConsecutiveAssertionCheck.class, - AssertJContextBeforeAssertionCheck.class, - AssertJTestForEmptinessCheck.class, - AssertThatThrownByAloneCheck.class, - AssertTrueInsteadOfDedicatedAssertCheck.class, - BadTestClassNameCheck.class, - BadTestMethodNameCheck.class, - BooleanOrNullLiteralInAssertionsCheck.class, - CallSuperInTestCaseCheck.class, - ExpectedExceptionCheck.class, - IgnoredTestsCheck.class, - JUnitCompatibleAnnotationsCheck.class, - JUnit4AnnotationsCheck.class, - JUnit45MethodAnnotationCheck.class, - JUnit5DefaultPackageClassAndMethodCheck.class, - JUnit5SilentlyIgnoreClassAndMethodCheck.class, - JunitNestedAnnotationCheck.class, - MockingAllMethodsCheck.class, - MockitoAnnotatedObjectsShouldBeInitializedCheck.class, - MockitoArgumentMatchersUsedOnAllParametersCheck.class, - MockitoEqSimplificationCheck.class, - NoTestInTestClassCheck.class, - OneExpectedCheckedExceptionCheck.class, - OneExpectedRuntimeExceptionCheck.class, - RandomizedTestDataCheck.class, - SpringAssertionsSimplificationCheck.class, - ParameterizedTestCheck.class, - TestAnnotationWithExpectedExceptionCheck.class, - TestsStabilityCheck.class, - ThreadSleepInTestsCheck.class, - TooManyAssertionsCheck.class, - UnusedTestRuleCheck.class); - - private static final List> JAVA_MAIN_AND_TEST_CHECKS = Arrays.asList( - ArrayDesignatorOnVariableCheck.class, - BadConstantNameCheck.class, - BadFieldNameCheck.class, - BadFieldNameStaticNonFinalCheck.class, - BadInterfaceNameCheck.class, - BadLocalVariableNameCheck.class, - BadTypeParameterNameCheck.class, - CallToDeprecatedCodeMarkedForRemovalCheck.class, - CallToDeprecatedMethodCheck.class, - CollapsibleIfCandidateCheck.class, - CollectorsToListCheck.class, - CommentedOutCodeLineCheck.class, - DeadStoreCheck.class, - DefaultPackageCheck.class, - EmptyBlockCheck.class, - EmptyMethodsCheck.class, - EmptyStatementUsageCheck.class, - FixmeTagPresenceCheck.class, - HiddenFieldCheck.class, - ImmediatelyReturnedVariableCheck.class, - LambdaOptionalParenthesisCheck.class, - MethodIdenticalImplementationsCheck.class, - MethodNameSameAsClassCheck.class, - MismatchPackageDirectoryCheck.class, - ModifiersOrderCheck.class, - OverrideAnnotationCheck.class, - PrintfMisuseCheck.class, - RedundantThrowsDeclarationCheck.class, - ReplaceGuavaWithJavaCheck.class, - RestrictedIdentifiersUsageCheck.class, - StringConcatToTextBlockCheck.class, - SwitchCasesShouldBeCommaSeparatedCheck.class, - SwitchCaseWithoutBreakCheck.class, - TodoTagPresenceCheck.class, - UnusedLocalVariableCheck.class, - UnusedMethodParameterCheck.class, - UnusedPrivateFieldCheck.class, - UnusedPrivateMethodCheck.class, - UselessParenthesesCheck.class, - UselessImportCheck.class, - SwitchLastCaseIsDefaultCheck.class); - - private static final List> ALL_CHECKS = Stream.of(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS) - .flatMap(List::stream) - .sorted(Comparator.comparing(Class::getSimpleName)) - .collect(Collectors.toList()); - - private static final Set> JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN = Set.of( - // Symbolic executions rules are not in this list because they are dynamically excluded - // Rules relying on correct setup of jdk.home - CallToDeprecatedCodeMarkedForRemovalCheck.class, - CallToDeprecatedMethodCheck.class, - // Rules relying on correct setup of java version - AbstractClassNoFieldShouldBeInterfaceCheck.class, - AnonymousClassShouldBeLambdaCheck.class, - CombineCatchCheck.class, - DateAndTimesCheck.class, - DateUtilsTruncateCheck.class, - DiamondOperatorCheck.class, - InsecureCreateTempFileCheck.class, - JdbcDriverExplicitLoadingCheck.class, - LambdaOptionalParenthesisCheck.class, - LambdaSingleExpressionCheck.class, - RepeatAnnotationCheck.class, - ReplaceGuavaWithJavaCheck.class, - ReplaceLambdaByMethodRefCheck.class, - SwitchInsteadOfIfSequenceCheck.class, - ThreadLocalWithInitialCheck.class, - TryWithResourcesCheck.class, - ValueBasedObjectUsedForLockCheck.class, - // Rules with a high deviation (>3%) - AccessibilityChangeCheck.class, - CipherBlockChainingCheck.class, - ClassNamedLikeExceptionCheck.class, - ClassWithOnlyStaticMethodsInstantiationCheck.class, - CollectionInappropriateCallsCheck.class, - DeadStoreCheck.class, - EqualsArgumentTypeCheck.class, - EqualsNotOverridenWithCompareToCheck.class, - EqualsOverridenWithHashCodeCheck.class, - ForLoopVariableTypeCheck.class, - JWTWithStrongCipherCheck.class, - MethodNamedEqualsCheck.class, - NioFileDeleteCheck.class, - PrivateFieldUsedLocallyCheck.class, - SillyEqualsCheck.class, - StandardCharsetsConstantsCheck.class, - ThreadLocalCleanupCheck.class, - ThreadOverridesRunCheck.class, - UnusedPrivateClassCheck.class, - UnusedPrivateFieldCheck.class, - VerifiedServerHostnamesCheck.class, - VolatileNonPrimitiveFieldCheck.class, - WeakSSLContextCheck.class); - - private CheckList() { - } - - public static List> getChecks() { - return ALL_CHECKS; - } - - public static List> getJavaChecks() { - return sortedJoin(JAVA_MAIN_CHECKS, JAVA_MAIN_AND_TEST_CHECKS); - } - - public static List> getJavaTestChecks() { - return sortedJoin(JAVA_MAIN_AND_TEST_CHECKS, JAVA_TEST_CHECKS); - } - - public static Set> getJavaChecksNotWorkingForAutoScan() { - return JAVA_CHECKS_NOT_WORKING_FOR_AUTOSCAN; - } - - @SafeVarargs - private static List> sortedJoin(List>... lists) { - return Arrays.stream(lists) - .flatMap(List::stream) - .sorted(Comparator.comparing(Class::getSimpleName)) - .toList(); - } -} diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/CheckListTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/CheckListTest.java deleted file mode 100644 index 392cf9bc801..00000000000 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/CheckListTest.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * SonarQube Java - * Copyright (C) 2012-2024 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.java; - -import com.google.gson.Gson; -import java.io.File; -import java.io.FileReader; -import java.lang.reflect.Constructor; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.Test; -import org.sonar.api.server.rule.RulesDefinition; -import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; -import org.sonar.api.utils.AnnotationUtils; -import org.sonar.check.Rule; -import org.sonar.plugins.java.api.JavaCheck; -import org.sonarsource.analyzer.commons.collections.SetUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Fail.fail; - -class CheckListTest { - - private static final String ARTIFICIAL_DESCRIPTION = "-1"; - - private final Gson gson = new Gson(); - - private static final Set BLACK_LIST = SetUtils.immutableSetOf( - "AbstractXPathBasedCheck.java", - "AbstractWebXmlXPathBasedCheck.java", - "AbstractRegexCheck.java"); - - /** - * Enforces that each check declared in list. - */ - @Test - void count() { - int count = 0; - List files = getCheckFiles(); - for (File file : files) { - if (file.getName().endsWith("Check.java") && !BLACK_LIST.contains(file.getName())) { - count++; - } - } - assertThat(CheckList.getChecks()).hasSize(count); - } - - private static List getCheckFiles() { - List files = (List) FileUtils.listFiles(new File("../java-checks/src/main/java/org/sonar/java/checks/"), new String[] {"java"}, true); - files.addAll(FileUtils.listFiles(new File("../java-checks-aws/src/main/java/org/sonar/java/checks/"), new String[] {"java"}, true)); - return files; - } - - @Test - void min_check_count() { - assertThat(CheckList.getJavaChecks()).hasSizeGreaterThan(500); - assertThat(CheckList.getJavaTestChecks()).hasSizeGreaterThan(40); - assertThat(CheckList.getJavaChecksNotWorkingForAutoScan()).hasSizeGreaterThan(40); - assertThat(CheckList.getChecks()).hasSizeGreaterThan(600); - } - - private static class CustomRulesDefinition implements RulesDefinition { - - @Override - public void define(Context context) { - String language = "java"; - NewRepository repository = context - .createRepository(CheckList.REPOSITORY_KEY, language) - .setName("SonarQube"); - - List> checks = CheckList.getChecks(); - new RulesDefinitionAnnotationLoader().load(repository, checks.toArray(new Class[checks.size()])); - - for (NewRule rule : repository.rules()) { - try { - rule.setName("Artificial Name (set via JSON files, no need to test it)"); - rule.setMarkdownDescription(ARTIFICIAL_DESCRIPTION); - } catch (IllegalStateException e) { - // it means that the html description was already set in Rule annotation - fail("Description of " + rule.key() + " should be in separate file"); - } - } - repository.done(); - } - } - - /** - * Enforces that each check has test, name and description. - */ - @Test - void test() { - Map keyMap = new HashMap<>(); - for (Class cls : CheckList.getChecks()) { - String testName = '/' + cls.getName().replace('.', '/') + "Test.java"; - List checkModules = List.of("java-checks", "java-checks-aws"); - - String simpleName = cls.getSimpleName(); - // Handle legacy keys. - Rule ruleAnnotation = AnnotationUtils.getAnnotation(cls, Rule.class); - keyMap.put(ruleAnnotation.key(), ruleAnnotation.key()); - assertThat(checkModules.stream() - .anyMatch(module -> Files.exists(Path.of("../", module, "src/test/java", testName)))) - .overridingErrorMessage("No test for " + simpleName) - .isTrue(); - } - - Set keys = new HashSet<>(); - Set names = new HashSet<>(); - CustomRulesDefinition definition = new CustomRulesDefinition(); - RulesDefinition.Context context = new RulesDefinition.Context(); - definition.define(context); - List rules = context.repository(CheckList.REPOSITORY_KEY).rules(); - for (RulesDefinition.Rule rule : rules) { - assertThat(keys).as("Duplicate key " + rule.key()).doesNotContain(rule.key()); - keys.add(rule.key()); - names.add(rule.name()); - assertThat(getClass().getResource("/org/sonar/l10n/java/rules/" + CheckList.REPOSITORY_KEY + "/" + keyMap.get(rule.key()) + ".html")) - .overridingErrorMessage("No description for " + rule.key() + " " + keyMap.get(rule.key())) - .isNotNull(); - assertThat(getClass().getResource("/org/sonar/l10n/java/rules/" + CheckList.REPOSITORY_KEY + "/" + keyMap.get(rule.key()) + ".json")) - .overridingErrorMessage("No json metadata file for " + rule.key() + " " + keyMap.get(rule.key())) - .isNotNull(); - - assertThat(rule.htmlDescription()).isNull(); - assertThat(rule.markdownDescription()).isEqualTo(ARTIFICIAL_DESCRIPTION); - - for (RulesDefinition.Param param : rule.params()) { - assertThat(param.description()).overridingErrorMessage(rule.key() + " missing description for param " + param.key()).isNotEmpty(); - } - } - } - - @Test - void enforce_CheckList_registration() { - List files = getCheckFiles(); - List> checks = CheckList.getChecks(); - files.stream() - .filter(file -> file.getName().endsWith("Check.java")) - .filter(file -> !file.getName().startsWith("Abstract")) - .map(File::getAbsolutePath) - .map(f -> f.replace(File.separatorChar, '.')) - .map(f -> f.substring(f.indexOf("org.sonar.java.checks"), f.length() - 5)) - .forEach(className -> { - try { - Class aClass = Class.forName(className); - assertThat(checks).as(className + " is not declared in CheckList").contains(aClass); - } catch (ClassNotFoundException e) { - throw new IllegalStateException(e); - } - }); - } - - @Test - void rules_targeting_tests_should_have_tests_tag() throws Exception { - Set> testChecks = new HashSet<>(CheckList.getJavaTestChecks()); - Set> mainChecks = new HashSet<>(CheckList.getJavaChecks()); - - for (Class cls : CheckList.getChecks()) { - String key = AnnotationUtils.getAnnotation(cls, Rule.class).key(); - URL metadataURL = getClass().getResource("/org/sonar/l10n/java/rules/" + CheckList.REPOSITORY_KEY + "/" + key + ".json"); - File metadataFile = new File(metadataURL.toURI()); - assertThat(metadataFile).exists(); - try (FileReader jsonReader = new FileReader(metadataFile)) { - DummyMetatada metadata = gson.fromJson(jsonReader, DummyMetatada.class); - - if (!"deprecated".equals(metadata.status)) { - // deprecated rules usually have no tags - if ((testChecks.contains(cls) && !mainChecks.contains(cls)) || "S3414".equals(key)) { - assertThat(metadata.tags) - .as("Rule " + key + " is targeting tests sources and should contain the 'tests' tag.") - .contains("tests"); - } else { - assertThat(metadata.tags) - .as("Rule " + key + " is targeting main sources and should not contain the 'tests' tag.") - .doesNotContain("tests"); - } - } - } - } - } - - private static class DummyMetatada { - // ignore all the other fields - String[] tags; - String status; - } - - @Test - void private_constructor() throws Exception { - Constructor constructor = CheckList.class.getDeclaredConstructor(); - assertThat(constructor.isAccessible()).isFalse(); - constructor.setAccessible(true); - constructor.newInstance(); - } - -} diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java index b7a23a45e8e..140dd315b16 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/GeneratedCheckListTest.java @@ -182,7 +182,7 @@ void rules_targeting_tests_should_have_tests_tag() throws Exception { for (Class cls : GeneratedCheckList.getChecks()) { String key = AnnotationUtils.getAnnotation(cls, Rule.class).key(); - URL metadataURL = getClass().getResource("/org/sonar/l10n/java/rules/" + CheckList.REPOSITORY_KEY + "/" + key + ".json"); + URL metadataURL = getClass().getResource("/org/sonar/l10n/java/rules/" + GeneratedCheckList.REPOSITORY_KEY + "/" + key + ".json"); File metadataFile = new File(metadataURL.toURI()); assertThat(metadataFile).exists(); try (FileReader jsonReader = new FileReader(metadataFile)) { From 4ba50bbb67f8418eb6b675973b84e1067ed2f0ef Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Mon, 24 Jun 2024 11:57:59 +0200 Subject: [PATCH 25/26] Remove update of scope to "All". Done in #4825 PR --- .../main/resources/org/sonar/l10n/java/rules/java/S1135.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json index 1f6d301fbb8..0d125cfc446 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json @@ -18,7 +18,7 @@ "defaultSeverity": "Info", "ruleSpecification": "RSPEC-1135", "sqKey": "S1135", - "scope": "All", + "scope": "Main", "securityStandards": { "CWE": [ 546 From 764904665b6ac278d4850d2591079104e7d33ffd Mon Sep 17 00:00:00 2001 From: Irina Batinic Date: Mon, 24 Jun 2024 12:25:46 +0200 Subject: [PATCH 26/26] Merge with master --- .../main/resources/org/sonar/l10n/java/rules/java/S1135.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json index 0d125cfc446..1f6d301fbb8 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S1135.json @@ -18,7 +18,7 @@ "defaultSeverity": "Info", "ruleSpecification": "RSPEC-1135", "sqKey": "S1135", - "scope": "Main", + "scope": "All", "securityStandards": { "CWE": [ 546