diff --git a/.gitignore b/.gitignore index 3633a5c..087d239 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ !.gitattributes !.github/ !.default.docker.env +!.vscode/ +!.idea/ # Ignore generated files target diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..fa1988e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,6 @@ +# Ignore all +* +# Except those files +!.gitignore +!externalDependencies.xml +!google-java-format.xml diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml new file mode 100644 index 0000000..37ac53f --- /dev/null +++ b/.idea/externalDependencies.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml new file mode 100644 index 0000000..8b57f45 --- /dev/null +++ b/.idea/google-java-format.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.vscode/.gitignore b/.vscode/.gitignore new file mode 100644 index 0000000..bdd9ee2 --- /dev/null +++ b/.vscode/.gitignore @@ -0,0 +1,6 @@ +# Ignore all +* +# Except those files +!__gitignore__ +!.gitignore +!extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..9ec6d94 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "josevseb.google-java-format-for-vs-code", + ] +} diff --git a/pom.xml b/pom.xml index a0daed8..db37e31 100644 --- a/pom.xml +++ b/pom.xml @@ -1,507 +1,540 @@ - 4.0.0 + 4.0.0 org.green-code-initiative creedengo-java-plugin 2.1.1-SNAPSHOT - sonar-plugin - - creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs - 2024 - + sonar-plugin + + creedengo - Java language + Provides rules to reduce the environmental footprint of your Java programs + + https://github.com/green-code-initiative/creedengo-java + 2024 + + green-code-initiative + https://github.com/green-code-initiative + + + + + GPL v3 + https://www.gnu.org/licenses/gpl-3.0.en.html + repo + + + + + scm:git:https://github.com/green-code-initiative/creedengo-java + scm:git:https://github.com/green-code-initiative/creedengo-java + HEAD https://github.com/green-code-initiative/creedengo-java - - green-code-initiative - https://github.com/green-code-initiative - - - - - GPL v3 - https://www.gnu.org/licenses/gpl-3.0.en.html - repo - - - - - scm:git:https://github.com/green-code-initiative/creedengo-java - scm:git:https://github.com/green-code-initiative/creedengo-java - https://github.com/green-code-initiative/creedengo-java - HEAD - - - - GitHub - https://github.com/green-code-initiative/creedengo-java/issues - - - - - 11 - ${java.version} - ${java.version} - - ${java.version} - - UTF-8 - ${encoding} - ${encoding} - - green-code-initiative - https://sonarcloud.io - - - 9.9.7.96285 - - 9.8.0.203 - - - 7.16.0.30901 - - 2.5.0.1358 - - 1.23.0.740 - - 5.9.1 - 3.23.1 - 5.3.1 - - 1.7 - - - 2.1.0 - - - https://repo1.maven.org/maven2 - - false - - - ${sonarqube.version} - - - ${sonarjava.version} - - - - - - - - org.green-code-initiative - creedengo-rules-specifications - ${creedengo-rules-specifications.version} - java - - - - org.sonarsource.java - sonar-java-plugin - ${sonarjava.version} - sonar-plugin - provided - - - - org.sonarsource.api.plugin - sonar-plugin-api - ${sonar.plugin.api.version} - provided - - - - org.sonarsource.analyzer-commons - sonar-analyzer-commons - ${sonar-analyzer-commons.version} - - - - - com.google.re2j - re2j - ${google.re2j} - - - - - org.sonarsource.java - java-checks-testkit - ${sonarjava.version} - test - - - - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test - - - - org.assertj - assertj-core - ${assertJ.version} - test - - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - - org.reflections - reflections - 0.10.2 - test - - - - - org.sonarsource.orchestrator - sonar-orchestrator-junit5 - 5.1.0.2254 - test - - - org.sonarsource.java - test-classpath-reader - 8.8.0.37665 - test - - - org.sonarsource.sonarqube - sonar-ws - ${sonarqube.version} - test - - - io.github.jycr - java-data-url-handler - 0.0.1 - test - - - org.slf4j - slf4j-api - 2.0.13 - test - - - ch.qos.logback - logback-classic - 1.5.6 - test - - - org.projectlombok - lombok - 1.18.36 - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.5.2 - - - org.jacoco - jacoco-maven-plugin - 0.8.12 - - - prepare-agent - - prepare-agent - - - - report - - report - - - - - - org.sonarsource.sonar-packaging-maven-plugin - sonar-packaging-maven-plugin - ${sonar-packaging.version} - true - - creedengojava - org.greencodeinitiative.creedengo.java.JavaPlugin - true - ${sonarqube.version} - true - ${java.version} - java - - - ${buildNumber} - - - - - - - org.codehaus.mojo - buildnumber-maven-plugin - 3.2.1 - - - validate - - create - - - - - true - 0 - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - package - - shade - - - false - true - false - - - org.sonarsource.analyzer-commons:sonar-analyzer-commons:* - - META-INF/** - - - - com.google.re2j:re2j:* - - META-INF/** - - - - org.green-code-initiative:creedengo-rules-specifications:* - - META-INF/** - - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.8.1 - - - - copy - test-compile - - copy - - - - - org.slf4j - slf4j-api - 1.7.30 - jar - - - org.apache.commons - commons-collections4 - 4.0 - jar - - - javax - javaee-api - 6.0 - jar - - - org.springframework - spring-webmvc - 5.2.3.RELEASE - jar - - - org.springframework - spring-web - 5.2.3.RELEASE - jar - - - org.springframework - spring-context - 5.2.3.RELEASE - jar - - - org.springframework.data - spring-data-jpa - 2.2.4.RELEASE - jar - - - org.springframework.data - spring-data-commons - 2.2.4.RELEASE - jar - - - ${project.build.directory}/test-jars - - - - - - com.mycila - license-maven-plugin - 4.6 - - - Green Code Initiative - https://green-code-initiative.org - - - -
com/mycila/maven/plugin/license/templates/GPL-3.txt
- - ${project.basedir}/src/**/*.java - - - ${project.basedir}/src/it/test-projects/** - -
-
-
- - - validate - - check - - validate - - -
- - - - org.codehaus.mojo - build-helper-maven-plugin - 3.6.0 - - - add-integration-test-sources - process-test-sources - - add-test-source - - - - ${project.basedir}/src/it/java - - - - - add-integration-test-resources - generate-test-resources - - add-test-resource - - - - - ${project.basedir}/src/it/resources - - - true - ${project.basedir}/src/it/resources-filtered - - - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 3.5.2 - - - - integration-test - verify - - - - ${test-it.sonarqube.keepRunning} - ${test-it.orchestrator.artifactory.url} - ${test-it.sonarqube.version} - ${test-it.sonarqube.port} - - - ${project.baseUri}/target/${project.artifactId}-${project.version}.jar, - org.sonarsource.java:sonar-java-plugin:${test-it.sonarjava.version}, - - - - ${project.baseUri}/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json, - - - - org.green-code-initiative:creedengo-java-plugin-test-project|creedengo Java Sonar Plugin Test Project|${project.baseUri}/src/it/test-projects/creedengo-java-plugin-test-project/pom.xml, - - - - java|creedengo way, - - - - - - -
-
- - - - keep-running - - true - - 33333 - - - +
+ + + GitHub + https://github.com/green-code-initiative/creedengo-java/issues + + + + + 11 + ${java.version} + ${java.version} + + ${java.version} + + UTF-8 + ${encoding} + ${encoding} + + green-code-initiative + https://sonarcloud.io + + + 9.9.7.96285 + + 9.8.0.203 + + + 7.16.0.30901 + + 2.5.0.1358 + + 1.23.0.740 + + 5.9.1 + 3.23.1 + 5.3.1 + + 1.7 + + + 2.1.0 + + + https://repo1.maven.org/maven2 + + false + + + ${sonarqube.version} + + + ${sonarjava.version} + + + + + + + + org.green-code-initiative + creedengo-rules-specifications + ${creedengo-rules-specifications.version} + java + + + + org.sonarsource.java + sonar-java-plugin + ${sonarjava.version} + sonar-plugin + provided + + + + org.sonarsource.api.plugin + sonar-plugin-api + ${sonar.plugin.api.version} + provided + + + + org.sonarsource.analyzer-commons + sonar-analyzer-commons + ${sonar-analyzer-commons.version} + + + + + com.google.re2j + re2j + ${google.re2j} + + + + + org.sonarsource.java + java-checks-testkit + ${sonarjava.version} + test + + + + org.junit.jupiter + junit-jupiter + ${junit.jupiter.version} + test + + + + org.assertj + assertj-core + ${assertJ.version} + test + + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + + org.reflections + reflections + 0.10.2 + test + + + + + org.sonarsource.orchestrator + sonar-orchestrator-junit5 + 5.1.0.2254 + test + + + org.sonarsource.java + test-classpath-reader + 8.8.0.37665 + test + + + org.sonarsource.sonarqube + sonar-ws + ${sonarqube.version} + test + + + io.github.jycr + java-data-url-handler + 0.0.1 + test + + + org.slf4j + slf4j-api + 2.0.13 + test + + + ch.qos.logback + logback-classic + 1.5.6 + test + + + org.projectlombok + lombok + 1.18.36 + test + + + + + + + com.diffplug.spotless + spotless-maven-plugin + 2.43.0 + + + + pom.xml + + + + + + 1.23.0 + + + + + + src/**/*.json + + + JSON + + + + true + 2 + + + + + + + + check + + process-sources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.2 + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + + + org.sonarsource.sonar-packaging-maven-plugin + sonar-packaging-maven-plugin + ${sonar-packaging.version} + true + + creedengojava + org.greencodeinitiative.creedengo.java.JavaPlugin + true + ${sonarqube.version} + true + ${java.version} + java + + + ${buildNumber} + + + + + + + org.codehaus.mojo + buildnumber-maven-plugin + 3.2.1 + + true + 0 + + + + + create + + validate + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.6.0 + + + + shade + + package + + false + true + false + + + org.sonarsource.analyzer-commons:sonar-analyzer-commons:* + + META-INF/** + + + + com.google.re2j:re2j:* + + META-INF/** + + + + org.green-code-initiative:creedengo-rules-specifications:* + + META-INF/** + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.8.1 + + + + copy + + copy + + test-compile + + + + org.slf4j + slf4j-api + 1.7.30 + jar + + + org.apache.commons + commons-collections4 + 4.0 + jar + + + javax + javaee-api + 6.0 + jar + + + org.springframework + spring-webmvc + 5.2.3.RELEASE + jar + + + org.springframework + spring-web + 5.2.3.RELEASE + jar + + + org.springframework + spring-context + 5.2.3.RELEASE + jar + + + org.springframework.data + spring-data-jpa + 2.2.4.RELEASE + jar + + + org.springframework.data + spring-data-commons + 2.2.4.RELEASE + jar + + + ${project.build.directory}/test-jars + + + + + + com.mycila + license-maven-plugin + 4.6 + + + Green Code Initiative + https://green-code-initiative.org + + + +
com/mycila/maven/plugin/license/templates/GPL-3.txt
+ + ${project.basedir}/src/**/*.java + + + ${project.basedir}/src/it/test-projects/** + +
+
+
+ + + validate + + check + + validate + + +
+ + + + org.codehaus.mojo + build-helper-maven-plugin + 3.6.0 + + + add-integration-test-sources + + add-test-source + + process-test-sources + + + ${project.basedir}/src/it/java + + + + + add-integration-test-resources + + add-test-resource + + generate-test-resources + + + + ${project.basedir}/src/it/resources + + + true + ${project.basedir}/src/it/resources-filtered + + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.2 + + + + integration-test + verify + + + + ${test-it.sonarqube.keepRunning} + ${test-it.orchestrator.artifactory.url} + ${test-it.sonarqube.version} + ${test-it.sonarqube.port} + + ${project.baseUri}/target/${project.artifactId}-${project.version}.jar, + org.sonarsource.java:sonar-java-plugin:${test-it.sonarjava.version}, + + ${project.baseUri}/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json, + + org.green-code-initiative:creedengo-java-plugin-test-project|creedengo Java Sonar Plugin Test Project|${project.baseUri}/src/it/test-projects/creedengo-java-plugin-test-project/pom.xml, + + java|creedengo way, + + + + + +
+
+ + + + keep-running + + true + + 33333 + + +
diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java index 791f0ce..45814b6 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java @@ -19,60 +19,55 @@ import java.util.Collections; import java.util.List; - import org.greencodeinitiative.creedengo.java.checks.*; import org.sonar.plugins.java.api.CheckRegistrar; import org.sonar.plugins.java.api.JavaCheck; import org.sonarsource.api.sonarlint.SonarLintSide; /** - * Provide the "checks" (implementations of rules) classes that are going be executed during - * source code analysis. - *

- * This class is a batch extension by implementing the {@link org.sonar.plugins.java.api.CheckRegistrar} interface. + * Provide the "checks" (implementations of rules) classes that are going be executed during source + * code analysis. + * + *

This class is a batch extension by implementing the {@link + * org.sonar.plugins.java.api.CheckRegistrar} interface. */ @SonarLintSide public class JavaCheckRegistrar implements CheckRegistrar { - static final List> ANNOTATED_RULE_CLASSES = List.of( - ArrayCopyCheck.class, - IncrementCheck.class, - AvoidUsageOfStaticCollections.class, - AvoidGettingSizeCollectionInLoop.class, - AvoidRegexPatternNotStatic.class, - NoFunctionCallWhenDeclaringForLoop.class, - AvoidStatementForDMLQueries.class, - AvoidSpringRepositoryCallInLoopOrStreamCheck.class, - AvoidSQLRequestInLoop.class, - AvoidFullSQLRequest.class, - OptimizeReadFileExceptions.class, - InitializeBufferWithAppropriateSize.class, - AvoidSetConstantInBatchUpdate.class, - FreeResourcesOfAutoCloseableInterface.class, - AvoidMultipleIfElseStatement.class, - UseOptionalOrElseGetVsOrElse.class, - MakeNonReassignedVariablesConstants.class - ); + static final List> ANNOTATED_RULE_CLASSES = + List.of( + ArrayCopyCheck.class, + IncrementCheck.class, + AvoidUsageOfStaticCollections.class, + AvoidGettingSizeCollectionInLoop.class, + AvoidRegexPatternNotStatic.class, + NoFunctionCallWhenDeclaringForLoop.class, + AvoidStatementForDMLQueries.class, + AvoidSpringRepositoryCallInLoopOrStreamCheck.class, + AvoidSQLRequestInLoop.class, + AvoidFullSQLRequest.class, + OptimizeReadFileExceptions.class, + InitializeBufferWithAppropriateSize.class, + AvoidSetConstantInBatchUpdate.class, + FreeResourcesOfAutoCloseableInterface.class, + AvoidMultipleIfElseStatement.class, + UseOptionalOrElseGetVsOrElse.class, + MakeNonReassignedVariablesConstants.class); - /** - * Register the classes that will be used to instantiate checks during analysis. - */ - @Override - public void register(RegistrarContext registrarContext) { - // Call to registerClassesForRepository to associate the classes with the correct repository key - registrarContext.registerClassesForRepository(JavaRulesDefinition.REPOSITORY_KEY, checkClasses(), testCheckClasses()); - } + /** Register the classes that will be used to instantiate checks during analysis. */ + @Override + public void register(RegistrarContext registrarContext) { + // Call to registerClassesForRepository to associate the classes with the correct repository key + registrarContext.registerClassesForRepository( + JavaRulesDefinition.REPOSITORY_KEY, checkClasses(), testCheckClasses()); + } - /** - * Lists all the main checks provided by the plugin - */ - public static List> checkClasses() { - return ANNOTATED_RULE_CLASSES; - } + /** Lists all the main checks provided by the plugin */ + public static List> checkClasses() { + return ANNOTATED_RULE_CLASSES; + } - /** - * Lists all the test checks provided by the plugin - */ - public static List> testCheckClasses() { - return Collections.emptyList(); - } + /** Lists all the test checks provided by the plugin */ + public static List> testCheckClasses() { + return Collections.emptyList(); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfile.java b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfile.java index 3d48034..5a27e0d 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfile.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfile.java @@ -17,24 +17,27 @@ */ package org.greencodeinitiative.creedengo.java; -import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; -import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader; - import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.LANGUAGE; import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.REPOSITORY_KEY; +import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; +import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader; + public final class JavaCreedengoWayProfile implements BuiltInQualityProfilesDefinition { - static final String PROFILE_NAME = "creedengo way"; - static final String PROFILE_PATH = JavaCreedengoWayProfile.class.getPackageName().replace('.', '/') + "/creedengo_way_profile.json"; + static final String PROFILE_NAME = "creedengo way"; + static final String PROFILE_PATH = + JavaCreedengoWayProfile.class.getPackageName().replace('.', '/') + + "/creedengo_way_profile.json"; - @Override - public void define(Context context) { - NewBuiltInQualityProfile creedengoProfile = context.createBuiltInQualityProfile(PROFILE_NAME, LANGUAGE); - loadProfile(creedengoProfile); - creedengoProfile.done(); - } + @Override + public void define(Context context) { + NewBuiltInQualityProfile creedengoProfile = + context.createBuiltInQualityProfile(PROFILE_NAME, LANGUAGE); + loadProfile(creedengoProfile); + creedengoProfile.done(); + } - private void loadProfile(NewBuiltInQualityProfile profile) { - BuiltInQualityProfileJsonLoader.load(profile, REPOSITORY_KEY, PROFILE_PATH); - } + private void loadProfile(NewBuiltInQualityProfile profile) { + BuiltInQualityProfileJsonLoader.load(profile, REPOSITORY_KEY, PROFILE_PATH); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/JavaPlugin.java b/src/main/java/org/greencodeinitiative/creedengo/java/JavaPlugin.java index ce2a95c..5dde796 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/JavaPlugin.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/JavaPlugin.java @@ -21,14 +21,12 @@ public class JavaPlugin implements Plugin { - @Override - public void define(Context context) { - // server extensions -> objects are instantiated during server startup - context.addExtension(JavaRulesDefinition.class); - - // batch extensions -> objects are instantiated during code analysis - context.addExtension(JavaCheckRegistrar.class); - - } + @Override + public void define(Context context) { + // server extensions -> objects are instantiated during server startup + context.addExtension(JavaRulesDefinition.class); + // batch extensions -> objects are instantiated during code analysis + context.addExtension(JavaCheckRegistrar.class); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinition.java b/src/main/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinition.java index ff30929..42c2db7 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinition.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinition.java @@ -18,39 +18,40 @@ package org.greencodeinitiative.creedengo.java; import java.util.ArrayList; - import org.sonar.api.SonarRuntime; import org.sonar.api.server.rule.RulesDefinition; import org.sonarsource.analyzer.commons.RuleMetadataLoader; /** - * Declare rule metadata in server repository of rules. - * That allows to list the rules in the page "Rules". + * Declare rule metadata in server repository of rules. That allows to list the rules in the page + * "Rules". */ public class JavaRulesDefinition implements RulesDefinition { - private static final String RESOURCE_BASE_PATH = "org/green-code-initiative/rules/java"; + private static final String RESOURCE_BASE_PATH = "org/green-code-initiative/rules/java"; - private static final String NAME = "creedengo"; - static final String LANGUAGE = "java"; - static final String REPOSITORY_KEY = "creedengo-java"; + private static final String NAME = "creedengo"; + static final String LANGUAGE = "java"; + static final String REPOSITORY_KEY = "creedengo-java"; - private final SonarRuntime sonarRuntime; + private final SonarRuntime sonarRuntime; - public JavaRulesDefinition(SonarRuntime sonarRuntime) { - this.sonarRuntime = sonarRuntime; - } + public JavaRulesDefinition(SonarRuntime sonarRuntime) { + this.sonarRuntime = sonarRuntime; + } - @Override - public void define(Context context) { - NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME); + @Override + public void define(Context context) { + NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME); - RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, sonarRuntime); + RuleMetadataLoader ruleMetadataLoader = + new RuleMetadataLoader(RESOURCE_BASE_PATH, sonarRuntime); - ruleMetadataLoader.addRulesByAnnotatedClass(repository, new ArrayList<>(JavaCheckRegistrar.checkClasses())); - repository.done(); - } + ruleMetadataLoader.addRulesByAnnotatedClass( + repository, new ArrayList<>(JavaCheckRegistrar.checkClasses())); + repository.done(); + } - public String repositoryKey() { - return REPOSITORY_KEY; - } + public String repositoryKey() { + return REPOSITORY_KEY; + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheck.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheck.java index bc4d569..c8fa804 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheck.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheck.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree; @@ -58,245 +57,262 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRPS0027") public class ArrayCopyCheck extends IssuableSubscriptionVisitor { - //@formatter:on - protected static final String MESSAGERULE = "Use System.arraycopy to copy arrays"; + // @formatter:on + protected static final String MESSAGERULE = "Use System.arraycopy to copy arrays"; - @Override - public List nodesToVisit() { - return Arrays.asList(Kind.FOR_STATEMENT, Kind.WHILE_STATEMENT, Kind.DO_STATEMENT, Kind.FOR_EACH_STATEMENT); - } + @Override + public List nodesToVisit() { + return Arrays.asList( + Kind.FOR_STATEMENT, Kind.WHILE_STATEMENT, Kind.DO_STATEMENT, Kind.FOR_EACH_STATEMENT); + } - /** - * Check a node. Report issue when found. - */ - @Override - public void visitNode(final Tree tree) { - // Determine blocks to be analyzed - final List blocs = getBlocsOfCode(tree); + /** Check a node. Report issue when found. */ + @Override + public void visitNode(final Tree tree) { + // Determine blocks to be analyzed + final List blocs = getBlocsOfCode(tree); - // Analyze blocks - for (final Bloc bloc : blocs) { - if (bloc.isForeach()) { - handleForEachAssignments(tree, bloc); - } - handleAssignments(tree, bloc); - } + // Analyze blocks + for (final Bloc bloc : blocs) { + if (bloc.isForeach()) { + handleForEachAssignments(tree, bloc); + } + handleAssignments(tree, bloc); } + } - /** - * Handle for-each assignments controls. - * - * @param tree - * @param bloc - */ - private void handleForEachAssignments(final Tree tree, final Bloc bloc) { - for (final AssignmentExpressionTree assignment : extractAssignments(tree, bloc)) { - final ExpressionTree destination = assignment.variable(); - final ExpressionTree source = assignment.expression(); - if (isArray(destination) && isVariable(source)) { - final String destinationIdentifier = getArrayIdentifier(destination); - final String sourceIdentifier = ((IdentifierTree) source).name(); - if (bloc.getValue().equals(sourceIdentifier) && !bloc.getIterable().equals(destinationIdentifier)) { - reportIssue(tree, MESSAGERULE); - } - } + /** + * Handle for-each assignments controls. + * + * @param tree + * @param bloc + */ + private void handleForEachAssignments(final Tree tree, final Bloc bloc) { + for (final AssignmentExpressionTree assignment : extractAssignments(tree, bloc)) { + final ExpressionTree destination = assignment.variable(); + final ExpressionTree source = assignment.expression(); + if (isArray(destination) && isVariable(source)) { + final String destinationIdentifier = getArrayIdentifier(destination); + final String sourceIdentifier = ((IdentifierTree) source).name(); + if (bloc.getValue().equals(sourceIdentifier) + && !bloc.getIterable().equals(destinationIdentifier)) { + reportIssue(tree, MESSAGERULE); } + } } + } - /** - * Handle assignments controls. - * - * @param tree - * @param bloc - */ - private void handleAssignments(final Tree tree, final Bloc bloc) { - for (final AssignmentExpressionTree assignment : extractAssignments(tree, bloc)) { - final ExpressionTree destVariable = assignment.variable(); - final ExpressionTree srcEspression = assignment.expression(); - if (isArray(destVariable) && isArray(srcEspression)) { - final String destArray = getArrayIdentifier(destVariable); - final String srcArray = getArrayIdentifier(srcEspression); - if (destArray != null && !destArray.equals(srcArray)) { - reportIssue(tree, MESSAGERULE); - } - } + /** + * Handle assignments controls. + * + * @param tree + * @param bloc + */ + private void handleAssignments(final Tree tree, final Bloc bloc) { + for (final AssignmentExpressionTree assignment : extractAssignments(tree, bloc)) { + final ExpressionTree destVariable = assignment.variable(); + final ExpressionTree srcEspression = assignment.expression(); + if (isArray(destVariable) && isArray(srcEspression)) { + final String destArray = getArrayIdentifier(destVariable); + final String srcArray = getArrayIdentifier(srcEspression); + if (destArray != null && !destArray.equals(srcArray)) { + reportIssue(tree, MESSAGERULE); } + } } + } - /** - * Extract variable's name of array - * - * @param expression of Array - * @return Array's name - */ - private String getArrayIdentifier(final ExpressionTree expression) { - if (expression instanceof ArrayAccessExpressionTree) { - final ExpressionTree identifier = ((ArrayAccessExpressionTree) expression).expression(); - if (identifier instanceof IdentifierTree) { - return ((IdentifierTree) identifier).identifierToken().text(); - } - } - return null; + /** + * Extract variable's name of array + * + * @param expression of Array + * @return Array's name + */ + private String getArrayIdentifier(final ExpressionTree expression) { + if (expression instanceof ArrayAccessExpressionTree) { + final ExpressionTree identifier = ((ArrayAccessExpressionTree) expression).expression(); + if (identifier instanceof IdentifierTree) { + return ((IdentifierTree) identifier).identifierToken().text(); + } } + return null; + } - /** - * Verify if expression is an Array - * - * @param expression - * @return true if instance of ArrayAccessExpressionTree, false else - */ - private boolean isArray(final ExpressionTree expression) { - return expression instanceof ArrayAccessExpressionTree; - } + /** + * Verify if expression is an Array + * + * @param expression + * @return true if instance of ArrayAccessExpressionTree, false else + */ + private boolean isArray(final ExpressionTree expression) { + return expression instanceof ArrayAccessExpressionTree; + } - /** - * Verify if expression is an variable - * - * @param source - * @return - */ - private boolean isVariable(final ExpressionTree source) { - return source instanceof IdentifierTree; - } + /** + * Verify if expression is an variable + * + * @param source + * @return + */ + private boolean isVariable(final ExpressionTree source) { + return source instanceof IdentifierTree; + } - /** - * Extract nested blocks of code - * - * @param tree - * @return - */ - private List getBlocsOfCode(final Tree tree) { - final List blocs = new ArrayList<>(); - if (tree instanceof ForStatementTree) { - ForStatementTree castedForTree = (ForStatementTree) tree; - addBloc(blocs, castedForTree.statement()); - } else if (tree instanceof ForEachStatement) { - ForEachStatement castedForEachTree = (ForEachStatement) tree; - addForEachBloc(blocs, castedForEachTree.statement(), castedForEachTree.variable(), - castedForEachTree.expression()); - } else if (tree instanceof WhileStatementTree) { - WhileStatementTree castedWhileTree = (WhileStatementTree) tree; - addBloc(blocs, castedWhileTree.statement()); - } else if (tree instanceof DoWhileStatementTree) { - DoWhileStatementTree castedDoWhileTree = (DoWhileStatementTree) tree; - addBloc(blocs, castedDoWhileTree.statement()); - } else if (tree instanceof IfStatementTree) { - IfStatementTree castedIfTree = (IfStatementTree) tree; - addBloc(blocs, castedIfTree.thenStatement()); - addBloc(blocs, castedIfTree.elseStatement()); - } else if (tree instanceof TryStatementTree) { - final TryStatementTree tryTree = (TryStatementTree) tree; - addBloc(blocs, tryTree.block()); - addBloc(blocs, extractCatchBlocks(tryTree)); - addBloc(blocs, tryTree.finallyBlock()); - } - return blocs; + /** + * Extract nested blocks of code + * + * @param tree + * @return + */ + private List getBlocsOfCode(final Tree tree) { + final List blocs = new ArrayList<>(); + if (tree instanceof ForStatementTree) { + ForStatementTree castedForTree = (ForStatementTree) tree; + addBloc(blocs, castedForTree.statement()); + } else if (tree instanceof ForEachStatement) { + ForEachStatement castedForEachTree = (ForEachStatement) tree; + addForEachBloc( + blocs, + castedForEachTree.statement(), + castedForEachTree.variable(), + castedForEachTree.expression()); + } else if (tree instanceof WhileStatementTree) { + WhileStatementTree castedWhileTree = (WhileStatementTree) tree; + addBloc(blocs, castedWhileTree.statement()); + } else if (tree instanceof DoWhileStatementTree) { + DoWhileStatementTree castedDoWhileTree = (DoWhileStatementTree) tree; + addBloc(blocs, castedDoWhileTree.statement()); + } else if (tree instanceof IfStatementTree) { + IfStatementTree castedIfTree = (IfStatementTree) tree; + addBloc(blocs, castedIfTree.thenStatement()); + addBloc(blocs, castedIfTree.elseStatement()); + } else if (tree instanceof TryStatementTree) { + final TryStatementTree tryTree = (TryStatementTree) tree; + addBloc(blocs, tryTree.block()); + addBloc(blocs, extractCatchBlocks(tryTree)); + addBloc(blocs, tryTree.finallyBlock()); } + return blocs; + } - /** - * Assignments extraction from block of code. - * - * @param tree - * @param block - * @return - */ - private List extractAssignments(final Tree tree, final Bloc bloc) { - final BlockTree block = bloc.getBlockTree(); + /** + * Assignments extraction from block of code. + * + * @param tree + * @param block + * @return + */ + private List extractAssignments(final Tree tree, final Bloc bloc) { + final BlockTree block = bloc.getBlockTree(); - // Prepare useful predicates - final Predicate blocksPredicate = statement -> statement.is(Kind.IF_STATEMENT) - || statement.is(Kind.TRY_STATEMENT); - final Predicate assignmentPredicate = statement -> statement.is(Kind.EXPRESSION_STATEMENT) + // Prepare useful predicates + final Predicate blocksPredicate = + statement -> statement.is(Kind.IF_STATEMENT) || statement.is(Kind.TRY_STATEMENT); + final Predicate assignmentPredicate = + statement -> + statement.is(Kind.EXPRESSION_STATEMENT) && ((ExpressionStatementTree) statement).expression().is(Kind.ASSIGNMENT); - // Filter expressions to find assignments - final List result = block.body().stream().filter(assignmentPredicate) - .map(assign -> (AssignmentExpressionTree) ((ExpressionStatementTree) assign).expression()) - .collect(Collectors.toList()); + // Filter expressions to find assignments + final List result = + block.body().stream() + .filter(assignmentPredicate) + .map( + assign -> + (AssignmentExpressionTree) ((ExpressionStatementTree) assign).expression()) + .collect(Collectors.toList()); - // Recursive loop for nested blocks, add nested assignments to results - final List ifStatements = block.body().stream().filter(blocksPredicate) - .collect(Collectors.toList()); - for (final StatementTree ifstatement : ifStatements) { - final List blocs = getBlocsOfCode(ifstatement); - for (final Bloc b : blocs) { - result.addAll(extractAssignments(tree, b)); - } - } - return result; + // Recursive loop for nested blocks, add nested assignments to results + final List ifStatements = + block.body().stream().filter(blocksPredicate).collect(Collectors.toList()); + for (final StatementTree ifstatement : ifStatements) { + final List blocs = getBlocsOfCode(ifstatement); + for (final Bloc b : blocs) { + result.addAll(extractAssignments(tree, b)); + } } + return result; + } - /** - * Extract all blocks of code from try/catch statement - * - * @param tryTree - * @return Array of StatementTree - */ - private BlockTree[] extractCatchBlocks(final TryStatementTree tryTree) { - final List catches = tryTree.catches(); - return catches.stream().map(CatchTree::block).collect(Collectors.toList()).toArray(new BlockTree[0]); - } + /** + * Extract all blocks of code from try/catch statement + * + * @param tryTree + * @return Array of StatementTree + */ + private BlockTree[] extractCatchBlocks(final TryStatementTree tryTree) { + final List catches = tryTree.catches(); + return catches.stream() + .map(CatchTree::block) + .collect(Collectors.toList()) + .toArray(new BlockTree[0]); + } - /** - * Add a Bloc in list after type checking - * - * @param blocs - * @param statements - */ - private void addBloc(final List blocs, final StatementTree... statements) { - for (final StatementTree statement : statements) { - if (statement instanceof BlockTree) { - blocs.add(new Bloc((BlockTree) statement)); - } - } + /** + * Add a Bloc in list after type checking + * + * @param blocs + * @param statements + */ + private void addBloc(final List blocs, final StatementTree... statements) { + for (final StatementTree statement : statements) { + if (statement instanceof BlockTree) { + blocs.add(new Bloc((BlockTree) statement)); + } } + } - /** - * Add a Bloc in list after type checking - * - * @param blocs - * @param statement - * @param variable - * @param expression - */ - private void addForEachBloc(final List blocs, final StatementTree statement, final VariableTree variable, - final ExpressionTree expression) { - if (statement instanceof BlockTree && expression instanceof IdentifierTree) { - blocs.add(new Bloc((BlockTree) statement, ((IdentifierTree) expression).identifierToken().text(), - variable.simpleName().identifierToken().text())); - } + /** + * Add a Bloc in list after type checking + * + * @param blocs + * @param statement + * @param variable + * @param expression + */ + private void addForEachBloc( + final List blocs, + final StatementTree statement, + final VariableTree variable, + final ExpressionTree expression) { + if (statement instanceof BlockTree && expression instanceof IdentifierTree) { + blocs.add( + new Bloc( + (BlockTree) statement, + ((IdentifierTree) expression).identifierToken().text(), + variable.simpleName().identifierToken().text())); } + } - private static class Bloc { - private final BlockTree blockTree; - private String iterable; - private String value; + private static class Bloc { + private final BlockTree blockTree; + private String iterable; + private String value; - public Bloc(final BlockTree blockTree, final String iterable, final String value) { - this.blockTree = blockTree; - this.iterable = iterable; - this.value = value; - } - - public boolean isForeach() { - return iterable != null && value != null; - } + public Bloc(final BlockTree blockTree, final String iterable, final String value) { + this.blockTree = blockTree; + this.iterable = iterable; + this.value = value; + } - public Bloc(final BlockTree blockTree) { - this.blockTree = blockTree; - } + public boolean isForeach() { + return iterable != null && value != null; + } - public BlockTree getBlockTree() { - return blockTree; - } + public Bloc(final BlockTree blockTree) { + this.blockTree = blockTree; + } - public String getIterable() { - return iterable; - } + public BlockTree getBlockTree() { + return blockTree; + } - public String getValue() { - return value; - } + public String getIterable() { + return iterable; + } + public String getValue() { + return value; } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequest.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequest.java index e2c7fb6..6a4c889 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequest.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequest.java @@ -17,13 +17,12 @@ */ package org.greencodeinitiative.creedengo.java.checks; -import java.util.List; -import java.util.function.Predicate; - import static java.util.Collections.singletonList; import static java.util.regex.Pattern.CASE_INSENSITIVE; import static java.util.regex.Pattern.compile; +import java.util.List; +import java.util.function.Predicate; import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.LiteralTree; @@ -36,20 +35,21 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S74") public class AvoidFullSQLRequest extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Don't use the query SELECT * FROM"; - private static final Predicate SELECT_FROM_REGEXP = - compile("select\\s*\\*\\s*from", CASE_INSENSITIVE).asPredicate(); //simple regexp, more precision + protected static final String MESSAGERULE = "Don't use the query SELECT * FROM"; + private static final Predicate SELECT_FROM_REGEXP = + compile("select\\s*\\*\\s*from", CASE_INSENSITIVE) + .asPredicate(); // simple regexp, more precision - @Override - public List nodesToVisit() { - return singletonList(Tree.Kind.STRING_LITERAL); - } + @Override + public List nodesToVisit() { + return singletonList(Tree.Kind.STRING_LITERAL); + } - @Override - public void visitNode(Tree tree) { - String value = ((LiteralTree) tree).value(); - if (SELECT_FROM_REGEXP.test(value)) { - reportIssue(tree, MESSAGERULE); - } + @Override + public void visitNode(Tree tree) { + String value = ((LiteralTree) tree).value(); + if (SELECT_FROM_REGEXP.test(value)) { + reportIssue(tree, MESSAGERULE); } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoop.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoop.java index 53f2e08..eeb2608 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoop.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoop.java @@ -19,7 +19,6 @@ import java.util.Arrays; import java.util.List; - import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.check.Rule; @@ -38,72 +37,77 @@ @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC3") @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GSCIL") public class AvoidGettingSizeCollectionInLoop extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Avoid getting the size of the collection in the loop"; - private static final MethodMatchers SIZE_METHOD = MethodMatchers.or( - MethodMatchers.create() - .ofAnyType() - .names("size", "length") - .withAnyParameters() - .build() - ); - private final AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor visitorInFile = new AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor(); + protected static final String MESSAGERULE = + "Avoid getting the size of the collection in the loop"; + private static final MethodMatchers SIZE_METHOD = + MethodMatchers.or( + MethodMatchers.create().ofAnyType().names("size", "length").withAnyParameters().build()); + private final AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor + visitorInFile = + new AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor(); - private static final Logger LOGGER = Loggers.get(AvoidGettingSizeCollectionInLoop.class); + private static final Logger LOGGER = Loggers.get(AvoidGettingSizeCollectionInLoop.class); - @Override - public List nodesToVisit() { - return Arrays.asList(Kind.FOR_STATEMENT, Kind.WHILE_STATEMENT); - } + @Override + public List nodesToVisit() { + return Arrays.asList(Kind.FOR_STATEMENT, Kind.WHILE_STATEMENT); + } - @Override - public void visitNode(Tree tree) { - LOGGER.debug("--------------------_____-----_____----- AvoidGettingSizeCollectionInLoop.visitNode METHOD - BEGIN"); - if (tree.is(Kind.FOR_STATEMENT)) { - LOGGER.debug("ForStatement found"); - ForStatementTree forStatementTree = (ForStatementTree) tree; + @Override + public void visitNode(Tree tree) { + LOGGER.debug( + "--------------------_____-----_____----- AvoidGettingSizeCollectionInLoop.visitNode METHOD - BEGIN"); + if (tree.is(Kind.FOR_STATEMENT)) { + LOGGER.debug("ForStatement found"); + ForStatementTree forStatementTree = (ForStatementTree) tree; - LOGGER.debug("Check if condition is a BinaryExpressionTree"); - if (forStatementTree.condition() instanceof BinaryExpressionTree) { + LOGGER.debug("Check if condition is a BinaryExpressionTree"); + if (forStatementTree.condition() instanceof BinaryExpressionTree) { - LOGGER.debug("Casting condition to BinaryExpressionTree"); - BinaryExpressionTree expressionTree = (BinaryExpressionTree) forStatementTree.condition(); - LOGGER.debug("Checking BinaryExpressionTree content"); - expressionTree.accept(visitorInFile); + LOGGER.debug("Casting condition to BinaryExpressionTree"); + BinaryExpressionTree expressionTree = (BinaryExpressionTree) forStatementTree.condition(); + LOGGER.debug("Checking BinaryExpressionTree content"); + expressionTree.accept(visitorInFile); - } else { - LOGGER.debug("Condition isn't a BinaryExpressionTree (real type : {}) => no issue launched", forStatementTree.condition()); - } - } else if (tree.is(Kind.WHILE_STATEMENT)) { - LOGGER.debug("WhileStatement found"); - WhileStatementTree whileStatementTree = (WhileStatementTree) tree; + } else { + LOGGER.debug( + "Condition isn't a BinaryExpressionTree (real type : {}) => no issue launched", + forStatementTree.condition()); + } + } else if (tree.is(Kind.WHILE_STATEMENT)) { + LOGGER.debug("WhileStatement found"); + WhileStatementTree whileStatementTree = (WhileStatementTree) tree; - LOGGER.debug("Check if condition is a BinaryExpressionTree"); - if (whileStatementTree.condition() instanceof BinaryExpressionTree) { + LOGGER.debug("Check if condition is a BinaryExpressionTree"); + if (whileStatementTree.condition() instanceof BinaryExpressionTree) { - LOGGER.debug("Casting condition to BinaryExpressionTree"); - BinaryExpressionTree expressionTree = (BinaryExpressionTree) whileStatementTree.condition(); - LOGGER.debug("Checking BinaryExpressionTree content"); - expressionTree.accept(visitorInFile); + LOGGER.debug("Casting condition to BinaryExpressionTree"); + BinaryExpressionTree expressionTree = (BinaryExpressionTree) whileStatementTree.condition(); + LOGGER.debug("Checking BinaryExpressionTree content"); + expressionTree.accept(visitorInFile); - } else { - LOGGER.debug("Condition isn't a BinaryExpressionTree (real type : {}) => no issue launched"); - } - } else { - throw new UnsupportedOperationException("Kind of statement NOT supported - real kind : " + tree.kind().getAssociatedInterface()); - } - LOGGER.debug("--------------------_____-----_____----- AvoidGettingSizeCollectionInLoop.visitNode METHOD - END"); + } else { + LOGGER.debug( + "Condition isn't a BinaryExpressionTree (real type : {}) => no issue launched"); + } + } else { + throw new UnsupportedOperationException( + "Kind of statement NOT supported - real kind : " + tree.kind().getAssociatedInterface()); } + LOGGER.debug( + "--------------------_____-----_____----- AvoidGettingSizeCollectionInLoop.visitNode METHOD - END"); + } - private class AvoidGettingSizeCollectionInLoopVisitor extends BaseTreeVisitor { - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (SIZE_METHOD.matches(tree.symbol())) { - LOGGER.debug("sizeMethod found => launching ISSUE !!!"); - reportIssue(tree, MESSAGERULE); - } else { - LOGGER.debug("sizeMethod NOT found : bypass and go next"); - super.visitMethodInvocation(tree); - } - } + private class AvoidGettingSizeCollectionInLoopVisitor extends BaseTreeVisitor { + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + if (SIZE_METHOD.matches(tree.symbol())) { + LOGGER.debug("sizeMethod found => launching ISSUE !!!"); + reportIssue(tree, MESSAGERULE); + } else { + LOGGER.debug("sizeMethod NOT found : bypass and go next"); + super.visitMethodInvocation(tree); + } } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatement.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatement.java index 7343979..79d6a96 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatement.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatement.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.BinaryExpressionTree; @@ -35,326 +34,320 @@ import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; /** - * FUNCTIONAL DESCRIPTION : please see ASCIIDOC description file of this rule (inside `creedengo-rules-spcifications`) - * TECHNICAL CHOICES : - * - Kind.IF_STATEMENT, Kind.ELSE_STATEMENT, Kind.ELSEIF_STATEMENT not used because it isn't possible - * to keep parent references to check later if variables already used or not in parent tree - * - only one way to keep parent history : manually go throw the all tree and thus, start at method declaration - * - an "ELSE" statement is considered as a second IF statement using the same variables used on previous - * - IF and ELSEIF statements are considered as an IF statement + * FUNCTIONAL DESCRIPTION : please see ASCIIDOC description file of this rule (inside + * `creedengo-rules-spcifications`) TECHNICAL CHOICES : - Kind.IF_STATEMENT, Kind.ELSE_STATEMENT, + * Kind.ELSEIF_STATEMENT not used because it isn't possible to keep parent references to check later + * if variables already used or not in parent tree - only one way to keep parent history : manually + * go throw the all tree and thus, start at method declaration - an "ELSE" statement is considered + * as a second IF statement using the same variables used on previous - IF and ELSEIF statements are + * considered as an IF statement */ @Rule(key = "GCI2") @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC2") @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "AMIES") public class AvoidMultipleIfElseStatement extends IssuableSubscriptionVisitor { - public static final String ERROR_MESSAGE = "Use a switch statement instead of multiple if-else if possible"; - - public static final int NB_MAX_VARIABLE_USAGE = 2; - - // data structure for following usage of variable inside all the AST tree - private VariablesPerLevelDataStructure variablesStruct = new VariablesPerLevelDataStructure(); - - // only visit each method to keep data of all conditional tree - // with IF, ELSE or ELSEIF statements, we can't keep all data of conditional tree - @Override - public List nodesToVisit() { - return List.of(Kind.METHOD); + public static final String ERROR_MESSAGE = + "Use a switch statement instead of multiple if-else if possible"; + + public static final int NB_MAX_VARIABLE_USAGE = 2; + + // data structure for following usage of variable inside all the AST tree + private VariablesPerLevelDataStructure variablesStruct = new VariablesPerLevelDataStructure(); + + // only visit each method to keep data of all conditional tree + // with IF, ELSE or ELSEIF statements, we can't keep all data of conditional tree + @Override + public List nodesToVisit() { + return List.of(Kind.METHOD); + } + + @Override + public void visitNode(@SuppressWarnings("NullableProblems") Tree pTree) { + + MethodTree method = (MethodTree) pTree; + if (method.block() + == null) // in an interface, there are some methods without block : thus, is to avoid NPE + return; + + // reinit data structure before each method analysis + variablesStruct = new VariablesPerLevelDataStructure(); + + // starting visit + visitNodeContent(method.block().body(), 0); + } + + /** + * Visit all content of a node for one level (with its statements list) + * + * @param pLstStatements statements list of current node + * @param pLevel level of current node + */ + private void visitNodeContent(List pLstStatements, int pLevel) { + if (pLstStatements == null || pLstStatements.isEmpty()) { + return; } - @Override - public void visitNode(@SuppressWarnings("NullableProblems") Tree pTree) { - - MethodTree method = (MethodTree)pTree; - if (method.block() == null) // in an interface, there are some methods without block : thus, is to avoid NPE - return; - - // reinit data structure before each method analysis - variablesStruct = new VariablesPerLevelDataStructure(); - - // starting visit - visitNodeContent(method.block().body(), 0); - + for (StatementTree statement : pLstStatements) { + if (statement.is(Kind.BLOCK)) { + // the current node is a block : visit block content + visitNodeContent(((BlockTree) statement).body(), pLevel); + } else if (statement.is(Kind.IF_STATEMENT)) { + visitIfNode((IfStatementTree) statement, pLevel); + } } - - /** - * Visit all content of a node for one level (with its statements list) - * - * @param pLstStatements statements list of current node - * @param pLevel level of current node - */ - private void visitNodeContent(List pLstStatements, int pLevel) { - if (pLstStatements == null || pLstStatements.isEmpty()) { - return; - } - - for (StatementTree statement : pLstStatements) { - if (statement.is(Kind.BLOCK)) { - // the current node is a block : visit block content - visitNodeContent(((BlockTree)statement).body(), pLevel); - } else if (statement.is(Kind.IF_STATEMENT)) { - visitIfNode((IfStatementTree) statement, pLevel); - } - } + } + + /** + * Visit an IF type node + * + * @param pIfTree the current node (Tree type) + * @param pLevel the level of node + */ + private void visitIfNode(IfStatementTree pIfTree, int pLevel) { + + if (pIfTree == null) return; + + // init current if structure with cleaning child levels + variablesStruct.reinitVariableUsageForLevel(pLevel + 1); + // init current if structure with cleaning for ELSE process checking + variablesStruct.reinitVariableUsageForLevelForCurrentIfStruct(pLevel); + + // analyze condition variables and raise error if needed + computeIfVariables(pIfTree, pLevel); + + // return if there is no block + if (!pIfTree.thenStatement().is(Kind.BLOCK)) return; + + // visit the content of if block + visitNodeContent(((BlockTree) pIfTree.thenStatement()).body(), pLevel + 1); + + // analyze ELSE clause et ELSE IF clauses + if (pIfTree.elseStatement() != null) { + if (pIfTree.elseStatement().is(Kind.BLOCK)) { // ELSE clause content + visitElseNode((BlockTree) pIfTree.elseStatement(), pLevel); + } else if (pIfTree.elseStatement().is(Kind.IF_STATEMENT)) { // ELSE IF clause + visitIfNode((IfStatementTree) pIfTree.elseStatement(), pLevel); + } } - - /** - * Visit an IF type node - * @param pIfTree the current node (Tree type) - * @param pLevel the level of node - */ - private void visitIfNode(IfStatementTree pIfTree, int pLevel) { - - if (pIfTree == null) return; - - // init current if structure with cleaning child levels - variablesStruct.reinitVariableUsageForLevel(pLevel + 1); - // init current if structure with cleaning for ELSE process checking - variablesStruct.reinitVariableUsageForLevelForCurrentIfStruct(pLevel); - - // analyze condition variables and raise error if needed - computeIfVariables(pIfTree, pLevel); - - // return if there is no block - if (!pIfTree.thenStatement().is(Kind.BLOCK)) - return; - - // visit the content of if block - visitNodeContent(((BlockTree)pIfTree.thenStatement()).body(), pLevel + 1); - - // analyze ELSE clause et ELSE IF clauses - if (pIfTree.elseStatement() != null) { - if (pIfTree.elseStatement().is(Kind.BLOCK)) { // ELSE clause content - visitElseNode((BlockTree) pIfTree.elseStatement(), pLevel); - } else if (pIfTree.elseStatement().is(Kind.IF_STATEMENT)) { // ELSE IF clause - visitIfNode((IfStatementTree) pIfTree.elseStatement(), pLevel); - } - } + } + + /** + * Analyze and compute variables usage for IF AST structure + * + * @param pIfTree IF node + * @param pLevel the level of IF node + */ + private void computeIfVariables(IfStatementTree pIfTree, int pLevel) { + + if (pIfTree.condition() == null) return; + + // analysing content of conditions of IF node + ExpressionTree expr = pIfTree.condition(); + if (expr instanceof BinaryExpressionTree) { + computeConditionVariables((BinaryExpressionTree) expr, pLevel); } - - /** - * Analyze and compute variables usage for IF AST structure - * @param pIfTree IF node - * @param pLevel the level of IF node - */ - private void computeIfVariables(IfStatementTree pIfTree, int pLevel) { - - if (pIfTree.condition() == null) return; - - // analysing content of conditions of IF node - ExpressionTree expr = pIfTree.condition(); - if (expr instanceof BinaryExpressionTree) { - computeConditionVariables((BinaryExpressionTree) expr, pLevel); - } - + } + + /** + * Analyze and compute variables usage for Expression structure + * + * @param pBinExprTree binary expression to analyze + * @param pLevel The level of binary expression + */ + private void computeConditionVariables(BinaryExpressionTree pBinExprTree, int pLevel) { + + // if multiple conditions, continue with each part of complex expression + if (pBinExprTree.is(Kind.CONDITIONAL_AND) || pBinExprTree.is(Kind.CONDITIONAL_OR)) { + if (pBinExprTree.leftOperand() instanceof BinaryExpressionTree) { + computeConditionVariables((BinaryExpressionTree) pBinExprTree.leftOperand(), pLevel); + } + if (pBinExprTree.rightOperand() instanceof BinaryExpressionTree) { + computeConditionVariables((BinaryExpressionTree) pBinExprTree.rightOperand(), pLevel); + } + } else if (pBinExprTree.is(Kind.EQUAL_TO) + || pBinExprTree.is(Kind.NOT_EQUAL_TO) + || pBinExprTree.is(Kind.GREATER_THAN) + || pBinExprTree.is(Kind.GREATER_THAN_OR_EQUAL_TO) + || pBinExprTree.is(Kind.LESS_THAN_OR_EQUAL_TO) + || pBinExprTree.is(Kind.LESS_THAN)) { + // continue analysis with variables if some key-words are found + if (pBinExprTree.leftOperand().is(Kind.IDENTIFIER)) { + computeVariables((IdentifierTree) pBinExprTree.leftOperand(), pLevel); + } + if (pBinExprTree.rightOperand().is(Kind.IDENTIFIER)) { + computeVariables((IdentifierTree) pBinExprTree.rightOperand(), pLevel); + } } - - /** - * Analyze and compute variables usage for Expression structure - * @param pBinExprTree binary expression to analyze - * @param pLevel The level of binary expression - */ - private void computeConditionVariables(BinaryExpressionTree pBinExprTree, int pLevel) { - - // if multiple conditions, continue with each part of complex expression - if (pBinExprTree.is(Kind.CONDITIONAL_AND) || pBinExprTree.is(Kind.CONDITIONAL_OR)) { - if (pBinExprTree.leftOperand() instanceof BinaryExpressionTree) { - computeConditionVariables((BinaryExpressionTree) pBinExprTree.leftOperand(), pLevel); - } - if (pBinExprTree.rightOperand() instanceof BinaryExpressionTree) { - computeConditionVariables((BinaryExpressionTree) pBinExprTree.rightOperand(), pLevel); - } - } else if (pBinExprTree.is(Kind.EQUAL_TO) - || pBinExprTree.is(Kind.NOT_EQUAL_TO) - || pBinExprTree.is(Kind.GREATER_THAN) - || pBinExprTree.is(Kind.GREATER_THAN_OR_EQUAL_TO) - || pBinExprTree.is(Kind.LESS_THAN_OR_EQUAL_TO) - || pBinExprTree.is(Kind.LESS_THAN) - ) { - // continue analysis with variables if some key-words are found - if (pBinExprTree.leftOperand().is(Kind.IDENTIFIER)) { - computeVariables((IdentifierTree) pBinExprTree.leftOperand(), pLevel); - } - if (pBinExprTree.rightOperand().is(Kind.IDENTIFIER)) { - computeVariables((IdentifierTree) pBinExprTree.rightOperand(), pLevel); - } - } + } + + /** + * Analyze and compute variables usage for Variable AST structure + * + * @param pVarIdTree The Variable AST structure + * @param pLevel the level of structure + */ + private void computeVariables(IdentifierTree pVarIdTree, int pLevel) { + if (pVarIdTree.is(Kind.IDENTIFIER) + && !pVarIdTree.symbolType().is("float") + && !pVarIdTree.symbolType().is("double")) { + // increment the variable counter to list of all variables + int nbUsed = variablesStruct.incrementVariableUsageForLevel(pVarIdTree.name(), pLevel); + + // increment variable counter to list of variables already declared for current if or elseif + // struture + variablesStruct.incrementVariableUsageForLevelForCurrentIfStruct(pVarIdTree.name(), pLevel); + + // raise an error if maximum + if (nbUsed > NB_MAX_VARIABLE_USAGE) { + reportIssue(pVarIdTree, ERROR_MESSAGE); + } } - - /** - * Analyze and compute variables usage for Variable AST structure - * @param pVarIdTree The Variable AST structure - * @param pLevel the level of structure - */ - private void computeVariables(IdentifierTree pVarIdTree, int pLevel) { - if (pVarIdTree.is(Kind.IDENTIFIER) - && !pVarIdTree.symbolType().is("float") - && !pVarIdTree.symbolType().is("double")) { - // increment the variable counter to list of all variables - int nbUsed = variablesStruct.incrementVariableUsageForLevel(pVarIdTree.name(), pLevel); - - // increment variable counter to list of variables already declared for current if or elseif struture - variablesStruct.incrementVariableUsageForLevelForCurrentIfStruct(pVarIdTree.name(), pLevel); - - // raise an error if maximum - if (nbUsed > NB_MAX_VARIABLE_USAGE) { - reportIssue(pVarIdTree, ERROR_MESSAGE); - } - } + } + + /** + * Analyze and compute variables usage for ELSE AST structure + * + * @param pElseTree ELSE node + * @param pLevel the level of ELSE node + */ + private void visitElseNode(BlockTree pElseTree, int pLevel) { + + if (pElseTree == null) { + return; } - /** - * Analyze and compute variables usage for ELSE AST structure - * @param pElseTree ELSE node - * @param pLevel the level of ELSE node - */ - private void visitElseNode(BlockTree pElseTree, int pLevel) { + // analyze variables and raise error if needed + computeElseVariables(pElseTree, pLevel); - if (pElseTree == null) { return; } + // go to next child level + visitNodeContent(pElseTree.body(), pLevel + 1); + } - // analyze variables and raise error if needed - computeElseVariables(pElseTree, pLevel); + /** + * Analyze and compute variables usage for ELSE AST structure + * + * @param pElseTree ELSE node + * @param pLevel the level of ELSE node + */ + private void computeElseVariables(StatementTree pElseTree, int pLevel) { - // go to next child level - visitNodeContent(pElseTree.body(), pLevel + 1); - } + Map mapVar = variablesStruct.getVariablesForCurrentIfStruct(pLevel); + if (mapVar != null) { + for (Map.Entry entry : mapVar.entrySet()) { + String variableName = entry.getKey(); - /** - * Analyze and compute variables usage for ELSE AST structure - * @param pElseTree ELSE node - * @param pLevel the level of ELSE node - */ - private void computeElseVariables(StatementTree pElseTree, int pLevel) { - - Map mapVar = variablesStruct.getVariablesForCurrentIfStruct(pLevel); - if (mapVar != null) { - for (Map.Entry entry : mapVar.entrySet()) { - String variableName = entry.getKey(); - - // increment usage of all variables in the same level of ELSE staetement - int nbUsed = variablesStruct.incrementVariableUsageForLevel(variableName, pLevel); - - // increment variable counter to list of variables already declared for current if or elseif struture - variablesStruct.incrementVariableUsageForLevelForCurrentIfStruct(variableName, pLevel); - - // raise an error if maximum - if (nbUsed > NB_MAX_VARIABLE_USAGE) { - reportIssue(pElseTree, ERROR_MESSAGE); - } - } - } - } + // increment usage of all variables in the same level of ELSE staetement + int nbUsed = variablesStruct.incrementVariableUsageForLevel(variableName, pLevel); - /** - * Complex data structure representing variables counters per AST level (cumulative counts with parent levels) - * Map> ==> - * - Key : index of Level (0 = first level) - * - Value : Map - * - Key : name of variable in the current or parent level - * - Value : number of usage of this variable in an IF statement in current level or one of parent levels - * - */ - private static class VariablesPerLevelDataStructure { - - // global map variable counters per level - private final Map> mapVariablesPerLevel; - - // map variable counters per level for current If / ElseIf structure - // purpose : used by compute variables Else process (because Else structure is particular : - // we don't know previous variables and we need previous If / ElseIf structure to know variables) - private final Map> mapVariablesPerLevelForCurrentIfStruct; - - public VariablesPerLevelDataStructure() { - mapVariablesPerLevel = new HashMap<>(10); - mapVariablesPerLevelForCurrentIfStruct = new HashMap<>(10); - } + // increment variable counter to list of variables already declared for current if or elseif + // struture + variablesStruct.incrementVariableUsageForLevelForCurrentIfStruct(variableName, pLevel); - /** - * increment variable counters on global map - */ - public int incrementVariableUsageForLevel(String variableName, int pLevel) { - return internalIncrementVariableUsage(mapVariablesPerLevel, variableName, pLevel); + // raise an error if maximum + if (nbUsed > NB_MAX_VARIABLE_USAGE) { + reportIssue(pElseTree, ERROR_MESSAGE); } + } + } + } + + /** + * Complex data structure representing variables counters per AST level (cumulative counts with + * parent levels) Map> ==> - Key : index of Level (0 = first level) + * - Value : Map - Key : name of variable in the current or parent level - Value + * : number of usage of this variable in an IF statement in current level or one of parent levels + */ + private static class VariablesPerLevelDataStructure { + + // global map variable counters per level + private final Map> mapVariablesPerLevel; + + // map variable counters per level for current If / ElseIf structure + // purpose : used by compute variables Else process (because Else structure is particular : + // we don't know previous variables and we need previous If / ElseIf structure to know + // variables) + private final Map> mapVariablesPerLevelForCurrentIfStruct; + + public VariablesPerLevelDataStructure() { + mapVariablesPerLevel = new HashMap<>(10); + mapVariablesPerLevelForCurrentIfStruct = new HashMap<>(10); + } - /** - * increment variable counters on input map - */ - private int internalIncrementVariableUsage(Map> pDataMap, String variableName, int pLevel) { - - // get variable usage map for current level and init if null - Map variablesMap = pDataMap.computeIfAbsent(pLevel, k -> new HashMap<>(5)); + /** increment variable counters on global map */ + public int incrementVariableUsageForLevel(String variableName, int pLevel) { + return internalIncrementVariableUsage(mapVariablesPerLevel, variableName, pLevel); + } - // get usage from parent if needed - Integer nbUsed = variablesMap.get(variableName); - if (nbUsed == null) { - Integer nbParentUsed = internalGetVariableUsageOfNearestParent(pDataMap, variableName, pLevel - 1); - nbUsed = nbParentUsed == null ? 0 : nbParentUsed; - } + /** increment variable counters on input map */ + private int internalIncrementVariableUsage( + Map> pDataMap, String variableName, int pLevel) { - // increment usage for current level - nbUsed++; - variablesMap.put(variableName, nbUsed); + // get variable usage map for current level and init if null + Map variablesMap = pDataMap.computeIfAbsent(pLevel, k -> new HashMap<>(5)); - return nbUsed; - } + // get usage from parent if needed + Integer nbUsed = variablesMap.get(variableName); + if (nbUsed == null) { + Integer nbParentUsed = + internalGetVariableUsageOfNearestParent(pDataMap, variableName, pLevel - 1); + nbUsed = nbParentUsed == null ? 0 : nbParentUsed; + } - /** - * get usage of a variable in top tree (nearest top parent) - */ - private Integer internalGetVariableUsageOfNearestParent(Map> pDataMap, String variableName, int pLevel) { + // increment usage for current level + nbUsed++; + variablesMap.put(variableName, nbUsed); - Integer nbParentUsed = null; - for (int i = pLevel; i >= 0 && nbParentUsed == null; i--) { - Map variablesParentLevelMap = pDataMap.get(i); - if (variablesParentLevelMap != null) { - nbParentUsed = variablesParentLevelMap.get(variableName); - } - } + return nbUsed; + } - return nbParentUsed; - } + /** get usage of a variable in top tree (nearest top parent) */ + private Integer internalGetVariableUsageOfNearestParent( + Map> pDataMap, String variableName, int pLevel) { - /** - * reinitialization of variable usages for input level and global map - */ - public void reinitVariableUsageForLevel(int pLevel) { - internalReinitVariableUsageForLevelForCurrentIfStruct(mapVariablesPerLevel, pLevel); + Integer nbParentUsed = null; + for (int i = pLevel; i >= 0 && nbParentUsed == null; i--) { + Map variablesParentLevelMap = pDataMap.get(i); + if (variablesParentLevelMap != null) { + nbParentUsed = variablesParentLevelMap.get(variableName); } + } - /** - * reinitialization of variable usages in input level in input map - */ - private void internalReinitVariableUsageForLevelForCurrentIfStruct(Map> pDataMap, int pLevel) { - if (pDataMap.get(pLevel) == null) { return; } - - // cleaning of current If Structure beginning at level specified - for (int i = pLevel; i < pDataMap.size(); i++) { - pDataMap.remove(i); - } - - } + return nbParentUsed; + } - /** - * reinitialization of variable usages for input level on if/elseif map - */ - public void reinitVariableUsageForLevelForCurrentIfStruct(int pLevel) { - internalReinitVariableUsageForLevelForCurrentIfStruct(mapVariablesPerLevelForCurrentIfStruct, pLevel); - } + /** reinitialization of variable usages for input level and global map */ + public void reinitVariableUsageForLevel(int pLevel) { + internalReinitVariableUsageForLevelForCurrentIfStruct(mapVariablesPerLevel, pLevel); + } - /** - * increment variable counters on if/elseif map - */ - public void incrementVariableUsageForLevelForCurrentIfStruct(String variableName, int pLevel) { - internalIncrementVariableUsage(mapVariablesPerLevelForCurrentIfStruct, variableName, pLevel); - } + /** reinitialization of variable usages in input level in input map */ + private void internalReinitVariableUsageForLevelForCurrentIfStruct( + Map> pDataMap, int pLevel) { + if (pDataMap.get(pLevel) == null) { + return; + } + + // cleaning of current If Structure beginning at level specified + for (int i = pLevel; i < pDataMap.size(); i++) { + pDataMap.remove(i); + } + } - /** - * get usage of a variable in a level on if/elseif map - */ - public Map getVariablesForCurrentIfStruct(int pLevel) { - return mapVariablesPerLevelForCurrentIfStruct.get(pLevel); - } + /** reinitialization of variable usages for input level on if/elseif map */ + public void reinitVariableUsageForLevelForCurrentIfStruct(int pLevel) { + internalReinitVariableUsageForLevelForCurrentIfStruct( + mapVariablesPerLevelForCurrentIfStruct, pLevel); + } + /** increment variable counters on if/elseif map */ + public void incrementVariableUsageForLevelForCurrentIfStruct(String variableName, int pLevel) { + internalIncrementVariableUsage(mapVariablesPerLevelForCurrentIfStruct, variableName, pLevel); } + /** get usage of a variable in a level on if/elseif map */ + public Map getVariablesForCurrentIfStruct(int pLevel) { + return mapVariablesPerLevelForCurrentIfStruct.get(pLevel); + } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java index beb1cea..63fe3b0 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java @@ -20,9 +20,7 @@ import java.util.Collections; import java.util.List; import java.util.regex.Pattern; - import javax.annotation.Nonnull; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.MethodMatchers; @@ -37,42 +35,43 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S77") public class AvoidRegexPatternNotStatic extends IssuableSubscriptionVisitor { - public static final String MESSAGE_RULE = "Avoid using Pattern.compile() in a non-static context."; + public static final String MESSAGE_RULE = + "Avoid using Pattern.compile() in a non-static context."; - private static final MethodMatchers PATTERN_COMPILE = MethodMatchers.create() - .ofTypes(Pattern.class.getName()) - .names("compile") - .withAnyParameters() - .build(); + private static final MethodMatchers PATTERN_COMPILE = + MethodMatchers.create() + .ofTypes(Pattern.class.getName()) + .names("compile") + .withAnyParameters() + .build(); - private final AvoidRegexPatternNotStaticVisitor visitor = new AvoidRegexPatternNotStaticVisitor(); + private final AvoidRegexPatternNotStaticVisitor visitor = new AvoidRegexPatternNotStaticVisitor(); - @Override - public List nodesToVisit() { - return Collections.singletonList(Tree.Kind.METHOD); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.METHOD); + } - @Override - public void visitNode(@Nonnull Tree tree) { - if (tree instanceof MethodTree) { - final MethodTree methodTree = (MethodTree) tree; + @Override + public void visitNode(@Nonnull Tree tree) { + if (tree instanceof MethodTree) { + final MethodTree methodTree = (MethodTree) tree; - if (!methodTree.is(Tree.Kind.CONSTRUCTOR)) { - methodTree.accept(visitor); - } - } + if (!methodTree.is(Tree.Kind.CONSTRUCTOR)) { + methodTree.accept(visitor); + } } + } - private class AvoidRegexPatternNotStaticVisitor extends BaseTreeVisitor { - - @Override - public void visitMethodInvocation(@Nonnull MethodInvocationTree tree) { - if (PATTERN_COMPILE.matches(tree)) { - reportIssue(tree, MESSAGE_RULE); - } else { - super.visitMethodInvocation(tree); - } - } + private class AvoidRegexPatternNotStaticVisitor extends BaseTreeVisitor { + @Override + public void visitMethodInvocation(@Nonnull MethodInvocationTree tree) { + if (PATTERN_COMPILE.matches(tree)) { + reportIssue(tree, MESSAGE_RULE); + } else { + super.visitMethodInvocation(tree); + } } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoop.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoop.java index 0e830dc..c102f1f 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoop.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoop.java @@ -17,13 +17,13 @@ */ package org.greencodeinitiative.creedengo.java.checks; +import static org.sonar.plugins.java.api.semantic.MethodMatchers.CONSTRUCTOR; + import java.util.Arrays; import java.util.List; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.MethodMatchers; -import static org.sonar.plugins.java.api.semantic.MethodMatchers.CONSTRUCTOR; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; import org.sonar.plugins.java.api.tree.MethodInvocationTree; import org.sonar.plugins.java.api.tree.Tree; @@ -35,58 +35,92 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S72") public class AvoidSQLRequestInLoop extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Avoid SQL request in loop"; - private static final String JAVA_SQL_STATEMENT = "java.sql.Statement"; - private static final String JAVA_SQL_CONNECTION = "java.sql.Connection"; - private static final String SPRING_JDBC_OPERATIONS = "org.springframework.jdbc.core.JdbcOperations"; + protected static final String MESSAGERULE = "Avoid SQL request in loop"; + private static final String JAVA_SQL_STATEMENT = "java.sql.Statement"; + private static final String JAVA_SQL_CONNECTION = "java.sql.Connection"; + private static final String SPRING_JDBC_OPERATIONS = + "org.springframework.jdbc.core.JdbcOperations"; - private static final MethodMatchers SQL_METHOD = MethodMatchers.or( - MethodMatchers.create().ofSubTypes("org.hibernate.Session").names("createQuery", "createSQLQuery") - .withAnyParameters().build(), - MethodMatchers.create().ofSubTypes(JAVA_SQL_STATEMENT) - .names("executeQuery", "execute", "executeUpdate", "executeLargeUpdate") // addBatch is recommended - .withAnyParameters().build(), - MethodMatchers.create().ofSubTypes(JAVA_SQL_CONNECTION) - .names("prepareStatement", "prepareCall", "nativeSQL") - .withAnyParameters().build(), - MethodMatchers.create().ofTypes("javax.persistence.EntityManager") - .names("createNativeQuery", "createQuery") - .withAnyParameters().build(), - MethodMatchers.create().ofSubTypes(SPRING_JDBC_OPERATIONS) - .names("batchUpdate", "execute", "query", "queryForList", "queryForMap", "queryForObject", - "queryForRowSet", "queryForInt", "queryForLong", "update") - .withAnyParameters().build(), - MethodMatchers.create().ofTypes("org.springframework.jdbc.core.PreparedStatementCreatorFactory") - .names(CONSTRUCTOR, "newPreparedStatementCreator") - .withAnyParameters().build(), - MethodMatchers.create().ofSubTypes("javax.jdo.PersistenceManager").names("newQuery") - .withAnyParameters().build(), - MethodMatchers.create().ofSubTypes("javax.jdo.Query").names("setFilter", "setGrouping") - .withAnyParameters().build()); + private static final MethodMatchers SQL_METHOD = + MethodMatchers.or( + MethodMatchers.create() + .ofSubTypes("org.hibernate.Session") + .names("createQuery", "createSQLQuery") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofSubTypes(JAVA_SQL_STATEMENT) + .names( + "executeQuery", + "execute", + "executeUpdate", + "executeLargeUpdate") // addBatch is recommended + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofSubTypes(JAVA_SQL_CONNECTION) + .names("prepareStatement", "prepareCall", "nativeSQL") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofTypes("javax.persistence.EntityManager") + .names("createNativeQuery", "createQuery") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofSubTypes(SPRING_JDBC_OPERATIONS) + .names( + "batchUpdate", + "execute", + "query", + "queryForList", + "queryForMap", + "queryForObject", + "queryForRowSet", + "queryForInt", + "queryForLong", + "update") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofTypes("org.springframework.jdbc.core.PreparedStatementCreatorFactory") + .names(CONSTRUCTOR, "newPreparedStatementCreator") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofSubTypes("javax.jdo.PersistenceManager") + .names("newQuery") + .withAnyParameters() + .build(), + MethodMatchers.create() + .ofSubTypes("javax.jdo.Query") + .names("setFilter", "setGrouping") + .withAnyParameters() + .build()); - private final AvoidSQLRequestInLoopVisitor visitorInFile = new AvoidSQLRequestInLoopVisitor(); + private final AvoidSQLRequestInLoopVisitor visitorInFile = new AvoidSQLRequestInLoopVisitor(); - @Override - public List nodesToVisit() { - return Arrays.asList( - Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, - Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT); - } + @Override + public List nodesToVisit() { + return Arrays.asList( + Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, + Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT); + } - @Override - public void visitNode(Tree tree) { - tree.accept(visitorInFile); - } + @Override + public void visitNode(Tree tree) { + tree.accept(visitorInFile); + } - private class AvoidSQLRequestInLoopVisitor extends BaseTreeVisitor { + private class AvoidSQLRequestInLoopVisitor extends BaseTreeVisitor { - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (SQL_METHOD.matches(tree)) { - reportIssue(tree, MESSAGERULE); - } else { - super.visitMethodInvocation(tree); - } - } + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + if (SQL_METHOD.matches(tree)) { + reportIssue(tree, MESSAGERULE); + } else { + super.visitMethodInvocation(tree); + } } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchUpdate.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchUpdate.java index 20c3e23..2997ba1 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchUpdate.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchUpdate.java @@ -17,18 +17,19 @@ */ package org.greencodeinitiative.creedengo.java.checks; +import static java.util.Arrays.asList; +import static org.greencodeinitiative.creedengo.java.checks.enums.ConstOrLiteralDeclare.isLiteral; +import static org.sonar.plugins.java.api.semantic.Type.Primitives.INT; +import static org.sonar.plugins.java.api.tree.Tree.Kind.MEMBER_SELECT; +import static org.sonar.plugins.java.api.tree.Tree.Kind.METHOD_INVOCATION; + import java.sql.PreparedStatement; import java.util.List; import java.util.stream.Stream; - import org.greencodeinitiative.creedengo.java.checks.enums.ConstOrLiteralDeclare; -import static org.greencodeinitiative.creedengo.java.checks.enums.ConstOrLiteralDeclare.isLiteral; -import static java.util.Arrays.asList; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.MethodMatchers; -import static org.sonar.plugins.java.api.semantic.Type.Primitives.INT; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; import org.sonar.plugins.java.api.tree.MethodInvocationTree; @@ -36,57 +37,66 @@ import org.sonar.plugins.java.api.tree.Tree.Kind; import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; -import static org.sonar.plugins.java.api.tree.Tree.Kind.MEMBER_SELECT; -import static org.sonar.plugins.java.api.tree.Tree.Kind.METHOD_INVOCATION; - @Rule(key = "GCI78") @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC78") @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S78") public class AvoidSetConstantInBatchUpdate extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Avoid setting constants in batch update"; - private final AvoidSetConstantInBatchUpdateVisitor visitorInFile = new AvoidSetConstantInBatchUpdateVisitor(); + protected static final String MESSAGERULE = "Avoid setting constants in batch update"; + private final AvoidSetConstantInBatchUpdateVisitor visitorInFile = + new AvoidSetConstantInBatchUpdateVisitor(); - @Override - public List nodesToVisit() { - return asList( - Tree.Kind.FOR_EACH_STATEMENT, - Tree.Kind.FOR_STATEMENT, - Tree.Kind.WHILE_STATEMENT, - Tree.Kind.DO_STATEMENT); - } + @Override + public List nodesToVisit() { + return asList( + Tree.Kind.FOR_EACH_STATEMENT, + Tree.Kind.FOR_STATEMENT, + Tree.Kind.WHILE_STATEMENT, + Tree.Kind.DO_STATEMENT); + } - @Override - public void visitNode(Tree tree) { - tree.accept(visitorInFile); - } + @Override + public void visitNode(Tree tree) { + tree.accept(visitorInFile); + } - private class AvoidSetConstantInBatchUpdateVisitor extends BaseTreeVisitor { + private class AvoidSetConstantInBatchUpdateVisitor extends BaseTreeVisitor { - private final MethodMatchers setters = MethodMatchers.create().ofSubTypes(PreparedStatement.class.getName()) - .names("setBoolean", "setByte", "setShort", "setInt", "setLong", "setFloat", "setDouble", - "setBigDecimal", "setString") - .addParametersMatcher(args -> args.size() == 2 && args.get(0).isPrimitive(INT)).build(); + private final MethodMatchers setters = + MethodMatchers.create() + .ofSubTypes(PreparedStatement.class.getName()) + .names( + "setBoolean", + "setByte", + "setShort", + "setInt", + "setLong", + "setFloat", + "setDouble", + "setBigDecimal", + "setString") + .addParametersMatcher(args -> args.size() == 2 && args.get(0).isPrimitive(INT)) + .build(); - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (setters.matches(tree) && isConstant(tree.arguments().get(1))) { - reportIssue(tree, MESSAGERULE); - } else { - super.visitMethodInvocation(tree); - } - } + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + if (setters.matches(tree) && isConstant(tree.arguments().get(1))) { + reportIssue(tree, MESSAGERULE); + } else { + super.visitMethodInvocation(tree); + } } + } - private static final boolean isConstant(Tree arg) { + private static final boolean isConstant(Tree arg) { - if (arg.is(METHOD_INVOCATION)) { - MethodInvocationTree m = (MethodInvocationTree) arg; - return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isLiteralDeclare(m)); - } else if (arg.is(MEMBER_SELECT)) { - MemberSelectExpressionTree m = (MemberSelectExpressionTree) arg; - return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isPublicMember(m)); - } - return isLiteral(arg); + if (arg.is(METHOD_INVOCATION)) { + MethodInvocationTree m = (MethodInvocationTree) arg; + return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isLiteralDeclare(m)); + } else if (arg.is(MEMBER_SELECT)) { + MemberSelectExpressionTree m = (MemberSelectExpressionTree) arg; + return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isPublicMember(m)); } + return isLiteral(arg); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopOrStreamCheck.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopOrStreamCheck.java index a71777c..b4c6d0e 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopOrStreamCheck.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopOrStreamCheck.java @@ -19,7 +19,6 @@ import java.util.Arrays; import java.util.List; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.MethodMatchers; @@ -31,94 +30,87 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRC1") public class AvoidSpringRepositoryCallInLoopOrStreamCheck extends IssuableSubscriptionVisitor { - protected static final String RULE_MESSAGE = "Avoid Spring repository call in loop or stream"; + protected static final String RULE_MESSAGE = "Avoid Spring repository call in loop or stream"; - private static final String BASE_STREAM = "java.util.stream.BaseStream"; - private static final String SPRING_REPOSITORY = "org.springframework.data.repository.Repository"; + private static final String BASE_STREAM = "java.util.stream.BaseStream"; + private static final String SPRING_REPOSITORY = "org.springframework.data.repository.Repository"; - private static final MethodMatchers SPRING_REPOSITORY_METHOD = - MethodMatchers - .create() - .ofSubTypes(SPRING_REPOSITORY) - .anyName() - .withAnyParameters() - .build(); + private static final MethodMatchers SPRING_REPOSITORY_METHOD = + MethodMatchers.create().ofSubTypes(SPRING_REPOSITORY).anyName().withAnyParameters().build(); - private static final MethodMatchers STREAM_FOREACH_METHOD = - MethodMatchers - .create() - .ofSubTypes(BASE_STREAM) - .names("forEach", "forEachOrdered", "map", "peek") - .withAnyParameters() - .build(); + private static final MethodMatchers STREAM_FOREACH_METHOD = + MethodMatchers.create() + .ofSubTypes(BASE_STREAM) + .names("forEach", "forEachOrdered", "map", "peek") + .withAnyParameters() + .build(); - private final AvoidSpringRepositoryCallInLoopCheckVisitor visitorInFile = new AvoidSpringRepositoryCallInLoopCheckVisitor(); - private final StreamVisitor streamVisitor = new StreamVisitor(); + private final AvoidSpringRepositoryCallInLoopCheckVisitor visitorInFile = + new AvoidSpringRepositoryCallInLoopCheckVisitor(); + private final StreamVisitor streamVisitor = new StreamVisitor(); - private final AncestorMethodVisitor ancestorMethodVisitor = new AncestorMethodVisitor(); + private final AncestorMethodVisitor ancestorMethodVisitor = new AncestorMethodVisitor(); - @Override - public List nodesToVisit() { - return Arrays.asList( - Tree.Kind.FOR_EACH_STATEMENT, // loop - Tree.Kind.FOR_STATEMENT, // loop - Tree.Kind.WHILE_STATEMENT, // loop - Tree.Kind.DO_STATEMENT, // loop - Tree.Kind.METHOD_INVOCATION // stream + @Override + public List nodesToVisit() { + return Arrays.asList( + Tree.Kind.FOR_EACH_STATEMENT, // loop + Tree.Kind.FOR_STATEMENT, // loop + Tree.Kind.WHILE_STATEMENT, // loop + Tree.Kind.DO_STATEMENT, // loop + Tree.Kind.METHOD_INVOCATION // stream ); + } + + @Override + public void visitNode(Tree tree) { + if (tree.is(Tree.Kind.METHOD_INVOCATION)) { // stream process + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; + if (STREAM_FOREACH_METHOD.matches(methodInvocationTree)) { + tree.accept(streamVisitor); + } + } else { // loop process + tree.accept(visitorInFile); } + } + private class AvoidSpringRepositoryCallInLoopCheckVisitor extends BaseTreeVisitor { @Override - public void visitNode(Tree tree) { - if (tree.is(Tree.Kind.METHOD_INVOCATION)) { // stream process - MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; - if (STREAM_FOREACH_METHOD.matches(methodInvocationTree)) { - tree.accept(streamVisitor); - } - } else { // loop process - tree.accept(visitorInFile); - } - } - - private class AvoidSpringRepositoryCallInLoopCheckVisitor extends BaseTreeVisitor { - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (SPRING_REPOSITORY_METHOD.matches(tree)) { - reportIssue(tree, RULE_MESSAGE); - } else { - super.visitMethodInvocation(tree); - } - } - + public void visitMethodInvocation(MethodInvocationTree tree) { + if (SPRING_REPOSITORY_METHOD.matches(tree)) { + reportIssue(tree, RULE_MESSAGE); + } else { + super.visitMethodInvocation(tree); + } } + } - private class StreamVisitor extends BaseTreeVisitor { - - @Override - public void visitLambdaExpression(LambdaExpressionTree tree) { - tree.accept(ancestorMethodVisitor); - } + private class StreamVisitor extends BaseTreeVisitor { + @Override + public void visitLambdaExpression(LambdaExpressionTree tree) { + tree.accept(ancestorMethodVisitor); } + } - private class AncestorMethodVisitor extends BaseTreeVisitor { + private class AncestorMethodVisitor extends BaseTreeVisitor { - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - // if the method is a spring repository method, report an issue - if (SPRING_REPOSITORY_METHOD.matches(tree)) { - reportIssue(tree, RULE_MESSAGE); - } else { // else, check if the method is a method invocation and check recursively - if (tree.methodSelect().is(Tree.Kind.MEMBER_SELECT)) { - MemberSelectExpressionTree memberSelectTree = (MemberSelectExpressionTree) tree.methodSelect(); - if ( memberSelectTree.expression().is(Tree.Kind.METHOD_INVOCATION)) { - MethodInvocationTree methodInvocationTree = (MethodInvocationTree) memberSelectTree.expression(); - methodInvocationTree.accept(ancestorMethodVisitor); - } - } - } + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + // if the method is a spring repository method, report an issue + if (SPRING_REPOSITORY_METHOD.matches(tree)) { + reportIssue(tree, RULE_MESSAGE); + } else { // else, check if the method is a method invocation and check recursively + if (tree.methodSelect().is(Tree.Kind.MEMBER_SELECT)) { + MemberSelectExpressionTree memberSelectTree = + (MemberSelectExpressionTree) tree.methodSelect(); + if (memberSelectTree.expression().is(Tree.Kind.METHOD_INVOCATION)) { + MethodInvocationTree methodInvocationTree = + (MethodInvocationTree) memberSelectTree.expression(); + methodInvocationTree.accept(ancestorMethodVisitor); + } } - + } } - + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java index cb335e0..28cfbb3 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java @@ -17,10 +17,9 @@ */ package org.greencodeinitiative.creedengo.java.checks; +import com.google.re2j.Pattern; import java.util.Collections; import java.util.List; - -import com.google.re2j.Pattern; import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.MethodMatchers; @@ -36,33 +35,35 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "SDMLQ1") public class AvoidStatementForDMLQueries extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "You must not use Statement for a DML query"; + protected static final String MESSAGERULE = "You must not use Statement for a DML query"; - private static final Pattern PATTERN = Pattern.compile("(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s?.*", Pattern.CASE_INSENSITIVE); + private static final Pattern PATTERN = + Pattern.compile("(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s?.*", Pattern.CASE_INSENSITIVE); - private static final MethodMatchers EXECUTE_METHOD = MethodMatchers.or( - MethodMatchers.create().ofSubTypes("java.sql.Statement").names("executeUpdate") - .withAnyParameters().build()); + private static final MethodMatchers EXECUTE_METHOD = + MethodMatchers.or( + MethodMatchers.create() + .ofSubTypes("java.sql.Statement") + .names("executeUpdate") + .withAnyParameters() + .build()); - @Override - public List nodesToVisit() { - return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); + } - @Override - public void visitNode(Tree tree) { - MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; - if (!EXECUTE_METHOD.matches(methodInvocationTree)) - return; - Arguments arguments = methodInvocationTree.arguments(); - if (arguments.isEmpty()) - return; - ExpressionTree first = arguments.get(0); - if (first.is(Tree.Kind.STRING_LITERAL)) { - LiteralTree literalTree = (LiteralTree) first; - String str = literalTree.value(); - if (PATTERN.matcher(str).find()) - reportIssue(literalTree, MESSAGERULE); - } + @Override + public void visitNode(Tree tree) { + MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; + if (!EXECUTE_METHOD.matches(methodInvocationTree)) return; + Arguments arguments = methodInvocationTree.arguments(); + if (arguments.isEmpty()) return; + ExpressionTree first = arguments.get(0); + if (first.is(Tree.Kind.STRING_LITERAL)) { + LiteralTree literalTree = (LiteralTree) first; + String str = literalTree.value(); + if (PATTERN.matcher(str).find()) reportIssue(literalTree, MESSAGERULE); } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java index 8017381..bd07b8f 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java @@ -20,9 +20,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; - import javax.annotation.Nonnull; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; @@ -35,36 +33,32 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S76") public class AvoidUsageOfStaticCollections extends IssuableSubscriptionVisitor { - protected static final String MESSAGE_RULE = "Avoid usage of static collections."; + protected static final String MESSAGE_RULE = "Avoid usage of static collections."; - private final AvoidUsageOfStaticCollectionsVisitor visitor = new AvoidUsageOfStaticCollectionsVisitor(); + private final AvoidUsageOfStaticCollectionsVisitor visitor = + new AvoidUsageOfStaticCollectionsVisitor(); - @Override - public List nodesToVisit() { - return Collections.singletonList( - Tree.Kind.VARIABLE - ); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.VARIABLE); + } - @Override - public void visitNode(@Nonnull Tree tree) { - tree.accept(visitor); - } - - private class AvoidUsageOfStaticCollectionsVisitor extends BaseTreeVisitor { + @Override + public void visitNode(@Nonnull Tree tree) { + tree.accept(visitor); + } - @Override - public void visitVariable(@Nonnull VariableTree tree) { - if (tree.symbol().isStatic() && - (tree.type().symbolType().isSubtypeOf(Iterable.class.getName()) || - tree.type().symbolType().is(Map.class.getName())) - ) { - reportIssue(tree, MESSAGE_RULE); - } else { - super.visitVariable(tree); - } - } + private class AvoidUsageOfStaticCollectionsVisitor extends BaseTreeVisitor { + @Override + public void visitVariable(@Nonnull VariableTree tree) { + if (tree.symbol().isStatic() + && (tree.type().symbolType().isSubtypeOf(Iterable.class.getName()) + || tree.type().symbolType().is(Map.class.getName()))) { + reportIssue(tree, MESSAGE_RULE); + } else { + super.visitVariable(tree); + } } - + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java index 2b66914..1552134 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java @@ -22,9 +22,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; - import javax.annotation.ParametersAreNonnullByDefault; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.JavaFileScannerContext; @@ -34,60 +32,62 @@ import org.sonar.plugins.java.api.tree.TryStatementTree; import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; - @Rule(key = "GCI79") @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC79") @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S79") public class FreeResourcesOfAutoCloseableInterface extends IssuableSubscriptionVisitor { - private final Deque withinTry = new LinkedList<>(); - private final Deque> toReport = new LinkedList<>(); + private final Deque withinTry = new LinkedList<>(); + private final Deque> toReport = new LinkedList<>(); - private static final String JAVA_LANG_AUTOCLOSEABLE = "java.lang.AutoCloseable"; - protected static final String MESSAGE_RULE = "try-with-resources Statement needs to be implemented for any object that implements the AutoClosable interface."; + private static final String JAVA_LANG_AUTOCLOSEABLE = "java.lang.AutoCloseable"; + protected static final String MESSAGE_RULE = + "try-with-resources Statement needs to be implemented for any object that implements the AutoClosable interface."; - @Override - @ParametersAreNonnullByDefault - public void leaveFile(JavaFileScannerContext context) { - withinTry.clear(); - toReport.clear(); - } + @Override + @ParametersAreNonnullByDefault + public void leaveFile(JavaFileScannerContext context) { + withinTry.clear(); + toReport.clear(); + } - @Override - public List nodesToVisit() { - return Arrays.asList(Tree.Kind.TRY_STATEMENT, Tree.Kind.NEW_CLASS); - } + @Override + public List nodesToVisit() { + return Arrays.asList(Tree.Kind.TRY_STATEMENT, Tree.Kind.NEW_CLASS); + } - @Override - public void visitNode(Tree tree) { - if (tree.is(Tree.Kind.TRY_STATEMENT)) { - withinTry.push((TryStatementTree) tree); - if (withinTry.size() != toReport.size()) { - toReport.push(new ArrayList<>()); - } - } - if (tree.is(Tree.Kind.NEW_CLASS) && ((NewClassTree) tree).symbolType().isSubtypeOf(JAVA_LANG_AUTOCLOSEABLE) && withinStandardTryWithFinally()) { - assert toReport.peek() != null; - toReport.peek().add(tree); - } + @Override + public void visitNode(Tree tree) { + if (tree.is(Tree.Kind.TRY_STATEMENT)) { + withinTry.push((TryStatementTree) tree); + if (withinTry.size() != toReport.size()) { + toReport.push(new ArrayList<>()); + } } - - @Override - public void leaveNode(Tree tree) { - if (tree.is(Tree.Kind.TRY_STATEMENT)) { - List secondaryTrees = toReport.pop(); - if (!secondaryTrees.isEmpty()) { - reportIssue(tree, MESSAGE_RULE); - } - } + if (tree.is(Tree.Kind.NEW_CLASS) + && ((NewClassTree) tree).symbolType().isSubtypeOf(JAVA_LANG_AUTOCLOSEABLE) + && withinStandardTryWithFinally()) { + assert toReport.peek() != null; + toReport.peek().add(tree); } + } - private boolean withinStandardTryWithFinally() { - if (withinTry.isEmpty() || !withinTry.peek().resourceList().isEmpty()) return false; - assert withinTry.peek() != null; - return withinTry.peek().finallyBlock() != null; + @Override + public void leaveNode(Tree tree) { + if (tree.is(Tree.Kind.TRY_STATEMENT)) { + List secondaryTrees = toReport.pop(); + if (!secondaryTrees.isEmpty()) { + reportIssue(tree, MESSAGE_RULE); + } } + } - public boolean isCompatibleWithJavaVersion(JavaVersion version) { - return version.isJava7Compatible(); - } + private boolean withinStandardTryWithFinally() { + if (withinTry.isEmpty() || !withinTry.peek().resourceList().isEmpty()) return false; + assert withinTry.peek() != null; + return withinTry.peek().finallyBlock() != null; + } + + public boolean isCompatibleWithJavaVersion(JavaVersion version) { + return version.isJava7Compatible(); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java index d5a2a42..cc2afc1 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.Tree; @@ -31,15 +30,15 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S67") public class IncrementCheck extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Use ++i instead of i++"; + protected static final String MESSAGERULE = "Use ++i instead of i++"; - @Override - public List nodesToVisit() { - return Collections.singletonList(Kind.POSTFIX_INCREMENT); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Kind.POSTFIX_INCREMENT); + } - @Override - public void visitNode(Tree tree) { - reportIssue(tree, MESSAGERULE); - } + @Override + public void visitNode(Tree tree) { + reportIssue(tree, MESSAGERULE); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java index 7bcb3b7..1f0897c 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.NewClassTree; @@ -32,20 +31,21 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRSP0032") public class InitializeBufferWithAppropriateSize extends IssuableSubscriptionVisitor { - protected static final String RULE_MESSAGE = "Initialize StringBuilder or StringBuffer with appropriate size"; + protected static final String RULE_MESSAGE = + "Initialize StringBuilder or StringBuffer with appropriate size"; - @Override - public List nodesToVisit() { - return Collections.singletonList(Kind.NEW_CLASS); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Kind.NEW_CLASS); + } - @Override - public void visitNode(Tree tree) { - NewClassTree newClassTree = (NewClassTree) tree; - if ((newClassTree.symbolType().is("java.lang.StringBuffer") - || newClassTree.symbolType().is("java.lang.StringBuilder")) - && newClassTree.arguments().isEmpty()) { - reportIssue(tree, RULE_MESSAGE); - } + @Override + public void visitNode(Tree tree) { + NewClassTree newClassTree = (NewClassTree) tree; + if ((newClassTree.symbolType().is("java.lang.StringBuffer") + || newClassTree.symbolType().is("java.lang.StringBuilder")) + && newClassTree.arguments().isEmpty()) { + reportIssue(tree, RULE_MESSAGE); } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstants.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstants.java index 6533256..fa0f6f4 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstants.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstants.java @@ -1,5 +1,7 @@ package org.greencodeinitiative.creedengo.java.checks; +import java.util.List; +import javax.annotation.Nonnull; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.check.Rule; @@ -7,121 +9,116 @@ import org.sonar.plugins.java.api.tree.*; import org.sonar.plugins.java.api.tree.Tree.Kind; -import javax.annotation.Nonnull; -import java.util.List; - @Rule(key = "GCI82") public class MakeNonReassignedVariablesConstants extends IssuableSubscriptionVisitor { - protected static final String MESSAGE_RULE = "The variable is never reassigned and can be 'final'"; - - private static final Logger LOGGER = Loggers.get(MakeNonReassignedVariablesConstants.class); - - @Override - public List nodesToVisit() { - return List.of(Kind.VARIABLE); + protected static final String MESSAGE_RULE = + "The variable is never reassigned and can be 'final'"; + + private static final Logger LOGGER = Loggers.get(MakeNonReassignedVariablesConstants.class); + + @Override + public List nodesToVisit() { + return List.of(Kind.VARIABLE); + } + + @Override + public void visitNode(@Nonnull Tree tree) { + VariableTree variableTree = (VariableTree) tree; + LOGGER.debug("Variable > " + getVariableNameForLogger(variableTree)); + LOGGER.debug( + " => isNotFinalAndNotStatic(variableTree) = " + isNotFinalAndNotStatic(variableTree)); + LOGGER.debug(" => usages = " + variableTree.symbol().usages().size()); + LOGGER.debug(" => isNotReassigned = " + isNotReassigned(variableTree)); + + if (isNotFinalAndNotStatic(variableTree) && isNotReassigned(variableTree)) { + reportIssue(tree, MESSAGE_RULE); + } else { + super.visitNode(tree); } - - @Override - public void visitNode(@Nonnull Tree tree) { - VariableTree variableTree = (VariableTree) tree; - LOGGER.debug("Variable > " + getVariableNameForLogger(variableTree)); - LOGGER.debug(" => isNotFinalAndNotStatic(variableTree) = " + isNotFinalAndNotStatic(variableTree)); - LOGGER.debug(" => usages = " + variableTree.symbol().usages().size()); - LOGGER.debug(" => isNotReassigned = " + isNotReassigned(variableTree)); - - if (isNotFinalAndNotStatic(variableTree) && isNotReassigned(variableTree)) { - reportIssue(tree, MESSAGE_RULE); - } else { - super.visitNode(tree); - } + } + + private static boolean isNotReassigned(VariableTree variableTree) { + return variableTree.symbol().usages().stream() + .noneMatch(MakeNonReassignedVariablesConstants::parentIsAssignment); + } + + private static boolean parentIsAssignment(Tree tree) { + return parentIsKind( + tree, + Kind.ASSIGNMENT, + Kind.MULTIPLY_ASSIGNMENT, + Kind.DIVIDE_ASSIGNMENT, + Kind.REMAINDER_ASSIGNMENT, + Kind.PLUS_ASSIGNMENT, + Kind.MINUS_ASSIGNMENT, + Kind.LEFT_SHIFT_ASSIGNMENT, + Kind.RIGHT_SHIFT_ASSIGNMENT, + Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, + Kind.AND_ASSIGNMENT, + Kind.XOR_ASSIGNMENT, + Kind.OR_ASSIGNMENT, + Kind.POSTFIX_INCREMENT, + Kind.POSTFIX_DECREMENT, + Kind.PREFIX_INCREMENT, + Kind.PREFIX_DECREMENT); + } + + private static boolean parentIsKind(Tree tree, Kind... orKind) { + Tree parent = tree.parent(); + if (parent == null) return false; + + for (Kind k : orKind) { + if (parent.is(k)) return true; } - private static boolean isNotReassigned(VariableTree variableTree) { - return variableTree.symbol() - .usages() - .stream() - .noneMatch(MakeNonReassignedVariablesConstants::parentIsAssignment); - } + return false; + } - private static boolean parentIsAssignment(Tree tree) { - return parentIsKind(tree, - Kind.ASSIGNMENT, - Kind.MULTIPLY_ASSIGNMENT, - Kind.DIVIDE_ASSIGNMENT, - Kind.REMAINDER_ASSIGNMENT, - Kind.PLUS_ASSIGNMENT, - Kind.MINUS_ASSIGNMENT, - Kind.LEFT_SHIFT_ASSIGNMENT, - Kind.RIGHT_SHIFT_ASSIGNMENT, - Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, - Kind.AND_ASSIGNMENT, - Kind.XOR_ASSIGNMENT, - Kind.OR_ASSIGNMENT, - Kind.POSTFIX_INCREMENT, - Kind.POSTFIX_DECREMENT, - Kind.PREFIX_INCREMENT, - Kind.PREFIX_DECREMENT - ); - } + private static boolean isNotFinalAndNotStatic(VariableTree variableTree) { + return hasNoneOf(variableTree.modifiers(), Modifier.FINAL, Modifier.STATIC); + } - private static boolean parentIsKind(Tree tree, Kind... orKind) { - Tree parent = tree.parent(); - if (parent == null) return false; + private static boolean hasNoneOf(ModifiersTree modifiersTree, Modifier... unexpectedModifiers) { + return !hasAnyOf(modifiersTree, unexpectedModifiers); + } - for (Kind k : orKind) { - if (parent.is(k)) return true; - } - - return false; + private static boolean hasAnyOf(ModifiersTree modifiersTree, Modifier... expectedModifiers) { + for (Modifier expectedModifier : expectedModifiers) { + if (hasModifier(modifiersTree, expectedModifier)) { + return true; + } } - - private static boolean isNotFinalAndNotStatic(VariableTree variableTree) { - return hasNoneOf(variableTree.modifiers(), Modifier.FINAL, Modifier.STATIC); + return false; + } + + public static boolean hasModifier(ModifiersTree modifiersTree, Modifier expectedModifier) { + for (ModifierKeywordTree modifierKeywordTree : modifiersTree.modifiers()) { + if (modifierKeywordTree.modifier() == expectedModifier) { + return true; + } } - private static boolean hasNoneOf(ModifiersTree modifiersTree, Modifier... unexpectedModifiers) { - return !hasAnyOf(modifiersTree, unexpectedModifiers); - } + return false; + } - private static boolean hasAnyOf(ModifiersTree modifiersTree, Modifier... expectedModifiers) { - for(Modifier expectedModifier : expectedModifiers) { - if (hasModifier(modifiersTree, expectedModifier)) { - return true; - } - } - return false; - } + private String getVariableNameForLogger(VariableTree variableTree) { + String name = variableTree.simpleName().name(); - public static boolean hasModifier(ModifiersTree modifiersTree, Modifier expectedModifier) { - for(ModifierKeywordTree modifierKeywordTree : modifiersTree.modifiers()) { - if (modifierKeywordTree.modifier() == expectedModifier) { - return true; - } - } + if (variableTree.parent() != null) return name; - return false; + if (variableTree.parent().is(Kind.CLASS)) { + ClassTree cTree = (ClassTree) variableTree.parent(); + name += " --- from CLASS '" + cTree.simpleName() + "'"; } - - private String getVariableNameForLogger(VariableTree variableTree) { - String name = variableTree.simpleName().name(); - - if (variableTree.parent() != null) return name; - - if (variableTree.parent().is(Kind.CLASS)) { - ClassTree cTree = (ClassTree) variableTree.parent(); - name += " --- from CLASS '" + cTree.simpleName() + "'"; - } - if (variableTree.parent().is(Kind.BLOCK)) { - BlockTree bTree = (BlockTree) variableTree.parent(); - if (bTree.parent() != null && bTree.parent().is(Kind.METHOD)) { - MethodTree mTree = (MethodTree) bTree.parent(); - name += " --- from METHOD '" + mTree.simpleName() + "'"; - } - } - - return name; - + if (variableTree.parent().is(Kind.BLOCK)) { + BlockTree bTree = (BlockTree) variableTree.parent(); + if (bTree.parent() != null && bTree.parent().is(Kind.METHOD)) { + MethodTree mTree = (MethodTree) bTree.parent(); + name += " --- from METHOD '" + mTree.simpleName() + "'"; + } } + return name; + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoop.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoop.java index b364b55..26ef213 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoop.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoop.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; @@ -42,104 +41,109 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S69") public class NoFunctionCallWhenDeclaringForLoop extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Do not call a function when declaring a for-type loop"; - - private static final Map> linesWithIssuesByClass = new HashMap<>(); + protected static final String MESSAGERULE = + "Do not call a function when declaring a for-type loop"; - @Override - public List nodesToVisit() { - return Collections.singletonList(Tree.Kind.FOR_STATEMENT); - } + private static final Map> linesWithIssuesByClass = new HashMap<>(); - @Override - public void visitNode(Tree tree) { - ForStatementTree method = (ForStatementTree) tree; - MethodInvocationInForStatementVisitor invocationMethodVisitor = new MethodInvocationInForStatementVisitor(); - ExpressionTree condition = method.condition(); - if (null != condition) { - method.condition().accept(invocationMethodVisitor); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.FOR_STATEMENT); + } - // update - method.update().accept(invocationMethodVisitor); + @Override + public void visitNode(Tree tree) { + ForStatementTree method = (ForStatementTree) tree; + MethodInvocationInForStatementVisitor invocationMethodVisitor = + new MethodInvocationInForStatementVisitor(); + ExpressionTree condition = method.condition(); + if (null != condition) { + method.condition().accept(invocationMethodVisitor); } - private class MethodInvocationInForStatementVisitor extends BaseTreeVisitor { + // update + method.update().accept(invocationMethodVisitor); + } - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (!lineAlreadyHasThisIssue(tree) && !isIteratorMethod(tree)) { - report(tree); - return; - } - super.visitMethodInvocation(tree); - } - - private boolean isIteratorMethod(MethodInvocationTree tree) { - boolean isIterator = tree.methodSymbol().owner().type().isSubtypeOf("java.util.Iterator"); - String methodName = tree.methodSelect().lastToken().text(); - boolean isMethodNext = methodName.equals("next"); - boolean isMethodHasNext = methodName.equals("hasNext"); - return isIterator && (isMethodNext || isMethodHasNext); - } + private class MethodInvocationInForStatementVisitor extends BaseTreeVisitor { - private boolean lineAlreadyHasThisIssue(Tree tree) { - if (tree.firstToken() != null) { - final String classname = getFullyQualifiedNameOfClassOf(tree); - final int line = tree.firstToken().range().start().line(); + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + if (!lineAlreadyHasThisIssue(tree) && !isIteratorMethod(tree)) { + report(tree); + return; + } + super.visitMethodInvocation(tree); + } - return linesWithIssuesByClass.containsKey(classname) - && linesWithIssuesByClass.get(classname).contains(line); - } + private boolean isIteratorMethod(MethodInvocationTree tree) { + boolean isIterator = tree.methodSymbol().owner().type().isSubtypeOf("java.util.Iterator"); + String methodName = tree.methodSelect().lastToken().text(); + boolean isMethodNext = methodName.equals("next"); + boolean isMethodHasNext = methodName.equals("hasNext"); + return isIterator && (isMethodNext || isMethodHasNext); + } - return false; - } + private boolean lineAlreadyHasThisIssue(Tree tree) { + if (tree.firstToken() != null) { + final String classname = getFullyQualifiedNameOfClassOf(tree); + final int line = tree.firstToken().range().start().line(); - private void report(Tree tree) { - if (tree.firstToken() != null) { - final String classname = getFullyQualifiedNameOfClassOf(tree); - final int line = tree.firstToken().range().start().line(); + return linesWithIssuesByClass.containsKey(classname) + && linesWithIssuesByClass.get(classname).contains(line); + } - linesWithIssuesByClass.computeIfAbsent(classname, k -> new ArrayList<>()); + return false; + } - linesWithIssuesByClass.get(classname).add(line); - } + private void report(Tree tree) { + if (tree.firstToken() != null) { + final String classname = getFullyQualifiedNameOfClassOf(tree); + final int line = tree.firstToken().range().start().line(); - reportIssue(tree, MESSAGERULE); - } + linesWithIssuesByClass.computeIfAbsent(classname, k -> new ArrayList<>()); - private String getFullyQualifiedNameOfClassOf(Tree tree) { - Tree parent = tree.parent(); + linesWithIssuesByClass.get(classname).add(line); + } - while (parent != null) { - final Tree grandparent = parent.parent(); + reportIssue(tree, MESSAGERULE); + } - if (parent.is(Tree.Kind.CLASS) && grandparent != null && grandparent.is(Tree.Kind.COMPILATION_UNIT)) { - final String packageName = getPackageName((CompilationUnitTree) grandparent); + private String getFullyQualifiedNameOfClassOf(Tree tree) { + Tree parent = tree.parent(); - return packageName.isEmpty() ? getClassName((ClassTree) parent) - : packageName + '.' + getClassName((ClassTree) parent); - } + while (parent != null) { + final Tree grandparent = parent.parent(); - parent = parent.parent(); - } + if (parent.is(Tree.Kind.CLASS) + && grandparent != null + && grandparent.is(Tree.Kind.COMPILATION_UNIT)) { + final String packageName = getPackageName((CompilationUnitTree) grandparent); - return ""; + return packageName.isEmpty() + ? getClassName((ClassTree) parent) + : packageName + '.' + getClassName((ClassTree) parent); } - private String getPackageName(CompilationUnitTree compilationUnitTree) { - final PackageDeclarationTree packageDeclarationTree = compilationUnitTree.packageDeclaration(); - if (packageDeclarationTree == null) { - return ""; - } + parent = parent.parent(); + } - return packageDeclarationTree.packageName().toString(); - } + return ""; + } - private String getClassName(ClassTree classTree) { - final IdentifierTree simpleName = classTree.simpleName(); - return simpleName == null ? "" : simpleName.toString(); - } + private String getPackageName(CompilationUnitTree compilationUnitTree) { + final PackageDeclarationTree packageDeclarationTree = + compilationUnitTree.packageDeclaration(); + if (packageDeclarationTree == null) { + return ""; + } + + return packageDeclarationTree.packageName().toString(); } + private String getClassName(ClassTree classTree) { + final IdentifierTree simpleName = classTree.simpleName(); + return simpleName == null ? "" : simpleName.toString(); + } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptions.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptions.java index 76a74b2..c8f97aa 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptions.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptions.java @@ -17,10 +17,8 @@ */ package org.greencodeinitiative.creedengo.java.checks; - import java.util.Arrays; import java.util.List; - import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.check.Rule; @@ -37,50 +35,57 @@ @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRSP0028") public class OptimizeReadFileExceptions extends IssuableSubscriptionVisitor { - protected static final String MESSAGERULE = "Optimize Read File Exceptions"; - private static final Logger LOGGER = Loggers.get(OptimizeReadFileExceptions.class); - private boolean isExceptionFound = false; + protected static final String MESSAGERULE = "Optimize Read File Exceptions"; + private static final Logger LOGGER = Loggers.get(OptimizeReadFileExceptions.class); + private boolean isExceptionFound = false; - @Override - public List nodesToVisit() { - return Arrays.asList(Kind.TRY_STATEMENT, Kind.NEW_CLASS); - } + @Override + public List nodesToVisit() { + return Arrays.asList(Kind.TRY_STATEMENT, Kind.NEW_CLASS); + } - @Override - public void visitNode(Tree tree) { - LOGGER.debug("--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - BEGIN"); - if (tree.kind().getAssociatedInterface().equals(NewClassTree.class)) { - LOGGER.debug("interface NewClassTree found"); - NewClassTree newClassTree = (NewClassTree) tree; - if (newClassTree.identifier().symbolType().toString().equals("FileInputStream")) { - LOGGER.debug("identifier 'FileInputStream' found"); - if (this.isExceptionFound) { - LOGGER.debug("exception found => launching 'reportIssue'"); - reportIssue(tree, MESSAGERULE); - } else { - LOGGER.debug("exception NOT found"); - } - } else { - LOGGER.debug("identifier 'FileInputStream' NOT found (real identifier : {}) => No issue launched", newClassTree.identifier().symbolType()); - } + @Override + public void visitNode(Tree tree) { + LOGGER.debug( + "--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - BEGIN"); + if (tree.kind().getAssociatedInterface().equals(NewClassTree.class)) { + LOGGER.debug("interface NewClassTree found"); + NewClassTree newClassTree = (NewClassTree) tree; + if (newClassTree.identifier().symbolType().toString().equals("FileInputStream")) { + LOGGER.debug("identifier 'FileInputStream' found"); + if (this.isExceptionFound) { + LOGGER.debug("exception found => launching 'reportIssue'"); + reportIssue(tree, MESSAGERULE); } else { - LOGGER.debug("interface NewClassTree NOT found (real interface : {}) => casting to TryStatementTree", tree.kind().getAssociatedInterface()); - TryStatementTree tryStatementTree = (TryStatementTree) tree; - List catchTreeList = tryStatementTree.catches(); - - LOGGER.debug("compute 'isExceptionFound'"); - this.isExceptionFound = computeIsExceptionFound(catchTreeList); - LOGGER.debug("isExceptionFound : " + isExceptionFound); + LOGGER.debug("exception NOT found"); } - LOGGER.debug("--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - END"); + } else { + LOGGER.debug( + "identifier 'FileInputStream' NOT found (real identifier : {}) => No issue launched", + newClassTree.identifier().symbolType()); + } + } else { + LOGGER.debug( + "interface NewClassTree NOT found (real interface : {}) => casting to TryStatementTree", + tree.kind().getAssociatedInterface()); + TryStatementTree tryStatementTree = (TryStatementTree) tree; + List catchTreeList = tryStatementTree.catches(); + + LOGGER.debug("compute 'isExceptionFound'"); + this.isExceptionFound = computeIsExceptionFound(catchTreeList); + LOGGER.debug("isExceptionFound : " + isExceptionFound); } + LOGGER.debug( + "--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - END"); + } - private boolean computeIsExceptionFound(List catchTreeList) { - return catchTreeList.stream().anyMatch(catchTree -> + private boolean computeIsExceptionFound(List catchTreeList) { + return catchTreeList.stream() + .anyMatch( + catchTree -> catchTree.parameter().type().symbolType().toString().equals("FileNotFoundException") - || catchTree.parameter().type().symbolType().toString().equals("IOException") - || catchTree.parameter().type().symbolType().toString().equals("Exception") - || catchTree.parameter().type().symbolType().toString().equals("Throwable") - ); - } + || catchTree.parameter().type().symbolType().toString().equals("IOException") + || catchTree.parameter().type().symbolType().toString().equals("Exception") + || catchTree.parameter().type().symbolType().toString().equals("Throwable")); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java index ec971a6..4a68174 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java @@ -17,43 +17,44 @@ */ package org.greencodeinitiative.creedengo.java.checks; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nonnull; import org.sonar.check.Rule; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.tree.BaseTreeVisitor; import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; import org.sonar.plugins.java.api.tree.MethodInvocationTree; import org.sonar.plugins.java.api.tree.Tree; -import javax.annotation.Nonnull; -import java.util.Collections; -import java.util.List; -import java.util.Objects; @Rule(key = "GCI94") public class UseOptionalOrElseGetVsOrElse extends IssuableSubscriptionVisitor { - private static final String MESSAGE_RULE = "Use optional orElseGet instead of orElse."; - private final UseOptionalOrElseGetVsOrElseVisitor visitorInFile = new UseOptionalOrElseGetVsOrElseVisitor(); + private static final String MESSAGE_RULE = "Use optional orElseGet instead of orElse."; + private final UseOptionalOrElseGetVsOrElseVisitor visitorInFile = + new UseOptionalOrElseGetVsOrElseVisitor(); - @Override - public List nodesToVisit() { - return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); - } + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); + } - @Override - public void visitNode(@Nonnull Tree tree) { - tree.accept(visitorInFile); - } + @Override + public void visitNode(@Nonnull Tree tree) { + tree.accept(visitorInFile); + } - private class UseOptionalOrElseGetVsOrElseVisitor extends BaseTreeVisitor { - @Override - public void visitMethodInvocation(MethodInvocationTree tree) { - if (tree.methodSelect().is(Tree.Kind.MEMBER_SELECT) && - Objects.requireNonNull(tree.methodSelect().firstToken()).text().equals("Optional")) { - MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) tree.methodSelect(); - if (memberSelect.identifier().name().equals("orElse")) { - reportIssue(memberSelect, MESSAGE_RULE); - } - } + private class UseOptionalOrElseGetVsOrElseVisitor extends BaseTreeVisitor { + @Override + public void visitMethodInvocation(MethodInvocationTree tree) { + if (tree.methodSelect().is(Tree.Kind.MEMBER_SELECT) + && Objects.requireNonNull(tree.methodSelect().firstToken()).text().equals("Optional")) { + MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) tree.methodSelect(); + if (memberSelect.identifier().name().equals("orElse")) { + reportIssue(memberSelect, MESSAGE_RULE); } + } } + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/checks/enums/ConstOrLiteralDeclare.java b/src/main/java/org/greencodeinitiative/creedengo/java/checks/enums/ConstOrLiteralDeclare.java index 1ef973a..0a09b24 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/checks/enums/ConstOrLiteralDeclare.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/checks/enums/ConstOrLiteralDeclare.java @@ -17,14 +17,7 @@ */ package org.greencodeinitiative.creedengo.java.checks.enums; -import java.math.BigDecimal; -import java.util.Set; - -import org.sonar.plugins.java.api.semantic.MethodMatchers; import static org.sonar.plugins.java.api.semantic.MethodMatchers.create; -import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; -import org.sonar.plugins.java.api.tree.MethodInvocationTree; -import org.sonar.plugins.java.api.tree.Tree; import static org.sonar.plugins.java.api.tree.Tree.Kind.BOOLEAN_LITERAL; import static org.sonar.plugins.java.api.tree.Tree.Kind.CHAR_LITERAL; import static org.sonar.plugins.java.api.tree.Tree.Kind.DOUBLE_LITERAL; @@ -33,197 +26,206 @@ import static org.sonar.plugins.java.api.tree.Tree.Kind.LONG_LITERAL; import static org.sonar.plugins.java.api.tree.Tree.Kind.STRING_LITERAL; import static org.sonar.plugins.java.api.tree.Tree.Kind.TYPE_CAST; + +import java.math.BigDecimal; +import java.util.Set; +import org.sonar.plugins.java.api.semantic.MethodMatchers; +import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; +import org.sonar.plugins.java.api.tree.MethodInvocationTree; +import org.sonar.plugins.java.api.tree.Tree; import org.sonar.plugins.java.api.tree.TypeCastTree; public enum ConstOrLiteralDeclare { + BOOLEAN { + @Override + String className() { + return Boolean.class.getName(); + } + + @Override + Set publicMembers() { + return Set.of("TRUE", "FALSE"); + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + BYTE { + @Override + String className() { + return Byte.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + SHORT { + @Override + String className() { + return Short.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + INTEGER { + @Override + String className() { + return Integer.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + LONG { + @Override + String className() { + return Long.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + FLOAT { + @Override + String className() { + return Float.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + DOUBLE { + @Override + String className() { + return Double.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + CHARACTER { + @Override + String className() { + return Character.class.getName(); + } + + @Override + Set publicMembers() { + return NUMBER_DEFAULT_MEMBERS; + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }, + + BIGDECIMAL { + @Override + String className() { + return BigDecimal.class.getName(); + } + + @Override + Set publicMembers() { + return Set.of("ZERO", "ONE", "TEN"); + } + + @Override + MethodMatchers methodMatchers() { + return DEFAULT_METHOD_MATCHERS; + } + }; + + public boolean isPublicMember(MemberSelectExpressionTree tree) { + + return className().equals(tree.expression().symbolType().fullyQualifiedName()) // strong check + && publicMembers().contains(tree.identifier().toString()); + } + + public boolean isLiteralDeclare(MethodInvocationTree tree) { + + return methodMatchers().matches(tree) + && tree.arguments().stream().allMatch(ConstOrLiteralDeclare::isLiteral); + } + + abstract String className(); + + abstract Set publicMembers(); + + abstract MethodMatchers methodMatchers(); + + private static final Set NUMBER_DEFAULT_MEMBERS = Set.of("MIN_VALUE", "MAX_VALUE"); + + private static final MethodMatchers DEFAULT_METHOD_MATCHERS = + create() + .ofSubTypes(Number.class.getName(), Boolean.class.getName(), Character.class.getName()) + .names("valueOf") + .addParametersMatcher(args -> !args.isEmpty()) + .build(); - BOOLEAN { - @Override - String className() { - return Boolean.class.getName(); - } - - @Override - Set publicMembers() { - return Set.of("TRUE", "FALSE"); - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - BYTE { - @Override - String className() { - return Byte.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - SHORT { - @Override - String className() { - return Short.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - INTEGER { - @Override - String className() { - return Integer.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - LONG { - @Override - String className() { - return Long.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - FLOAT { - @Override - String className() { - return Float.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - DOUBLE { - @Override - String className() { - return Double.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - CHARACTER { - @Override - String className() { - return Character.class.getName(); - } - - @Override - Set publicMembers() { - return NUMBER_DEFAULT_MEMBERS; - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }, - - BIGDECIMAL { - @Override - String className() { - return BigDecimal.class.getName(); - } - - @Override - Set publicMembers() { - return Set.of("ZERO", "ONE", "TEN"); - } - - @Override - MethodMatchers methodMatchers() { - return DEFAULT_METHOD_MATCHERS; - } - }; - - public boolean isPublicMember(MemberSelectExpressionTree tree) { - - return className().equals(tree.expression().symbolType().fullyQualifiedName()) //strong check - && publicMembers().contains(tree.identifier().toString()); - } - - public boolean isLiteralDeclare(MethodInvocationTree tree) { - - return methodMatchers().matches(tree) - && tree.arguments().stream().allMatch(ConstOrLiteralDeclare::isLiteral); - } - - abstract String className(); - - abstract Set publicMembers(); - - abstract MethodMatchers methodMatchers(); - - private static final Set NUMBER_DEFAULT_MEMBERS = Set.of("MIN_VALUE", "MAX_VALUE"); - - private static final MethodMatchers DEFAULT_METHOD_MATCHERS = create() - .ofSubTypes(Number.class.getName(), Boolean.class.getName(), Character.class.getName()).names("valueOf") - .addParametersMatcher(args -> !args.isEmpty()).build(); - - public static final boolean isLiteral(Tree arg) { - if (arg.is(TYPE_CAST)) { - arg = ((TypeCastTree) arg).expression(); - } - return arg.is(BOOLEAN_LITERAL) || - arg.is(INT_LITERAL) || - arg.is(LONG_LITERAL) || - arg.is(FLOAT_LITERAL) || - arg.is(DOUBLE_LITERAL) || - arg.is(STRING_LITERAL) || - arg.is(CHAR_LITERAL); + public static final boolean isLiteral(Tree arg) { + if (arg.is(TYPE_CAST)) { + arg = ((TypeCastTree) arg).expression(); } + return arg.is(BOOLEAN_LITERAL) + || arg.is(INT_LITERAL) + || arg.is(LONG_LITERAL) + || arg.is(FLOAT_LITERAL) + || arg.is(DOUBLE_LITERAL) + || arg.is(STRING_LITERAL) + || arg.is(CHAR_LITERAL); + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/utils/PrinterVisitor.java b/src/main/java/org/greencodeinitiative/creedengo/java/utils/PrinterVisitor.java index fa24589..deec4ce 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/utils/PrinterVisitor.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/utils/PrinterVisitor.java @@ -19,53 +19,51 @@ import java.util.List; import java.util.function.Consumer; - import javax.annotation.Nullable; - import org.sonar.plugins.java.api.tree.BaseTreeVisitor; import org.sonar.plugins.java.api.tree.Tree; public class PrinterVisitor extends BaseTreeVisitor { - private static final int INDENT_SPACES = 2; + private static final int INDENT_SPACES = 2; - private final StringBuilder sb; - private int indentLevel; + private final StringBuilder sb; + private int indentLevel; - public PrinterVisitor() { - sb = new StringBuilder(); - indentLevel = 0; - } + public PrinterVisitor() { + sb = new StringBuilder(); + indentLevel = 0; + } - public static void print(Tree tree, Consumer output) { - PrinterVisitor pv = new PrinterVisitor(); - pv.scan(tree); - output.accept(pv.sb.toString()); - } + public static void print(Tree tree, Consumer output) { + PrinterVisitor pv = new PrinterVisitor(); + pv.scan(tree); + output.accept(pv.sb.toString()); + } - private StringBuilder indent() { - return sb.append(StringUtils.spaces(INDENT_SPACES * indentLevel)); - } + private StringBuilder indent() { + return sb.append(StringUtils.spaces(INDENT_SPACES * indentLevel)); + } - @Override - protected void scan(List trees) { - if (!trees.isEmpty()) { - sb.deleteCharAt(sb.length() - 1); - sb.append(" : [\n"); - super.scan(trees); - indent().append("]\n"); - } + @Override + protected void scan(List trees) { + if (!trees.isEmpty()) { + sb.deleteCharAt(sb.length() - 1); + sb.append(" : [\n"); + super.scan(trees); + indent().append("]\n"); } + } - @Override - protected void scan(@Nullable Tree tree) { - if (tree != null) { - Class[] interfaces = tree.getClass().getInterfaces(); - if (interfaces.length > 0) { - indent().append(interfaces[0].getSimpleName()).append("\n"); - } - } - indentLevel++; - super.scan(tree); - indentLevel--; + @Override + protected void scan(@Nullable Tree tree) { + if (tree != null) { + Class[] interfaces = tree.getClass().getInterfaces(); + if (interfaces.length > 0) { + indent().append(interfaces[0].getSimpleName()).append("\n"); + } } + indentLevel++; + super.scan(tree); + indentLevel--; + } } diff --git a/src/main/java/org/greencodeinitiative/creedengo/java/utils/StringUtils.java b/src/main/java/org/greencodeinitiative/creedengo/java/utils/StringUtils.java index ce66a88..b2238e5 100644 --- a/src/main/java/org/greencodeinitiative/creedengo/java/utils/StringUtils.java +++ b/src/main/java/org/greencodeinitiative/creedengo/java/utils/StringUtils.java @@ -19,20 +19,19 @@ public final class StringUtils { - private StringUtils() { - // Utility class - } - - public static String spaces(int number) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < number; i++) { - sb.append(' '); - } - return sb.toString(); - } + private StringUtils() { + // Utility class + } - public static boolean isNotEmpty(String string) { - return string != null && !string.isEmpty(); + public static String spaces(int number) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < number; i++) { + sb.append(' '); } + return sb.toString(); + } + public static boolean isNotEmpty(String string) { + return string != null && !string.isEmpty(); + } } diff --git a/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json b/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json index 059bf0f..5746c11 100644 --- a/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json +++ b/src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json @@ -2,22 +2,22 @@ "name": "creedengo way", "language": "java", "ruleKeys": [ - "GCI1", - "GCI2", - "GCI3", - "GCI5", - "GCI27", - "GCI28", - "GCI32", - "GCI67", - "GCI69", - "GCI72", - "GCI74", - "GCI76", - "GCI77", - "GCI78", - "GCI79", - "GCI82", - "GCI94" + "GCI1", + "GCI2", + "GCI3", + "GCI5", + "GCI27", + "GCI28", + "GCI32", + "GCI67", + "GCI69", + "GCI72", + "GCI74", + "GCI76", + "GCI77", + "GCI78", + "GCI79", + "GCI82", + "GCI94" ] } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrarTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrarTest.java index 89541a5..4f49370 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrarTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrarTest.java @@ -17,33 +17,30 @@ */ package org.greencodeinitiative.creedengo.java; -import java.util.Set; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Set; import org.junit.jupiter.api.Test; import org.reflections.Reflections; import org.sonar.check.Rule; import org.sonar.plugins.java.api.CheckRegistrar; -import static org.assertj.core.api.Assertions.assertThat; - class JavaCheckRegistrarTest { - @Test - void checkNumberRules() { - final CheckRegistrar.RegistrarContext context = new CheckRegistrar.RegistrarContext(); - - final JavaCheckRegistrar registrar = new JavaCheckRegistrar(); - registrar.register(context); - assertThat(context.checkClasses()) - .describedAs("All implemented rules must be registered into " + JavaCheckRegistrar.class) - .containsExactlyInAnyOrder(getDefinedRules().toArray(new Class[0])); - assertThat(context.testCheckClasses()).isEmpty(); - - } - - static Set> getDefinedRules() { - Reflections r = new Reflections(JavaCheckRegistrar.class.getPackageName() + ".checks"); - return r.getTypesAnnotatedWith(Rule.class); - } - + @Test + void checkNumberRules() { + final CheckRegistrar.RegistrarContext context = new CheckRegistrar.RegistrarContext(); + + final JavaCheckRegistrar registrar = new JavaCheckRegistrar(); + registrar.register(context); + assertThat(context.checkClasses()) + .describedAs("All implemented rules must be registered into " + JavaCheckRegistrar.class) + .containsExactlyInAnyOrder(getDefinedRules().toArray(new Class[0])); + assertThat(context.testCheckClasses()).isEmpty(); + } + + static Set> getDefinedRules() { + Reflections r = new Reflections(JavaCheckRegistrar.class.getPackageName() + ".checks"); + return r.getTypesAnnotatedWith(Rule.class); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfileTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfileTest.java index 7db8134..6f58cf0 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfileTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfileTest.java @@ -17,35 +17,41 @@ */ package org.greencodeinitiative.creedengo.java; +import static org.assertj.core.api.Assertions.assertThat; +import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrarTest.getDefinedRules; +import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_NAME; +import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_PATH; +import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.LANGUAGE; + import java.util.List; import java.util.stream.Collectors; - import org.junit.jupiter.api.Test; import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; import org.sonar.check.Rule; -import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrarTest.getDefinedRules; -import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_NAME; -import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_PATH; -import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.LANGUAGE; -import static org.assertj.core.api.Assertions.assertThat; - class JavaCreedengoWayProfileTest { - @Test - void should_create_creedengo_profile() { - BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); + @Test + void should_create_creedengo_profile() { + BuiltInQualityProfilesDefinition.Context context = + new BuiltInQualityProfilesDefinition.Context(); - JavaCreedengoWayProfile definition = new JavaCreedengoWayProfile(); - definition.define(context); + JavaCreedengoWayProfile definition = new JavaCreedengoWayProfile(); + definition.define(context); - BuiltInQualityProfilesDefinition.BuiltInQualityProfile profile = context.profile(LANGUAGE, PROFILE_NAME); + BuiltInQualityProfilesDefinition.BuiltInQualityProfile profile = + context.profile(LANGUAGE, PROFILE_NAME); - assertThat(profile.language()).isEqualTo(LANGUAGE); - assertThat(profile.name()).isEqualTo(PROFILE_NAME); - List definedRuleIds = getDefinedRules().stream().map(c -> c.getAnnotation(Rule.class).key()).collect(Collectors.toList()); - assertThat(profile.rules()) - .describedAs("All implemented rules must be declared in '%s' profile file: %s", PROFILE_NAME, PROFILE_PATH) - .map(BuiltInQualityProfilesDefinition.BuiltInActiveRule::ruleKey) - .containsExactlyInAnyOrderElementsOf(definedRuleIds); - } + assertThat(profile.language()).isEqualTo(LANGUAGE); + assertThat(profile.name()).isEqualTo(PROFILE_NAME); + List definedRuleIds = + getDefinedRules().stream() + .map(c -> c.getAnnotation(Rule.class).key()) + .collect(Collectors.toList()); + assertThat(profile.rules()) + .describedAs( + "All implemented rules must be declared in '%s' profile file: %s", + PROFILE_NAME, PROFILE_PATH) + .map(BuiltInQualityProfilesDefinition.BuiltInActiveRule::ruleKey) + .containsExactlyInAnyOrderElementsOf(definedRuleIds); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/JavaPluginTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/JavaPluginTest.java index b54f59b..a42a105 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/JavaPluginTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/JavaPluginTest.java @@ -17,27 +17,26 @@ */ package org.greencodeinitiative.creedengo.java; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.sonar.api.Plugin; import org.sonar.api.SonarRuntime; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - class JavaPluginTest { private Plugin.Context context; - @BeforeEach - void init() { - SonarRuntime sonarRuntime = mock(SonarRuntime.class); - context = new Plugin.Context(sonarRuntime); - new JavaPlugin().define(context); - } - - @Test - void test() { - assertThat(context.getExtensions()).hasSize(2); - } + @BeforeEach + void init() { + SonarRuntime sonarRuntime = mock(SonarRuntime.class); + context = new Plugin.Context(sonarRuntime); + new JavaPlugin().define(context); + } + @Test + void test() { + assertThat(context.getExtensions()).hasSize(2); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinitionTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinitionTest.java index d0f53da..77450da 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinitionTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinitionTest.java @@ -17,6 +17,11 @@ */ package org.greencodeinitiative.creedengo.java; +import static org.assertj.core.api.Assertions.assertThat; +import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrar.ANNOTATED_RULE_CLASSES; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -28,64 +33,61 @@ import org.sonar.api.server.rule.RulesDefinition.Rule; import org.sonar.api.utils.Version; -import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrar.ANNOTATED_RULE_CLASSES; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - class JavaRulesDefinitionTest { - private RulesDefinition.Repository repository; - - @BeforeEach - void init() { - final SonarRuntime sonarRuntime = mock(SonarRuntime.class); - doReturn(Version.create(0, 0)).when(sonarRuntime).getApiVersion(); - JavaRulesDefinition rulesDefinition = new JavaRulesDefinition(sonarRuntime); - RulesDefinition.Context context = new RulesDefinition.Context(); - rulesDefinition.define(context); - repository = context.repository(rulesDefinition.repositoryKey()); - } + private RulesDefinition.Repository repository; - @Test - @DisplayName("Test repository metadata") - void testMetadata() { - assertThat(repository.name()).isEqualTo("creedengo"); - assertThat(repository.language()).isEqualTo("java"); - assertThat(repository.key()).isEqualTo("creedengo-java"); - } + @BeforeEach + void init() { + final SonarRuntime sonarRuntime = mock(SonarRuntime.class); + doReturn(Version.create(0, 0)).when(sonarRuntime).getApiVersion(); + JavaRulesDefinition rulesDefinition = new JavaRulesDefinition(sonarRuntime); + RulesDefinition.Context context = new RulesDefinition.Context(); + rulesDefinition.define(context); + repository = context.repository(rulesDefinition.repositoryKey()); + } - @Test - void testRegistredRules() { - assertThat(repository.rules()).hasSize(ANNOTATED_RULE_CLASSES.size()); - } + @Test + @DisplayName("Test repository metadata") + void testMetadata() { + assertThat(repository.name()).isEqualTo("creedengo"); + assertThat(repository.language()).isEqualTo("java"); + assertThat(repository.key()).isEqualTo("creedengo-java"); + } - @Test - @DisplayName("All rule keys must be prefixed by 'GCI'") - void testRuleKeyPrefix() { - SoftAssertions assertions = new SoftAssertions(); - repository.rules().forEach( - rule -> assertions.assertThat(rule.key()).startsWith("GCI") - ); - assertions.assertAll(); - } + @Test + void testRegistredRules() { + assertThat(repository.rules()).hasSize(ANNOTATED_RULE_CLASSES.size()); + } - @Test - void assertRuleProperties() { - Rule rule = repository.rule("GCI67"); - assertThat(rule).isNotNull(); - assertThat(rule.name()).isEqualTo("Use ++i instead of i++"); - assertThat(rule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE); - assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL); - } + @Test + @DisplayName("All rule keys must be prefixed by 'GCI'") + void testRuleKeyPrefix() { + SoftAssertions assertions = new SoftAssertions(); + repository.rules().forEach(rule -> assertions.assertThat(rule.key()).startsWith("GCI")); + assertions.assertAll(); + } - @Test - void testAllRuleParametersHaveDescription() { - SoftAssertions assertions = new SoftAssertions(); - repository.rules().stream() - .flatMap(rule -> rule.params().stream()) - .forEach(param -> assertions.assertThat(param.description()).as("description for " + param.key()).isNotEmpty()); - assertions.assertAll(); - } + @Test + void assertRuleProperties() { + Rule rule = repository.rule("GCI67"); + assertThat(rule).isNotNull(); + assertThat(rule.name()).isEqualTo("Use ++i instead of i++"); + assertThat(rule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE); + assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL); + } + @Test + void testAllRuleParametersHaveDescription() { + SoftAssertions assertions = new SoftAssertions(); + repository.rules().stream() + .flatMap(rule -> rule.params().stream()) + .forEach( + param -> + assertions + .assertThat(param.description()) + .as("description for " + param.key()) + .isNotEmpty()); + assertions.assertAll(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheckTest.java index 49deaa1..c56e23a 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheckTest.java @@ -22,15 +22,14 @@ class ArrayCopyCheckTest { - /** - * @formatter:off - */ - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/ArrayCopyCheck.java") - .withCheck(new ArrayCopyCheck()) - .verifyIssues(); - } - + /** + * @formatter:off + */ + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/ArrayCopyCheck.java") + .withCheck(new ArrayCopyCheck()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheckTest.java index 889721b..a6dc373 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheckTest.java @@ -22,12 +22,11 @@ class AvoidFullSQLRequestCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidFullSQLRequestCheck.java") - .withCheck(new AvoidFullSQLRequest()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidFullSQLRequestCheck.java") + .withCheck(new AvoidFullSQLRequest()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoopTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoopTest.java index 4d4b3fd..33331b0 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoopTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoopTest.java @@ -21,59 +21,59 @@ import org.sonar.java.checks.verifier.CheckVerifier; class AvoidGettingSizeCollectionInLoopTest { - @Test - void testBadForLoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopBad.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyIssues(); - } + @Test + void testBadForLoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopBad.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyIssues(); + } - @Test - void testIgnoredForLoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopIgnored.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyNoIssues(); - } + @Test + void testIgnoredForLoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopIgnored.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyNoIssues(); + } - @Test - void testGoodForLoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopGood.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyNoIssues(); - } + @Test + void testGoodForLoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopGood.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyNoIssues(); + } - @Test - void testBadWhileFoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopBad.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyIssues(); - } + @Test + void testBadWhileFoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopBad.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyIssues(); + } - @Test - void testIgnoredWhileFoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopIgnored.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyNoIssues(); - } + @Test + void testIgnoredWhileFoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopIgnored.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyNoIssues(); + } - @Test - void testGoodWhileLoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopGood.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyNoIssues(); - } + @Test + void testGoodWhileLoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopGood.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyNoIssues(); + } - @Test - void testIgnoredForEachLoop() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidGettingSizeCollectionInForEachLoopIgnored.java") - .withCheck(new AvoidGettingSizeCollectionInLoop()) - .verifyNoIssues(); - } + @Test + void testIgnoredForEachLoop() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidGettingSizeCollectionInForEachLoopIgnored.java") + .withCheck(new AvoidGettingSizeCollectionInLoop()) + .verifyNoIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementTest.java index f63326e..cf38a17 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementTest.java @@ -21,41 +21,39 @@ import org.sonar.java.checks.verifier.CheckVerifier; class AvoidMultipleIfElseStatementTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidMultipleIfElseStatement.java") - .withCheck(new AvoidMultipleIfElseStatement()) - .verifyIssues(); - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidMultipleIfElseStatementNoIssue.java") - .withCheck(new AvoidMultipleIfElseStatement()) - .verifyNoIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidMultipleIfElseStatement.java") + .withCheck(new AvoidMultipleIfElseStatement()) + .verifyIssues(); + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidMultipleIfElseStatementNoIssue.java") + .withCheck(new AvoidMultipleIfElseStatement()) + .verifyNoIssues(); + } - @Test - void testInterfaceMethodStatement() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidMultipleIfElseStatementInterface.java") - .withCheck(new AvoidMultipleIfElseStatement()) - .verifyNoIssues(); - } - - @Test - void testNotBlockStatement() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidMultipleIfElseStatementNotBlock.java") - .withCheck(new AvoidMultipleIfElseStatement()) - .verifyNoIssues(); - } - - @Test - void testCompareMethod() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidMultipleIfElseStatementCompareMethod.java") - .withCheck(new AvoidMultipleIfElseStatement()) - .verifyNoIssues(); - } + @Test + void testInterfaceMethodStatement() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidMultipleIfElseStatementInterface.java") + .withCheck(new AvoidMultipleIfElseStatement()) + .verifyNoIssues(); + } + @Test + void testNotBlockStatement() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidMultipleIfElseStatementNotBlock.java") + .withCheck(new AvoidMultipleIfElseStatement()) + .verifyNoIssues(); + } + @Test + void testCompareMethod() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidMultipleIfElseStatementCompareMethod.java") + .withCheck(new AvoidMultipleIfElseStatement()) + .verifyNoIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticTest.java index 874b03b..b19c6f7 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticTest.java @@ -22,23 +22,22 @@ class AvoidRegexPatternNotStaticTest { - @Test - void testHasIssues() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidRegexPatternNotStatic.java") - .withCheck(new AvoidRegexPatternNotStatic()) - .verifyIssues(); - } + @Test + void testHasIssues() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidRegexPatternNotStatic.java") + .withCheck(new AvoidRegexPatternNotStatic()) + .verifyIssues(); + } - @Test - void testHasNoIssues() { - CheckVerifier.newVerifier() - .onFiles( - "src/test/files/ValidRegexPattern.java", - "src/test/files/ValidRegexPattern2.java", - "src/test/files/ValidRegexPattern3.java" - ) - .withCheck(new AvoidRegexPatternNotStatic()) - .verifyNoIssues(); - } + @Test + void testHasNoIssues() { + CheckVerifier.newVerifier() + .onFiles( + "src/test/files/ValidRegexPattern.java", + "src/test/files/ValidRegexPattern2.java", + "src/test/files/ValidRegexPattern3.java") + .withCheck(new AvoidRegexPatternNotStatic()) + .verifyNoIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoopCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoopCheckTest.java index bd64a6a..7a5dcb8 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoopCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoopCheckTest.java @@ -22,12 +22,11 @@ class AvoidSQLRequestInLoopCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidSQLRequestInLoopCheck.java") - .withCheck(new AvoidSQLRequestInLoop()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidSQLRequestInLoopCheck.java") + .withCheck(new AvoidSQLRequestInLoop()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchInsertTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchInsertTest.java index 9dffe6f..536a954 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchInsertTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchInsertTest.java @@ -22,12 +22,11 @@ class AvoidSetConstantInBatchInsertTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidSetConstantInBatchUpdateCheck.java") - .withCheck(new AvoidSetConstantInBatchUpdate()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidSetConstantInBatchUpdateCheck.java") + .withCheck(new AvoidSetConstantInBatchUpdate()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java index 8041f0a..b260b27 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java @@ -23,13 +23,12 @@ class AvoidSpringRepositoryCallInLoopCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidSpringRepositoryCallInLoopCheck.java") - .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) - .withClassPath(FilesUtils.getClassPath("target/test-jars")) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidSpringRepositoryCallInLoopCheck.java") + .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInStreamCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInStreamCheckTest.java index 1be55d7..2644552 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInStreamCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInStreamCheckTest.java @@ -23,13 +23,12 @@ class AvoidSpringRepositoryCallInStreamCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidSpringRepositoryCallInStreamCheck.java") - .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) - .withClassPath(FilesUtils.getClassPath("target/test-jars")) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidSpringRepositoryCallInStreamCheck.java") + .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) + .withClassPath(FilesUtils.getClassPath("target/test-jars")) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueriesTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueriesTest.java index 3caac84..b81da09 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueriesTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueriesTest.java @@ -21,11 +21,11 @@ import org.sonar.java.checks.verifier.CheckVerifier; class AvoidStatementForDMLQueriesTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidStatementForDMLQueries.java") - .withCheck(new AvoidStatementForDMLQueries()) - .verifyIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidStatementForDMLQueries.java") + .withCheck(new AvoidStatementForDMLQueries()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsTests.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsTests.java index 876525f..0392431 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsTests.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsTests.java @@ -22,20 +22,19 @@ class AvoidUsageOfStaticCollectionsTests { - @Test - void testHasIssues() { - CheckVerifier.newVerifier() - .onFile("src/test/files/AvoidUsageOfStaticCollections.java") - .withCheck(new AvoidUsageOfStaticCollections()) - .verifyIssues(); - } - - @Test - void testNoIssues() { - CheckVerifier.newVerifier() - .onFile("src/test/files/GoodUsageOfStaticCollections.java") - .withCheck(new AvoidUsageOfStaticCollections()) - .verifyNoIssues(); - } + @Test + void testHasIssues() { + CheckVerifier.newVerifier() + .onFile("src/test/files/AvoidUsageOfStaticCollections.java") + .withCheck(new AvoidUsageOfStaticCollections()) + .verifyIssues(); + } + @Test + void testNoIssues() { + CheckVerifier.newVerifier() + .onFile("src/test/files/GoodUsageOfStaticCollections.java") + .withCheck(new AvoidUsageOfStaticCollections()) + .verifyNoIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java index aecce2d..08d2d7b 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java @@ -22,20 +22,20 @@ class FreeResourcesOfAutoCloseableInterfaceTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") - .withCheck(new FreeResourcesOfAutoCloseableInterface()) - .withJavaVersion(7) - .verifyIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") + .withCheck(new FreeResourcesOfAutoCloseableInterface()) + .withJavaVersion(7) + .verifyIssues(); + } - @Test - void test_no_java_version() { - CheckVerifier.newVerifier() - .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") - .withCheck(new FreeResourcesOfAutoCloseableInterface()) - .verifyIssues(); - } + @Test + void test_no_java_version() { + CheckVerifier.newVerifier() + .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") + .withCheck(new FreeResourcesOfAutoCloseableInterface()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheckTest.java index d11de84..1c3f9cf 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheckTest.java @@ -22,12 +22,11 @@ class IncrementCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/IncrementCheck.java") - .withCheck(new IncrementCheck()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/IncrementCheck.java") + .withCheck(new IncrementCheck()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSizeTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSizeTest.java index 0261b8f..1333c90 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSizeTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSizeTest.java @@ -22,12 +22,11 @@ class InitializeBufferWithAppropriateSizeTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/InitializeBufferWithAppropriateSize.java") - .withCheck(new InitializeBufferWithAppropriateSize()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/InitializeBufferWithAppropriateSize.java") + .withCheck(new InitializeBufferWithAppropriateSize()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstantsTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstantsTest.java index 837a632..08cefc3 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstantsTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstantsTest.java @@ -22,12 +22,11 @@ class MakeNonReassignedVariablesConstantsTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/MakeNonReassignedVariablesConstants.java") - .withCheck(new MakeNonReassignedVariablesConstants()) - .verifyIssues(); - } - + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/MakeNonReassignedVariablesConstants.java") + .withCheck(new MakeNonReassignedVariablesConstants()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoopTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoopTest.java index e4dff73..9031527 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoopTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoopTest.java @@ -21,11 +21,11 @@ import org.sonar.java.checks.verifier.CheckVerifier; class NoFunctionCallWhenDeclaringForLoopTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/NoFunctionCallWhenDeclaringForLoop.java") - .withCheck(new NoFunctionCallWhenDeclaringForLoop()) - .verifyIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/NoFunctionCallWhenDeclaringForLoop.java") + .withCheck(new NoFunctionCallWhenDeclaringForLoop()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheckTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheckTest.java index d3f1def..5eabbb3 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheckTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheckTest.java @@ -22,44 +22,43 @@ class OptimizeReadFileExceptionCheckTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/OptimizeReadFileExceptionCheck.java") - .withCheck(new OptimizeReadFileExceptions()) - .verifyIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/OptimizeReadFileExceptionCheck.java") + .withCheck(new OptimizeReadFileExceptions()) + .verifyIssues(); + } - @Test - void test2() { - CheckVerifier.newVerifier() - .onFile("src/test/files/OptimizeReadFileExceptionCheck2.java") - .withCheck(new OptimizeReadFileExceptions()) - .verifyIssues(); - } + @Test + void test2() { + CheckVerifier.newVerifier() + .onFile("src/test/files/OptimizeReadFileExceptionCheck2.java") + .withCheck(new OptimizeReadFileExceptions()) + .verifyIssues(); + } - @Test - void test3() { - CheckVerifier.newVerifier() - .onFile("src/test/files/OptimizeReadFileExceptionCheck3.java") - .withCheck(new OptimizeReadFileExceptions()) - .verifyIssues(); - } + @Test + void test3() { + CheckVerifier.newVerifier() + .onFile("src/test/files/OptimizeReadFileExceptionCheck3.java") + .withCheck(new OptimizeReadFileExceptions()) + .verifyIssues(); + } - @Test - void test4() { - CheckVerifier.newVerifier() - .onFile("src/test/files/OptimizeReadFileExceptionCheck4.java") - .withCheck(new OptimizeReadFileExceptions()) - .verifyIssues(); - } - - @Test - void test5() { - CheckVerifier.newVerifier() - .onFile("src/test/files/OptimizeReadFileExceptionCheck5.java") - .withCheck(new OptimizeReadFileExceptions()) - .verifyIssues(); - } + @Test + void test4() { + CheckVerifier.newVerifier() + .onFile("src/test/files/OptimizeReadFileExceptionCheck4.java") + .withCheck(new OptimizeReadFileExceptions()) + .verifyIssues(); + } + @Test + void test5() { + CheckVerifier.newVerifier() + .onFile("src/test/files/OptimizeReadFileExceptionCheck5.java") + .withCheck(new OptimizeReadFileExceptions()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElseTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElseTest.java index 2edc271..162dce5 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElseTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElseTest.java @@ -21,11 +21,11 @@ import org.sonar.java.checks.verifier.CheckVerifier; class UseOptionalOrElseGetVsOrElseTest { - @Test - void test() { - CheckVerifier.newVerifier() - .onFile("src/test/files/UseOptionalOrElseGetVsOrElse.java") - .withCheck(new UseOptionalOrElseGetVsOrElse()) - .verifyIssues(); - } + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/UseOptionalOrElseGetVsOrElse.java") + .withCheck(new UseOptionalOrElseGetVsOrElse()) + .verifyIssues(); + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/utils/FilesUtils.java b/src/test/java/org/greencodeinitiative/creedengo/java/utils/FilesUtils.java index d32c90d..004e73e 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/utils/FilesUtils.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/utils/FilesUtils.java @@ -31,41 +31,40 @@ import java.util.List; /** - * Duplicates org.sonar.java.checks.verifier.FilesUtils to locate test jars within the custom-rules plugin + * Duplicates org.sonar.java.checks.verifier.FilesUtils to locate test jars within the custom-rules + * plugin */ public class FilesUtils { - private FilesUtils() { - } + private FilesUtils() {} - /** - * Default location of the jars/zips to be taken into account when performing the analysis. - */ - private static final String DEFAULT_TEST_JARS_DIRECTORY = "target/test-jars"; + /** Default location of the jars/zips to be taken into account when performing the analysis. */ + private static final String DEFAULT_TEST_JARS_DIRECTORY = "target/test-jars"; - public static List getClassPath(String jarsDirectory) { - List classpath = new LinkedList<>(); - Path testJars = Paths.get(jarsDirectory); - if (testJars.toFile().exists()) { - classpath = getFilesRecursively(testJars, "jar", "zip"); - } else if (!DEFAULT_TEST_JARS_DIRECTORY.equals(jarsDirectory)) { - throw new AssertionError("The directory to be used to extend class path does not exists (" - + testJars.toAbsolutePath() - + ")."); - } - classpath.add(new File("target/test-classes")); - return classpath; + public static List getClassPath(String jarsDirectory) { + List classpath = new LinkedList<>(); + Path testJars = Paths.get(jarsDirectory); + if (testJars.toFile().exists()) { + classpath = getFilesRecursively(testJars, "jar", "zip"); + } else if (!DEFAULT_TEST_JARS_DIRECTORY.equals(jarsDirectory)) { + throw new AssertionError( + "The directory to be used to extend class path does not exists (" + + testJars.toAbsolutePath() + + ")."); } + classpath.add(new File("target/test-classes")); + return classpath; + } - private static List getFilesRecursively(Path root, String... extensions) { - final List files = new ArrayList<>(); + private static List getFilesRecursively(Path root, String... extensions) { + final List files = new ArrayList<>(); - FileVisitor visitor = new SimpleFileVisitor<>() { + FileVisitor visitor = + new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) { for (String extension : extensions) { - if (filePath.toString().endsWith("." - + extension)) { + if (filePath.toString().endsWith("." + extension)) { files.add(filePath.toFile()); break; } @@ -79,13 +78,12 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) { } }; - try { - Files.walkFileTree(root, visitor); - } catch (IOException e) { - // we already ignore errors in the visitor - } - - return files; + try { + Files.walkFileTree(root, visitor); + } catch (IOException e) { + // we already ignore errors in the visitor } + return files; + } } diff --git a/src/test/java/org/greencodeinitiative/creedengo/java/utils/StringUtilsTest.java b/src/test/java/org/greencodeinitiative/creedengo/java/utils/StringUtilsTest.java index de5082d..58d38c6 100644 --- a/src/test/java/org/greencodeinitiative/creedengo/java/utils/StringUtilsTest.java +++ b/src/test/java/org/greencodeinitiative/creedengo/java/utils/StringUtilsTest.java @@ -18,24 +18,22 @@ package org.greencodeinitiative.creedengo.java.utils; import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.Test; class StringUtilsTest { - @Test - void spaces() { - assertThat(StringUtils.spaces(5)) - .hasSize(5) - .containsOnlyWhitespaces(); - } - - @Test - void isNotEmpty() { - assertThat(StringUtils.isNotEmpty(null)).isFalse(); - assertThat(StringUtils.isNotEmpty("")).isFalse(); - assertThat(StringUtils.isNotEmpty(" ")).isTrue(); - assertThat(StringUtils.isNotEmpty("bob")).isTrue(); - assertThat(StringUtils.isNotEmpty(" bob ")).isTrue(); - } + @Test + void spaces() { + assertThat(StringUtils.spaces(5)).hasSize(5).containsOnlyWhitespaces(); + } + @Test + void isNotEmpty() { + assertThat(StringUtils.isNotEmpty(null)).isFalse(); + assertThat(StringUtils.isNotEmpty("")).isFalse(); + assertThat(StringUtils.isNotEmpty(" ")).isTrue(); + assertThat(StringUtils.isNotEmpty("bob")).isTrue(); + assertThat(StringUtils.isNotEmpty(" bob ")).isTrue(); + } }