diff --git a/src/main/java/fr/greencodeinitiative/java/JavaCheckRegistrar.java b/src/main/java/fr/greencodeinitiative/java/JavaCheckRegistrar.java index 50ada18..5e8eb7b 100644 --- a/src/main/java/fr/greencodeinitiative/java/JavaCheckRegistrar.java +++ b/src/main/java/fr/greencodeinitiative/java/JavaCheckRegistrar.java @@ -20,21 +20,7 @@ import java.util.Collections; import java.util.List; -import fr.greencodeinitiative.java.checks.ArrayCopyCheck; -import fr.greencodeinitiative.java.checks.AvoidFullSQLRequest; -import fr.greencodeinitiative.java.checks.AvoidGettingSizeCollectionInLoop; -import fr.greencodeinitiative.java.checks.AvoidMultipleIfElseStatement; -import fr.greencodeinitiative.java.checks.AvoidRegexPatternNotStatic; -import fr.greencodeinitiative.java.checks.AvoidSQLRequestInLoop; -import fr.greencodeinitiative.java.checks.AvoidSetConstantInBatchUpdate; -import fr.greencodeinitiative.java.checks.AvoidSpringRepositoryCallInLoopOrStreamCheck; -import fr.greencodeinitiative.java.checks.AvoidStatementForDMLQueries; -import fr.greencodeinitiative.java.checks.AvoidUsageOfStaticCollections; -import fr.greencodeinitiative.java.checks.FreeResourcesOfAutoCloseableInterface; -import fr.greencodeinitiative.java.checks.IncrementCheck; -import fr.greencodeinitiative.java.checks.InitializeBufferWithAppropriateSize; -import fr.greencodeinitiative.java.checks.NoFunctionCallWhenDeclaringForLoop; -import fr.greencodeinitiative.java.checks.OptimizeReadFileExceptions; +import fr.greencodeinitiative.java.checks.*; import org.sonar.plugins.java.api.CheckRegistrar; import org.sonar.plugins.java.api.JavaCheck; import org.sonarsource.api.sonarlint.SonarLintSide; @@ -62,7 +48,8 @@ public class JavaCheckRegistrar implements CheckRegistrar { InitializeBufferWithAppropriateSize.class, AvoidSetConstantInBatchUpdate.class, FreeResourcesOfAutoCloseableInterface.class, - AvoidMultipleIfElseStatement.class + AvoidMultipleIfElseStatement.class, + UseOptionalOrElseGetVsOrElse.class ); /** diff --git a/src/main/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElse.java b/src/main/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElse.java new file mode 100644 index 0000000..39b71e4 --- /dev/null +++ b/src/main/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElse.java @@ -0,0 +1,59 @@ +/* + * ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs + * Copyright © 2023 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fr.greencodeinitiative.java.checks; + +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 = "EC1369") +public class UseOptionalOrElseGetVsOrElse extends IssuableSubscriptionVisitor { + + 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 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); + } + } + } + } +} diff --git a/src/test/files/UseOptionalOrElseGetVsOrElse.java b/src/test/files/UseOptionalOrElseGetVsOrElse.java new file mode 100644 index 0000000..a35928c --- /dev/null +++ b/src/test/files/UseOptionalOrElseGetVsOrElse.java @@ -0,0 +1,25 @@ +/* + * ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs + * Copyright © 2023 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class UseOptionalOrElseGetVsOrElse { + + public static final String name = Optional.of("ecoCode").orElse(getUnpredictedMethod()); // Noncompliant {{Use optional orElseGet instead of orElse.}} + + public static final String name = Optional.of("ecoCode").orElseGet(() -> getUnpredictedMethod()); // Compliant + + public static final String name = randomClass.orElse(getUnpredictedMethod()); // Compliant +} diff --git a/src/test/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElseTest.java b/src/test/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElseTest.java new file mode 100644 index 0000000..b2ad362 --- /dev/null +++ b/src/test/java/fr/greencodeinitiative/java/checks/UseOptionalOrElseGetVsOrElseTest.java @@ -0,0 +1,31 @@ +/* + * ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs + * Copyright © 2023 Green Code Initiative (https://www.ecocode.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fr.greencodeinitiative.java.checks; + +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +class UseOptionalOrElseGetVsOrElseTest { + @Test + void test() { + CheckVerifier.newVerifier() + .onFile("src/test/files/UseOptionalOrElseGetVsOrElse.java") + .withCheck(new UseOptionalOrElseGetVsOrElse()) + .verifyIssues(); + } +}