]]>
code-smell
diff --git a/src/android-plugin/src/test/java/org/sonar/plugins/groovy/GroovySonarWayProfileTest.java b/src/android-plugin/src/test/java/org/sonar/plugins/groovy/GroovySonarWayProfileTest.java
index 27a304691..f0e7dd711 100644
--- a/src/android-plugin/src/test/java/org/sonar/plugins/groovy/GroovySonarWayProfileTest.java
+++ b/src/android-plugin/src/test/java/org/sonar/plugins/groovy/GroovySonarWayProfileTest.java
@@ -45,7 +45,7 @@ public void shouldCreateSonarWayProfile() {
profileContext.profile(Groovy.KEY, Groovy.PROFILE_NAME);
assertThat(profile.language()).isEqualTo(Groovy.KEY);
List activeRules = profile.rules();
- assertThat(activeRules).as("Expected number of rules in profile").hasSize(2);
+ assertThat(activeRules).as("Expected number of rules in profile").hasSize(3);
assertThat(profile.name()).isEqualTo(Groovy.PROFILE_NAME);
// Check that we use severity from the read rule and not default one.
diff --git a/src/android-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinitionTest.java b/src/android-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinitionTest.java
index a636183cc..8a255fab1 100644
--- a/src/android-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinitionTest.java
+++ b/src/android-plugin/src/test/java/org/sonar/plugins/groovy/codenarc/CodeNarcRulesDefinitionTest.java
@@ -41,6 +41,6 @@ public void test() {
assertThat(repository.language()).isEqualTo(Groovy.KEY);
List rules = repository.rules();
- assertThat(rules).hasSize(2);
+ assertThat(rules).hasSize(3);
}
}
diff --git a/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRules.groovy.txt b/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRules.groovy.txt
index 990e6a23d..31e595c62 100644
--- a/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRules.groovy.txt
+++ b/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRules.groovy.txt
@@ -76,7 +76,8 @@ ruleset {
CrapMetric // Requires the GMetrics jar and a Cobertura coverage file
CyclomaticComplexity // Requires the GMetrics jar
DeadCode
- DirectConnectionManagement
+ DirectConnectionManagement
+ DisableObfuscation
DoubleCheckedLocking
DoubleNegative
DuplicateCaseStatement
diff --git a/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRulesByCategory.groovy.txt b/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRulesByCategory.groovy.txt
index f2be3ace1..1586a2668 100644
--- a/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRulesByCategory.groovy.txt
+++ b/src/codenarc-converter/CodeNarc/docs/StarterRuleSet-AllRulesByCategory.groovy.txt
@@ -168,6 +168,7 @@ ruleset {
// rulesets/ecocode.xml
FatApp
SupportedVersionRange
+ DisableObfuscation
// rulesets/enhanced.xml
CloneWithoutCloneable
diff --git a/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index-by-name.md b/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index-by-name.md
index 0afdffe96..e68338d3a 100644
--- a/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index-by-name.md
+++ b/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index-by-name.md
@@ -79,6 +79,7 @@ title: CodeNarc - Rule Index by Name
* [CyclomaticComplexity](./codenarc-rules-size.html#cyclomaticcomplexity-rule) (Requires the GMetrics jar)
* [DeadCode](./codenarc-rules-basic.html#deadcode-rule)
* [DirectConnectionManagement](./codenarc-rules-jdbc.html#directconnectionmanagement-rule)
+* [DisableObfuscation](./codenarc-rules-ecocode.html#disableobfuscation-rule)
* [DoubleCheckedLocking](./codenarc-rules-concurrency.html#doublecheckedlocking-rule)
* [DoubleNegative](./codenarc-rules-basic.html#doublenegative-rule)
* [DuplicateCaseStatement](./codenarc-rules-basic.html#duplicatecasestatement-rule)
diff --git a/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index.md b/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index.md
index 2221ca5a4..260c3f88c 100644
--- a/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index.md
+++ b/src/codenarc-converter/CodeNarc/docs/codenarc-rule-index.md
@@ -169,6 +169,7 @@ title: CodeNarc - Rule Index
## [Ecocode](./codenarc-rules-ecocode.html)
* [FatApp](./codenarc-rules-ecocode.html#fatapp-rule)
* [SupportedVersionRange](./codenarc-rules-ecocode.html#supportedversionrange-rule)
+* [DisableObfuscation](./codenarc-rules-ecocode.html#disableobfuscation-rule)
## [Enhanced](./codenarc-rules-enhanced.html)
* [CloneWithoutCloneable](./codenarc-rules-enhanced.html#clonewithoutcloneable-rule)
diff --git a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
index 67f6cb34c..7bdda726b 100644
--- a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
+++ b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
@@ -82,3 +82,41 @@ android {
}
}
```
+
+## DisableObfuscation Rule
+
+*Since CodeNarc 2.2.1*
+
+Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
+
+Example of violations:
+
+```
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersion 28
+ targetSdkVersion 32
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+```
+
diff --git a/src/codenarc-converter/CodeNarc/gradlew b/src/codenarc-converter/CodeNarc/gradlew
old mode 100644
new mode 100755
diff --git a/src/codenarc-converter/CodeNarc/src/main/groovy/org/codenarc/rule/ecocode/DisableObfuscationRule.groovy b/src/codenarc-converter/CodeNarc/src/main/groovy/org/codenarc/rule/ecocode/DisableObfuscationRule.groovy
new file mode 100644
index 000000000..aa2c887eb
--- /dev/null
+++ b/src/codenarc-converter/CodeNarc/src/main/groovy/org/codenarc/rule/ecocode/DisableObfuscationRule.groovy
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codenarc.rule.ecocode
+
+
+import org.codehaus.groovy.ast.expr.ConstantExpression
+import org.codehaus.groovy.ast.expr.MethodCallExpression
+import org.codenarc.rule.AbstractAstVisitor
+import org.codenarc.rule.AbstractAstVisitorRule
+import org.codenarc.util.AstUtil
+
+/**
+ * Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
+ *
+ * @author Berque Justin
+ */
+class DisableObfuscationRule extends AbstractAstVisitorRule {
+
+ String name = 'DisableObfuscation'
+ int priority = 2
+ Class astVisitorClass = DisableObfuscationAstVisitor
+}
+
+class DisableObfuscationAstVisitor extends AbstractAstVisitor {
+
+ @Override
+ void visitMethodCallExpression(MethodCallExpression methodCallExpression) {
+ if (((ConstantExpression) methodCallExpression.getMethod()).getValue() == 'minifyEnabled') {
+ for (Object value : AstUtil.getArgumentsValue(methodCallExpression.getArguments())) {
+ if (value == true)
+ addViolation(methodCallExpression, getViolationMessage())
+ else {
+ this.getSourceCode().getLines().each { string ->
+ if (string.contains(value + ' = true')) {
+ addViolation(methodCallExpression, getViolationMessage())
+ }
+ }
+ }
+ }
+ }
+ super.visitMethodCallExpression(methodCallExpression)
+ }
+
+ private String getViolationMessage() {
+ return 'Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.'
+ }
+}
diff --git a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-messages.properties b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-messages.properties
index 5ba5fd43a..fce48fe2f 100644
--- a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-messages.properties
+++ b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-messages.properties
@@ -1,3 +1,6 @@
+DisableObfuscation.description=Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
+DisableObfuscation.description.html=Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
+
SupportedVersionRange.description=The amplitude of supported platform versions should not be too wide, at the risk of making the app too heavy to handle all cases.
SupportedVersionRange.description.html=The amplitude of supported platform versions should not be too wide, at the risk of making the app too heavy to handle all cases.
diff --git a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-rules.properties b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-rules.properties
index 0d9ec5a8c..6df09e8fb 100644
--- a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-rules.properties
+++ b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-base-rules.properties
@@ -69,6 +69,7 @@ CoupledTestCase = org.codenarc.rule.junit.CoupledTestCaseRule
CrapMetric = org.codenarc.rule.size.CrapMetricRule
CyclomaticComplexity = org.codenarc.rule.size.CyclomaticComplexityRule
DeadCode = org.codenarc.rule.basic.DeadCodeRule
+DisableObfuscation = org.codenarc.rule.ecocode.DisableObfuscationRule
DirectConnectionManagement = org.codenarc.rule.jdbc.DirectConnectionManagementRule
DoubleCheckedLocking = org.codenarc.rule.concurrency.DoubleCheckedLockingRule
DoubleNegative = org.codenarc.rule.basic.DoubleNegativeRule
diff --git a/src/codenarc-converter/CodeNarc/src/main/resources/rulesets/ecocode.xml b/src/codenarc-converter/CodeNarc/src/main/resources/rulesets/ecocode.xml
index 5c10668ee..8c8bc7514 100644
--- a/src/codenarc-converter/CodeNarc/src/main/resources/rulesets/ecocode.xml
+++ b/src/codenarc-converter/CodeNarc/src/main/resources/rulesets/ecocode.xml
@@ -9,4 +9,5 @@
+
diff --git a/src/codenarc-converter/CodeNarc/src/test/groovy/org/codenarc/rule/ecocode/DisableObfuscationRuleTest.groovy b/src/codenarc-converter/CodeNarc/src/test/groovy/org/codenarc/rule/ecocode/DisableObfuscationRuleTest.groovy
new file mode 100644
index 000000000..2b39dbd36
--- /dev/null
+++ b/src/codenarc-converter/CodeNarc/src/test/groovy/org/codenarc/rule/ecocode/DisableObfuscationRuleTest.groovy
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.codenarc.rule.ecocode
+
+import org.junit.Test
+import org.codenarc.rule.AbstractRuleTestCase
+
+/**
+ * Tests for DisableObfuscationRule
+ *
+ * @author Leboulanger Mickael
+ */
+class DisableObfuscationRuleTest extends AbstractRuleTestCase {
+
+ @Test
+ void test_RuleProperties() {
+ assert rule.priority == 2
+ assert rule.name == 'DisableObfuscation'
+ }
+
+ @Test
+ void test_SomeCondition_NoViolations() {
+ final SOURCE = '''
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersion 28
+ targetSdkVersion 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro\'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+ '''
+ assertNoViolations(SOURCE)
+ }
+
+ @Test
+ void testDetect_minifyEnabled_true() {
+ final SOURCE = '''
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersionVersionVersion 28
+ targetSdkVersionVersionVersion 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro\'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+ '''
+ assertSingleViolation(SOURCE, 17, 'minifyEnabled', getViolationMessage())
+ }
+
+ @Test
+ void testDetect_minifyEnabled_variable_true_before() {
+ final SOURCE = '''
+ def minify = true
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersionVersion 28
+ targetSdkVersionVersion 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled minify
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro\'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+ '''
+ assertSingleViolation(SOURCE, 18, 'minifyEnabled', getViolationMessage())
+ }
+
+ @Test
+ void testDetect_multiDexEnabled_variable_true_after() {
+ final SOURCE = '''
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersion 28
+ targetSdkVersion 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled minify
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro\'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+ def minify = true
+ '''
+ assertSingleViolation(SOURCE, 17, 'minifyEnabled', getViolationMessage())
+ }
+
+ @Test
+ void testDetect_minifyEnabled_variable_may_be_true() {
+ final SOURCE = '''
+ def minify = false
+ android {
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.sampleForSonar"
+ minSdkVersion 28
+ targetSdkVersion 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled minify
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro\'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+ }
+ if (true) {
+ minify = true
+ }
+ '''
+ assertSingleViolation(SOURCE, 18, 'minifyEnabled', getViolationMessage())
+ }
+
+ @Override
+ protected DisableObfuscationRule createRule() {
+ new DisableObfuscationRule()
+ }
+ private String getViolationMessage() {
+ return 'Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.'
+ }
+}
From 3a9a8bdc88b120d01f80c64b93aa52e27b3ab794 Mon Sep 17 00:00:00 2001
From: Romain DUCASSE
Date: Fri, 3 Jun 2022 11:47:22 +0200
Subject: [PATCH 031/119] Add rule for string buffer/builder initialization
#GRSP0032-JAVA
---
.../main/java/fr/cnumr/java/RulesList.java | 3 +-
.../InitializeBufferWithAppropriateSize.java | 37 +++++++++++++++++++
.../cnumr/l10n/java/rules/java/GRSP0032.html | 18 +++++++++
.../cnumr/l10n/java/rules/java/GRSP0032.json | 13 +++++++
.../InitializeBufferWithAppropriateSize.java | 31 ++++++++++++++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
...itializeBufferWithAppropriateSizeTest.java | 16 ++++++++
7 files changed, 118 insertions(+), 2 deletions(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSize.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.json
create mode 100644 src/java-plugin/src/test/files/InitializeBufferWithAppropriateSize.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSizeTest.java
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index 7bcd53578..ad37dc770 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -46,7 +46,8 @@ public static List> getJavaChecks() {
AvoidSQLRequestInLoop.class,
AvoidFullSQLRequest.class,
UseCorrectForLoop.class,
- UnnecessarilyAssignValuesToVariables.class
+ UnnecessarilyAssignValuesToVariables.class,
+ InitializeBufferWithAppropriateSize.class
));
}
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSize.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSize.java
new file mode 100644
index 000000000..01d9e1df0
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSize.java
@@ -0,0 +1,37 @@
+package fr.cnumr.java.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.tree.NewClassTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.plugins.java.api.tree.Tree.Kind;
+
+import java.util.Collections;
+import java.util.List;
+
+@Rule(
+ key = "GRSP0032",
+ name = "Developpement",
+ description = InitializeBufferWithAppropriateSize.RULE_MESSAGE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
+public class InitializeBufferWithAppropriateSize extends IssuableSubscriptionVisitor {
+
+ 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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.html
new file mode 100644
index 000000000..f4ae02219
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.html
@@ -0,0 +1,18 @@
+
+ If you know in advance how many characters would be appended, initialize builder/buffer with the appropriate size.
+ They will thus never have to be resized.
+
+
Noncompliant Code Example
+
+ StringBuilder sb = new StringBuilder(); // Noncompliant
+ for (int i = 0; i < 100; i++) {
+ sb.append(...);
+ }
+
+
Compliant Solution
+
+ StringBuilder sb = new StringBuilder(100);
+ for (int i = 0; i < 100; i++) {
+ sb.append(...);
+ }
+
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.json
new file mode 100644
index 000000000..b51e2b3c6
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0032.json
@@ -0,0 +1,13 @@
+{
+ "title": "Initialize builder/buffer with the appropriate size",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/InitializeBufferWithAppropriateSize.java b/src/java-plugin/src/test/files/InitializeBufferWithAppropriateSize.java
new file mode 100644
index 000000000..664575af0
--- /dev/null
+++ b/src/java-plugin/src/test/files/InitializeBufferWithAppropriateSize.java
@@ -0,0 +1,31 @@
+package fr.cnumr.java.checks;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+class InitializeBufferWithAppropriateSize {
+ InitializeBufferWithAppropriateSize(InitializeBufferWithAppropriateSize mc) {
+ }
+
+ public void testBufferCompliant() {
+ StringBuffer stringBuffer = new StringBuffer(16);
+ }
+
+ public void testBufferCompliant2() {
+ StringBuffer stringBuffer = new StringBuffer(Integer.valueOf(16));
+ }
+
+ public void testBufferNonCompliant() {
+ StringBuffer stringBuffer = new StringBuffer(); // Noncompliant
+ }
+
+ public void testBuilderCompliant() {
+ StringBuilder stringBuilder = new StringBuilder(16);
+ }
+
+ public void testBuilderNonCompliant() {
+ StringBuilder stringBuilder = new StringBuilder(); // Noncompliant
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index bbc12316c..81ad838e2 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -32,7 +32,7 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(6);
+ assertThat(context.checkClasses()).hasSize(7);
assertThat(context.testCheckClasses()).isEmpty();
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSizeTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSizeTest.java
new file mode 100644
index 000000000..134b6c5ef
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/InitializeBufferWithAppropriateSizeTest.java
@@ -0,0 +1,16 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+class InitializeBufferWithAppropriateSizeTest {
+
+ @Test
+ void test() {
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/InitializeBufferWithAppropriateSize.java")
+ .withCheck(new InitializeBufferWithAppropriateSize())
+ .verifyIssues();
+ }
+
+}
\ No newline at end of file
From be437a3fb49d1c92af0525aa0260a0bfe3d54f1e Mon Sep 17 00:00:00 2001
From: MP-Aubay
Date: Thu, 16 Jun 2022 11:44:24 +0200
Subject: [PATCH 032/119] GRC1 - Calling Spring repository in loops (#117)
---
docs/rules/web-matrix.md | 3 +-
src/java-plugin/pom.xml | 21 ++++++--
.../main/java/fr/cnumr/java/RulesList.java | 1 +
.../AvoidSpringRepositoryCallInLoopCheck.java | 51 +++++++++++++++++++
.../fr/cnumr/l10n/java/rules/java/GRC1.html | 21 ++++++++
.../fr/cnumr/l10n/java/rules/java/GRC1.json | 13 +++++
.../AvoidSpringRepositoryCallInLoopCheck.java | 30 +++++++++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
...idSpringRepositoryCallInLoopCheckTest.java | 19 +++++++
9 files changed, 155 insertions(+), 6 deletions(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
create mode 100644 src/java-plugin/src/test/files/AvoidSpringRepositoryCallInLoopCheck.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java
diff --git a/docs/rules/web-matrix.md b/docs/rules/web-matrix.md
index b5b5009ce..5a9a3f781 100644
--- a/docs/rules/web-matrix.md
+++ b/docs/rules/web-matrix.md
@@ -35,4 +35,5 @@ Here is the list of rules already available in ecoCode project code.
| Use the $i++ variable during an iteration | ✅ | ✅ | | | | |
| Calling a function in the declaration of a for loop | ✅ | ✅ | | ✅ | | |
| Perform an SQL query inside a loop | ✅ | ✅ | | | | |
-| Write SELECT * FROM | ✅ | ✅ | | ✅ | | |
\ No newline at end of file
+| Write SELECT * FROM | ✅ | ✅ | | ✅ | | |
+| Calling a Spring repository inside a loop | ✅ | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
\ No newline at end of file
diff --git a/src/java-plugin/pom.xml b/src/java-plugin/pom.xml
index b391b0899..02007682d 100644
--- a/src/java-plugin/pom.xml
+++ b/src/java-plugin/pom.xml
@@ -59,6 +59,7 @@
org.assertjassertj-core
+
@@ -87,7 +88,7 @@
copy-bundlepackage
- copy
+ copy
@@ -169,21 +170,33 @@
org.springframeworkspring-webmvc
- 4.3.3.RELEASE
+ 5.2.3.RELEASEjarorg.springframeworkspring-web
- 4.3.3.RELEASE
+ 5.2.3.RELEASEjarorg.springframeworkspring-context
- 4.3.3.RELEASE
+ 5.2.3.RELEASEjar
+
+ 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
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index 7bcd53578..bebf41b05 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -43,6 +43,7 @@ public static List> getJavaChecks() {
return Collections.unmodifiableList(Arrays.asList(
IncrementCheck.class,
NoFunctionCallWhenDeclaringForLoop.class,
+ AvoidSpringRepositoryCallInLoopCheck.class,
AvoidSQLRequestInLoop.class,
AvoidFullSQLRequest.class,
UseCorrectForLoop.class,
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
new file mode 100644
index 000000000..f0eb5b8dd
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
@@ -0,0 +1,51 @@
+package fr.cnumr.java.checks;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.MethodMatchers;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.MethodInvocationTree;
+import org.sonar.plugins.java.api.tree.Tree;
+
+@Rule(key = "GRC1",
+ name = "Developpement",
+ description = AvoidSpringRepositoryCallInLoopCheck.RULE_MESSAGE,
+ priority = Priority.MINOR,
+ tags = {"bug" })
+public class AvoidSpringRepositoryCallInLoopCheck extends IssuableSubscriptionVisitor {
+
+ protected static final String RULE_MESSAGE = "Avoid Spring repository call in loop";
+
+ private static final String SPRING_REPOSITORY = "org.springframework.data.repository.Repository";
+
+ private static final MethodMatchers REPOSITORY_METHOD =
+ MethodMatchers.create().ofSubTypes(SPRING_REPOSITORY).anyName().withAnyParameters()
+ .build();
+
+ private final AvoidSpringRepositoryCallInLoopCheckVisitor visitorInFile = new AvoidSpringRepositoryCallInLoopCheckVisitor();
+
+ @Override
+ public List nodesToVisit() {
+ return Arrays.asList(Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, Tree.Kind.WHILE_STATEMENT);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ tree.accept(visitorInFile);
+ }
+
+ private class AvoidSpringRepositoryCallInLoopCheckVisitor extends BaseTreeVisitor {
+ @Override
+ public void visitMethodInvocation(MethodInvocationTree tree) {
+ if (REPOSITORY_METHOD.matches(tree)) {
+ reportIssue(tree, RULE_MESSAGE);
+ } else {
+ super.visitMethodInvocation(tree);
+ }
+ }
+ }
+}
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
new file mode 100644
index 000000000..9b81f5b10
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
@@ -0,0 +1,21 @@
+
Avoid Spring repository call in loop
+
Noncompliant Code Example
+
+ private final List ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+ List employees = new ArrayList<>();
+
+ for (Integer id: ids) {
+ Optional employee = employeeRepository.findById(id); // Noncompliant {{Avoid Spring repository call in loop}}
+ if (employee.isPresent()) {
+ employees.add(employee.get());
+ }
+ }
+
+
+
Compliant Solution
+
+ private final List ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+
+ List employees = employeeRepository.findAllById(ids);
+
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
new file mode 100644
index 000000000..5991d83ec
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid Spring repository call in loop",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "50min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidSpringRepositoryCallInLoopCheck.java b/src/java-plugin/src/test/files/AvoidSpringRepositoryCallInLoopCheck.java
new file mode 100644
index 000000000..1b3527bb7
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidSpringRepositoryCallInLoopCheck.java
@@ -0,0 +1,30 @@
+package fr.cnumr.java.checks;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class AvoidRepositoryCallInLoopCheck {
+ @Autowired
+ private EmployeeRepository employeeRepository;
+
+ public List smellGetAllEmployeesByIds(List ids){
+ List employees = new ArrayList<>();
+ for (Integer id: ids) {
+ Optional employee = employeeRepository.findById(id); // Noncompliant {{Avoid Spring repository call in loop}}
+ if (employee.isPresent()) {
+ employees.add(employee.get());
+ }
+ }
+ return employees;
+ }
+
+ public class Employee {}
+
+ public interface EmployeeRepository extends JpaRepository{
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index bbc12316c..81ad838e2 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -32,7 +32,7 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(6);
+ assertThat(context.checkClasses()).hasSize(7);
assertThat(context.testCheckClasses()).isEmpty();
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java
new file mode 100644
index 000000000..d3a5c30e5
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java
@@ -0,0 +1,19 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.CheckVerifier;
+
+import fr.cnumr.java.utils.FilesUtils;
+
+public class AvoidSpringRepositoryCallInLoopCheckTest {
+
+ @Test
+ void test() {
+ CheckVerifier.newVerifier()
+ .onFile("src/test/files/AvoidSpringRepositoryCallInLoopCheck.java")
+ .withCheck(new AvoidSpringRepositoryCallInLoopCheck())
+ .withClassPath(FilesUtils.getClassPath("target/test-jars"))
+ .verifyIssues();
+ }
+
+}
From 63bc5d6373813b9fae9b4d6c0633ffbd121fb465 Mon Sep 17 00:00:00 2001
From: Jules Delecour
Date: Fri, 17 Jun 2022 11:42:06 +0200
Subject: [PATCH 033/119] fixing tag eco-conception to ecocode
---
.../src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S34.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S66.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S69.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S74.json | 2 +-
17 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
index 5991d83ec..95ed2e54d 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
@@ -7,7 +7,7 @@
"constantCost": "50min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
index ff78ee1be..a666eb11a 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
index bc29be46b..c56e5a649 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
index c6b6e9b09..ec02eda10 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
index d51cbccf7..4d7785f65 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
index 73743a5a5..ec95852ce 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
@@ -7,7 +7,7 @@
"constantCost": "10min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
index f561e6a84..b19da3c57 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
index 72a37f621..05a6db7cf 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
index 55464b52c..487ca6e41 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
index 2934198d6..074c72d5d 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
index 68cabdd39..1bd29a466 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
index 73743a5a5..ec95852ce 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
@@ -7,7 +7,7 @@
"constantCost": "10min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
index f561e6a84..b19da3c57 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
index e3718d9f9..03e92cc86 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
index 1fd95da11..6ccc84e55 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
index e3718d9f9..03e92cc86 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
index f561e6a84..b19da3c57 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "eco-conception"
+ "ecocode"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
From 9abebd0e74929fe83e20b5d33f0f99c121f6587a Mon Sep 17 00:00:00 2001
From: Jules Delecour
Date: Fri, 17 Jun 2022 11:55:18 +0200
Subject: [PATCH 034/119] Revert "fixing tag eco-conception to ecocode"
This reverts commit 63bc5d6373813b9fae9b4d6c0633ffbd121fb465.
---
.../src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json | 2 +-
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S34.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S66.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S69.json | 2 +-
.../main/resources/fr/cnumr/l10n/python/rules/python/S74.json | 2 +-
17 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
index 95ed2e54d..5991d83ec 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.json
@@ -7,7 +7,7 @@
"constantCost": "50min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
index a666eb11a..ff78ee1be 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S53.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
index c56e5a649..bc29be46b 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S63.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
index ec02eda10..c6b6e9b09 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S67.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
index 4d7785f65..d51cbccf7 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
index ec95852ce..73743a5a5 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.json
@@ -7,7 +7,7 @@
"constantCost": "10min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
index b19da3c57..f561e6a84 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
index 05a6db7cf..72a37f621 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
index 487ca6e41..55464b52c 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
index 074c72d5d..2934198d6 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S67.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
index 1bd29a466..68cabdd39 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
index ec95852ce..73743a5a5 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.json
@@ -7,7 +7,7 @@
"constantCost": "10min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
index b19da3c57..f561e6a84 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
index 03e92cc86..e3718d9f9 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
index 6ccc84e55..1fd95da11 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
index 03e92cc86..e3718d9f9 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
@@ -7,7 +7,7 @@
"constantCost": "5min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
index b19da3c57..f561e6a84 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.json
@@ -7,7 +7,7 @@
"constantCost": "20min"
},
"tags": [
- "ecocode"
+ "eco-conception"
],
"defaultSeverity": "Minor"
}
\ No newline at end of file
From 4430ebde46b055458796a5aa5cc9fd4745cebd83 Mon Sep 17 00:00:00 2001
From: rcollin
Date: Fri, 17 Jun 2022 12:04:11 +0200
Subject: [PATCH 035/119] 99 rule (#136)
* 99 rule
* Update S99.html
Co-authored-by: Jules Delecour <72793427+jules-delecour-dav@users.noreply.github.com>
---
src/xml-plugin/README.md | 1 +
src/xml-plugin/pom.xml | 102 +++++++
.../main/java/fr/cnumr/xml/MyXmlRules.java | 55 ++++
.../fr/cnumr/xml/XMLCustomRulesPlugin.java | 33 +++
.../java/fr/cnumr/xml/checks/CheckList.java | 34 +++
.../xml/checks/UseUnoptimizedVectorImage.java | 37 +++
.../fr/cnumr/l10n/xml/rules/custom/S99.html | 11 +
.../fr/cnumr/l10n/xml/rules/custom/S99.json | 13 +
.../java/fr/cnumr/xml/MyXmlRulesTest.java | 20 ++
.../checks/UseUnoptimizedVectorImageTest.java | 28 ++
.../UseUnoptimizedVectorImage.svg | 56 ++++
.../UseUnoptimizedVectorImageSVGO.svg | 1 +
.../checks/UseUnoptimizedVectorImage/pom.xml | 265 ++++++++++++++++++
13 files changed, 656 insertions(+)
create mode 100644 src/xml-plugin/README.md
create mode 100644 src/xml-plugin/pom.xml
create mode 100644 src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
create mode 100644 src/xml-plugin/src/main/java/fr/cnumr/xml/XMLCustomRulesPlugin.java
create mode 100644 src/xml-plugin/src/main/java/fr/cnumr/xml/checks/CheckList.java
create mode 100644 src/xml-plugin/src/main/java/fr/cnumr/xml/checks/UseUnoptimizedVectorImage.java
create mode 100644 src/xml-plugin/src/main/resources/fr/cnumr/l10n/xml/rules/custom/S99.html
create mode 100644 src/xml-plugin/src/main/resources/fr/cnumr/l10n/xml/rules/custom/S99.json
create mode 100644 src/xml-plugin/src/test/java/fr/cnumr/xml/MyXmlRulesTest.java
create mode 100644 src/xml-plugin/src/test/java/fr/cnumr/xml/checks/UseUnoptimizedVectorImageTest.java
create mode 100644 src/xml-plugin/src/test/resources/checks/UseUnoptimizedVectorImage/UseUnoptimizedVectorImage.svg
create mode 100644 src/xml-plugin/src/test/resources/checks/UseUnoptimizedVectorImage/UseUnoptimizedVectorImageSVGO.svg
create mode 100644 src/xml-plugin/src/test/resources/checks/UseUnoptimizedVectorImage/pom.xml
diff --git a/src/xml-plugin/README.md b/src/xml-plugin/README.md
new file mode 100644
index 000000000..bbcc22d84
--- /dev/null
+++ b/src/xml-plugin/README.md
@@ -0,0 +1 @@
+https://github.com/SonarSource/sonar-custom-rules-examples/tree/master/xml-custom-rules
\ No newline at end of file
diff --git a/src/xml-plugin/pom.xml b/src/xml-plugin/pom.xml
new file mode 100644
index 000000000..0d91c8804
--- /dev/null
+++ b/src/xml-plugin/pom.xml
@@ -0,0 +1,102 @@
+
+
+ 4.0.0
+
+ fr.cnumr
+ ecocode
+ 1.0.0-SNAPSHOT
+
+
+ ecocode-xml-plugin
+ sonar-plugin
+ ecoCode XML Sonar Plugin
+
+
+
+
+
+ org.sonarsource.sonarqube
+ sonar-plugin-api
+
+
+
+ org.sonarsource.xml
+ sonar-xml-plugin
+ sonar-plugin
+ 2.5.0.3376
+
+
+
+ org.sonarsource.analyzer-commons
+ sonar-xml-parsing
+ 1.25.0.1003
+
+
+
+ junit
+ junit
+
+
+
+ org.sonarsource.analyzer-commons
+ test-sonar-xml-parsing
+ 1.25.0.1003
+ test
+
+
+
+
+
+
+ org.sonarsource.sonar-packaging-maven-plugin
+ sonar-packaging-maven-plugin
+ ${sonar-packaging.version}
+ true
+
+ ${project.artifactId}
+ ${project.name}
+ fr.cnumr.xml.XMLCustomRulesPlugin
+ true
+ 6.7
+ xml
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ copy-bundle
+ package
+
+ copy
+
+
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ jar
+ true
+
+
+ ../lib
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.0
+
+
+ 1.8
+
+
+
+
+
+
diff --git a/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java b/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
new file mode 100644
index 000000000..e54090e06
--- /dev/null
+++ b/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
@@ -0,0 +1,55 @@
+/*
+ * SonarQube PHP Custom Rules Example
+ * Copyright (C) 2016-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package fr.cnumr.xml;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonarsource.analyzer.commons.RuleMetadataLoader;
+
+import fr.cnumr.xml.checks.CheckList;
+
+/**
+ * Extension point to define a PHP rule repository.
+ */
+public class MyXmlRules implements RulesDefinition {
+
+ public static final String LANGUAGE = "xml";
+ public static final String NAME = "MyCompany Custom Repository";
+ public static final String RESOURCE_BASE_PATH = "fr/cnumr/l10n/xml/rules/custom";
+ public static final String REPOSITORY_KEY = "cnumr-xml";
+ private static final Set RULE_TEMPLATES_KEY = Collections.emptySet();
+
+ @Override
+ public void define(Context context) {
+ NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME);
+
+ RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH);
+
+ // add the new checks
+ ruleMetadataLoader.addRulesByAnnotatedClass(repository, CheckList.getCheckClasses());
+
+// repository.rule("XPathCheck").setTemplate(true);
+// repository.rule("S3417").setTemplate(true);
+ repository.done();
+ }
+
+}
diff --git a/src/xml-plugin/src/main/java/fr/cnumr/xml/XMLCustomRulesPlugin.java b/src/xml-plugin/src/main/java/fr/cnumr/xml/XMLCustomRulesPlugin.java
new file mode 100644
index 000000000..b3cd9d0d3
--- /dev/null
+++ b/src/xml-plugin/src/main/java/fr/cnumr/xml/XMLCustomRulesPlugin.java
@@ -0,0 +1,33 @@
+/*
+ * SonarQube PHP Custom Rules Example
+ * Copyright (C) 2016-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package fr.cnumr.xml;
+
+import org.sonar.api.Plugin;
+
+/**
+ * Extension point to define a Sonar Plugin.
+ */
+public class XMLCustomRulesPlugin implements Plugin {
+
+ @Override
+ public void define(Context context) {
+ context.addExtension(MyXmlRules.class);
+ }
+}
diff --git a/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/CheckList.java b/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/CheckList.java
new file mode 100644
index 000000000..9f21859a4
--- /dev/null
+++ b/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/CheckList.java
@@ -0,0 +1,34 @@
+/*
+ * SonarQube XML Plugin
+ * Copyright (C) 2010-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package fr.cnumr.xml.checks;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CheckList {
+
+ private CheckList() {
+ }
+
+ public static List> getCheckClasses() {
+ return Arrays.asList(UseUnoptimizedVectorImage.class);
+ }
+
+}
diff --git a/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/UseUnoptimizedVectorImage.java b/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/UseUnoptimizedVectorImage.java
new file mode 100644
index 000000000..01aa9360f
--- /dev/null
+++ b/src/xml-plugin/src/main/java/fr/cnumr/xml/checks/UseUnoptimizedVectorImage.java
@@ -0,0 +1,37 @@
+package fr.cnumr.xml.checks;
+
+import java.util.Collections;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonarsource.analyzer.commons.xml.XmlFile;
+import org.sonarsource.analyzer.commons.xml.checks.SonarXmlCheck;
+
+@Rule(key = "S99", name = "Developpement", description = UseUnoptimizedVectorImage.MESSAGERULE, priority = Priority.MINOR, tags = { "bug" })
+public class UseUnoptimizedVectorImage extends SonarXmlCheck {
+
+ protected static final String MESSAGERULE = "Avoid the use of unoptimized vector images";
+
+ private static final String PATTERN_METADATA = " ");
+ }
+ if (file.getContents().contains(PATTERN_TITLE)) {
+ nodesError = nodesError.append(" ");
+ }
+ if (file.getContents().contains(PATTERN_DESCRIPTION)) {
+ nodesError = nodesError.append(" ");
+
+ }
+ if (nodesError.length() > 0) {
+ reportIssueOnFile("Issue on node(s) " + nodesError.toString() + "of the vector image.", Collections.emptyList());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/xml-plugin/src/main/resources/fr/cnumr/l10n/xml/rules/custom/S99.html b/src/xml-plugin/src/main/resources/fr/cnumr/l10n/xml/rules/custom/S99.html
new file mode 100644
index 000000000..949989ca2
--- /dev/null
+++ b/src/xml-plugin/src/main/resources/fr/cnumr/l10n/xml/rules/custom/S99.html
@@ -0,0 +1,11 @@
+
Avoid the use of unoptimized vector images
+
Noncompliant Code Example
+
+Votre image contient des métadata non nécessaires à la visualisation de l'image
+Your image has metadatas that are not necessary to visualize it
+
+
+
+ def foo():
+ ...
+ baseQuery= "SELECT name FROM users where id = "
+ for i in range(0,20):
+ query=query + str(i)
+ cursor.execute(query) #Noncompliant
+ for row in cursor:
+ print(row)
+ ...
+ cursor.close()
+-----------------------------------------------------------
+ def foo():
+ ...
+ baseQuery= "SELECT name FROM users where id = "
+ data = [ i for i in range(0,20) ]
+ cursor.executemany(baseQuery,data)
+ for row in cursor:
+ print(row)
+ ...
+ cursor.close()
+
+
+
+
+
Compliant Solution
+
+
+ def foo() {
+ ...
+ query = "SELECT name FROM users where id in (0 "
+ for i in range(0,20):
+ query = query +","+str(i)
+ query+=")"
+ cursor.execute(query) #compliant
+
+ # iterate through the resultset
+ for row in cursor:
+ print(row)
+
+ cursor.close();
+ ...
+ }
+
+
diff --git a/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json b/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json
new file mode 100644
index 000000000..7f1dc865f
--- /dev/null
+++ b/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json
@@ -0,0 +1,14 @@
+{
+ "title": "Avoid SQL request in loop",
+ "type": "CODE_SMELL",
+
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java b/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
new file mode 100644
index 000000000..dc5a47206
--- /dev/null
+++ b/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
@@ -0,0 +1,12 @@
+package fr.cnumr.python.checks;
+
+import org.junit.Test;
+import org.sonar.python.checks.utils.PythonCheckVerifier;
+
+public class AvoidSQLRequestInLoopCheckTest {
+
+ @Test
+ public void test() {
+ PythonCheckVerifier.verify("src/test/resources/checks/AvoidSQLRequestInLoopCheck.py", new AvoidSQLRequestInLoopCheckTest());
+ }
+}
\ No newline at end of file
diff --git a/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py b/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
new file mode 100644
index 000000000..1b0412875
--- /dev/null
+++ b/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
@@ -0,0 +1,64 @@
+import mysql.connector
+
+
+class AvoidSQLRequestInLoopCheck:
+ def testWithNoLoop(self):
+ try :
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor=db.cursor()
+ query = "SELECT * FROM users"
+ cursor.execute(query)
+ with row in cursor:
+ print(row.id)
+ cursor.close()
+ db.close()
+ except :
+ print("Got an exception")
+ db.close()
+
+ def testWithForLoop():
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ query = "SELECT * FROM users where id = "
+ for i in range(0,20):
+ cursor=db.cursor()
+ query+=str(i)
+ cursor.execute(query) #Noncompliant
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ except :
+ print("Got an exception")
+ db.close()
+
+ def testWithWhileLoop():
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ query = "SELECT * FROM users where id = "
+ i = 0
+ while i<20:
+
+ cursor=db.cursor()
+ query+=str(i)
+ cursor.execute(query) #Noncompliant
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ i+=1
+ except :
+ print("Got an exception")
+ db.close()
+
+ def testWithExecuteMany():
+ try:
+ db =db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ query = "SELECT * FROM users where id = %d"
+ cursor=db.cursor()
+ data = [i for i in range(20)]
+ cursor.executemany(query,data)
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ except:
+ print("Got an exception")
+ db.close()
\ No newline at end of file
diff --git a/src/python-plugin/pom.xml b/src/python-plugin/pom.xml
index 7ed2f4244..2e9477fba 100644
--- a/src/python-plugin/pom.xml
+++ b/src/python-plugin/pom.xml
@@ -40,6 +40,12 @@
org.sonarsource.sonarqubesonar-plugin-api-impl
+
+ org.sonarsource.java
+ java-frontend
+ 6.3.0.21585
+ compile
+
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
new file mode 100644
index 000000000..6c4a426a7
--- /dev/null
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -0,0 +1,83 @@
+package fr.cnumr.python.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.python.api.PythonSubscriptionCheck;
+import org.sonar.plugins.python.api.tree.*;
+
+import java.util.*;
+
+
+@Rule(
+ key = "S64",
+ name = "Developpement",
+ description = AvoidSQLRequestInLoop.MESSAGERULE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
+public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
+
+ public static final String MESSAGERULE = "Avoid perform an SQL query inside a loop";
+ private static final Map> linesWithIssuesByFile = new HashMap<>();
+
+ @Override
+ public void initialize(Context context) {
+
+ context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
+ ForStatement forStatement = (ForStatement) ctx.syntaxNode();
+ StatementList list = (StatementList) forStatement.body();
+ for (Statement a : list.statements()) {
+ if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
+ ExpressionStatement expression = (ExpressionStatement) a;
+ for (Expression i : expression.expressions()) {
+ CallExpression call = (CallExpression) i;
+ for (Tree ele : call.callee().children()) {
+
+ if (ele.getKind().equals(Tree.Kind.NAME)) {
+ Name name = (Name) ele;
+ if (name.name().equals("execute")) {
+ for (Argument argument : call.arguments()) {
+ StringLiteral string = (StringLiteral) argument.children().get(0);
+ if (string.stringElements().get(0).value().toUpperCase().contains("SELECT")) {
+ ctx.addIssue(call, MESSAGERULE);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ });
+ context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
+ WhileStatement forStatement = (WhileStatement) ctx.syntaxNode();
+ StatementList list = (StatementList) forStatement.body();
+ for (Statement a : list.statements()) {
+ if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
+ ExpressionStatement expression = (ExpressionStatement) a;
+ for (Expression i : expression.expressions()) {
+ CallExpression call = (CallExpression) i;
+ for (Tree ele : call.callee().children()) {
+ if (ele.getKind().equals(Tree.Kind.NAME)) {
+ Name name = (Name) ele;
+ if (name.name().equals("execute")) {
+ for (Argument argument : call.arguments()) {
+ StringLiteral string = (StringLiteral) argument.children().get(0);
+ if (string.stringElements().get(0).value().toUpperCase().contains("SELECT")) {
+ ctx.addIssue(call, MESSAGERULE);
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ });
+ }
+
+}
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html
new file mode 100644
index 000000000..61e1620cb
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html
@@ -0,0 +1,49 @@
+
Do not execute an SQL request in a loop
+
Noncompliant Code Example
+
+
+ def foo():
+ ...
+ baseQuery = "SELECT name FROM users where id = "
+ for i in range(0,20):
+ query = query + str(i)
+ cursor.execute(query) # Noncompliant
+ for row in cursor:
+ print(row)
+ ...
+ cursor.close()
+-----------------------------------------------------------
+ def foo():
+ ...
+ baseQuery = "SELECT name FROM users where id = "
+ data = [ i for i in range(0,20) ]
+ cursor.executemany(baseQuery,data)
+ for row in cursor:
+ print(row)
+ ...
+ cursor.close()
+
+
+
+
+
Compliant Solution
+
+
+ def foo() {
+ ...
+ query = "SELECT name FROM users where id in (0 "
+ for i in range(0,20):
+ query = query + "," + str(i)
+ query += ")"
+ cursor.execute(query) # Compliant
+
+ # iterate through the resultset
+ for row in cursor:
+ print(row)
+
+ cursor.close();
+ ...
+ }
+
+
+
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.json
new file mode 100644
index 000000000..b86e91d8a
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.json
@@ -0,0 +1,14 @@
+{
+ "title": "Avoid SQL request in loop",
+ "type": "CODE_SMELL",
+
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
new file mode 100644
index 000000000..57aa12412
--- /dev/null
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
@@ -0,0 +1,12 @@
+package fr.cnumr.python.checks;
+
+import org.junit.Test;
+import org.sonar.python.checks.utils.PythonCheckVerifier;
+
+public class AvoidSQLRequestInLoopCheckTest {
+
+ @Test
+ public void test() {
+ PythonCheckVerifier.verify("src/test/resources/checks/AvoidSQLRequestInLoopCheck.py", new AvoidSQLRequestInLoop());
+ }
+}
diff --git a/src/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py b/src/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
new file mode 100644
index 000000000..177d70a1d
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
@@ -0,0 +1,64 @@
+import mysql.connector
+
+
+class AvoidSQLRequestInLoopCheck:
+ def testWithNoLoop(self):
+ try :
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor=db.cursor()
+ query = "SELECT * FROM users"
+ cursor.execute(query)
+ with row in cursor:
+ print(row.id)
+ cursor.close()
+ db.close()
+ except :
+ print("Got an exception")
+ db.close()
+
+ def testWithForLoop():
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor=db.cursor()
+ for i in range(0,20):
+ query+=str(i)
+ cursor.execute("SELECT * from users") #Noncompliant
+
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ except :
+ print("Got an exception")
+ db.close()
+
+ def testWithWhileLoop():
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ query = "SELECT * "
+ i = 0
+ while i<20:
+ cursor=db.cursor()
+ cursor.execute("SELECT * FROM users where id = "+str(i)) #Noncompliant
+ i+=1
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ except :
+ print("Got an exception")
+ db.close()
+ def testWithWhileLoop():
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ i = 0
+ while i<20:
+ cursor=db.cursor()
+ cursor.execute("UPDATE users set id="+str(i))
+ i+=1
+ with row in cursor:
+ print(row.name)
+ cursor.close()
+ except :
+ print("Got an exception")
+ db.close()
+
+
From ba491934c77fd2ad4bcd0a798f9bb2126b805e4a Mon Sep 17 00:00:00 2001
From: Jules Delecour <72793427+jules-delecour-dav@users.noreply.github.com>
Date: Fri, 17 Jun 2022 12:51:07 +0200
Subject: [PATCH 037/119] Revert "64-PYTHON (#135)" (#138)
This reverts commit 2256ea7b9a2e744d5517d5eea437c7611144e91d.
---
.idea/.gitignore | 8 --
.idea/ecoCode.iml | 9 --
.idea/inspectionProfiles/Project_Default.xml | 6 --
.idea/misc.xml | 4 -
.idea/modules.xml | 8 --
.idea/vcs.xml | 6 --
.../fr/cnumr/l10n/python/rules/python/64.html | 48 -----------
.../fr/cnumr/l10n/python/rules/python/64.json | 14 ----
.../AvoidSQLRequestInLoopCheckTest.java | 12 ---
.../checks/AvoidSQLRequestInLoopCheck.py | 64 --------------
src/python-plugin/pom.xml | 6 --
.../python/checks/AvoidSQLRequestInLoop.java | 83 -------------------
.../cnumr/l10n/python/rules/python/S64.html | 49 -----------
.../cnumr/l10n/python/rules/python/S64.json | 14 ----
.../AvoidSQLRequestInLoopCheckTest.java | 12 ---
.../checks/AvoidSQLRequestInLoopCheck.py | 64 --------------
16 files changed, 407 deletions(-)
delete mode 100644 .idea/.gitignore
delete mode 100644 .idea/ecoCode.iml
delete mode 100644 .idea/inspectionProfiles/Project_Default.xml
delete mode 100644 .idea/misc.xml
delete mode 100644 .idea/modules.xml
delete mode 100644 .idea/vcs.xml
delete mode 100644 sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.html
delete mode 100644 sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json
delete mode 100644 sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
delete mode 100644 sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
delete mode 100644 src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
delete mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html
delete mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.json
delete mode 100644 src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
delete mode 100644 src/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b81b..000000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/ecoCode.iml b/.idea/ecoCode.iml
deleted file mode 100644
index d6ebd4805..000000000
--- a/.idea/ecoCode.iml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index ac21435ff..000000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 412cda9dd..000000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 648097b9c..000000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1ddfb..000000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.html b/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.html
deleted file mode 100644
index d40de7588..000000000
--- a/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
Do not execute an SQL request in a loop
-
Noncompliant Code Example
-
-
- def foo():
- ...
- baseQuery= "SELECT name FROM users where id = "
- for i in range(0,20):
- query=query + str(i)
- cursor.execute(query) #Noncompliant
- for row in cursor:
- print(row)
- ...
- cursor.close()
------------------------------------------------------------
- def foo():
- ...
- baseQuery= "SELECT name FROM users where id = "
- data = [ i for i in range(0,20) ]
- cursor.executemany(baseQuery,data)
- for row in cursor:
- print(row)
- ...
- cursor.close()
-
-
-
-
-
Compliant Solution
-
-
- def foo() {
- ...
- query = "SELECT name FROM users where id in (0 "
- for i in range(0,20):
- query = query +","+str(i)
- query+=")"
- cursor.execute(query) #compliant
-
- # iterate through the resultset
- for row in cursor:
- print(row)
-
- cursor.close();
- ...
- }
-
-
diff --git a/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json b/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json
deleted file mode 100644
index 7f1dc865f..000000000
--- a/sonarqube-plugin-greenit/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/64.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "title": "Avoid SQL request in loop",
- "type": "CODE_SMELL",
-
- "status": "ready",
- "remediation": {
- "func": "Constant\/Issue",
- "constantCost": "10min"
- },
- "tags": [
- "eco-conception"
- ],
- "defaultSeverity": "Minor"
-}
\ No newline at end of file
diff --git a/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java b/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
deleted file mode 100644
index dc5a47206..000000000
--- a/sonarqube-plugin-greenit/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package fr.cnumr.python.checks;
-
-import org.junit.Test;
-import org.sonar.python.checks.utils.PythonCheckVerifier;
-
-public class AvoidSQLRequestInLoopCheckTest {
-
- @Test
- public void test() {
- PythonCheckVerifier.verify("src/test/resources/checks/AvoidSQLRequestInLoopCheck.py", new AvoidSQLRequestInLoopCheckTest());
- }
-}
\ No newline at end of file
diff --git a/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py b/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
deleted file mode 100644
index 1b0412875..000000000
--- a/sonarqube-plugin-greenit/python-plugin/src/test/resources/checks/AvoidSQLRequestInLoopCheck.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import mysql.connector
-
-
-class AvoidSQLRequestInLoopCheck:
- def testWithNoLoop(self):
- try :
- db = mysql.connector.connect(option_files='my.conf', use_pure=True)
- cursor=db.cursor()
- query = "SELECT * FROM users"
- cursor.execute(query)
- with row in cursor:
- print(row.id)
- cursor.close()
- db.close()
- except :
- print("Got an exception")
- db.close()
-
- def testWithForLoop():
- try:
- db = mysql.connector.connect(option_files='my.conf', use_pure=True)
- query = "SELECT * FROM users where id = "
- for i in range(0,20):
- cursor=db.cursor()
- query+=str(i)
- cursor.execute(query) #Noncompliant
- with row in cursor:
- print(row.name)
- cursor.close()
- except :
- print("Got an exception")
- db.close()
-
- def testWithWhileLoop():
- try:
- db = mysql.connector.connect(option_files='my.conf', use_pure=True)
- query = "SELECT * FROM users where id = "
- i = 0
- while i<20:
-
- cursor=db.cursor()
- query+=str(i)
- cursor.execute(query) #Noncompliant
- with row in cursor:
- print(row.name)
- cursor.close()
- i+=1
- except :
- print("Got an exception")
- db.close()
-
- def testWithExecuteMany():
- try:
- db =db = mysql.connector.connect(option_files='my.conf', use_pure=True)
- query = "SELECT * FROM users where id = %d"
- cursor=db.cursor()
- data = [i for i in range(20)]
- cursor.executemany(query,data)
- with row in cursor:
- print(row.name)
- cursor.close()
- except:
- print("Got an exception")
- db.close()
\ No newline at end of file
diff --git a/src/python-plugin/pom.xml b/src/python-plugin/pom.xml
index 2e9477fba..7ed2f4244 100644
--- a/src/python-plugin/pom.xml
+++ b/src/python-plugin/pom.xml
@@ -40,12 +40,6 @@
org.sonarsource.sonarqubesonar-plugin-api-impl
-
- org.sonarsource.java
- java-frontend
- 6.3.0.21585
- compile
-
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
deleted file mode 100644
index 6c4a426a7..000000000
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package fr.cnumr.python.checks;
-
-import org.sonar.check.Priority;
-import org.sonar.check.Rule;
-import org.sonar.plugins.python.api.PythonSubscriptionCheck;
-import org.sonar.plugins.python.api.tree.*;
-
-import java.util.*;
-
-
-@Rule(
- key = "S64",
- name = "Developpement",
- description = AvoidSQLRequestInLoop.MESSAGERULE,
- priority = Priority.MINOR,
- tags = {"bug"})
-public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
-
- public static final String MESSAGERULE = "Avoid perform an SQL query inside a loop";
- private static final Map> linesWithIssuesByFile = new HashMap<>();
-
- @Override
- public void initialize(Context context) {
-
- context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
- ForStatement forStatement = (ForStatement) ctx.syntaxNode();
- StatementList list = (StatementList) forStatement.body();
- for (Statement a : list.statements()) {
- if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
- ExpressionStatement expression = (ExpressionStatement) a;
- for (Expression i : expression.expressions()) {
- CallExpression call = (CallExpression) i;
- for (Tree ele : call.callee().children()) {
-
- if (ele.getKind().equals(Tree.Kind.NAME)) {
- Name name = (Name) ele;
- if (name.name().equals("execute")) {
- for (Argument argument : call.arguments()) {
- StringLiteral string = (StringLiteral) argument.children().get(0);
- if (string.stringElements().get(0).value().toUpperCase().contains("SELECT")) {
- ctx.addIssue(call, MESSAGERULE);
- }
- }
- }
- }
- }
- }
- }
- }
-
-
- });
- context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
- WhileStatement forStatement = (WhileStatement) ctx.syntaxNode();
- StatementList list = (StatementList) forStatement.body();
- for (Statement a : list.statements()) {
- if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
- ExpressionStatement expression = (ExpressionStatement) a;
- for (Expression i : expression.expressions()) {
- CallExpression call = (CallExpression) i;
- for (Tree ele : call.callee().children()) {
- if (ele.getKind().equals(Tree.Kind.NAME)) {
- Name name = (Name) ele;
- if (name.name().equals("execute")) {
- for (Argument argument : call.arguments()) {
- StringLiteral string = (StringLiteral) argument.children().get(0);
- if (string.stringElements().get(0).value().toUpperCase().contains("SELECT")) {
- ctx.addIssue(call, MESSAGERULE);
-
- }
- }
- }
- }
- }
- }
-
- }
- }
-
- });
- }
-
-}
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html
deleted file mode 100644
index 61e1620cb..000000000
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S64.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
Do not execute an SQL request in a loop
-
Noncompliant Code Example
-
-
- def foo():
- ...
- baseQuery = "SELECT name FROM users where id = "
- for i in range(0,20):
- query = query + str(i)
- cursor.execute(query) # Noncompliant
- for row in cursor:
- print(row)
- ...
- cursor.close()
------------------------------------------------------------
- def foo():
- ...
- baseQuery = "SELECT name FROM users where id = "
- data = [ i for i in range(0,20) ]
- cursor.executemany(baseQuery,data)
- for row in cursor:
- print(row)
- ...
- cursor.close()
-
-
-
-
-
Compliant Solution
-
-
- def foo() {
- ...
- query = "SELECT name FROM users where id in (0 "
- for i in range(0,20):
- query = query + "," + str(i)
- query += ")"
- cursor.execute(query) # Compliant
-
- # iterate through the resultset
- for row in cursor:
- print(row)
-
- cursor.close();
- ...
- }
-
-
Do not call a function in the declaration of a for-type loop
+
Do not call a function when declaring a for-type loop in order to avoid function calls each iterations. It saves CPU cycles
Noncompliant Code Example
public void foo() {
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
index d51cbccf7..68cabdd39 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S69.json
@@ -1,5 +1,5 @@
{
- "title": "Do not call a function in the declaration of a for-type loop",
+ "title": "Do not call a function when declaring a for-type loop",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.html
index d62845123..4bb67e113 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S72.html
@@ -1,4 +1,4 @@
-
Do not execute an SQL request in a loop
+
Executing SQL queries in loop induced unnecessary calculation by the cpu, RAM usage and network transfert.
Noncompliant Code Example
public void foo() {
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.html
index d919af7a8..8d977de29 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S74.html
@@ -1,4 +1,4 @@
-
Don't use the query SELECT * FROM
+
Databases servers have to solves fileds regarding to schema. Knowing and using the schema save CPU cycles and network transfer.
Noncompliant Code Example
public void foo() {
diff --git a/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java b/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
index 29393a555..022ac95d7 100644
--- a/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
+++ b/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
@@ -34,7 +34,7 @@
public class MyPhpRules implements RulesDefinition, PHPCustomRuleRepository {
public static final String LANGUAGE = "php";
- public static final String NAME = "MyCompany Custom Repository";
+ public static final String NAME = "Collectif Conception Numérique Responsable";
public static final String RESOURCE_BASE_PATH = "fr/cnumr/l10n/php/rules/custom";
public static final String REPOSITORY_KEY = "cnumr-php";
private static final Set RULE_TEMPLATES_KEY = Collections.emptySet();
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.html
index ff380b1d0..5444a6196 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S34.html
@@ -1,7 +1,8 @@
-
Avoid using try-catch-finally statement
+
Inside complex code parts (for exemple multiple loops, complex data constructions...), avoid using try...catch...finally.
+
When an exception is thrown, a variable (the exception itself) is created in a catch block and it's destruction consumes unnecessary CPU cycles and RAM. Prefer using logical tests in this cases.
Noncompliant Code Example
-try // NOK
+try
{
$picture = PDF_open_image_file($PDF, "jpeg", $imgFile, "", 0); // This is the original statement, this works on PHP4
}
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.html
index 95b8cd396..28e745335 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S66.html
@@ -1,4 +1,4 @@
-
Avoid using double quote ("), prefer using simple quote (')
+
PHP allows declaring a string with simple or double quotes. Using double quotes allows developers to insert variables which will be substituted during execution. When the string has no variables, using simple quotes avoid PHP to search inexisting variables. It will save CPU cycles consumption.
Do not call a function when declaring a for-type loop
+
Do not call a function when declaring a for-type loop in order to avoid function calls each iterations. It saves CPU cycles
Noncompliant Code Example
for ($i = 0; $i <= foo(); $i++) { // NOK
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.html
index dd8b7dabf..3b51bdc50 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S72.html
@@ -1,4 +1,4 @@
-
Do not execute an SQL request in a loop
+
Executing SQL queries in loop induced unnecessary calculation by the cpu, RAM usage and network transfert.
Noncompliant Code Example
public function foo() {
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.html
index daf3f389f..0315dcc4a 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/S74.html
@@ -1,4 +1,4 @@
-
Don't use the query SELECT * FROM
+
Databases servers have to solves fileds regarding to schema. Knowing and using the schema save CPU cycles and network transfer.
Noncompliant Code Example
public function foo() {
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
index 2333305c3..2f0282b66 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
@@ -29,7 +29,7 @@
public class CustomPythonRuleRepository implements RulesDefinition, PythonCustomRuleRepository {
public static final String LANGUAGE = "py";
- public static final String NAME = "MyCompany Custom Repository";
+ public static final String NAME = "Collectif Conception Numérique Responsable";
public static final String RESOURCE_BASE_PATH = "fr/cnumr/l10n/python/rules/python";
public static final String REPOSITORY_KEY = "cnumr-python";
private static final Set RULE_TEMPLATES_KEY = Collections.emptySet();
@@ -54,8 +54,7 @@ public String repositoryKey() {
@Override
public List checkClasses() {
- return Arrays.asList(NoFunctionCallWhenDeclaringForLoop.class, AvoidTryCatchFinallyCheck.class,
- AvoidDoubleQuoteCheck.class, AvoidFullSQLRequest.class, AvoidGlobalVariableInFunctionCheck.class);
+ return Arrays.asList(NoFunctionCallWhenDeclaringForLoop.class, AvoidTryCatchFinallyCheck.class, AvoidFullSQLRequest.class, AvoidGlobalVariableInFunctionCheck.class);
}
private static void setTemplates(NewRepository repository) {
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheck.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheck.java
deleted file mode 100644
index 0977fc510..000000000
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheck.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package fr.cnumr.python.checks;
-
-import org.sonar.check.Priority;
-import org.sonar.check.Rule;
-import org.sonar.plugins.python.api.PythonSubscriptionCheck;
-import org.sonar.plugins.python.api.SubscriptionContext;
-import org.sonar.plugins.python.api.tree.StringElement;
-import org.sonar.plugins.python.api.tree.StringLiteral;
-import org.sonar.plugins.python.api.tree.Tree;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-@Rule(
- key = AvoidDoubleQuoteCheck.RULE_KEY,
- name = "Developpement",
- description = AvoidDoubleQuoteCheck.DESCRIPTION,
- priority = Priority.MINOR,
- tags = {"bug"})
-public class AvoidDoubleQuoteCheck extends PythonSubscriptionCheck {
-
- public static final String RULE_KEY = "S66";
- public static final String DESCRIPTION = "Use single quote (') instead of double quote (\")";
- private static final Map> linesWithIssuesByFile = new HashMap<>();
-
- @Override
- public void initialize(Context context) {
- context.registerSyntaxNodeConsumer(Tree.Kind.STRING_LITERAL, this::visitNodeString);
- }
-
- public void visitNodeString(SubscriptionContext ctx) {
- StringLiteral stringLiteral = (StringLiteral) ctx.syntaxNode();
- stringLiteral.stringElements().forEach(stringElement -> {
- checkIssue(stringElement, ctx);
- });
- }
-
- public void checkIssue(StringElement stringElement, SubscriptionContext ctx) {
- if (lineAlreadyHasThisIssue(stringElement, ctx)) return;
- if (stringElement.value().indexOf("\"") == 0 && stringElement.value().lastIndexOf("\"") == stringElement.value().length() - 1) {
- repport(stringElement, ctx);
- return;
- }
- }
-
- private void repport(StringElement stringElement, SubscriptionContext ctx) {
- if (stringElement.firstToken() != null) {
- final String classname = ctx.pythonFile().fileName();
- final int line = stringElement.firstToken().line();
- if (!linesWithIssuesByFile.containsKey(classname)) {
- linesWithIssuesByFile.put(classname, new ArrayList<>());
- }
- linesWithIssuesByFile.get(classname).add(line);
- }
- ctx.addIssue(stringElement, DESCRIPTION);
- }
-
- private boolean lineAlreadyHasThisIssue(StringElement stringElement, SubscriptionContext ctx) {
- if (stringElement.firstToken() != null) {
- final String filename = ctx.pythonFile().fileName();
- final int line = stringElement.firstToken().line();
-
- return linesWithIssuesByFile.containsKey(filename)
- && linesWithIssuesByFile.get(filename).contains(line);
- }
-
- return false;
- }
-
-
-}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/NoFunctionCallWhenDeclaringForLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/NoFunctionCallWhenDeclaringForLoop.java
index 210d2f53e..5a2911ad8 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/NoFunctionCallWhenDeclaringForLoop.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/NoFunctionCallWhenDeclaringForLoop.java
@@ -18,7 +18,7 @@
public class NoFunctionCallWhenDeclaringForLoop extends PythonSubscriptionCheck {
public static final String RULE_KEY = "S69";
- public static final String DESCRIPTION = "Do not call a function in the declaration of a for-type loop";
+ public static final String DESCRIPTION = "Do not call a function when declaring a for-type loop";
@Override
public void initialize(Context context) {
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.html
index f4d820293..812ad2886 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.html
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.html
@@ -1,11 +1,11 @@
-
Eviter d'utiliser des variables globales directement
+
When function calls global variables, a lot a CPU cycles is consumed
Noncompliant Code Example
global_var = 'foo'
def print_global_var_details():
print(len(global_var)) # Noncompliant
- print('Global var : ', global_var) # Noncompliant {{Use local variable
- print('Global var : ' + global_var) # Noncompliant {{Use local variable
+ print('Global var : ', global_var) # Noncompliant
+ print('Global var : ' + global_var) # Noncompliant
print_global_var_details()
Compliant Solution
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.json
index 5d2e79adb..0f6c9be50 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D4.json
@@ -1,5 +1,5 @@
{
- "title": "Ne pas appeler de variable globale directement dans les fonctions",
+ "title": "Do not call global variables directly inside functions",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.html
index 3d1aca04c..e72e14b5b 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.html
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.html
@@ -1,4 +1,6 @@
-
Eviter d'utiliser try-catch-finally
+
Inside complex code parts (for exemple multiple loops, complex data constructions...), avoid using try...catch...finally.
+
When an exception is thrown, a variable (the exception itself) is created in a catch block and it's destruction consumes unnecessary CPU cycles and RAM. Prefer using logical tests in this cases.
+
Noncompliant Code Example
try:
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
index e3718d9f9..72a37f621 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S34.json
@@ -1,5 +1,5 @@
{
- "title": "Ne pas appeler de fonction dans la déclaration d’une boucle de type for",
+ "title": "Avoid using try-catch-finally statement",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.html
deleted file mode 100644
index 6773f86bc..000000000
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
Utiliser la simple côte (') au lieu du guillemet (")
-
Noncompliant Code Example
-
-print("foo")
-myvalue = "foo"
-
-
-
Compliant Solution
-
-print('foo')
-myvalue = 'foo'
-
-
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
deleted file mode 100644
index 1fd95da11..000000000
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S66.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "title": "Utiliser la simple côte (') au lieu du guillemet (\")",
- "type": "CODE_SMELL",
- "status": "ready",
- "remediation": {
- "func": "Constant\/Issue",
- "constantCost": "5min"
- },
- "tags": [
- "eco-conception"
- ],
- "defaultSeverity": "Minor"
-}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
index e3718d9f9..68cabdd39 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.json
@@ -1,5 +1,5 @@
{
- "title": "Ne pas appeler de fonction dans la déclaration d’une boucle de type for",
+ "title": "Do not call a function when declaring a for-type loop",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.html
index d919af7a8..8d977de29 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.html
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S74.html
@@ -1,4 +1,4 @@
-
Don't use the query SELECT * FROM
+
Databases servers have to solves fileds regarding to schema. Knowing and using the schema save CPU cycles and network transfer.
Noncompliant Code Example
public void foo() {
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
index b9b20dbbc..80c6ff227 100644
--- a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
@@ -33,7 +33,7 @@ public void test_rule_repository() {
customPythonRuleRepository.define(context);
assertThat(customPythonRuleRepository.repositoryKey()).isEqualTo(CustomPythonRuleRepository.REPOSITORY_KEY);
assertThat(context.repositories()).hasSize(1).extracting("key").containsExactly(customPythonRuleRepository.repositoryKey());
- assertThat(context.repositories().get(0).rules()).hasSize(5);
- assertThat(customPythonRuleRepository.checkClasses()).hasSize(5);
+ assertThat(context.repositories().get(0).rules()).hasSize(4);
+ assertThat(customPythonRuleRepository.checkClasses()).hasSize(4);
}
}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheckTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheckTest.java
deleted file mode 100644
index b56e9b7b4..000000000
--- a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidDoubleQuoteCheckTest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package fr.cnumr.python.checks;
-
-import org.junit.Test;
-import org.sonar.python.checks.utils.PythonCheckVerifier;
-
-public class AvoidDoubleQuoteCheckTest {
-
- @Test
- public void test() {
- PythonCheckVerifier.verify("src/test/resources/checks/avoidDoubleQuote.py", new AvoidDoubleQuoteCheck());
- }
-}
diff --git a/src/python-plugin/src/test/resources/checks/avoidDoubleQuote.py b/src/python-plugin/src/test/resources/checks/avoidDoubleQuote.py
deleted file mode 100644
index 360ff284b..000000000
--- a/src/python-plugin/src/test/resources/checks/avoidDoubleQuote.py
+++ /dev/null
@@ -1,30 +0,0 @@
-def displayMessage(argument1, argument2, argument3):
- print(argument1+" "+argument2+" "+argument3) # Noncompliant {{Use single quote (') instead of double quote (")}}
-
-# function call
-displayMessage("Geeks", "4", "Geeks") # Noncompliant {{Use single quote (') instead of double quote (")}}
-
-
-
-
-
-print("foo") # Noncompliant {{Use single quote (') instead of double quote (")}}
-
-
-
-print('faa')
-
-
-
-
-print(e)
-
-
-print(6)
-
-
-print('"Rien de grand ne s\'est accompli dans le monde sans passion." - Georg Wilhelm Friedrich Hegel')
-
-myvalue = "foo" # Noncompliant {{Use single quote (') instead of double quote (")}}
-
-myvalue = 'foo'
\ No newline at end of file
diff --git a/src/python-plugin/src/test/resources/checks/noFunctionCallWhenDeclaringForLoop.py b/src/python-plugin/src/test/resources/checks/noFunctionCallWhenDeclaringForLoop.py
index 4cc39dc0d..a3755d3e3 100644
--- a/src/python-plugin/src/test/resources/checks/noFunctionCallWhenDeclaringForLoop.py
+++ b/src/python-plugin/src/test/resources/checks/noFunctionCallWhenDeclaringForLoop.py
@@ -1,7 +1,7 @@
def my_function():
return 6
-for i in my_function(): # Noncompliant {{Do not call a function in the declaration of a for-type loop}}
+for i in my_function(): # Noncompliant {{Do not call a function when declaring a for-type loop}}
print("Test")
my_function()
pass
diff --git a/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java b/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
index e54090e06..f0265c021 100644
--- a/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
+++ b/src/xml-plugin/src/main/java/fr/cnumr/xml/MyXmlRules.java
@@ -33,7 +33,7 @@
public class MyXmlRules implements RulesDefinition {
public static final String LANGUAGE = "xml";
- public static final String NAME = "MyCompany Custom Repository";
+ public static final String NAME = "Collectif Conception Numérique Responsable";
public static final String RESOURCE_BASE_PATH = "fr/cnumr/l10n/xml/rules/custom";
public static final String REPOSITORY_KEY = "cnumr-xml";
private static final Set RULE_TEMPLATES_KEY = Collections.emptySet();
From 2f48b68df114b10165e8991ad6191a9de66cb51c Mon Sep 17 00:00:00 2001
From: Jules Delecour <72793427+jules-delecour-dav@users.noreply.github.com>
Date: Thu, 23 Jun 2022 17:29:40 +0200
Subject: [PATCH 040/119] update to debug (#140)
* update to debug
* preparing file for real python test (not sure it's the right place) but sure that we can continue to chek AST with non fonctional python code
* Insure that python code is functionnal (we can manualy test it), doing homogeneous tests
* all other file have lowercase in first char
* all other file have lowercase in first char (Oup's registring right filename)
* Updating rules test
Co-authored-by: Vincent Cagnard
---
.../python/checks/AvoidSQLRequestInLoop.java | 74 +++++++++++++++++
.../AvoidSQLRequestInLoopCheckTest.java | 12 +++
.../src/test/resources/checks/.gitignore | 1 +
.../checks/avoidSQLRequestInLoopCheck.py | 83 +++++++++++++++++++
.../src/test/resources/checks/init_dbtest.sql | 34 ++++++++
.../src/test/resources/checks/my.conf.sample | 5 ++
6 files changed, 209 insertions(+)
create mode 100644 src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
create mode 100644 src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
create mode 100644 src/python-plugin/src/test/resources/checks/.gitignore
create mode 100644 src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopCheck.py
create mode 100644 src/python-plugin/src/test/resources/checks/init_dbtest.sql
create mode 100644 src/python-plugin/src/test/resources/checks/my.conf.sample
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
new file mode 100644
index 000000000..10e7c38e1
--- /dev/null
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -0,0 +1,74 @@
+package fr.cnumr.python.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.python.api.PythonSubscriptionCheck;
+import org.sonar.plugins.python.api.SubscriptionContext;
+import org.sonar.plugins.python.api.tree.*;
+
+import java.util.*;
+import java.lang.*;
+
+@Rule(
+ key = "S64",
+ name = "Developpement",
+ description = AvoidSQLRequestInLoop.MESSAGERULE,
+ priority = Priority.MINOR,
+ tags = {"bug"}
+)
+
+public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
+
+ public static final String MESSAGERULE = "Avoid perform an SQL query inside a loop";
+ private static final Map> linesWithIssuesByFile = new HashMap<>();
+
+ @Override
+ public void initialize(Context context) {
+ context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
+ System.out.println("FOR_STMT");
+ visitLoopNode(((ForStatement) ctx.syntaxNode()).body(), ctx);
+ });
+ context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
+ System.out.println("WHILE_STMT");
+ visitLoopNode(((WhileStatement) ctx.syntaxNode()).body(), ctx);
+ });
+ }
+
+ private void visitLoopNode(StatementList list, SubscriptionContext ctx) {
+ for (Statement a: list.statements()) {
+ if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
+ ExpressionStatement expression = (ExpressionStatement) a;
+ for (Expression i: expression.expressions()) {
+ if (i.is(Tree.Kind.CALL_EXPR))
+ visitCallExpressionNode((CallExpression) i, ctx);
+ }
+ }
+ }
+ }
+
+ private void visitCallExpressionNode(CallExpression ce, SubscriptionContext ctx) {
+ for (Tree ele : ce.callee().children()) {
+ if (ele.getKind().equals(Tree.Kind.NAME)) {
+ Name name = (Name) ele;
+ if (name.name().equals("execute")) {
+ for (Argument a: ce.arguments()) {
+ if (checkLitteralInTree((Tree) a))
+ ctx.addIssue(ce, MESSAGERULE);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean checkLitteralInTree(Tree t) {
+ for (Tree tc : t.children()) {
+ if (tc.is(Tree.Kind.STRING_LITERAL)) {
+ if (((StringLiteral) tc).trimmedQuotesValue().toUpperCase().contains("SELECT"))
+ return true;
+ }
+ return checkLitteralInTree(tc);
+ }
+ return false;
+ }
+
+}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
new file mode 100644
index 000000000..42c43c427
--- /dev/null
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
@@ -0,0 +1,12 @@
+package fr.cnumr.python.checks;
+
+import org.junit.Test;
+import org.sonar.python.checks.utils.PythonCheckVerifier;
+
+public class AvoidSQLRequestInLoopCheckTest {
+
+ @Test
+ public void test() {
+ PythonCheckVerifier.verify("src/test/resources/checks/avoidSQLRequestInLoopCheck.py", new AvoidSQLRequestInLoop());
+ }
+}
diff --git a/src/python-plugin/src/test/resources/checks/.gitignore b/src/python-plugin/src/test/resources/checks/.gitignore
new file mode 100644
index 000000000..b6b51e9bb
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/.gitignore
@@ -0,0 +1 @@
+my.conf
diff --git a/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopCheck.py b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopCheck.py
new file mode 100644
index 000000000..7f98cd548
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopCheck.py
@@ -0,0 +1,83 @@
+import mysql.connector
+
+
+class AvoidSQLRequestInLoopCheck:
+ maxrows = 20
+
+ def testWithNoLoop(self):
+ try :
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor = db.cursor(dictionary=True)
+
+ cursor.execute('SELECT id, name FROM users LIMIT %(limit)s', {'limit': self.maxrows})
+ for row in cursor.fetchall():
+ print("{}: {}".format(row['id'], row['name']))
+
+ cursor.close()
+ db.close()
+ except mysql.connector.Error as err:
+ print("Got an exception: {}".format(err))
+ db.close()
+
+ def testWithForLoop(self):
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor = db.cursor(dictionary=True)
+
+ for i in range(0, self.maxrows):
+ cursor.execute("SELECT id, name FROM users WHERE id = %(id)s", {'id': i+1}) #Noncompliant
+ for row in cursor.fetchall():
+ print("{}: {}".format(row['id'], row['name']))
+
+ cursor.close()
+ db.close()
+ except mysql.connector.Error as err:
+ print("Got an exception: {}".format(err))
+ db.close()
+
+ def testWithWhileLoop(self):
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor = db.cursor(dictionary=True)
+
+ i = 0
+ while i < self.maxrows:
+ cursor.execute("SELECT id, name FROM users WHERE id = %(id)s", {'id': i+1}) #Noncompliant
+ for row in cursor.fetchall():
+ print("name: {}".format(row['name']))
+ i += 1
+
+ cursor.close()
+ db.close()
+ except mysql.connector.Error as err:
+ print("Got an exception: {}".format(err))
+ db.close()
+
+ def testWithWhileLoopUpdate(self):
+ try:
+ db = mysql.connector.connect(option_files='my.conf', use_pure=True)
+ cursor=db.cursor()
+
+ i = 0
+ while i < self.maxrows:
+ cursor.execute('UPDATE users set name=%(name)s where id=%(id)s', {'name': "anonymous", 'id': i+1})
+ i+=1
+ db.commit()
+
+ cursor.close()
+ db.close()
+ except mysql.connector.Error as err:
+ print("Got an exception: {}".format(err))
+ db.close()
+
+if __name__ == '__main__':
+ test = AvoidSQLRequestInLoopCheck()
+
+ print("testWithNoLoop")
+ test.testWithNoLoop()
+ print("testWithForLoop")
+ test.testWithForLoop()
+ print("testWithWhileLoop")
+ test.testWithWhileLoop()
+ print("testWithWhileLoopUpdate")
+ test.testWithWhileLoopUpdate()
diff --git a/src/python-plugin/src/test/resources/checks/init_dbtest.sql b/src/python-plugin/src/test/resources/checks/init_dbtest.sql
new file mode 100644
index 000000000..9a7a0a524
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/init_dbtest.sql
@@ -0,0 +1,34 @@
+DROP TABLE IF EXISTS users;
+
+CREATE TABLE users (
+ id INT NOT NULL AUTO_INCREMENT,
+ name VARCHAR(255),
+ PRIMARY KEY (id)
+);
+
+INSERT INTO users(name) VALUES('a');
+INSERT INTO users(name) VALUES('b');
+INSERT INTO users(name) VALUES('c');
+INSERT INTO users(name) VALUES('d');
+INSERT INTO users(name) VALUES('e');
+INSERT INTO users(name) VALUES('f');
+INSERT INTO users(name) VALUES('g');
+INSERT INTO users(name) VALUES('h');
+INSERT INTO users(name) VALUES('i');
+INSERT INTO users(name) VALUES('j');
+INSERT INTO users(name) VALUES('k');
+INSERT INTO users(name) VALUES('l');
+INSERT INTO users(name) VALUES('m');
+INSERT INTO users(name) VALUES('n');
+INSERT INTO users(name) VALUES('o');
+INSERT INTO users(name) VALUES('p');
+INSERT INTO users(name) VALUES('q');
+INSERT INTO users(name) VALUES('r');
+INSERT INTO users(name) VALUES('s');
+INSERT INTO users(name) VALUES('t');
+INSERT INTO users(name) VALUES('u');
+INSERT INTO users(name) VALUES('v');
+INSERT INTO users(name) VALUES('w');
+INSERT INTO users(name) VALUES('x');
+INSERT INTO users(name) VALUES('y');
+INSERT INTO users(name) VALUES('z');
diff --git a/src/python-plugin/src/test/resources/checks/my.conf.sample b/src/python-plugin/src/test/resources/checks/my.conf.sample
new file mode 100644
index 000000000..e10dc23bc
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/my.conf.sample
@@ -0,0 +1,5 @@
+[client]
+host = localhost
+user = dbtest
+password = dbtest
+database = dbtest
From d72799b107586594f4d57a62ddb96323bbdfa5c0 Mon Sep 17 00:00:00 2001
From: Vincent Cagnard
Date: Thu, 23 Jun 2022 17:44:41 +0200
Subject: [PATCH 041/119] Hotfix for return rule (SQ bug)
---
.../java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
index 10e7c38e1..f18f07d81 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -66,7 +66,8 @@ private boolean checkLitteralInTree(Tree t) {
if (((StringLiteral) tc).trimmedQuotesValue().toUpperCase().contains("SELECT"))
return true;
}
- return checkLitteralInTree(tc);
+ if (checkLitteralInTree(tc))
+ return true;
}
return false;
}
From edffd861b0c5291a5a59ed4ba02e27a0d4462ecd Mon Sep 17 00:00:00 2001
From: Vincent Cagnard
Date: Fri, 24 Jun 2022 07:39:00 +0200
Subject: [PATCH 042/119] HOTFIX removing code smells
---
.../fr/cnumr/python/checks/AvoidSQLRequestInLoop.java | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
index f18f07d81..c691d4369 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -7,7 +7,6 @@
import org.sonar.plugins.python.api.tree.*;
import java.util.*;
-import java.lang.*;
@Rule(
key = "S64",
@@ -20,16 +19,13 @@
public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
public static final String MESSAGERULE = "Avoid perform an SQL query inside a loop";
- private static final Map> linesWithIssuesByFile = new HashMap<>();
@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
- System.out.println("FOR_STMT");
visitLoopNode(((ForStatement) ctx.syntaxNode()).body(), ctx);
});
context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
- System.out.println("WHILE_STMT");
visitLoopNode(((WhileStatement) ctx.syntaxNode()).body(), ctx);
});
}
@@ -52,7 +48,7 @@ private void visitCallExpressionNode(CallExpression ce, SubscriptionContext ctx)
Name name = (Name) ele;
if (name.name().equals("execute")) {
for (Argument a: ce.arguments()) {
- if (checkLitteralInTree((Tree) a))
+ if (checkLitteralInTree(a))
ctx.addIssue(ce, MESSAGERULE);
}
}
@@ -66,7 +62,7 @@ private boolean checkLitteralInTree(Tree t) {
if (((StringLiteral) tc).trimmedQuotesValue().toUpperCase().contains("SELECT"))
return true;
}
- if (checkLitteralInTree(tc))
+ else if (checkLitteralInTree(tc))
return true;
}
return false;
From 327981918f94ad15784273b3560d068f00e9be45 Mon Sep 17 00:00:00 2001
From: Vincent Cagnard
Date: Fri, 24 Jun 2022 08:59:28 +0200
Subject: [PATCH 043/119] HOTFIX removing code smells (again)
---
.../fr/cnumr/python/checks/AvoidSQLRequestInLoop.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
index c691d4369..807a71ad2 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -6,8 +6,6 @@
import org.sonar.plugins.python.api.SubscriptionContext;
import org.sonar.plugins.python.api.tree.*;
-import java.util.*;
-
@Rule(
key = "S64",
name = "Developpement",
@@ -23,10 +21,12 @@ public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
@Override
public void initialize(Context context) {
context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
- visitLoopNode(((ForStatement) ctx.syntaxNode()).body(), ctx);
+ ForStatement fs = (ForStatement) ctx.syntaxNode();
+ visitLoopNode(fs.body(), ctx);
});
context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
- visitLoopNode(((WhileStatement) ctx.syntaxNode()).body(), ctx);
+ WhileStatement ws = (WhileStatement) ctx.syntaxNode();
+ visitLoopNode(ws.body(), ctx);
});
}
From 7b4425a7a08f78aa9518cd5f1c67816cd290d4d9 Mon Sep 17 00:00:00 2001
From: Jules Delecour <72793427+jules-delecour-dav@users.noreply.github.com>
Date: Fri, 8 Jul 2022 15:36:20 +0200
Subject: [PATCH 044/119] Delete
sonarqube-plugin-greenit/native-analyzer/android-plugin/src/test/java/io/ecocode/java
directory
---
.../ecocode/java/JavaRulesDefinitionTest.java | 215 ------------------
1 file changed, 215 deletions(-)
delete mode 100644 sonarqube-plugin-greenit/native-analyzer/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
diff --git a/sonarqube-plugin-greenit/native-analyzer/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java b/sonarqube-plugin-greenit/native-analyzer/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
deleted file mode 100644
index bc0debbd0..000000000
--- a/sonarqube-plugin-greenit/native-analyzer/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * SonarQube Java Custom Rules Example
- * Copyright (C) 2016-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package io.ecocode.java;
-
-import org.junit.Test;
-import org.sonar.api.rules.RuleType;
-import org.sonar.api.server.debt.DebtRemediationFunction.Type;
-import org.sonar.api.server.rule.RulesDefinition;
-import org.sonar.api.server.rule.RulesDefinition.Param;
-import org.sonar.api.server.rule.RulesDefinition.Repository;
-import org.sonar.api.server.rule.RulesDefinition.Rule;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class JavaRulesDefinitionTest {
-
- @Test
- public void test() {
- JavaRulesDefinition rulesDefinition = new JavaRulesDefinition();
- RulesDefinition.Context context = new RulesDefinition.Context();
- rulesDefinition.define(context);
- RulesDefinition.Repository repository = context.repository(Java.REPOSITORY_KEY);
-
- assertThat(repository.name()).isEqualTo(Java.REPOSITORY_NAME);
- assertThat(repository.language()).isEqualTo(Java.KEY);
- assertThat(repository.rules()).hasSize(JavaCheckList.getChecks().size());
-
- assertRuleProperties(repository);
- assertAllRuleParametersHaveDescription(repository);
- }
-
- private void assertRuleProperties(Repository repository) {
- Rule rule = repository.rule("EOPT001");
- assertThat(rule).isNotNull();
- assertThat(rule.name()).isEqualTo("Optimized API: Fused Location");
- assertThat(rule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule bleRule = repository.rule("EOPT002");
- assertThat(bleRule).isNotNull();
- assertThat(bleRule.name()).isEqualTo("Optimized API: Bluetooth Low-Energy");
- assertThat(bleRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(bleRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule keepScreenOnAddFlagRule = repository.rule("EIDL001");
- assertThat(keepScreenOnAddFlagRule).isNotNull();
- assertThat(keepScreenOnAddFlagRule.name()).isEqualTo("Idleness: Keep Screen On (addFlags)");
- assertThat(keepScreenOnAddFlagRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(keepScreenOnAddFlagRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule keepScreenOnSetFlagRule = repository.rule("EIDL002");
- assertThat(keepScreenOnSetFlagRule).isNotNull();
- assertThat(keepScreenOnSetFlagRule.name()).isEqualTo("Idleness: Keep Screen On (setFlags)");
- assertThat(keepScreenOnSetFlagRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(keepScreenOnSetFlagRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule brightnessRule = repository.rule("ESOB002");
- assertThat(brightnessRule).isNotNull();
- assertThat(brightnessRule.name()).isEqualTo("Sobriety: Brightness Override");
- assertThat(brightnessRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(brightnessRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule internetInTheLoopRule = repository.rule("EBOT001");
- assertThat(internetInTheLoopRule).isNotNull();
- assertThat(internetInTheLoopRule.name()).isEqualTo("Bottleneck: Internet In The Loop");
- assertThat(internetInTheLoopRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(internetInTheLoopRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule keepCpuOnRule = repository.rule("EIDL004");
- assertThat(keepCpuOnRule).isNotNull();
- assertThat(keepCpuOnRule.name()).isEqualTo("Idleness: Keep Cpu On");
- assertThat(keepCpuOnRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(keepCpuOnRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyMotionSensorRule = repository.rule("ESOB001");
- assertThat(thriftyMotionSensorRule).isNotNull();
- assertThat(thriftyMotionSensorRule.name()).isEqualTo("Sobriety: Thrifty Motion Sensor");
- assertThat(thriftyMotionSensorRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyMotionSensorRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule wifiMulticastLockRule = repository.rule("EBOT002");
- assertThat(wifiMulticastLockRule).isNotNull();
- assertThat(wifiMulticastLockRule.name()).isEqualTo("Bottleneck: Wifi Multicast Lock");
- assertThat(wifiMulticastLockRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(wifiMulticastLockRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule cameraLeakRule = repository.rule("ELEA002");
- assertThat(cameraLeakRule).isNotNull();
- assertThat(cameraLeakRule.name()).isEqualTo("Leakage: Camera Leak");
- assertThat(cameraLeakRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(cameraLeakRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule locationLeakRule = repository.rule("ELEA003");
- assertThat(locationLeakRule).isNotNull();
- assertThat(locationLeakRule.name()).isEqualTo("Leakage: Location Leak");
- assertThat(locationLeakRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(locationLeakRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule sensorManagerLeakRule = repository.rule("ELEA004");
- assertThat(sensorManagerLeakRule).isNotNull();
- assertThat(sensorManagerLeakRule.name()).isEqualTo("Leakage: SensorManager Leak");
- assertThat(sensorManagerLeakRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(sensorManagerLeakRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule mediaLeakMediaRecorderLeakRule = repository.rule("ELEA005");
- assertThat(mediaLeakMediaRecorderLeakRule).isNotNull();
- assertThat(mediaLeakMediaRecorderLeakRule.name()).isEqualTo("Leakage: Media Leak (MediaRecorder)");
- assertThat(mediaLeakMediaRecorderLeakRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(mediaLeakMediaRecorderLeakRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule mediaLeakMediaPlayerLeakRule = repository.rule("ELEA006");
- assertThat(mediaLeakMediaPlayerLeakRule).isNotNull();
- assertThat(mediaLeakMediaPlayerLeakRule.name()).isEqualTo("Leakage: Media Leak (MediaPlayer)");
- assertThat(mediaLeakMediaPlayerLeakRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(mediaLeakMediaPlayerLeakRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule durableWakeLockRule = repository.rule("EIDL006");
- assertThat(durableWakeLockRule).isNotNull();
- assertThat(durableWakeLockRule.name()).isEqualTo("Idleness: Durable Wake Lock");
- assertThat(durableWakeLockRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(durableWakeLockRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule rigidAlarmSetRepeatingRule = repository.rule("EIDL007");
- assertThat(rigidAlarmSetRepeatingRule).isNotNull();
- assertThat(rigidAlarmSetRepeatingRule.name()).isEqualTo("Idleness: Rigid Alarm");
- assertThat(rigidAlarmSetRepeatingRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(rigidAlarmSetRepeatingRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule continuousRenderingRule = repository.rule("EIDL008");
- assertThat(continuousRenderingRule).isNotNull();
- assertThat(continuousRenderingRule.name()).isEqualTo("Idleness: Continuous Rendering");
- assertThat(continuousRenderingRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(continuousRenderingRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule keepVoiceAwakeRule = repository.rule("EIDL009");
- assertThat(keepVoiceAwakeRule).isNotNull();
- assertThat(keepVoiceAwakeRule.name()).isEqualTo("Idleness: Keep Voice Awake");
- assertThat(keepVoiceAwakeRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(keepVoiceAwakeRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyGeolocationMinTimeRule = repository.rule("ESOB005");
- assertThat(thriftyGeolocationMinTimeRule).isNotNull();
- assertThat(thriftyGeolocationMinTimeRule.name()).isEqualTo("Sobriety: Thrifty Geolocation (minTime)");
- assertThat(thriftyGeolocationMinTimeRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyGeolocationMinTimeRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyBluetoothLowEnergySetAdvertiseMode = repository.rule("ESOB007");
- assertThat(thriftyBluetoothLowEnergySetAdvertiseMode).isNotNull();
- assertThat(thriftyBluetoothLowEnergySetAdvertiseMode.name()).isEqualTo("Sobriety: Thrifty Bluetooth Low Energy (setAdvertiseMode)");
- assertThat(thriftyBluetoothLowEnergySetAdvertiseMode.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyBluetoothLowEnergySetAdvertiseMode.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyBluetoothLowEnergyRequestConnectionPriority = repository.rule("ESOB008");
- assertThat(thriftyBluetoothLowEnergyRequestConnectionPriority).isNotNull();
- assertThat(thriftyBluetoothLowEnergyRequestConnectionPriority.name()).isEqualTo("Sobriety: Thrifty Bluetooth Low Energy (requestConnectionPriority)");
- assertThat(thriftyBluetoothLowEnergyRequestConnectionPriority.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyBluetoothLowEnergyRequestConnectionPriority.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyGeolocationMinDistanceRule = repository.rule("ESOB010");
- assertThat(thriftyGeolocationMinDistanceRule).isNotNull();
- assertThat(thriftyGeolocationMinDistanceRule.name()).isEqualTo("Sobriety: Thrifty Geolocation (minDistance)");
- assertThat(thriftyGeolocationMinDistanceRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyGeolocationMinDistanceRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule vibrationFreeRule = repository.rule("ESOB011");
- assertThat(vibrationFreeRule).isNotNull();
- assertThat(vibrationFreeRule.name()).isEqualTo("Sobriety: Vibration Free");
- assertThat(vibrationFreeRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(vibrationFreeRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule thriftyNotification = repository.rule("ESOB012");
- assertThat(thriftyNotification).isNotNull();
- assertThat(thriftyNotification.name()).isEqualTo("Sobriety: Thrifty Notification");
- assertThat(thriftyNotification.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(thriftyNotification.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule torchFreeRule = repository.rule("ESOB013");
- assertThat(torchFreeRule).isNotNull();
- assertThat(torchFreeRule.name()).isEqualTo("Sobriety: Torch Free");
- assertThat(torchFreeRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(torchFreeRule.type()).isEqualTo(RuleType.CODE_SMELL);
-
- Rule chargeAwarenessRule = repository.rule("EPOW004");
- assertThat(chargeAwarenessRule).isNotNull();
- assertThat(chargeAwarenessRule.name()).isEqualTo("Power: Charge Awareness");
- assertThat(chargeAwarenessRule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
- assertThat(chargeAwarenessRule.type()).isEqualTo(RuleType.CODE_SMELL);
- }
-
- private void assertAllRuleParametersHaveDescription(Repository repository) {
- for (Rule rule : repository.rules()) {
- for (Param param : rule.params()) {
- assertThat(param.description()).as("description for " + param.key()).isNotEmpty();
- }
- }
- }
-
-}
From f594f52ce13cf58bd3eab5a257842fc31cb4ec96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olivier=20Le=20Goa=C3=ABr?=
Date: Thu, 25 Aug 2022 16:48:32 +0200
Subject: [PATCH 045/119] fixed start pack link
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index ec19fd4bf..5a954c133 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ We are listening to you to make the project progress collectively, and maybe wit
WE NEED YOU !
-Here the starter-pack : https://github.com/cnumr/ecoCode/blob/start-pack/hackathon/starter-pack.md
+Here the [starter-pack](./hackathon/starter-pack.md)
## 🤓 Main contributors
From 1321a641fcb9a3fa641e796d175bb4fee542a09b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olivier=20Le=20Goa=C3=ABr?=
Date: Thu, 25 Aug 2022 16:56:45 +0200
Subject: [PATCH 046/119] Added academic citation
---
src/android-plugin/README.md | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/android-plugin/README.md b/src/android-plugin/README.md
index eaeffedbe..c2e2ef6cd 100644
--- a/src/android-plugin/README.md
+++ b/src/android-plugin/README.md
@@ -119,3 +119,16 @@ For XML rules:
## License
Licensed under the [GNU Lesser General Public License, Version 3.0](https://www.gnu.org/licenses/lgpl.txt)
+
+## How to cite this work?
+
+If you use ecoCode in an academic work we would be really glad if you cite our seminal paper using the following bibtex (to appear):
+```
+@inproceedings{DBLP:conf/ase/LeGoaer2022,
+ author = {Olivier Le Goaer and Julien Hertout},
+ title = {ecoCode: a SonarQube Plugin to Remove Energy Smells from Android Projects},
+ booktitle = {{ACM/IEEE} International Conference on Automated Software Engineering,
+ {ASE} '22, Michigan, USA - October 10 - 14, 2022},
+ year = {2022}
+}
+```
From 04f3869e618017c39d1deeb0b908f985223cf7c8 Mon Sep 17 00:00:00 2001
From: MP-Aubay
Date: Wed, 7 Sep 2022 17:08:31 +0200
Subject: [PATCH 047/119] fix - Adding 'call' before gradlew to avoid exiting
before the end (#150)
---
src/prepare-codenarc.bat | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/prepare-codenarc.bat b/src/prepare-codenarc.bat
index f552a6f87..53bce432e 100644
--- a/src/prepare-codenarc.bat
+++ b/src/prepare-codenarc.bat
@@ -3,7 +3,7 @@ set codenarc_version=2.2.2
REM == Build CodeNarc
cd codenarc-converter/CodeNarc
-./gradlew build -x test
+call ./gradlew build -x test
REM == Deploy to local repository
mvn -B install:install-file -Dfile=build/libs/CodeNarc-%codenarc_version%.jar -DgroupId=org.codenarc -DartifactId=CodeNarc -Dversion=%codenarc_version% -Dpackaging=jar
From 251c5e5949baa15c92ac2bccdc8cc19d805fffb1 Mon Sep 17 00:00:00 2001
From: France
Date: Wed, 21 Sep 2022 17:10:35 +0200
Subject: [PATCH 048/119] francebax: initial commit with tests for rule
gettingSizeCollectionInLoop
---
.idea/workspace.xml | 33 +++++++++---
.../main/java/fr/cnumr/java/RulesList.java | 1 +
.../AvoidGettingSizeCollectionInLoop.java | 51 +++++++++++++++++++
.../AvoidSpringRepositoryCallInLoopCheck.java | 1 +
.../fr/cnumr/l10n/java/rules/java/GSCIL.html | 19 +++++++
.../fr/cnumr/l10n/java/rules/java/GSCIL.json | 13 +++++
.../AvoidGettingSizeCollectionInLoopBad.java | 20 ++++++++
.../AvoidGettingSizeCollectionInLoopGood.java | 17 +++++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
.../AvoidGettingSizeCollectionInLoopTest.java | 14 +++++
10 files changed, 164 insertions(+), 7 deletions(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.json
create mode 100644 src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
create mode 100644 src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 33efe0875..4770f957b 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,7 +1,12 @@
+
+
+
-
+
+
+
@@ -10,16 +15,21 @@
+
+
+
-
-
-
-
-
+
@@ -31,4 +41,15 @@
+
+
+
\ No newline at end of file
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index bebf41b05..cb29cc4cc 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -42,6 +42,7 @@ public static List> getChecks() {
public static List> getJavaChecks() {
return Collections.unmodifiableList(Arrays.asList(
IncrementCheck.class,
+ AvoidGettingSizeCollectionInLoop.class,
NoFunctionCallWhenDeclaringForLoop.class,
AvoidSpringRepositoryCallInLoopCheck.class,
AvoidSQLRequestInLoop.class,
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
new file mode 100644
index 000000000..c4cd16efc
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
@@ -0,0 +1,51 @@
+package fr.cnumr.java.checks;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.MethodMatchers;
+import org.sonar.plugins.java.api.tree.*;
+import org.sonar.plugins.java.api.tree.Tree.Kind;
+
+@Rule(key = "GSCIL",
+ name = "Developpement",
+ description = AvoidGettingSizeCollectionInLoop.MESSAGERULE,
+ priority = Priority.MINOR,
+ tags = {"bug" })
+public class AvoidGettingSizeCollectionInLoop extends IssuableSubscriptionVisitor {
+ protected static final String MESSAGERULE = "Avoid getting the size of the collection in the loop";
+
+
+ private final AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor visitorInFile = new AvoidGettingSizeCollectionInLoop.AvoidGettingSizeCollectionInLoopVisitor();
+
+
+ @Override
+ public List nodesToVisit() {
+ return Arrays.asList(Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, Tree.Kind.WHILE_STATEMENT);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ if (tree instanceof ForStatementTree) {
+ ForStatementTree forStatementTree = (ForStatementTree) tree;
+ ExpressionTree expressionTree = forStatementTree.condition();
+ System.out.println("OK");
+ }
+ tree.accept(visitorInFile);
+ }
+
+ private class AvoidGettingSizeCollectionInLoopVisitor extends BaseTreeVisitor {
+ @Override
+ public void visitForStatement(ForStatementTree tree) {
+ ExpressionTree expression = tree.condition();
+
+
+ super.visitForStatement(tree);
+ }
+
+
+ }
+}
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
index f0eb5b8dd..5a8fcf61e 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidSpringRepositoryCallInLoopCheck.java
@@ -47,5 +47,6 @@ public void visitMethodInvocation(MethodInvocationTree tree) {
super.visitMethodInvocation(tree);
}
}
+
}
}
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.html
new file mode 100644
index 000000000..701cbfbc6
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.html
@@ -0,0 +1,19 @@
+
While iterating through any collection get the size of the collection beforehand and never get it during iteration. The sample is provided below as an illustration which is to be avoided as follows.
+
Noncompliant Code Example
+
+ List<String> objList = getData();
+
+ for (int i = 0; i < objList.size(); i++) {
+ // execute code
+ }
+
+
+
Compliant Solution
+
+ List<String> objList = getData();
+
+ int size = objList.size();
+ for (int i = 0; i < size; i++) {
+ // execute code
+ }
+
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.json
new file mode 100644
index 000000000..c0d4f0ccf
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GSCIL.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid getting the size of the collection in the loop",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
new file mode 100644
index 000000000..b9b17cd2f
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
@@ -0,0 +1,20 @@
+package fr.cnumr.java.checks;
+
+class AvoidGettingSizeCollectionInLoopBad {
+ AvoidGettingSizeCollectionInLoopBad(AvoidGettingSizeCollectionInLoopBad obj) {
+
+ }
+
+ public void badLoop()
+ {
+ Integer[] numbers = new Integer[] { 1, 2, 3 };
+ List numberList = new ArrayList();
+ numberList.add(10);
+ numberList.add(20);
+ numberList.add(10);
+
+ for (int i = 0; i < numberList.size(); i++) { // Noncompliant
+ System.out.println(numberList[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
new file mode 100644
index 000000000..3a898d79b
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
@@ -0,0 +1,17 @@
+package fr.cnumr.java.checks;
+
+class AvoidGettingSizeCollectionInLoopGood {
+ AvoidGettingSizeCollectionInLoopGood(AvoidGettingSizeCollectionInLoopGood obj) {
+
+ }
+
+ public void goodLoop()
+ {
+ List numberList = [10, 20, 30, 40, 50];
+
+ int size = numberList.size();
+ for (int i = 0; i < size; i++) {
+ System.out.println(numberList[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index 81ad838e2..2ba76056c 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -32,7 +32,7 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(7);
+ assertThat(context.checkClasses()).hasSize(8);
assertThat(context.testCheckClasses()).isEmpty();
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
new file mode 100644
index 000000000..c48a198eb
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
@@ -0,0 +1,14 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidGettingSizeCollectionInLoopTest {
+ @Test
+ void test() {
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/AvoidGettingSizeCollectionInLoopBad.java")
+ .withCheck(new AvoidGettingSizeCollectionInLoop())
+ .verifyIssues();
+ }
+}
\ No newline at end of file
From 1c33e4153aacb1580fa2056f05265f62b9621a82 Mon Sep 17 00:00:00 2001
From: France
Date: Tue, 27 Sep 2022 12:12:53 +0200
Subject: [PATCH 049/119] france bax: AvoidGettingSizeCollectionInLoop done
(with tests)
---
.../AvoidGettingSizeCollectionInLoop.java | 33 ++++++++++---------
.../AvoidGettingSizeCollectionInLoopBad.java | 10 +++---
.../AvoidGettingSizeCollectionInLoopGood.java | 11 +++++--
.../AvoidGettingSizeCollectionInLoopTest.java | 4 +++
4 files changed, 36 insertions(+), 22 deletions(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
index c4cd16efc..324e7fe8c 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
@@ -1,6 +1,7 @@
package fr.cnumr.java.checks;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import org.sonar.check.Priority;
@@ -10,6 +11,8 @@
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Tree.Kind;
+import static org.sonar.plugins.java.api.semantic.MethodMatchers.CONSTRUCTOR;
+
@Rule(key = "GSCIL",
name = "Developpement",
description = AvoidGettingSizeCollectionInLoop.MESSAGERULE,
@@ -17,11 +20,15 @@
tags = {"bug" })
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();
-
@Override
public List nodesToVisit() {
return Arrays.asList(Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, Tree.Kind.WHILE_STATEMENT);
@@ -29,23 +36,19 @@ public List nodesToVisit() {
@Override
public void visitNode(Tree tree) {
- if (tree instanceof ForStatementTree) {
ForStatementTree forStatementTree = (ForStatementTree) tree;
- ExpressionTree expressionTree = forStatementTree.condition();
- System.out.println("OK");
- }
- tree.accept(visitorInFile);
+ BinaryExpressionTree expressionTree = (BinaryExpressionTree) forStatementTree.condition();
+ expressionTree.accept(visitorInFile);
}
private class AvoidGettingSizeCollectionInLoopVisitor extends BaseTreeVisitor {
@Override
- public void visitForStatement(ForStatementTree tree) {
- ExpressionTree expression = tree.condition();
-
-
- super.visitForStatement(tree);
+ public void visitMethodInvocation(MethodInvocationTree tree) {
+ if (SIZE_METHOD.matches(tree.symbol())) {
+ reportIssue(tree, MESSAGERULE);
+ } else {
+ super.visitMethodInvocation(tree);
+ }
}
-
-
}
}
diff --git a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
index b9b17cd2f..b4d101dbb 100644
--- a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
+++ b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopBad.java
@@ -1,20 +1,22 @@
package fr.cnumr.java.checks;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
+
class AvoidGettingSizeCollectionInLoopBad {
- AvoidGettingSizeCollectionInLoopBad(AvoidGettingSizeCollectionInLoopBad obj) {
+ AvoidGettingSizeCollectionInLoopBad() {
}
public void badLoop()
{
- Integer[] numbers = new Integer[] { 1, 2, 3 };
List numberList = new ArrayList();
numberList.add(10);
numberList.add(20);
- numberList.add(10);
for (int i = 0; i < numberList.size(); i++) { // Noncompliant
- System.out.println(numberList[i]);
+ System.out.println("numberList.size()");
}
}
}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
index 3a898d79b..33d5cbc5d 100644
--- a/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
+++ b/src/java-plugin/src/test/files/AvoidGettingSizeCollectionInLoopGood.java
@@ -1,5 +1,8 @@
package fr.cnumr.java.checks;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
class AvoidGettingSizeCollectionInLoopGood {
AvoidGettingSizeCollectionInLoopGood(AvoidGettingSizeCollectionInLoopGood obj) {
@@ -7,11 +10,13 @@ class AvoidGettingSizeCollectionInLoopGood {
public void goodLoop()
{
- List numberList = [10, 20, 30, 40, 50];
+ List numberList = new ArrayList();
+ numberList.add(10);
+ numberList.add(20);
int size = numberList.size();
- for (int i = 0; i < size; i++) {
- System.out.println(numberList[i]);
+ for (int i = 0; i < size; i++) { // Compliant
+ System.out.println("numberList.size()");
}
}
}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
index c48a198eb..d4222ed2a 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
@@ -10,5 +10,9 @@ void test() {
.onFile("src/test/files/AvoidGettingSizeCollectionInLoopBad.java")
.withCheck(new AvoidGettingSizeCollectionInLoop())
.verifyIssues();
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/AvoidGettingSizeCollectionInLoopGood.java")
+ .withCheck(new AvoidGettingSizeCollectionInLoop())
+ .verifyNoIssues();
}
}
\ No newline at end of file
From 38d900fba302034bb4a3a24b64d13d0490ce3c32 Mon Sep 17 00:00:00 2001
From: France
Date: Wed, 28 Sep 2022 00:50:31 +0200
Subject: [PATCH 050/119] francebax: done rule AvoidStatementForDMLQueries
(with tests)
---
.../main/java/fr/cnumr/java/RulesList.java | 1 +
.../checks/AvoidStatementForDMLQueries.java | 46 +++++++++++++++++++
.../fr/cnumr/l10n/java/rules/java/SDMLQ1.html | 18 ++++++++
.../fr/cnumr/l10n/java/rules/java/SDMLQ1.json | 13 ++++++
.../files/AvoidStatementForDMLQueries.java | 18 ++++++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
.../AvoidStatementForDMLQueriesTest.java | 13 ++++++
7 files changed, 110 insertions(+), 1 deletion(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.json
create mode 100644 src/java-plugin/src/test/files/AvoidStatementForDMLQueries.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidStatementForDMLQueriesTest.java
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index bebf41b05..420dbef1e 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -43,6 +43,7 @@ public static List> getJavaChecks() {
return Collections.unmodifiableList(Arrays.asList(
IncrementCheck.class,
NoFunctionCallWhenDeclaringForLoop.class,
+ AvoidStatementForDMLQueries.class,
AvoidSpringRepositoryCallInLoopCheck.class,
AvoidSQLRequestInLoop.class,
AvoidFullSQLRequest.class,
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
new file mode 100644
index 000000000..951f4e8dc
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
@@ -0,0 +1,46 @@
+package fr.cnumr.java.checks;
+
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.MethodMatchers;
+import org.sonar.plugins.java.api.tree.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import java.util.Collections;
+import java.util.List;
+
+@Rule(key = "SDMLQ1")
+public class AvoidStatementForDMLQueries extends IssuableSubscriptionVisitor {
+
+ private 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 void visitNode(Tree tree) {
+ MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
+ if (!EXECUTE_METHOD.matches(methodInvocationTree))
+ return;
+ Arguments arguments = methodInvocationTree.arguments();
+ if (arguments.size() < 1)
+ return;
+ ExpressionTree first = arguments.get(0);
+ if (first.is(Tree.Kind.STRING_LITERAL))
+ {
+ LiteralTree literalTree = (LiteralTree) first;
+ String str = literalTree.value();
+ String regex = "(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s(.+,?)+\\s(FROM|VALUES|SET|WHERE)\\s?.*";
+ Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = pattern.matcher(str);
+ if (matcher.find())
+ reportIssue(literalTree, "You must not use Statement for a DML query");
+ }
+ }
+}
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
new file mode 100644
index 000000000..f4416989b
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
@@ -0,0 +1,18 @@
+
A l'appel d'une variable globale, le moteur d'interprétation doit vérifier son existence dans tous les scopes, qu'elle dispose d'une valeur, etc. Passer les variables globales en argument de routines les rend locales dans la fonction, permettant ainsi d'économiser du temps de calcul (cycles CPU).
+
When calling a global variable, the interpretation engine must check that it exists in all the scopes, that it has a value, etc. Passing global variables as arguments gives them the statut of local variables inside the function, thus saving computing time (CPU cycles).
-
exemple:
+
example:
var aGlobal = new String('Hello');
function globalLength(){
length = aGlobal.length;
@@ -16,4 +16,4 @@
length = str.length;
console.log(length);
}
- somVarLength(aGlobal);
\ No newline at end of file
+ somVarLength(aGlobal);
From 04dea124118d3dabe52bb01209bb0a233247ae12 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 19 Oct 2022 09:15:50 +0100
Subject: [PATCH 053/119] Update D4.html
Detailed for a concrete example
---
.../main/resources/fr/cnumr/l10n/java/rules/java/D4.html | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/D4.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/D4.html
index 91bed4a8e..a3ee9fe6e 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/D4.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/D4.html
@@ -3,6 +3,13 @@
When calling a global variable, the interpretation engine must check that it exists in all the scopes, that it has a value, etc. Passing global variables as arguments gives them the statut of local variables inside the function, thus saving computing time (CPU cycles).
+
+CASE 1 (Avoid as possible):
+You are back on the service code. You see that the func1() uses globalVariabl1. Okay, but whats its value by now ? How does it change ? Who mutates the globalVariabl1 before it comes to this function ? What have been the sequence of all these mutations ? You would have no idea. It will be quite difficult to figure all this out.
+
+CASE 2 (Recommended):
+You are back to you code, and see that the func0() fetches something and then passes it to func1(param1) as a parameter. You clearly know what the data is, how does it gets here.
+
diff --git a/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java b/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
index 2d1ae43df..7c3832395 100644
--- a/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
+++ b/src/php-plugin/src/main/java/fr/cnumr/php/MyPhpRules.java
@@ -57,7 +57,7 @@ public String repositoryKey() {
@Override
public ImmutableList checkClasses() {
return ImmutableList.of(AvoidUsingGlobalVariablesCheck.class, IncrementCheck.class, AvoidTryCatchFinallyCheck.class, AvoidDoubleQuoteCheck.class,
- AvoidFullSQLRequestCheck.class, AvoidSQLRequestInLoopCheck.class, NoFunctionCallWhenDeclaringForLoop.class);
+ AvoidFullSQLRequestCheck.class, AvoidSQLRequestInLoopCheck.class, NoFunctionCallWhenDeclaringForLoop.class, UseOfMethodsForBasicOperations.class);
}
@Override
diff --git a/src/php-plugin/src/main/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperations.java b/src/php-plugin/src/main/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperations.java
new file mode 100644
index 000000000..e843ee486
--- /dev/null
+++ b/src/php-plugin/src/main/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperations.java
@@ -0,0 +1,95 @@
+package fr.cnumr.php.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.php.api.tree.ScriptTree;
+import org.sonar.plugins.php.api.tree.Tree;
+import org.sonar.plugins.php.api.tree.declaration.ClassDeclarationTree;
+import org.sonar.plugins.php.api.tree.declaration.ClassMemberTree;
+import org.sonar.plugins.php.api.tree.declaration.MethodDeclarationTree;
+import org.sonar.plugins.php.api.tree.expression.FunctionCallTree;
+import org.sonar.plugins.php.api.tree.statement.*;
+import org.sonar.plugins.php.api.visitors.PHPSubscriptionCheck;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+@Rule(
+ key = "D2",
+ name = "Developpement",
+ description = UseOfMethodsForBasicOperations.ERROR_MESSAGE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
+public class UseOfMethodsForBasicOperations extends PHPSubscriptionCheck {
+
+ protected static final String ERROR_MESSAGE = "Use of methods for basic operations";
+
+ @Override
+ public List nodesToVisit() {
+ return Collections.singletonList(Tree.Kind.FUNCTION_CALL);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ AtomicBoolean contains = new AtomicBoolean(false);
+
+ final FunctionCallTree functionTree = ((FunctionCallTree) tree);
+ final String functionName = functionTree.callee().toString();
+
+ final List parents = this.getAllParent(tree, new ArrayList<>());
+
+ parents.forEach(parent -> {
+ if(parent.is(Tree.Kind.SCRIPT)) {
+
+ final ScriptTree specific = (ScriptTree) parent;
+ final List trees = specific.statements();
+
+ trees.forEach(statement -> {
+
+ if(statement.is(Tree.Kind.CLASS_DECLARATION)) {
+
+ final List methodDeclarations = ((ClassDeclarationTree) statement).members()
+ .stream()
+ .filter(member -> member.is(Tree.Kind.METHOD_DECLARATION))
+ .map(MethodDeclarationTree.class::cast)
+ .filter(declarationTree -> this.isFunctionDeclared(declarationTree, functionName))
+ .collect(Collectors.toList());
+
+ if(methodDeclarations != null && !methodDeclarations.isEmpty()) {
+ contains.set(true);
+ }
+ }
+ });
+ }
+ });
+
+ if(!contains.get()) {
+ context().newIssue(this, tree, ERROR_MESSAGE);
+ }
+ }
+
+ public boolean isFunctionDeclared(final MethodDeclarationTree method, final String name) {
+ if(method == null) {
+ return false;
+ }
+
+ return method.name().text()
+ .trim()
+ .equals(name.trim());
+ }
+
+ public List getAllParent(final Tree tree, final List list) {
+ if(tree == null)
+ return list;
+
+ final Tree parent = tree.getParent();
+
+ if(parent == null)
+ return list;
+
+ list.add(parent);
+
+ return this.getAllParent(parent, list);
+ }
+}
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.html
new file mode 100644
index 000000000..8b10e7217
--- /dev/null
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.html
@@ -0,0 +1,9 @@
+
Use of methods for basic operations
+
Noncompliant Code Example
+
+ $min = min($a, $b); // NOK
+
+
Compliant Solution
+
+ $min = ($a < $b) ? $a : $b; // NOK
+
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.json b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.json
new file mode 100644
index 000000000..6c998b285
--- /dev/null
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D2.json
@@ -0,0 +1,13 @@
+{
+ "title": "Use of methods for basic operations",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java b/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
index 4fb8302af..8944787ab 100644
--- a/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
+++ b/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
@@ -7,7 +7,7 @@
public class MyPhpRulesTest {
- private int NumberOfRuleInRepository = 7;
+ private int NumberOfRuleInRepository = 8;
@Test
public void rules() {
diff --git a/src/php-plugin/src/test/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperationsTest.java b/src/php-plugin/src/test/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperationsTest.java
new file mode 100644
index 000000000..34d431f49
--- /dev/null
+++ b/src/php-plugin/src/test/java/fr/cnumr/php/checks/UseOfMethodsForBasicOperationsTest.java
@@ -0,0 +1,15 @@
+package fr.cnumr.php.checks;
+
+import org.junit.Test;
+import org.sonar.plugins.php.api.tests.PHPCheckTest;
+import org.sonar.plugins.php.api.tests.PhpTestFile;
+
+import java.io.File;
+
+public class UseOfMethodsForBasicOperationsTest {
+
+ @Test
+ public void test() throws Exception {
+ PHPCheckTest.check(new UseOfMethodsForBasicOperations(), new PhpTestFile(new File("src/test/resources/checks/useOfMethodsForBasicOperations.php")));
+ }
+}
diff --git a/src/php-plugin/src/test/resources/checks/useOfMethodsForBasicOperations.php b/src/php-plugin/src/test/resources/checks/useOfMethodsForBasicOperations.php
new file mode 100644
index 000000000..d767e3907
--- /dev/null
+++ b/src/php-plugin/src/test/resources/checks/useOfMethodsForBasicOperations.php
@@ -0,0 +1,18 @@
+
\ No newline at end of file
From ec62c1e22e11dce503652979984d0c036f425af0 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Tue, 25 Oct 2022 10:20:47 +0100
Subject: [PATCH 057/119] Update D1.html
---
.../src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
index dc1b235b5..edf22ff81 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
@@ -1,2 +1,2 @@
Avoid using try-catch-finally statement
-
Lorsqu'une exception est levée, une variable (l'exception elle-même) est créée dans le bloc catch et détruite à la fin du bloc. La création de cette variable et sa destruction consomment inutilement des cycle CPU et de la mémoire vive. Il faut mieux lui préférer autant que possible un test logique.
+
When an exception is thrown, a variable (the exception itself) is created in the catch block and destroyed at the end of the block. Creating this variable and destroying it consumes CPU cycles and RAM unnecessarily. It is better to prefer a logical test as much as possible.
From 5de3d4e81f510fb3dadfeafb7099b6683c26cdf3 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Tue, 25 Oct 2022 10:25:52 +0100
Subject: [PATCH 058/119] Update MyPhpRulesTest.java
---
src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java b/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
index 8944787ab..4fb8302af 100644
--- a/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
+++ b/src/php-plugin/src/test/java/fr/cnumr/php/MyPhpRulesTest.java
@@ -7,7 +7,7 @@
public class MyPhpRulesTest {
- private int NumberOfRuleInRepository = 8;
+ private int NumberOfRuleInRepository = 7;
@Test
public void rules() {
From 8b7185bebaff7f0e527ebc0e46b788d324bb7069 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Renault <81814445+bantra7@users.noreply.github.com>
Date: Tue, 25 Oct 2022 11:29:38 +0200
Subject: [PATCH 059/119] Add rule D7 Python - Avoid Getters and Setters in
class (#101)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Add rule D7 Python - Avoid Getters and Setters in class
* Add rule D7 Python - Avoid Getters and Setters in class
* Add rule D7 Python - Add new tests
* D7-PYTHON Ajout de la vérification des setters
* Add rule D7 Python - Avoid Getters and Setters in class
* Add rule D7 Python - Add new tests
* D7-PYTHON Ajout de la vérification des setters
* D7 Python - merge two if
* Refactoring code to pass sonar
* ix sonar issue
* Fix sonar issue
* Fix sonar issue
* fix sonar issue
Co-authored-by: oussamaLaribi <63214114+oussamaLaribi@users.noreply.github.com>
---
.../python/CustomPythonRuleRepository.java | 4 +-
.../python/checks/AvoidGettersAndSetters.java | 76 +++++++++++++++++++
.../fr/cnumr/l10n/python/rules/python/D7.html | 36 +++++++++
.../fr/cnumr/l10n/python/rules/python/D7.json | 13 ++++
.../CustomPythonRuleRepositoryTest.java | 4 +-
.../checks/AvoidGettersAndSettersTest.java | 12 +++
.../checks/avoidGettersAndSetters.py | 26 +++++++
7 files changed, 168 insertions(+), 3 deletions(-)
create mode 100644 src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidGettersAndSetters.java
create mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.html
create mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.json
create mode 100644 src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidGettersAndSettersTest.java
create mode 100644 src/python-plugin/src/test/resources/checks/avoidGettersAndSetters.py
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
index 2f0282b66..d35b28954 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
@@ -20,6 +20,7 @@
package fr.cnumr.python;
+
import fr.cnumr.python.checks.*;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.plugins.python.api.PythonCustomRuleRepository;
@@ -54,7 +55,8 @@ public String repositoryKey() {
@Override
public List checkClasses() {
- return Arrays.asList(NoFunctionCallWhenDeclaringForLoop.class, AvoidTryCatchFinallyCheck.class, AvoidFullSQLRequest.class, AvoidGlobalVariableInFunctionCheck.class);
+ return Arrays.asList(NoFunctionCallWhenDeclaringForLoop.class, AvoidTryCatchFinallyCheck.class,
+ AvoidFullSQLRequest.class, AvoidGlobalVariableInFunctionCheck.class, AvoidGettersAndSetters.class);
}
private static void setTemplates(NewRepository repository) {
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidGettersAndSetters.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidGettersAndSetters.java
new file mode 100644
index 000000000..cb44282b2
--- /dev/null
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidGettersAndSetters.java
@@ -0,0 +1,76 @@
+package fr.cnumr.python.checks;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.python.api.PythonSubscriptionCheck;
+import org.sonar.plugins.python.api.tree.AnyParameter;
+import org.sonar.plugins.python.api.tree.AssignmentStatement;
+import org.sonar.plugins.python.api.tree.FunctionDef;
+import org.sonar.plugins.python.api.tree.ParameterList;
+import org.sonar.plugins.python.api.tree.QualifiedExpression;
+import org.sonar.plugins.python.api.tree.ReturnStatement;
+import org.sonar.plugins.python.api.tree.Statement;
+import org.sonar.plugins.python.api.tree.StatementList;
+import org.sonar.plugins.python.api.tree.Tree;
+import org.sonar.plugins.python.api.SubscriptionContext;
+
+@Rule(
+ key = AvoidGettersAndSetters.RULE_KEY,
+ name = "Developpement",
+ description = AvoidGettersAndSetters.DESCRIPTION,
+ priority = Priority.MINOR,
+ tags = { "bug" })
+public class AvoidGettersAndSetters extends PythonSubscriptionCheck {
+
+ public static final String RULE_KEY = "D7";
+ public static final String DESCRIPTION = "Avoid the use of getters and setters";
+
+ @Override
+ public void initialize(Context context) {
+ context.registerSyntaxNodeConsumer(Tree.Kind.FUNCDEF, ctx -> {
+ FunctionDef functionDef = (FunctionDef) ctx.syntaxNode();
+ StatementList statementList = functionDef.body();
+ List statements = statementList.statements();
+ if (functionDef.parent().parent().is(Tree.Kind.CLASSDEF)) {
+ checkAllGetters(statements,functionDef,ctx);
+ checkAllSetters(statements,functionDef,ctx);
+ }
+ });
+ }
+ public void checkAllSetters(List statements,FunctionDef functionDef,SubscriptionContext ctx){
+ if(statements.size() == 1 && statements.get(0).is(Tree.Kind.ASSIGNMENT_STMT)){
+ AssignmentStatement assignmentStatement = (AssignmentStatement) statements.get(0);
+ if(checkIfStatementIsQualifiedExpressionAndStartsWithSelfDot((QualifiedExpression) assignmentStatement.children().get(0).children().get(0))){
+ // Check if assignedValue is a parameter of the function
+ ParameterList parameters = functionDef.parameters();
+ if(parameters != null && !parameters.all().stream().filter(p -> checkAssignementFromParameter(assignmentStatement, p)).collect(Collectors.toList()).isEmpty()){
+ ctx.addIssue(functionDef.defKeyword(), AvoidGettersAndSetters.DESCRIPTION);
+ }
+ }
+ }
+ }
+ public void checkAllGetters(List statements,FunctionDef functionDef,SubscriptionContext ctx){
+ Statement lastStatement = statements.get(statements.size() - 1);
+ if (lastStatement.is(Tree.Kind.RETURN_STMT)) {
+ List returnStatementChildren = ((ReturnStatement) lastStatement).children();
+ if (returnStatementChildren.get(1).is(Tree.Kind.QUALIFIED_EXPR) &&
+ checkIfStatementIsQualifiedExpressionAndStartsWithSelfDot((QualifiedExpression) returnStatementChildren.get(1))){
+ ctx.addIssue(functionDef.defKeyword(), AvoidGettersAndSetters.DESCRIPTION);
+ }
+ }
+ }
+ public boolean checkAssignementFromParameter(AssignmentStatement assignmentStatement, AnyParameter parameter){
+ String parameterToString = parameter.firstToken().value();
+ return assignmentStatement.assignedValue().firstToken().value().equalsIgnoreCase(parameterToString);
+ }
+
+ public boolean checkIfStatementIsQualifiedExpressionAndStartsWithSelfDot(QualifiedExpression qualifiedExpression){
+ List qualifedExpressionChildren = qualifiedExpression.children();
+ return qualifedExpressionChildren.size() == 3 &&
+ qualifedExpressionChildren.get(0).firstToken().value().equalsIgnoreCase("self") &&
+ qualifedExpressionChildren.get(1).firstToken().value().equalsIgnoreCase(".");
+ }
+}
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.html
new file mode 100644
index 000000000..ec24f940d
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.html
@@ -0,0 +1,36 @@
+
Eviter de créer des méthodes getter et setter dans les classes.
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.json
new file mode 100644
index 000000000..e32253fc5
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/D7.json
@@ -0,0 +1,13 @@
+{
+ "title": "Eviter de créer des méthodes getter et setter dans les classes.",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+ }
\ No newline at end of file
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
index 80c6ff227..b9b20dbbc 100644
--- a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
@@ -33,7 +33,7 @@ public void test_rule_repository() {
customPythonRuleRepository.define(context);
assertThat(customPythonRuleRepository.repositoryKey()).isEqualTo(CustomPythonRuleRepository.REPOSITORY_KEY);
assertThat(context.repositories()).hasSize(1).extracting("key").containsExactly(customPythonRuleRepository.repositoryKey());
- assertThat(context.repositories().get(0).rules()).hasSize(4);
- assertThat(customPythonRuleRepository.checkClasses()).hasSize(4);
+ assertThat(context.repositories().get(0).rules()).hasSize(5);
+ assertThat(customPythonRuleRepository.checkClasses()).hasSize(5);
}
}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidGettersAndSettersTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidGettersAndSettersTest.java
new file mode 100644
index 000000000..a4a265069
--- /dev/null
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidGettersAndSettersTest.java
@@ -0,0 +1,12 @@
+package fr.cnumr.python.checks;
+
+import org.junit.Test;
+import org.sonar.python.checks.utils.PythonCheckVerifier;
+
+public class AvoidGettersAndSettersTest {
+
+ @Test
+ public void test() {
+ PythonCheckVerifier.verify("src/test/resources/checks/avoidGettersAndSetters.py", new AvoidGettersAndSetters());
+ }
+}
diff --git a/src/python-plugin/src/test/resources/checks/avoidGettersAndSetters.py b/src/python-plugin/src/test/resources/checks/avoidGettersAndSetters.py
new file mode 100644
index 000000000..e8a3efd1c
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/avoidGettersAndSetters.py
@@ -0,0 +1,26 @@
+from datetime import date
+
+class Client():
+
+ def __init__(self, age, weight):
+ self.age = age
+ self.weight = weight
+
+ def set_age(self, age): # Noncompliant {{Avoid the use of getters and setters}}
+ self.age = age
+
+ def set_age(self, age2): # Noncompliant {{Avoid the use of getters and setters}}
+ self.age = age2
+
+ def get_age_in_five_years(self):
+ a = Client()
+ return a.age
+
+ def get_age(self): # Noncompliant {{Avoid the use of getters and setters}}
+ return self.age
+
+ def is_major(self):
+ return self.age >= 18
+
+ def get_weight(self): # Noncompliant {{Avoid the use of getters and setters}}
+ return self.weight
\ No newline at end of file
From 9c12c157bc434988f2cf0d1dccba0c5cd871d03f Mon Sep 17 00:00:00 2001
From: Nicolas Le Cam
Date: Tue, 25 Oct 2022 11:47:01 +0200
Subject: [PATCH 060/119] ecoCode Challenge: Rule 64-PYTHON (#94)
* Add rule 64 - [PYTHON] - Perform an SQL query inside a loop
* Expose new rule in repository
* Add rule documentation
* Chage a test to use a while loop
* cancel old test
* delete old test AvoidSQLRequestInLoop
* Change Size to 6
Co-authored-by: Nicolas Le Cam
Co-authored-by: oussamaLaribi <63214114+oussamaLaribi@users.noreply.github.com>
---
.../python/CustomPythonRuleRepository.java | 25 +++--
.../python/checks/AvoidSQLRequestInLoop.java | 93 ++++++++++---------
.../cnumr/l10n/python/rules/python/S72.html | 21 +++++
.../cnumr/l10n/python/rules/python/S72.json | 13 +++
.../CustomPythonRuleRepositoryTest.java | 4 +-
.../AvoidSQLRequestInLoopCheckTest.java | 12 ---
.../checks/AvoidSQLRequestInLoopTest.java | 12 +++
.../resources/checks/avoidSQLRequestInLoop.py | 42 +++++++++
.../checks/avoidSQLRequestInLoopNoImports.py | 26 ++++++
9 files changed, 180 insertions(+), 68 deletions(-)
create mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
create mode 100644 src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.json
delete mode 100644 src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
create mode 100644 src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopTest.java
create mode 100644 src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoop.py
create mode 100644 src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopNoImports.py
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
index d35b28954..67a35ea14 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/CustomPythonRuleRepository.java
@@ -35,6 +35,13 @@ public class CustomPythonRuleRepository implements RulesDefinition, PythonCustom
public static final String REPOSITORY_KEY = "cnumr-python";
private static final Set RULE_TEMPLATES_KEY = Collections.emptySet();
+ private static void setTemplates(NewRepository repository) {
+ RULE_TEMPLATES_KEY.stream()
+ .map(repository::rule)
+ .filter(Objects::nonNull)
+ .forEach(rule -> rule.setTemplate(true));
+ }
+
@Override
public void define(Context context) {
NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME);
@@ -55,15 +62,13 @@ public String repositoryKey() {
@Override
public List checkClasses() {
- return Arrays.asList(NoFunctionCallWhenDeclaringForLoop.class, AvoidTryCatchFinallyCheck.class,
- AvoidFullSQLRequest.class, AvoidGlobalVariableInFunctionCheck.class, AvoidGettersAndSetters.class);
+ return Arrays.asList(
+ AvoidGlobalVariableInFunctionCheck.class,
+ AvoidFullSQLRequest.class,
+ AvoidSQLRequestInLoop.class,
+ AvoidTryCatchFinallyCheck.class,
+ NoFunctionCallWhenDeclaringForLoop.class,
+ AvoidGettersAndSetters.class
+ );
}
-
- private static void setTemplates(NewRepository repository) {
- RULE_TEMPLATES_KEY.stream()
- .map(repository::rule)
- .filter(Objects::nonNull)
- .forEach(rule -> rule.setTemplate(true));
- }
-
}
diff --git a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
index 807a71ad2..344164358 100644
--- a/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
+++ b/src/python-plugin/src/main/java/fr/cnumr/python/checks/AvoidSQLRequestInLoop.java
@@ -4,68 +4,73 @@
import org.sonar.check.Rule;
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
import org.sonar.plugins.python.api.SubscriptionContext;
+import org.sonar.plugins.python.api.symbols.Symbol;
import org.sonar.plugins.python.api.tree.*;
-@Rule(
- key = "S64",
- name = "Developpement",
- description = AvoidSQLRequestInLoop.MESSAGERULE,
- priority = Priority.MINOR,
- tags = {"bug"}
-)
+import java.util.*;
+@Rule(
+ key = "S72",
+ name = "Developpement",
+ description = AvoidSQLRequestInLoop.MESSAGE_RULE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
public class AvoidSQLRequestInLoop extends PythonSubscriptionCheck {
+ // TODO: Handle ORM lib
+ private static final List SQL_LIBS = Arrays.asList("cx_Oracle", "mysql.connector", "psycopg2", "pymssql", "pyodbc", "sqlite3");
+
+ protected static final String MESSAGE_RULE = "Avoid performing SQL queries within a loop";
- public static final String MESSAGERULE = "Avoid perform an SQL query inside a loop";
+ private boolean isUsingSqlLib = false;
@Override
public void initialize(Context context) {
- context.registerSyntaxNodeConsumer(Tree.Kind.FOR_STMT, ctx -> {
- ForStatement fs = (ForStatement) ctx.syntaxNode();
- visitLoopNode(fs.body(), ctx);
- });
- context.registerSyntaxNodeConsumer(Tree.Kind.WHILE_STMT, ctx -> {
- WhileStatement ws = (WhileStatement) ctx.syntaxNode();
- visitLoopNode(ws.body(), ctx);
- });
+ context.registerSyntaxNodeConsumer(Tree.Kind.FILE_INPUT, this::visitFile);
+ context.registerSyntaxNodeConsumer(Tree.Kind.CALL_EXPR, this::checkCallExpression);
}
- private void visitLoopNode(StatementList list, SubscriptionContext ctx) {
- for (Statement a: list.statements()) {
- if (a.getKind().equals(Tree.Kind.EXPRESSION_STMT)) {
- ExpressionStatement expression = (ExpressionStatement) a;
- for (Expression i: expression.expressions()) {
- if (i.is(Tree.Kind.CALL_EXPR))
- visitCallExpressionNode((CallExpression) i, ctx);
- }
- }
+ private void visitFile(SubscriptionContext ctx) {
+ FileInput tree = (FileInput) ctx.syntaxNode();
+ SymbolsFromImport visitor = new SymbolsFromImport();
+ tree.accept(visitor);
+ visitor.symbols.stream()
+ .filter(Objects::nonNull)
+ .map(Symbol::fullyQualifiedName)
+ .filter(Objects::nonNull)
+ .forEach(qualifiedName -> {
+ if (SQL_LIBS.contains(qualifiedName)) {
+ isUsingSqlLib = true;
+ }
+ });
+ }
+
+ private static class SymbolsFromImport extends BaseTreeVisitor {
+ private Set symbols = new HashSet<>();
+
+ @Override
+ public void visitAliasedName(AliasedName aliasedName) {
+ List names = aliasedName.dottedName().names();
+ symbols.add(names.get(names.size() - 1).symbol());
}
}
+ private void checkCallExpression(SubscriptionContext context) {
+ CallExpression expression = (CallExpression) context.syntaxNode();
- private void visitCallExpressionNode(CallExpression ce, SubscriptionContext ctx) {
- for (Tree ele : ce.callee().children()) {
- if (ele.getKind().equals(Tree.Kind.NAME)) {
- Name name = (Name) ele;
- if (name.name().equals("execute")) {
- for (Argument a: ce.arguments()) {
- if (checkLitteralInTree(a))
- ctx.addIssue(ce, MESSAGERULE);
- }
- }
+ if (expression.callee().is(Tree.Kind.QUALIFIED_EXPR)) {
+ String name = ((QualifiedExpression) expression.callee()).name().name();
+ if (isUsingSqlLib && "execute".equals(name) && hasLoopParent(expression)) {
+ context.addIssue(expression, AvoidSQLRequestInLoop.MESSAGE_RULE);
}
}
}
- private boolean checkLitteralInTree(Tree t) {
- for (Tree tc : t.children()) {
- if (tc.is(Tree.Kind.STRING_LITERAL)) {
- if (((StringLiteral) tc).trimmedQuotesValue().toUpperCase().contains("SELECT"))
- return true;
+ private boolean hasLoopParent(Tree tree) {
+ for (Tree parent = tree.parent(); parent != null; parent = parent.parent()) {
+ Tree.Kind kind = parent.getKind();
+ if (kind == Tree.Kind.FOR_STMT || kind == Tree.Kind.WHILE_STMT) {
+ return true;
}
- else if (checkLitteralInTree(tc))
- return true;
}
return false;
}
-
-}
+}
\ No newline at end of file
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
new file mode 100644
index 000000000..1d47ab791
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
@@ -0,0 +1,21 @@
+
Do not execute an SQL request in a loop
+
Noncompliant Code Example
+
+ def foo():
+ ...
+ results = []
+ for id in range(20):
+ results.append(cursor.execute("SELECT name FROM users where id = ?", (id)).fetchone()) # Noncompliant {{Avoid performing SQL queries within a loop}}
+ ...
+
+
Compliant Solution
+
+
+ def foo():
+ ...
+ ids = range(20)
+ results = cursor.execute("SELECT name FROM users where id IN ({0})".format(', '.join("?" * len(ids))), ids).fetchmany() # Compliant
+ ...
+ }
+
+
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.json b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.json
new file mode 100644
index 000000000..73743a5a5
--- /dev/null
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid SQL request in loop",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
index b9b20dbbc..391a2f335 100644
--- a/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/CustomPythonRuleRepositoryTest.java
@@ -33,7 +33,7 @@ public void test_rule_repository() {
customPythonRuleRepository.define(context);
assertThat(customPythonRuleRepository.repositoryKey()).isEqualTo(CustomPythonRuleRepository.REPOSITORY_KEY);
assertThat(context.repositories()).hasSize(1).extracting("key").containsExactly(customPythonRuleRepository.repositoryKey());
- assertThat(context.repositories().get(0).rules()).hasSize(5);
- assertThat(customPythonRuleRepository.checkClasses()).hasSize(5);
+ assertThat(context.repositories().get(0).rules()).hasSize(6);
+ assertThat(customPythonRuleRepository.checkClasses()).hasSize(6);
}
}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
deleted file mode 100644
index 42c43c427..000000000
--- a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopCheckTest.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package fr.cnumr.python.checks;
-
-import org.junit.Test;
-import org.sonar.python.checks.utils.PythonCheckVerifier;
-
-public class AvoidSQLRequestInLoopCheckTest {
-
- @Test
- public void test() {
- PythonCheckVerifier.verify("src/test/resources/checks/avoidSQLRequestInLoopCheck.py", new AvoidSQLRequestInLoop());
- }
-}
diff --git a/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopTest.java b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopTest.java
new file mode 100644
index 000000000..811cae909
--- /dev/null
+++ b/src/python-plugin/src/test/java/fr/cnumr/python/checks/AvoidSQLRequestInLoopTest.java
@@ -0,0 +1,12 @@
+package fr.cnumr.python.checks;
+
+import org.junit.Test;
+import org.sonar.python.checks.utils.PythonCheckVerifier;
+
+public class AvoidSQLRequestInLoopTest {
+ @Test
+ public void test() {
+ PythonCheckVerifier.verify("src/test/resources/checks/avoidSQLRequestInLoop.py", new AvoidSQLRequestInLoop());
+ PythonCheckVerifier.verifyNoIssue("src/test/resources/checks/avoidSQLRequestInLoopNoImports.py", new AvoidSQLRequestInLoop());
+ }
+}
diff --git a/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoop.py b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoop.py
new file mode 100644
index 000000000..394088199
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoop.py
@@ -0,0 +1,42 @@
+import mysql.connector
+import psycopg2
+import pyodbc
+import sqlite3
+
+def mysql_loop():
+ connection = mysql.connector.connect(database='local')
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # Noncompliant {{Avoid performing SQL queries within a loop}}
+ connection.close()
+ return results
+
+def psycopg2_loop():
+ connection = psycopg2.connect(database='local')
+ cursor = connection.cursor()
+ results = []
+ id = 0
+ while id <= 5:
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # Noncompliant {{Avoid performing SQL queries within a loop}}
+ id += 1
+ connection.close()
+ return results
+
+def pyodbc_loop():
+ connection = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=local')
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # Noncompliant {{Avoid performing SQL queries within a loop}}
+ connection.close()
+ return results
+
+def sqlite3_loop():
+ connection = sqlite3.connect("local.db")
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # Noncompliant {{Avoid performing SQL queries within a loop}}
+ connection.close()
+ return results
diff --git a/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopNoImports.py b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopNoImports.py
new file mode 100644
index 000000000..fe8513844
--- /dev/null
+++ b/src/python-plugin/src/test/resources/checks/avoidSQLRequestInLoopNoImports.py
@@ -0,0 +1,26 @@
+def mysql_loop():
+ connection = mysql.connector.connect(database='local')
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # OK
+ connection.close()
+ return results
+
+def pyodbc_loop():
+ connection = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=local')
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # OK
+ connection.close()
+ return results
+
+def sqlite3_loop():
+ connection = sqlite3.connect("local.db")
+ cursor = connection.cursor()
+ results = []
+ for id in range(5):
+ results.append(cursor.execute("SELECT name FROM user WHERE id = ?", (id)).fetchone()) # OK
+ connection.close()
+ return results
From c3f048e982b9097bee22c3adc0d80b2713c29d19 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 08:29:25 +0100
Subject: [PATCH 061/119] Update MyJavaFileCheckRegistrarTest.java
Fixed Build Issue
---
.../test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index 0bc3bcd6b..071e0bb4c 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -33,7 +33,7 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(9);
+ assertThat(context.checkClasses()).hasSize(10);
assertThat(context.testCheckClasses()).isEmpty();
}
From c399690d6989b2974543266c24905c07bbc9fe1f Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 08:38:22 +0100
Subject: [PATCH 062/119] Update AvoidStatementForDMLQueries.java
---
.../java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
index 951f4e8dc..520372964 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidStatementForDMLQueries.java
@@ -36,7 +36,7 @@ public void visitNode(Tree tree) {
{
LiteralTree literalTree = (LiteralTree) first;
String str = literalTree.value();
- String regex = "(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s(.+,?)+\\s(FROM|VALUES|SET|WHERE)\\s?.*";
+ String regex = "(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s?.*";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
if (matcher.find())
From a518404dd08224c90883fe8be188645acca5a7ee Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 09:10:29 +0100
Subject: [PATCH 063/119] Update RulesList.java
Fixe conflit and compilation error
---
src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index ca1363e08..daff7780a 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -49,7 +49,7 @@ public static List> getJavaChecks() {
AvoidFullSQLRequest.class,
UseCorrectForLoop.class,
UnnecessarilyAssignValuesToVariables.class,
- InitializeBufferWithAppropriateSize.class
+ InitializeBufferWithAppropriateSize.class,
AvoidUsingGlobalVariablesCheck.class,
AvoidSetConstantInBatchUpdate.class
));
From d5a022e265b8df7c6567f4b4ef7313a026cdf39e Mon Sep 17 00:00:00 2001
From: Antoine PRONNIER <44138938+FunixG@users.noreply.github.com>
Date: Wed, 26 Oct 2022 10:47:01 +0200
Subject: [PATCH 064/119] [Rule-S77] Java Rule: Regex and Patterns usage (#156)
* [Rule-S77] New java rule about Regex and Patterns
* [Rule-S77] Fix test
Co-authored-by: oussamaLaribi <63214114+oussamaLaribi@users.noreply.github.com>
---
.../main/java/fr/cnumr/java/RulesList.java | 1 +
.../checks/AvoidRegexPatternNotStatic.java | 63 ++++++++++++++++++
.../fr/cnumr/l10n/java/rules/java/S77.html | 66 +++++++++++++++++++
.../fr/cnumr/l10n/java/rules/java/S77.json | 13 ++++
.../files/AvoidRegexPatternNotStatic.java | 11 ++++
.../src/test/files/ValidRegexPattern.java | 12 ++++
.../src/test/files/ValidRegexPattern2.java | 12 ++++
.../src/test/files/ValidRegexPattern3.java | 16 +++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
.../AvoidRegexPatternNotStaticTest.java | 27 ++++++++
10 files changed, 222 insertions(+), 1 deletion(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidRegexPatternNotStatic.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.json
create mode 100644 src/java-plugin/src/test/files/AvoidRegexPatternNotStatic.java
create mode 100644 src/java-plugin/src/test/files/ValidRegexPattern.java
create mode 100644 src/java-plugin/src/test/files/ValidRegexPattern2.java
create mode 100644 src/java-plugin/src/test/files/ValidRegexPattern3.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidRegexPatternNotStaticTest.java
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index daff7780a..84fae7b2c 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -42,6 +42,7 @@ public static List> getChecks() {
public static List> getJavaChecks() {
return Collections.unmodifiableList(Arrays.asList(
IncrementCheck.class,
+ AvoidRegexPatternNotStatic.class,
NoFunctionCallWhenDeclaringForLoop.class,
AvoidStatementForDMLQueries.class,
AvoidSpringRepositoryCallInLoopCheck.class,
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidRegexPatternNotStatic.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidRegexPatternNotStatic.java
new file mode 100644
index 000000000..4201d6cda
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidRegexPatternNotStatic.java
@@ -0,0 +1,63 @@
+package fr.cnumr.java.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.MethodMatchers;
+import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
+import org.sonar.plugins.java.api.tree.MethodInvocationTree;
+import org.sonar.plugins.java.api.tree.MethodTree;
+import org.sonar.plugins.java.api.tree.Tree;
+
+import javax.annotation.Nonnull;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@Rule(
+ key = "S77",
+ name = "Developpement",
+ description = AvoidRegexPatternNotStatic.MESSAGE_RULE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
+public class AvoidRegexPatternNotStatic extends IssuableSubscriptionVisitor {
+
+ 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 final AvoidRegexPatternNotStaticVisitor visitor = new AvoidRegexPatternNotStaticVisitor();
+
+ @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;
+
+ 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);
+ }
+ }
+
+ }
+}
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
new file mode 100644
index 000000000..f5b98e93a
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
@@ -0,0 +1,66 @@
+
+ Avoid using Pattern.compile() in a non-static context.
+
+
+
Noncompliant Code Example
+
+
+ public class AvoidRegexPatternNotStatic {
+
+ public boolean foo() {
+ final Pattern pattern = Pattern.compile("foo"); // Noncompliant
+ return pattern.matcher("foo").find();
+ }
+
+ }
+
+
+
+
Compliant Solution N°1
+
+
+ public class ValidRegexPattern {
+
+ private static final Pattern pattern = Pattern.compile("foo"); // Compliant
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+
+ }
+
+
+
+
Compliant Solution N°2
+
+
+ public class ValidRegexPattern2 {
+
+ private final Pattern pattern = Pattern.compile("foo"); // Compliant
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+
+ }
+
+
+
+
Compliant Solution N°3
+
+
+ public class ValidRegexPattern3 {
+
+ private final Pattern pattern;
+
+ public ValidRegexPattern3() {
+ pattern = Pattern.compile("foo"); // Compliant
+ }
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+
+ }
+
+
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.json
new file mode 100644
index 000000000..a3bfcf120
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid using Pattern.compile() in a non-static context.",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
diff --git a/src/java-plugin/src/test/files/AvoidRegexPatternNotStatic.java b/src/java-plugin/src/test/files/AvoidRegexPatternNotStatic.java
new file mode 100644
index 000000000..be39ca75a
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidRegexPatternNotStatic.java
@@ -0,0 +1,11 @@
+package fr.cnumr.java.checks;
+
+import java.util.regex.Pattern;
+
+public class AvoidRegexPatternNotStatic {
+
+ public boolean foo() {
+ final Pattern pattern = Pattern.compile("foo"); // Noncompliant
+ return pattern.matcher("foo").find();
+ }
+}
diff --git a/src/java-plugin/src/test/files/ValidRegexPattern.java b/src/java-plugin/src/test/files/ValidRegexPattern.java
new file mode 100644
index 000000000..958c18eea
--- /dev/null
+++ b/src/java-plugin/src/test/files/ValidRegexPattern.java
@@ -0,0 +1,12 @@
+package fr.cnumr.java.checks;
+
+import java.util.regex.Pattern;
+
+public class ValidRegexPattern {
+
+ private static final Pattern pattern = Pattern.compile("foo"); // Compliant
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+}
diff --git a/src/java-plugin/src/test/files/ValidRegexPattern2.java b/src/java-plugin/src/test/files/ValidRegexPattern2.java
new file mode 100644
index 000000000..56b624fbd
--- /dev/null
+++ b/src/java-plugin/src/test/files/ValidRegexPattern2.java
@@ -0,0 +1,12 @@
+package fr.cnumr.java.checks;
+
+import java.util.regex.Pattern;
+
+public class ValidRegexPattern2 {
+
+ private final Pattern pattern = Pattern.compile("foo"); // Compliant
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+}
diff --git a/src/java-plugin/src/test/files/ValidRegexPattern3.java b/src/java-plugin/src/test/files/ValidRegexPattern3.java
new file mode 100644
index 000000000..6c1388abb
--- /dev/null
+++ b/src/java-plugin/src/test/files/ValidRegexPattern3.java
@@ -0,0 +1,16 @@
+package fr.cnumr.java.checks;
+
+import java.util.regex.Pattern;
+
+public class ValidRegexPattern3 {
+
+ private final Pattern pattern;
+
+ public ValidRegexPattern3() {
+ pattern = Pattern.compile("foo"); // Compliant
+ }
+
+ public boolean foo() {
+ return pattern.matcher("foo").find();
+ }
+}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index 765a38986..0b0654e33 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -33,8 +33,8 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(11);
+ assertThat(context.checkClasses()).hasSize(12);
assertThat(context.testCheckClasses()).isEmpty();
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidRegexPatternNotStaticTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidRegexPatternNotStaticTest.java
new file mode 100644
index 000000000..710b3dea9
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidRegexPatternNotStaticTest.java
@@ -0,0 +1,27 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidRegexPatternNotStaticTest {
+
+ @Test
+ public void testHasIssues() {
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/AvoidRegexPatternNotStatic.java")
+ .withCheck(new AvoidRegexPatternNotStatic())
+ .verifyIssues();
+ }
+
+ @Test
+ public void testHasNoIssues() {
+ JavaCheckVerifier.newVerifier()
+ .onFiles(
+ "src/test/files/ValidRegexPattern.java",
+ "src/test/files/ValidRegexPattern2.java",
+ "src/test/files/ValidRegexPattern3.java"
+ )
+ .withCheck(new AvoidRegexPatternNotStatic())
+ .verifyNoIssues();
+ }
+}
From c74303f7756feb1dae75fda979abf24078aed692 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 10:57:28 +0100
Subject: [PATCH 065/119] Update build.yml
Fix build error in sonarqube workflow
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b5a240ac0..87b5fd7e7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -40,4 +40,4 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- run: mvn -e -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=cnumr_ecoCode -Dsonar.organization=cnumr_1 -Dsonar.exclusions=**/src/codenarc-converter/**,**/*.groovy,**/src/android-plugin/src/test/**,**/*.dummy
+ run: mvn -e -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=cnumr_ecoCode -Dsonar.exclusions=**/src/codenarc-converter/**,**/*.groovy,**/src/android-plugin/src/test/**,**/*.dummy
From 2269271cbe4bcf6a21055d5f47e187110b5f2585 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 11:08:03 +0100
Subject: [PATCH 066/119] Update AvoidGettingSizeCollectionInLoop.java
Remove unused imports
---
.../fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
index 324e7fe8c..7571eff3f 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoop.java
@@ -1,7 +1,6 @@
package fr.cnumr.java.checks;
import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import org.sonar.check.Priority;
@@ -11,8 +10,6 @@
import org.sonar.plugins.java.api.tree.*;
import org.sonar.plugins.java.api.tree.Tree.Kind;
-import static org.sonar.plugins.java.api.semantic.MethodMatchers.CONSTRUCTOR;
-
@Rule(key = "GSCIL",
name = "Developpement",
description = AvoidGettingSizeCollectionInLoop.MESSAGERULE,
From f433f9d4e414af5902da2c847a4284360296264a Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 11:14:22 +0100
Subject: [PATCH 067/119] Update AvoidGettingSizeCollectionInLoopTest.java
Fixed Code Smell
---
.../java/checks/AvoidGettingSizeCollectionInLoopTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
index d4222ed2a..07b4c8454 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidGettingSizeCollectionInLoopTest.java
@@ -3,7 +3,7 @@
import org.junit.jupiter.api.Test;
import org.sonar.java.checks.verifier.JavaCheckVerifier;
-public class AvoidGettingSizeCollectionInLoopTest {
+class AvoidGettingSizeCollectionInLoopTest {
@Test
void test() {
JavaCheckVerifier.newVerifier()
@@ -15,4 +15,4 @@ void test() {
.withCheck(new AvoidGettingSizeCollectionInLoop())
.verifyNoIssues();
}
-}
\ No newline at end of file
+}
From cafdcdb063e6a58cbe9ae7bde65ee69fce4ae392 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:14:53 +0100
Subject: [PATCH 068/119] Update OptimizeReadFileException.java
Fixe SonarCloud Code Smell
---
.../java/fr/cnumr/java/checks/OptimizeReadFileException.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java
index 3e0f6fb08..0d1ba7d5f 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java
@@ -3,7 +3,6 @@
import org.sonar.check.Priority;
import org.sonar.check.Rule;
-import org.sonar.java.model.statement.CatchTreeImpl;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.CatchTree;
import org.sonar.plugins.java.api.tree.NewClassTree;
@@ -20,7 +19,7 @@
description = OptimizeReadFileException.MESSAGERULE,
priority = Priority.MINOR,
tags = {"bug"})
-public class OptimizeReadFileException extends IssuableSubscriptionVisitor {
+public class OptimizeReadFileExceptions extends IssuableSubscriptionVisitor {
protected static final String MESSAGERULE = "Optimize Read File Exception";
private boolean isFileNotFoundException = false;
@@ -45,4 +44,4 @@ public void visitNode(Tree tree) {
}
return;
}
-}
\ No newline at end of file
+}
From 401618581eb410032a16ce7e4e7f0f9c4126a685 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:17:24 +0100
Subject: [PATCH 069/119] Rename OptimizeReadFileException.java to
OptimizeReadFileExceptions.java
---
...mizeReadFileException.java => OptimizeReadFileExceptions.java} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename src/java-plugin/src/main/java/fr/cnumr/java/checks/{OptimizeReadFileException.java => OptimizeReadFileExceptions.java} (100%)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java
similarity index 100%
rename from src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileException.java
rename to src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java
From d8784c750458d29f0be6b91f4cf1669914e020a0 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:20:17 +0100
Subject: [PATCH 070/119] Update RulesList.java
---
src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index 1a44a67d6..0e7b521cd 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -51,7 +51,7 @@ public static List> getJavaChecks() {
AvoidFullSQLRequest.class,
UseCorrectForLoop.class,
UnnecessarilyAssignValuesToVariables.class,
- OptimizeReadFileException.class,
+ OptimizeReadFileExceptions.class,
InitializeBufferWithAppropriateSize.class,
AvoidUsingGlobalVariablesCheck.class,
AvoidSetConstantInBatchUpdate.class
From 01583e0fcc351ee858e29024a1d8cf69eb03dae6 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:21:44 +0100
Subject: [PATCH 071/119] Update OptimizeReadFileExceptions.java
---
.../java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java
index 0d1ba7d5f..d76c8dcc9 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/OptimizeReadFileExceptions.java
@@ -16,12 +16,12 @@
@Rule(
key = "GRSP0028",
name = "Developpement",
- description = OptimizeReadFileException.MESSAGERULE,
+ description = OptimizeReadFileExceptions.MESSAGERULE,
priority = Priority.MINOR,
tags = {"bug"})
public class OptimizeReadFileExceptions extends IssuableSubscriptionVisitor {
- protected static final String MESSAGERULE = "Optimize Read File Exception";
+ protected static final String MESSAGERULE = "Optimize Read File Exceptions";
private boolean isFileNotFoundException = false;
@Override
From 3ce33960eeab96a3cbf6e3174a4b1a173c54d0b1 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:22:10 +0100
Subject: [PATCH 072/119] Update GRSP0028.json
---
.../resources/fr/cnumr/l10n/java/rules/java/GRSP0028.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0028.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0028.json
index f22f6b6c2..ff67d411c 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0028.json
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRSP0028.json
@@ -1,5 +1,5 @@
{
- "title": "Optimize read file exception",
+ "title": "Optimize read file exceptions",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
@@ -10,4 +10,4 @@
"eco-conception"
],
"defaultSeverity": "Minor"
-}
\ No newline at end of file
+}
From 5aafacd200a5e10eaaed09c361da1577148c1233 Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 15:22:46 +0100
Subject: [PATCH 073/119] Update OptimizeReadFileExceptionCheckTest.java
---
.../cnumr/java/checks/OptimizeReadFileExceptionCheckTest.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/OptimizeReadFileExceptionCheckTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/OptimizeReadFileExceptionCheckTest.java
index 008e58b23..998c97035 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/checks/OptimizeReadFileExceptionCheckTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/OptimizeReadFileExceptionCheckTest.java
@@ -9,8 +9,8 @@ class OptimizeReadFileExceptionCheckTest {
void test() {
JavaCheckVerifier.newVerifier()
.onFile("src/test/files/OptimizeReadFileExceptionCheck.java")
- .withCheck(new OptimizeReadFileException())
+ .withCheck(new OptimizeReadFileExceptions())
.verifyIssues();
}
-}
\ No newline at end of file
+}
From 5f87a6d35a1c85bfa33d14a12b652d4488a04548 Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 26 Oct 2022 16:54:12 +0200
Subject: [PATCH 074/119] correction of markdown typo
---
hackathon/starter-pack.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hackathon/starter-pack.md b/hackathon/starter-pack.md
index 779647d7a..21e1e3794 100644
--- a/hackathon/starter-pack.md
+++ b/hackathon/starter-pack.md
@@ -31,8 +31,11 @@ https://olegoaer.perso.univ-pau.fr/android-energy-smells/
### Prerequesites
You will need to install Docker : https://docs.docker.com/get-docker/
+
Docker-compose 3.9 : https://docs.docker.com/compose/install/
+
Java >=8 for Sonarqube plugin Development : https://www.java.com/fr/download/manual.jsp
+
Maven 3 for Sonarqube plugin Development : https://maven.apache.org/download.cgi
Additionnaly, install Git : https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
From 2f3ff53d2f0fbc3da8ed055491e44dea3e68d192 Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 26 Oct 2022 16:55:13 +0200
Subject: [PATCH 075/119] add shell scripts to make it easy for installation
and use + upgrade documentation
---
src/INSTALL.md | 27 ++++++++++++++++++++++-----
src/build.sh | 3 +++
src/init_reinit.sh | 3 +++
src/start.sh | 3 +++
src/stop.sh | 3 +++
5 files changed, 34 insertions(+), 5 deletions(-)
create mode 100755 src/build.sh
create mode 100755 src/init_reinit.sh
create mode 100755 src/start.sh
create mode 100755 src/stop.sh
diff --git a/src/INSTALL.md b/src/INSTALL.md
index db4a3ae13..0a09bb220 100644
--- a/src/INSTALL.md
+++ b/src/INSTALL.md
@@ -33,7 +33,7 @@ You will find more information about the plugins’ architecture in their folder
- Mvn 3
-### Preliminary steps
+### Preliminary steps (only Android)
The Android plugin uses [CodeNarc](https://codenarc.org/) to scan the gradle files of Android projects. To have more information about CodeNarc: [CodeNarc](/codenarc-converter/CodeNarc/README.md).
@@ -52,10 +52,12 @@ You can build the project code by running the following command in the `src` dir
Maven will download the required dependencies.
```sh
-mvn clean install
+./build.sh
+
+# execute `mvn clean install`
```
-Each plugin is generated in its own `src//target` directory, but they are also copied to the `src/lib` directory.
+Each plugin is generated in its own `/target` directory, but they are also copied to the `lib` directory.
@@ -71,7 +73,9 @@ You must have built the plugins (see the steps above).
Run the SonarQube + PostgreSQL stack:
```sh
-docker-compose up --build -d
+./init_reinit.sh
+
+# execute `docker-compose up --build -d`
```
Check if the containers are up:
@@ -134,7 +138,20 @@ Install dependencies from the root directory:
mvn clean install
```
-.jar files (one per plugin) will be moved in `src/lib` repository after build.
+.jar files (one per plugin) will be moved in `lib` repository after build.
+
+## Howto start or stop service (already installed)
+
+Once you did the installation a first time (and then you did custom configuration like quality gates, quality profiles, ...),
+if you only want to start (or stop properly) existing services :
+
+```sh
+./start.sh
+# execute `docker-compose start`
+
+./stop.sh
+# execute `docker-compose stop`
+```
## Links
diff --git a/src/build.sh b/src/build.sh
new file mode 100755
index 000000000..3d3e0d89d
--- /dev/null
+++ b/src/build.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+mvn clean compile
diff --git a/src/init_reinit.sh b/src/init_reinit.sh
new file mode 100755
index 000000000..fbc860637
--- /dev/null
+++ b/src/init_reinit.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+docker-compose up --build -d
\ No newline at end of file
diff --git a/src/start.sh b/src/start.sh
new file mode 100755
index 000000000..4d6041949
--- /dev/null
+++ b/src/start.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+docker-compose start
\ No newline at end of file
diff --git a/src/stop.sh b/src/stop.sh
new file mode 100755
index 000000000..460c5aa22
--- /dev/null
+++ b/src/stop.sh
@@ -0,0 +1,3 @@
+#!/usr/bin/env sh
+
+docker-compose stop
\ No newline at end of file
From f47d38f62924931c67ef9d52a76aa79ac608ddbd Mon Sep 17 00:00:00 2001
From: Mohamed SALHAOUI <50855585+med-S@users.noreply.github.com>
Date: Wed, 26 Oct 2022 16:13:47 +0100
Subject: [PATCH 076/119] Update .gitignore
---
.gitignore | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 94ad6a98e..0b3aa33ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ buildNumber.properties
# Eclipse m2e generated files
# Eclipse Core
.project
+.idea
# JDT-specific (Eclipse Java Development Tools)
.classpath
-**/.settings
\ No newline at end of file
+**/.settings
From d903119f88051bf67af86fa9574a065abbcc7230 Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 26 Oct 2022 17:42:46 +0200
Subject: [PATCH 077/119] upgrade gitignore to ignore all '.*' files except
'.gitignore' file
---
src/.gitignore | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/.gitignore b/src/.gitignore
index 97a5726b0..f7a6afc7f 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,8 +1,8 @@
+!.gitignore
+.*
node_modules
yarn.lock
target/
node/
-.idea
-.DS_Store
*.iml
/lib/*.jar
From 55bd806c3a796a97d51bbb1fdcefa552312d124b Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 26 Oct 2022 17:45:34 +0200
Subject: [PATCH 078/119] delete worcspace files - best practice : do not
commit workscpace files
---
.idea/workspace.xml | 55 ---------------------------------------------
1 file changed, 55 deletions(-)
delete mode 100644 .idea/workspace.xml
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 4770f957b..000000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1654173028185
-
-
- 1654173028185
-
-
-
-
-
-
-
\ No newline at end of file
From 9229d72c40c634f5769829d42eab51ede306c5e5 Mon Sep 17 00:00:00 2001
From: oussamaLaribi <63214114+oussamaLaribi@users.noreply.github.com>
Date: Fri, 28 Oct 2022 10:23:11 +0100
Subject: [PATCH 079/119] Adapt the description of the rules (#163)
---
.../fr/cnumr/l10n/java/rules/java/GRC1.html | 2 +-
.../cnumr/l10n/java/rules/java/GRSP0032.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/GSCIL.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/S53.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/S63.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/S69.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/S77.html | 1 +
.../fr/cnumr/l10n/java/rules/java/S78.html | 2 +-
.../fr/cnumr/l10n/java/rules/java/SDMLQ1.html | 3 +-
.../fr/cnumr/l10n/php/rules/custom/D1.html | 30 +++++++++++++++++--
.../fr/cnumr/l10n/php/rules/custom/S69.html | 2 +-
.../fr/cnumr/l10n/python/rules/python/D4.html | 2 +-
.../fr/cnumr/l10n/python/rules/python/D7.html | 2 +-
.../cnumr/l10n/python/rules/python/S69.html | 2 +-
.../cnumr/l10n/python/rules/python/S72.html | 2 +-
15 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
index 4b7c6e79a..8660346b6 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/GRC1.html
@@ -1,4 +1,4 @@
-
Using Spring repository in loop induced unnecessary calculation by the cpu so unless energy consumption
+
Using Spring repository in loop induced unnecessary calculation by the cpu so unless energy consumption.
If you know in advance how many characters would be appended, initialize builder/buffer with the appropriate size.
- They will thus never have to be resized.
+ They will thus never have to be resized, It saves CPU cycles so unless energy consumption.
While iterating through any collection get the size of the collection beforehand and never get it during iteration. The sample is provided below as an illustration which is to be avoided as follows.
+
While iterating through any collection get the size of the collection beforehand and never get it during iteration, It saves CPU cycles so unless energy consumption. The sample is provided below as an illustration which is to be avoided as follows.
Do not call a function when declaring a for-type loop in order to avoid function calls each iterations. It saves CPU cycles
+
Do not call a function when declaring a for-type loop in order to avoid function calls each iterations. It saves CPU cycles.
Noncompliant Code Example
public void foo() {
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
index f5b98e93a..8de04cef2 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S77.html
@@ -1,5 +1,6 @@
Avoid using Pattern.compile() in a non-static context.
+ This operation requires a non negligible amount of computational power, Using a single match saves CPU cycles and RAM consumption.
Don't set const parameter in batch update => Put its in query
+
Don't set const parameter in batch update => Put its in query. Creating this parameter and destroying it consumes CPU cycles and RAM unnecessarily.
Noncompliant Code Example
public void foo() {
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
index f4416989b..e46b2c398 100644
--- a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/SDMLQ1.html
@@ -1,4 +1,5 @@
-
Use PreparedStatement instead of Statement
+
Use PreparedStatement instead of Statement, that's because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
+ This induced unnecessary calculation by the cpu so unless energy consumption.
Noncompliant Code Example
public void select() {
diff --git a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
index edf22ff81..5444a6196 100644
--- a/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
+++ b/src/php-plugin/src/main/resources/fr/cnumr/l10n/php/rules/custom/D1.html
@@ -1,2 +1,28 @@
-
Avoid using try-catch-finally statement
-
When an exception is thrown, a variable (the exception itself) is created in the catch block and destroyed at the end of the block. Creating this variable and destroying it consumes CPU cycles and RAM unnecessarily. It is better to prefer a logical test as much as possible.
+
Inside complex code parts (for exemple multiple loops, complex data constructions...), avoid using try...catch...finally.
+
When an exception is thrown, a variable (the exception itself) is created in a catch block and it's destruction consumes unnecessary CPU cycles and RAM. Prefer using logical tests in this cases.
+
Noncompliant Code Example
+
+try
+{
+ $picture = PDF_open_image_file($PDF, "jpeg", $imgFile, "", 0); // This is the original statement, this works on PHP4
+}
+catch(Exception $ex)
+{
+ $msg = "Error opening $imgFile for Product $row['Identifier']";
+ throw new Exception($msg);
+}
+
+
Eviter de créer des méthodes getter et setter dans les classes.
+
Avoid Getters and Setters in class, It increase unless RAM memory usage.
Noncompliant Code Example
class Client():
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.html
index 088ad39de..4b90e50d4 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.html
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S69.html
@@ -1,4 +1,4 @@
-
raises an issue on a For statement. with a visitor on which you can control the visit.
+
Do not call a function when declaring a for-type loop in order to avoid function calls each iterations. It saves CPU cycles.
Noncompliant Code Example
for i in my_function():
diff --git a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
index 1d47ab791..837f0493d 100644
--- a/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
+++ b/src/python-plugin/src/main/resources/fr/cnumr/l10n/python/rules/python/S72.html
@@ -1,4 +1,4 @@
-
Do not execute an SQL request in a loop
+
Executing SQL queries in loop induced unnecessary calculation by the cpu, RAM usage and network transfert.
+ Avoid usage of static collections.
+ If you want to use static collections make them final and create for example a singleton if needed containing the collections.
+ The static fields are more complicated for the Garbage Collector to manage and can lead to memory leaks.
+
+
+
Noncompliant Code Example
+
+
+ /**
+ * Not compliant
+ */
+ public class AvoidUsageOfStaticCollections {
+ public static final List<> LIST = new ArrayList<>();
+ public static final Set<> SET = new HashSet<>();
+ public static final Map<> MAP = new HashMap<>();
+ }
+
+
+
+
Compliant Solution
+
+
+ /**
+ * Compliant
+ */
+ public class GoodUsageOfStaticCollections {
+ public static volatile GoodUsageOfStaticCollections INSTANCE = new GoodUsageOfStaticCollections();
+
+ public final List<> LIST = new ArrayList<>();
+ public final Set<> SET = new HashSet<>();
+ public final Map<> MAP = new HashMap<>();
+
+ private GoodUsageOfStaticCollections() {
+ }
+ }
+
+
\ No newline at end of file
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S76.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S76.json
new file mode 100644
index 000000000..e59d0fc9f
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S76.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid usage of static collections.",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidUsageOfStaticCollections.java b/src/java-plugin/src/test/files/AvoidUsageOfStaticCollections.java
new file mode 100644
index 000000000..ec3736106
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidUsageOfStaticCollections.java
@@ -0,0 +1,19 @@
+package fr.cnumr.java.checks;
+
+import java.util.*;
+
+/**
+ * Not compliant
+ */
+public class AvoidUsageOfStaticCollections {
+
+ public static final List LIST = new ArrayList(); // Noncompliant
+
+ public static final Set SET = new HashSet(); // Noncompliant
+
+ public static final Map MAP = new HashMap(); // Noncompliant
+
+ public AvoidUsageOfStaticCollections() {
+ }
+
+}
diff --git a/src/java-plugin/src/test/files/GoodUsageOfStaticCollections.java b/src/java-plugin/src/test/files/GoodUsageOfStaticCollections.java
new file mode 100644
index 000000000..bab0372e2
--- /dev/null
+++ b/src/java-plugin/src/test/files/GoodUsageOfStaticCollections.java
@@ -0,0 +1,17 @@
+package fr.cnumr.java.checks;
+
+import java.util.*;
+
+/**
+ * Compliant
+ */
+public class GoodUsageOfStaticCollections {
+ public static volatile GoodUsageOfStaticCollections INSTANCE = new GoodUsageOfStaticCollections();
+
+ public final List LIST = new ArrayList(); // Compliant
+ public final Set SET = new HashSet(); // Compliant
+ public final Map MAP = new HashMap(); // Compliant
+
+ private GoodUsageOfStaticCollections() {
+ }
+}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index 570fc4578..aeb839f49 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -33,8 +33,8 @@ void checkNumberRules() {
MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(14);
+ assertThat(context.checkClasses()).hasSize(15);
assertThat(context.testCheckClasses()).isEmpty();
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidUsageOfStaticCollectionsTests.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidUsageOfStaticCollectionsTests.java
new file mode 100644
index 000000000..74ddfc6b7
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidUsageOfStaticCollectionsTests.java
@@ -0,0 +1,24 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
+
+public class AvoidUsageOfStaticCollectionsTests {
+
+ @Test
+ public void testHasIssues() {
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/AvoidUsageOfStaticCollections.java")
+ .withCheck(new AvoidUsageOfStaticCollections())
+ .verifyIssues();
+ }
+
+ @Test
+ public void testNoIssues() {
+ JavaCheckVerifier.newVerifier()
+ .onFile("src/test/files/GoodUsageOfStaticCollections.java")
+ .withCheck(new AvoidUsageOfStaticCollections())
+ .verifyNoIssues();
+ }
+
+}
From 910ec5ffc8a64b969ad78437b5529a2696663395 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Thu, 2 Jun 2022 14:42:15 +0200
Subject: [PATCH 081/119] Adding all three files in draft.
---
.../java/checks/sobriety/HighFrameRateRule.java | 17 +++++++++++++++++
.../test/files/sobriety/HighFrameRateCheck.java | 7 +++++++
.../checks/sobriety/HighFrameRateCheckTest.java | 14 ++++++++++++++
3 files changed, 38 insertions(+)
create mode 100644 src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
create mode 100644 src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
create mode 100644 src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
new file mode 100644
index 000000000..590fc0110
--- /dev/null
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -0,0 +1,17 @@
+package org.sonar.samples.java.checks;
+
+import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.tree.Tree.Kind;
+import java.util.Collections;
+import java.util.List;
+
+@Rule(key = "HighFrameRateRule")
+class HighFrameRateCheck {
+
+ @Override
+ public List nodesToVisit() {
+ return Collections.emptyList();
+ }
+
+}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
new file mode 100644
index 000000000..0c69247c7
--- /dev/null
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -0,0 +1,7 @@
+class HighFrameRateCheck {
+
+ public void test() {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
new file mode 100644
index 000000000..20c914dc0
--- /dev/null
+++ b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
@@ -0,0 +1,14 @@
+package org.sonar.samples.java.checks;
+
+import org.junit.jupiter.api.Test;
+
+class HighFrameRateCheckTest {
+
+ @Test
+ public void verify() {
+ JavaCheckVerifier.newVerifier().onFile("src/test/files/sobriety/HighFrameRateRule.java")
+ .withChecks(new HighFrameRateRule())
+ .verifyIssues();
+ }
+
+}
\ No newline at end of file
From 097c2a9687a952190d3214b4f4e2da4befb10270 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Thu, 2 Jun 2022 15:45:20 +0200
Subject: [PATCH 082/119] Adding specific method check super type to the rule.
---
.../checks/sobriety/HighFrameRateRule.java | 20 +++++++++----------
.../files/sobriety/HighFrameRateCheck.java | 17 +++++++++++++++-
.../sobriety/HighFrameRateCheckTest.java | 4 +++-
3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index 590fc0110..8b7e9b167 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -1,17 +1,17 @@
-package org.sonar.samples.java.checks;
+package io.ecocode.java.checks.sobriety;
+import io.ecocode.java.checks.helpers.SpecificMethodCheck;
import org.sonar.check.Rule;
-import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
-import org.sonar.plugins.java.api.tree.Tree.Kind;
-import java.util.Collections;
-import java.util.List;
-@Rule(key = "HighFrameRateRule")
-class HighFrameRateCheck {
+@Rule(key = "ESOB014", name= "ecoCodeHighFrameRate")
+public class HighFrameRateRule extends SpecificMethodCheck {
- @Override
- public List nodesToVisit() {
- return Collections.emptyList();
+ public HighFrameRateRule() {
+ super("android.view.Surface","setFrameRate");
}
+ @Override
+ public String getMessage() {
+ return "";
+ }
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index 0c69247c7..c3b1baf51 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -1,7 +1,22 @@
-class HighFrameRateCheck {
+package android.view;
+
+class Surface {
+
+ public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0;
+ public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
+ public static final int CHANGE_FRAME_RATE_ALWAYS = 1;
+ public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
public void test() {
+ Surface surface = new Surface();
+ }
+
+ public void setFrameRate(float frameRate, int compatibility) {
+ return;
+ }
+ public void setFrameRate(float frameRate, int compatibility, int changeFrameRateStrategy) {
+ return;
}
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
index 20c914dc0..61ac0bab2 100644
--- a/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
+++ b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
@@ -1,6 +1,8 @@
package org.sonar.samples.java.checks;
-import org.junit.jupiter.api.Test;
+import io.ecocode.java.checks.sobriety.HighFrameRateRule;
+import org.junit.Test;
+import org.sonar.java.checks.verifier.JavaCheckVerifier;
class HighFrameRateCheckTest {
From 19488238134d7a6c89d0878559d97757b459d157 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Thu, 2 Jun 2022 16:22:21 +0200
Subject: [PATCH 083/119] Adding test case to test file.
---
.../java/checks/sobriety/HighFrameRateRule.java | 2 +-
.../src/test/files/sobriety/HighFrameRateCheck.java | 10 ++++++----
.../java/checks/sobriety/HighFrameRateCheckTest.java | 7 +++----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index 8b7e9b167..5166da422 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -12,6 +12,6 @@ public HighFrameRateRule() {
@Override
public String getMessage() {
- return "";
+ return "Not overriding setFrameRate default behavior is recommanded to avoid higher battery usage.";
}
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index c3b1baf51..05628a599 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -2,13 +2,15 @@
class Surface {
- public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0;
- public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
- public static final int CHANGE_FRAME_RATE_ALWAYS = 1;
- public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
+ private static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0;
+ private static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
+ private static final int CHANGE_FRAME_RATE_ALWAYS = 1;
+ private static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
public void test() {
Surface surface = new Surface();
+ surface.setFrameRate(120.0f,0); // Noncompliant
+// surface.setFrameRate(90.0f,FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
}
public void setFrameRate(float frameRate, int compatibility) {
diff --git a/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
index 61ac0bab2..162a11564 100644
--- a/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
+++ b/src/android-plugin/src/test/java/io/ecocode/java/checks/sobriety/HighFrameRateCheckTest.java
@@ -1,14 +1,13 @@
-package org.sonar.samples.java.checks;
+package io.ecocode.java.checks.sobriety;
-import io.ecocode.java.checks.sobriety.HighFrameRateRule;
import org.junit.Test;
import org.sonar.java.checks.verifier.JavaCheckVerifier;
-class HighFrameRateCheckTest {
+public class HighFrameRateCheckTest {
@Test
public void verify() {
- JavaCheckVerifier.newVerifier().onFile("src/test/files/sobriety/HighFrameRateRule.java")
+ JavaCheckVerifier.newVerifier().onFile("src/test/files/sobriety/HighFrameRateCheck.java")
.withChecks(new HighFrameRateRule())
.verifyIssues();
}
From 4809574e3c376559362301d931f84858e245509f Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Thu, 2 Jun 2022 17:46:38 +0200
Subject: [PATCH 084/119] Updating test file with according sonar message rule
test.
---
.../src/test/files/sobriety/HighFrameRateCheck.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index 05628a599..4fe1b1f92 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -7,10 +7,9 @@ class Surface {
private static final int CHANGE_FRAME_RATE_ALWAYS = 1;
private static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
- public void test() {
+ public void test() {
Surface surface = new Surface();
- surface.setFrameRate(120.0f,0); // Noncompliant
-// surface.setFrameRate(90.0f,FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
+ surface.setFrameRate(0.0f,0); // Noncompliant {{Not overriding setFrameRate default behavior is recommanded to avoid higher battery usage.}}
}
public void setFrameRate(float frameRate, int compatibility) {
From a368fabbf7cb186709253fcc61b5eeec768b9c91 Mon Sep 17 00:00:00 2001
From: PJCR0451
Date: Thu, 2 Jun 2022 18:05:36 +0200
Subject: [PATCH 085/119] add html and json files
---
.../l10n/java/rules/squid/ESOB014_java.html | 18 ++++++++++++++++++
.../l10n/java/rules/squid/ESOB014_java.json | 15 +++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.html
create mode 100644 src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.json
diff --git a/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.html b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.html
new file mode 100644
index 000000000..16847c7f0
--- /dev/null
+++ b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.html
@@ -0,0 +1,18 @@
+
+
In Android 11 (API level 30) or higher, a call to
+ Surface#setFrameRate(float frameRate, int compatibility) results in a change to the display refresh
+ rate. However, a regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence
+ saving energy, this frequency should not be raised to 90Hz or 120Hz, despite this is now supported by many devices.
+
\ No newline at end of file
diff --git a/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.json b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.json
new file mode 100644
index 000000000..4cad3847f
--- /dev/null
+++ b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ESOB014_java.json
@@ -0,0 +1,15 @@
+{
+ "title": "Sobriety: High Frame Rate",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
From 464de201dc6d333c941711622d14925db0d53595 Mon Sep 17 00:00:00 2001
From: PJCR0451
Date: Thu, 2 Jun 2022 18:18:56 +0200
Subject: [PATCH 086/119] add rule to java profile
---
.../src/main/java/io/ecocode/java/JavaCheckList.java | 3 ++-
.../l10n/java/rules/squid/ecocode_java_profile.json | 12 +-----------
.../io/ecocode/java/JavaRulesDefinitionTest.java | 6 ++++++
3 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/JavaCheckList.java b/src/android-plugin/src/main/java/io/ecocode/java/JavaCheckList.java
index 774710505..74f8fea7a 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/JavaCheckList.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/JavaCheckList.java
@@ -82,7 +82,8 @@ public static List> getJavaChecks() {
SensorCoalesceRule.class,
JobCoalesceRule.class,
SaveModeAwarenessRule.class,
- ThriftyGeolocationCriteriaRule.class
+ ThriftyGeolocationCriteriaRule.class,
+ HighFrameRateRule.class
));
}
diff --git a/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ecocode_java_profile.json b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ecocode_java_profile.json
index 5dccc9efd..eaffad9a8 100644
--- a/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ecocode_java_profile.json
+++ b/src/android-plugin/src/main/resources/org/sonar/l10n/java/rules/squid/ecocode_java_profile.json
@@ -32,16 +32,6 @@
"ESOB011",
"ESOB012",
"ESOB013",
- "EOPT001",
- "EOPT002",
- "EIDL001",
- "EIDL002",
- "EIDL004",
- "EIDL006",
- "EIDL007",
- "EIDL008",
- "EIDL009",
- "EPOW004",
- "ESOB012"
+ "ESOB014"
]
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java b/src/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
index 8f78edbca..c2fd381c3 100644
--- a/src/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
+++ b/src/android-plugin/src/test/java/io/ecocode/java/JavaRulesDefinitionTest.java
@@ -233,6 +233,12 @@ private void assertRuleProperties(Repository repository) {
assertThat(torchFree.name()).isEqualTo("Sobriety: Torch Free");
assertThat(torchFree.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
assertThat(torchFree.type()).isEqualTo(RuleType.CODE_SMELL);
+
+ Rule highFrameRate = repository.rule("ESOB014");
+ assertThat(highFrameRate).isNotNull();
+ assertThat(highFrameRate.name()).isEqualTo("Sobriety: High Frame Rate");
+ assertThat(highFrameRate.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE);
+ assertThat(highFrameRate.type()).isEqualTo(RuleType.CODE_SMELL);
}
private void assertAllRuleParametersHaveDescription(Repository repository) {
From 505608773f9b0d21988084b75e4e438dfdb02676 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Thu, 2 Jun 2022 18:48:26 +0200
Subject: [PATCH 087/119] Adding the argument matcher for fps greater than 60.
---
.../checks/sobriety/HighFrameRateRule.java | 39 +++++++++++++++++--
.../files/sobriety/HighFrameRateCheck.java | 5 ++-
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index 5166da422..e7ce0f3bf 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -1,17 +1,48 @@
package io.ecocode.java.checks.sobriety;
+import com.google.common.collect.ImmutableList;
+import io.ecocode.java.checks.helpers.CheckArgumentComplexType;
import io.ecocode.java.checks.helpers.SpecificMethodCheck;
import org.sonar.check.Rule;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.semantic.MethodMatchers;
+import org.sonar.plugins.java.api.tree.*;
+
+import java.util.List;
@Rule(key = "ESOB014", name= "ecoCodeHighFrameRate")
-public class HighFrameRateRule extends SpecificMethodCheck {
+public class HighFrameRateRule extends IssuableSubscriptionVisitor {
+
+ private final MethodMatchers surfaceListenerMethodMatcher = MethodMatchers.create().ofTypes("android.view.Surface").names("setFrameRate").withAnyParameters().build();
public HighFrameRateRule() {
- super("android.view.Surface","setFrameRate");
+ super();
}
@Override
- public String getMessage() {
- return "Not overriding setFrameRate default behavior is recommanded to avoid higher battery usage.";
+ public List nodesToVisit() {
+ return ImmutableList.of(Tree.Kind.METHOD_INVOCATION);
+ }
+
+ @Override
+ public void visitNode(Tree tree) {
+ if (tree.is(Tree.Kind.METHOD_INVOCATION)) {
+ MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
+ if (surfaceListenerMethodMatcher.matches(methodInvocationTree)) {
+ if (!isRefreshSixtyOrLower(methodInvocationTree.arguments())) {
+ reportIssue(methodInvocationTree, "A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.");
+ }
+ }
+ }
+ }
+
+ private boolean isRefreshSixtyOrLower(Arguments arguments) {
+ ExpressionTree firstArg = arguments.get(0);
+ while (firstArg.is(Tree.Kind.TYPE_CAST, Tree.Kind.MEMBER_SELECT, Tree.Kind.PARENTHESIZED_EXPRESSION)) {
+ firstArg = (ExpressionTree) CheckArgumentComplexType.getChildExpression(firstArg);
+ }
+ LiteralTree lit = (LiteralTree) firstArg;
+ return firstArg.is(Tree.Kind.FLOAT_LITERAL)
+ && Float.valueOf(lit.value()) <= 60.0f;
}
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index 4fe1b1f92..428ccfec1 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -9,7 +9,10 @@ class Surface {
public void test() {
Surface surface = new Surface();
- surface.setFrameRate(0.0f,0); // Noncompliant {{Not overriding setFrameRate default behavior is recommanded to avoid higher battery usage.}}
+ surface.setFrameRate(0.0f,0);
+ surface.setFrameRate(60.0f,0);
+ surface.setFrameRate(90.0f,0); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f,0); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
}
public void setFrameRate(float frameRate, int compatibility) {
From cb81eefddd00ed733917c1aafb368cf4439cbcc7 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 09:35:26 +0200
Subject: [PATCH 088/119] Adding java doc and fixing code smells.
---
.../checks/sobriety/HighFrameRateRule.java | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index e7ce0f3bf..47685b264 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -2,7 +2,6 @@
import com.google.common.collect.ImmutableList;
import io.ecocode.java.checks.helpers.CheckArgumentComplexType;
-import io.ecocode.java.checks.helpers.SpecificMethodCheck;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.MethodMatchers;
@@ -10,10 +9,11 @@
import java.util.List;
-@Rule(key = "ESOB014", name= "ecoCodeHighFrameRate")
+@Rule(key = "ESOB014", name = "ecoCodeHighFrameRate")
public class HighFrameRateRule extends IssuableSubscriptionVisitor {
- private final MethodMatchers surfaceListenerMethodMatcher = MethodMatchers.create().ofTypes("android.view.Surface").names("setFrameRate").withAnyParameters().build();
+ private final MethodMatchers surfaceListenerMethodMatcher = MethodMatchers.create().
+ ofTypes("android.view.Surface").names("setFrameRate").withAnyParameters().build();
public HighFrameRateRule() {
super();
@@ -28,14 +28,18 @@ public List nodesToVisit() {
public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
- if (surfaceListenerMethodMatcher.matches(methodInvocationTree)) {
- if (!isRefreshSixtyOrLower(methodInvocationTree.arguments())) {
- reportIssue(methodInvocationTree, "A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.");
- }
+ if (surfaceListenerMethodMatcher.matches(methodInvocationTree) &&
+ !isRefreshSixtyOrLower(methodInvocationTree.arguments())) {
+ reportIssue(methodInvocationTree, "A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.");
}
}
}
+ /**
+ * Checking if method arguments are complying to the rule
+ * @param arguments Arguments of the method called
+ * @return true if argument is a float under or equal 60
+ */
private boolean isRefreshSixtyOrLower(Arguments arguments) {
ExpressionTree firstArg = arguments.get(0);
while (firstArg.is(Tree.Kind.TYPE_CAST, Tree.Kind.MEMBER_SELECT, Tree.Kind.PARENTHESIZED_EXPRESSION)) {
From fb7c9cc5b4b769ca9bc74028d8dfded9d92a801e Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 10:45:57 +0200
Subject: [PATCH 089/119] Adding some tests for 3 args and flags.
---
.../files/sobriety/HighFrameRateCheck.java | 34 ++++++++++++++++---
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index 428ccfec1..7d8198e30 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -9,10 +9,36 @@ class Surface {
public void test() {
Surface surface = new Surface();
- surface.setFrameRate(0.0f,0);
- surface.setFrameRate(60.0f,0);
- surface.setFrameRate(90.0f,0); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f,0); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ // Test with compatibility fixed source
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ // Test with 3 args
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+
+ surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+ surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+ surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+
}
public void setFrameRate(float frameRate, int compatibility) {
From 3696921be773059f9a64c86954cdeb53f5554dfa Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 12:16:35 +0200
Subject: [PATCH 090/119] Adding Identifier tests and fixing rulefor
identifiers management.
---
.../checks/sobriety/HighFrameRateRule.java | 21 ++++++++----
.../files/sobriety/HighFrameRateCheck.java | 32 ++++---------------
2 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index 47685b264..df40a1b03 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -12,6 +12,8 @@
@Rule(key = "ESOB014", name = "ecoCodeHighFrameRate")
public class HighFrameRateRule extends IssuableSubscriptionVisitor {
+ private static final float FRAME_RATE_60 = 60.0f;
+
private final MethodMatchers surfaceListenerMethodMatcher = MethodMatchers.create().
ofTypes("android.view.Surface").names("setFrameRate").withAnyParameters().build();
@@ -29,7 +31,7 @@ public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree;
if (surfaceListenerMethodMatcher.matches(methodInvocationTree) &&
- !isRefreshSixtyOrLower(methodInvocationTree.arguments())) {
+ isRefreshSixtyOrHigher(methodInvocationTree.arguments())) {
reportIssue(methodInvocationTree, "A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.");
}
}
@@ -40,13 +42,20 @@ public void visitNode(Tree tree) {
* @param arguments Arguments of the method called
* @return true if argument is a float under or equal 60
*/
- private boolean isRefreshSixtyOrLower(Arguments arguments) {
+ private boolean isRefreshSixtyOrHigher(Arguments arguments) {
ExpressionTree firstArg = arguments.get(0);
- while (firstArg.is(Tree.Kind.TYPE_CAST, Tree.Kind.MEMBER_SELECT, Tree.Kind.PARENTHESIZED_EXPRESSION)) {
+ if (firstArg.is(Tree.Kind.IDENTIFIER)) {
+ IdentifierTree expressionTree = (IdentifierTree) firstArg;
+ Object argValue = expressionTree.asConstant().get();
+ if (argValue instanceof Float) {
+ return ((Float) argValue).floatValue() > FRAME_RATE_60;
+ }
+ } else if (firstArg.is(Tree.Kind.FLOAT_LITERAL)) {
firstArg = (ExpressionTree) CheckArgumentComplexType.getChildExpression(firstArg);
+ LiteralTree lit = (LiteralTree) firstArg;
+ return Float.valueOf(lit.value()) > FRAME_RATE_60;
}
- LiteralTree lit = (LiteralTree) firstArg;
- return firstArg.is(Tree.Kind.FLOAT_LITERAL)
- && Float.valueOf(lit.value()) <= 60.0f;
+ // not compliant case
+ return false;
}
}
\ No newline at end of file
diff --git a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
index 7d8198e30..37e9e5834 100644
--- a/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
+++ b/src/android-plugin/src/test/files/sobriety/HighFrameRateCheck.java
@@ -6,37 +6,17 @@ class Surface {
private static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
private static final int CHANGE_FRAME_RATE_ALWAYS = 1;
private static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
+ private static final float FRAME_RATE_0 = 0.0f;
+ private static final float FRAME_RATE_60 = 60.0f;
+ private static final float FRAME_RATE_90 = 90.0f;
+ private static final float FRAME_RATE_120 = 120.0f;
public void test() {
Surface surface = new Surface();
surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT);
- surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- // Test with compatibility fixed source
- surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
+ surface.setFrameRate(FRAME_RATE_60, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- // Test with 3 args
- surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
- surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
-
- surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS);
- surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_DEFAULT, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
-
- surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS);
- surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
- surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
-
- surface.setFrameRate(0.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
- surface.setFrameRate(60.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
- surface.setFrameRate(90.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
+ surface.setFrameRate(FRAME_RATE_120, FRAME_RATE_COMPATIBILITY_DEFAULT); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
surface.setFrameRate(120.0f, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); // Noncompliant {{A regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz.}}
}
From 168b1fea280bf3dddf48f499443fafe8d2122171 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 12:21:44 +0200
Subject: [PATCH 091/119] Cleaning code bug.
---
.../io/ecocode/java/checks/sobriety/HighFrameRateRule.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index df40a1b03..44871dddd 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -44,9 +44,8 @@ public void visitNode(Tree tree) {
*/
private boolean isRefreshSixtyOrHigher(Arguments arguments) {
ExpressionTree firstArg = arguments.get(0);
- if (firstArg.is(Tree.Kind.IDENTIFIER)) {
- IdentifierTree expressionTree = (IdentifierTree) firstArg;
- Object argValue = expressionTree.asConstant().get();
+ if (firstArg.is(Tree.Kind.IDENTIFIER) && firstArg.asConstant().isPresent()) {
+ Object argValue = firstArg.asConstant().get();
if (argValue instanceof Float) {
return ((Float) argValue).floatValue() > FRAME_RATE_60;
}
From 9fd5274563c4d352ea080824848c77df842691e4 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 12:29:25 +0200
Subject: [PATCH 092/119] Cleaning code bug.
---
.../java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index 44871dddd..f4cd0ece3 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -44,7 +44,7 @@ public void visitNode(Tree tree) {
*/
private boolean isRefreshSixtyOrHigher(Arguments arguments) {
ExpressionTree firstArg = arguments.get(0);
- if (firstArg.is(Tree.Kind.IDENTIFIER) && firstArg.asConstant().isPresent()) {
+ if (firstArg.asConstant().isPresent() && firstArg.is(Tree.Kind.IDENTIFIER)) {
Object argValue = firstArg.asConstant().get();
if (argValue instanceof Float) {
return ((Float) argValue).floatValue() > FRAME_RATE_60;
From 099371404a6893889b7a38054cc3343e74a1d7a6 Mon Sep 17 00:00:00 2001
From: David Crescence
Date: Fri, 3 Jun 2022 13:16:19 +0200
Subject: [PATCH 093/119] Adding optional unwrapping in test..
---
.../io/ecocode/java/checks/sobriety/HighFrameRateRule.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
index f4cd0ece3..105677a52 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/sobriety/HighFrameRateRule.java
@@ -8,6 +8,7 @@
import org.sonar.plugins.java.api.tree.*;
import java.util.List;
+import java.util.Optional;
@Rule(key = "ESOB014", name = "ecoCodeHighFrameRate")
public class HighFrameRateRule extends IssuableSubscriptionVisitor {
@@ -44,8 +45,9 @@ public void visitNode(Tree tree) {
*/
private boolean isRefreshSixtyOrHigher(Arguments arguments) {
ExpressionTree firstArg = arguments.get(0);
- if (firstArg.asConstant().isPresent() && firstArg.is(Tree.Kind.IDENTIFIER)) {
- Object argValue = firstArg.asConstant().get();
+ Optional
+
org.codenarc.rule.ecocode.DisableObfuscationRuleMINOR
diff --git a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
index 7bdda726b..863dff5ce 100644
--- a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
+++ b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
@@ -85,7 +85,7 @@ android {
## DisableObfuscation Rule
-*Since CodeNarc 2.2.1*
+*Since CodeNarc 2.2.2*
Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
From d75cd3ad6a386c5fd15679bbfbb8c21f3760518a Mon Sep 17 00:00:00 2001
From: Julien Hertout
Date: Wed, 2 Nov 2022 07:26:57 +0100
Subject: [PATCH 099/119] Update CodeNarc version to 2.2.3 since we add a new
rule (Disable Obfuscation)
---
src/android-plugin/pom.xml | 2 +-
.../src/main/resources/org/sonar/plugins/groovy/rules.xml | 2 +-
src/codenarc-converter/CodeNarc/CHANGELOG.md | 5 +++++
src/codenarc-converter/CodeNarc/build.gradle | 2 +-
.../CodeNarc/docs/codenarc-rules-ecocode.md | 2 +-
.../CodeNarc/src/main/resources/codenarc-version.txt | 2 +-
src/codenarc-converter/pom.xml | 2 +-
src/prepare-codenarc | 2 +-
src/prepare-codenarc.bat | 2 +-
9 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/android-plugin/pom.xml b/src/android-plugin/pom.xml
index 1c01a6218..cfc75b6c5 100644
--- a/src/android-plugin/pom.xml
+++ b/src/android-plugin/pom.xml
@@ -191,7 +191,7 @@
org.codenarcCodeNarc
- 2.2.2
+ 2.2.3org.gmetrics
diff --git a/src/android-plugin/src/main/resources/org/sonar/plugins/groovy/rules.xml b/src/android-plugin/src/main/resources/org/sonar/plugins/groovy/rules.xml
index b3521344c..acbdffb84 100644
--- a/src/android-plugin/src/main/resources/org/sonar/plugins/groovy/rules.xml
+++ b/src/android-plugin/src/main/resources/org/sonar/plugins/groovy/rules.xml
@@ -84,7 +84,7 @@
code-smell
-
+
org.codenarc.rule.ecocode.DisableObfuscationRuleMINOR
diff --git a/src/codenarc-converter/CodeNarc/CHANGELOG.md b/src/codenarc-converter/CodeNarc/CHANGELOG.md
index 0c1280b18..dcaa1a4b9 100644
--- a/src/codenarc-converter/CodeNarc/CHANGELOG.md
+++ b/src/codenarc-converter/CodeNarc/CHANGELOG.md
@@ -5,6 +5,11 @@
# CodeNarc Change Log
+Version 2.2.3 (November 2022)
+--------------------------------------
+Build and Infrastructure
+- Upgrade Gradle to wrapper 6.9.2 (avoid Log4Shell vulnerability)
+
Version 2.2.2 (May 2022)
--------------------------------------
Build and Infrastructure
diff --git a/src/codenarc-converter/CodeNarc/build.gradle b/src/codenarc-converter/CodeNarc/build.gradle
index 13b8d0a90..0b2194168 100644
--- a/src/codenarc-converter/CodeNarc/build.gradle
+++ b/src/codenarc-converter/CodeNarc/build.gradle
@@ -14,7 +14,7 @@ shadowJar {
group = 'org.codenarc'
archivesBaseName = 'CodeNarc'
-version = '2.2.2'
+version = '2.2.3'
sourceCompatibility = '1.7'
targetCompatibility = '1.7'
diff --git a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
index 863dff5ce..516dcf8b3 100644
--- a/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
+++ b/src/codenarc-converter/CodeNarc/docs/codenarc-rules-ecocode.md
@@ -85,7 +85,7 @@ android {
## DisableObfuscation Rule
-*Since CodeNarc 2.2.2*
+*Since CodeNarc 2.2.3*
Using minifyEnabled true will obfuscate code and will have a sligthly negative impact on power consumption at runtime.
diff --git a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-version.txt b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-version.txt
index b1b25a5ff..585940699 100644
--- a/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-version.txt
+++ b/src/codenarc-converter/CodeNarc/src/main/resources/codenarc-version.txt
@@ -1 +1 @@
-2.2.2
+2.2.3
diff --git a/src/codenarc-converter/pom.xml b/src/codenarc-converter/pom.xml
index 8952c6c76..e90cb7578 100644
--- a/src/codenarc-converter/pom.xml
+++ b/src/codenarc-converter/pom.xml
@@ -13,7 +13,7 @@
Sonar CodeNarc Converter
- 2.2.2
+ 2.2.31.8.2true
diff --git a/src/prepare-codenarc b/src/prepare-codenarc
index bd1257ff8..ee9582001 100755
--- a/src/prepare-codenarc
+++ b/src/prepare-codenarc
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
# Define CodeNarc version
-codenarcVersion="2.2.2"
+codenarcVersion="2.2.3"
# Build CodeNarc
cd codenarc-converter/CodeNarc
diff --git a/src/prepare-codenarc.bat b/src/prepare-codenarc.bat
index 53bce432e..0890818bd 100644
--- a/src/prepare-codenarc.bat
+++ b/src/prepare-codenarc.bat
@@ -1,5 +1,5 @@
REM == Define CodeNarc version
-set codenarc_version=2.2.2
+set codenarc_version=2.2.3
REM == Build CodeNarc
cd codenarc-converter/CodeNarc
From 076c4de955b8fd168683dffa815e4321a3f515c0 Mon Sep 17 00:00:00 2001
From: Julien Hertout
Date: Wed, 2 Nov 2022 07:27:31 +0100
Subject: [PATCH 100/119] Slightly improve Android readme for clarity
---
src/android-plugin/README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/android-plugin/README.md b/src/android-plugin/README.md
index c2e2ef6cd..3e30e1f11 100644
--- a/src/android-plugin/README.md
+++ b/src/android-plugin/README.md
@@ -43,6 +43,7 @@ Tests are located under:
Build CodeNarc (gradle 6.9.2, Java 11):
```sh
+cd /codenarc-converter/CodeNarc
./gradlew build -x test
```
From 5830a41d4200f93c9dd7dcf7d4893bedc687c323 Mon Sep 17 00:00:00 2001
From: Julien Hertout
Date: Wed, 2 Nov 2022 07:33:48 +0100
Subject: [PATCH 101/119] Improve CodeNarc changelog for 2.2.1 and 2.2.3 by
indicating added rules
---
src/codenarc-converter/CodeNarc/CHANGELOG.md | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/src/codenarc-converter/CodeNarc/CHANGELOG.md b/src/codenarc-converter/CodeNarc/CHANGELOG.md
index dcaa1a4b9..3f83a198a 100644
--- a/src/codenarc-converter/CodeNarc/CHANGELOG.md
+++ b/src/codenarc-converter/CodeNarc/CHANGELOG.md
@@ -1,26 +1,22 @@
-#TODO: Sort the following line into the file
-- FatApp rule (ecocode) - Using "multiDexEnabled true" goes against the overall reduction of the weight of the apps and hence must be avoided.
-
# CodeNarc Change Log
Version 2.2.3 (November 2022)
--------------------------------------
-Build and Infrastructure
-- Upgrade Gradle to wrapper 6.9.2 (avoid Log4Shell vulnerability)
+Added rule
+- ecoCode: Disable Obfuscation
Version 2.2.2 (May 2022)
--------------------------------------
Build and Infrastructure
- Upgrade Gradle to wrapper 6.9.2 (avoid Log4Shell vulnerability)
-
Version 2.2.1 (Mar 2022)
--------------------------------------
-Updated/Enhanced Rules and Bug Fixes
-- Add ecoCode rules
-
+Added rules
+- ecoCode: Fat App
+- ecoCode: Supported Version Range
Version 2.2.0 (Aug 2021)
--------------------------------------
From 0e49a2b92c4a76bbbe26b70036fe0ce15db4aa3e Mon Sep 17 00:00:00 2001
From: hugodezordo <55738275+hugodezordo@users.noreply.github.com>
Date: Wed, 2 Nov 2022 15:24:04 +0100
Subject: [PATCH 102/119] [Rule-S79] test and rule free resources of auto
closeable interface (#165)
* [Rule-S79] test and rule free resources of auto closeable interface
* Fix sonar code smells
* Chnage rules size to 17
* Change size to 17
* Adapt the description of the rule
Co-authored-by: oussamaLaribi <63214114+oussamaLaribi@users.noreply.github.com>
---
.../main/java/fr/cnumr/java/RulesList.java | 3 +-
...FreeResourcesOfAutoCloseableInterface.java | 76 +++++++++++++++++++
.../fr/cnumr/l10n/java/rules/java/S79.html | 24 ++++++
.../fr/cnumr/l10n/java/rules/java/S79.json | 13 ++++
...FreeResourcesOfAutoCloseableInterface.java | 37 +++++++++
.../java/MyJavaFileCheckRegistrarTest.java | 2 +-
...ResourcesOfAutoCloseableInterfaceTest.java | 24 ++++++
7 files changed, 177 insertions(+), 2 deletions(-)
create mode 100644 src/java-plugin/src/main/java/fr/cnumr/java/checks/FreeResourcesOfAutoCloseableInterface.java
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S79.html
create mode 100644 src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S79.json
create mode 100644 src/java-plugin/src/test/files/FreeResourcesOfAutoCloseableInterface.java
create mode 100644 src/java-plugin/src/test/java/fr/cnumr/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
index 2fcaa323d..cb36feae7 100644
--- a/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/RulesList.java
@@ -56,7 +56,8 @@ public static List> getJavaChecks() {
OptimizeReadFileExceptions.class,
InitializeBufferWithAppropriateSize.class,
AvoidUsingGlobalVariablesCheck.class,
- AvoidSetConstantInBatchUpdate.class
+ AvoidSetConstantInBatchUpdate.class,
+ FreeResourcesOfAutoCloseableInterface.class
));
}
diff --git a/src/java-plugin/src/main/java/fr/cnumr/java/checks/FreeResourcesOfAutoCloseableInterface.java b/src/java-plugin/src/main/java/fr/cnumr/java/checks/FreeResourcesOfAutoCloseableInterface.java
new file mode 100644
index 000000000..fa314116b
--- /dev/null
+++ b/src/java-plugin/src/main/java/fr/cnumr/java/checks/FreeResourcesOfAutoCloseableInterface.java
@@ -0,0 +1,76 @@
+package fr.cnumr.java.checks;
+
+import org.sonar.check.Priority;
+import org.sonar.check.Rule;
+import org.sonar.java.JavaVersionAwareVisitor;
+import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
+import org.sonar.plugins.java.api.JavaFileScannerContext;
+import org.sonar.plugins.java.api.JavaVersion;
+import org.sonar.plugins.java.api.tree.NewClassTree;
+import org.sonar.plugins.java.api.tree.Tree;
+import org.sonar.plugins.java.api.tree.TryStatementTree;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+import java.util.*;
+
+
+@Rule(
+ key = "S79",
+ name = "Developpement",
+ description = FreeResourcesOfAutoCloseableInterface.MESSAGE_RULE,
+ priority = Priority.MINOR,
+ tags = {"bug"})
+public class FreeResourcesOfAutoCloseableInterface extends IssuableSubscriptionVisitor implements JavaVersionAwareVisitor {
+ 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.";
+
+ @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 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 leaveNode(Tree tree) {
+ if (tree.is(Tree.Kind.TRY_STATEMENT)) {
+ List secondaryTrees = toReport.pop();
+ if (!secondaryTrees.isEmpty()) {
+ reportIssue(tree, MESSAGE_RULE);
+ }
+ }
+ }
+
+ private boolean withinStandardTryWithFinally() {
+ if (withinTry.isEmpty() || !withinTry.peek().resourceList().isEmpty()) return false;
+ assert withinTry.peek() != null;
+ return withinTry.peek().finallyBlock() != null;
+ }
+
+ @Override
+ public boolean isCompatibleWithJavaVersion(JavaVersion version) {
+ return version.isJava7Compatible();
+ }
+}
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S79.html b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S79.html
new file mode 100644
index 000000000..f8801ef21
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/S79.html
@@ -0,0 +1,24 @@
+
try-with-resources Statement needs to be implemented for any object that implements the AutoCloseable interface, it save computer resources.
+
Noncompliant Code Example
+
+ private static void printFileJava7() throws IOException {
+ FileInputStream input = new FileInputStream("file.txt");
+ int data = input.read();
+ while(data != -1){
+ System.out.print((char) data);
+ data = input.read();
+ }
+ }
+
+
Compliant Solution
+
+ private static void printFileJava7() throws IOException {
+ try(FileInputStream input = new FileInputStream("file.txt")) {
+ int data = input.read();
+ while(data != -1){
+ System.out.print((char) data);
+ data = input.read();
+ }
+ }
+ }
+
If we are using too many conditional if-else statements it will impact performance since JVM will have to compare the conditions. We can think of using a switch statement instead of multiple if-else if possible. Switch statement has a performance advantage over if – else.
+
+
Non-compliant Code Example
+
+ int index = 1;
+ int nb = 2;
+
+ if (nb > index) {
+ nb = nb + index;
+ } else {
+ nb = nb - 1;
+ }
+ if (nb != index + 1) {
+ nb = nb + index;
+ } else {
+ nb = nb - 1;
+ }
+
+
+
+
Compliant Code Example
+
+ int index = 1;
+ int nb = 2;
+
+ if (nb > index) {
+ nb = nb + index;
+ } else {
+ nb = nb - 1;
+ }
+
diff --git a/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/AMIES.json b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/AMIES.json
new file mode 100644
index 000000000..859f8bf3f
--- /dev/null
+++ b/src/java-plugin/src/main/resources/fr/cnumr/l10n/java/rules/java/AMIES.json
@@ -0,0 +1,13 @@
+{
+ "title": "Avoid multiple if-else statement",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "eco-conception"
+ ],
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidMultipleIfElseStatement.java b/src/java-plugin/src/test/files/AvoidMultipleIfElseStatement.java
new file mode 100644
index 000000000..6b06cf825
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidMultipleIfElseStatement.java
@@ -0,0 +1,38 @@
+package fr.cnumr.java.checks;
+
+class AvoidMultipleIfElseStatementCheck {
+ AvoidMultipleIfElseStatementCheck (AvoidMultipleIfElseStatementCheck mc) {
+ }
+
+ public void methodWithMultipleIfElseIf() {
+ int nb1 = 0;
+ int nb2 = 10;
+
+ if (nb1 == 1) { // Noncompliant
+ nb1 = 1;
+ } else if (nb1 == nb2) {
+ //
+ } else if (nb2 == nb1) {
+ //
+ } else {
+ //
+ }
+ nb1 = nb2;
+ }
+
+ public void methodWithMultipleIfElse() {
+ int nb1 = 0;
+ int nb2 = 10;
+
+ if (nb1 == 1) { // Noncompliant
+ nb1 = 1;
+ } else {
+ //
+ }
+ if (nb1 == 1) { // Noncompliant
+ nb1 = 1;
+ } else {
+ //
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/files/AvoidMultipleIfElseStatementNoIssue.java b/src/java-plugin/src/test/files/AvoidMultipleIfElseStatementNoIssue.java
new file mode 100644
index 000000000..89c2de6d3
--- /dev/null
+++ b/src/java-plugin/src/test/files/AvoidMultipleIfElseStatementNoIssue.java
@@ -0,0 +1,31 @@
+package fr.cnumr.java.checks;
+
+class AvoidMultipleIfElseStatementNoIssueCheck {
+ AvoidMultipleIfElseStatementNoIssueCheck (AvoidMultipleIfElseStatementNoIssueCheck mc) {
+ }
+
+ public void methodWithOneIfElseIf() {
+ int nb1 = 0;
+ int nb2 = 10;
+
+ if (nb1 == 1) {
+ nb1 = 1;
+ } else if (nb1 == nb2) {
+ //
+ } else {
+ //
+ }
+ nb1 = nb2;
+ }
+
+ public void methodWithOneIfElse() {
+ int nb1 = 0;
+ int nb2 = 10;
+
+ if (nb1 == 1) {
+ nb1 = 1;
+ } else {
+ //
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
index fb368adee..2baa3fac9 100644
--- a/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/MyJavaFileCheckRegistrarTest.java
@@ -34,7 +34,7 @@ void checkNumberRules() {
final MyJavaFileCheckRegistrar registrar = new MyJavaFileCheckRegistrar();
registrar.register(context);
- assertThat(context.checkClasses()).hasSize(18);
+ assertThat(context.checkClasses()).hasSize(19);
assertThat(context.testCheckClasses()).isEmpty();
}
}
diff --git a/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidMultipleIfElseStatementTest.java b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidMultipleIfElseStatementTest.java
new file mode 100644
index 000000000..99227ffc4
--- /dev/null
+++ b/src/java-plugin/src/test/java/fr/cnumr/java/checks/AvoidMultipleIfElseStatementTest.java
@@ -0,0 +1,20 @@
+package fr.cnumr.java.checks;
+
+import org.junit.jupiter.api.Test;
+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();
+ }
+
+
+}
From b4d0e58e46d65300df9e68dd3317b632c492d909 Mon Sep 17 00:00:00 2001
From: MP-Aubay
Date: Thu, 10 Nov 2022 14:19:03 +0100
Subject: [PATCH 113/119] Fix some Sonar Bugs and code smell (#141)
* fix sonar issues and clean up
* feat - Taking review in account
---
.gitignore | 2 +-
README.md | 2 +-
src/.gitignore | 1 +
.../java/checks/batch/JobCoalesceRule.java | 18 +--
.../java/checks/batch/SensorCoalesceRule.java | 17 +--
.../UncompressedDataTransmissionRule.java | 28 ++--
...ava => CheckArgumentComplexTypeUtils.java} | 5 +-
.../helpers/ConstructorBeforeMethodCheck.java | 2 +-
.../java/checks/helpers/TreeHelper.java | 123 +++++++++++++-----
.../constant/ArgumentValueOnMethodCheck.java | 4 +-
.../checks/idleness/KeepVoiceAwakeRule.java | 20 ++-
.../checks/power/ChargeAwarenessRule.java | 37 ++++--
.../checks/power/SaveModeAwarenessRule.java | 36 ++---
.../checks/sobriety/HighFrameRateRule.java | 4 +-
.../ThriftyGeolocationCriteriaRule.java | 43 +++---
.../ThriftyGeolocationMinDistanceRule.java | 32 +++--
.../ThriftyGeolocationMinTimeRule.java | 32 +++--
.../checks/sobriety/VibrationFreeRule.java | 10 +-
.../checks/helpers/CheckPermissionsRule.java | 2 +-
.../checks/power/ChargeAwarenessXmlRule.java | 3 +-
.../ecocode/java/JavaEcoCodeProfileTest.java | 2 +-
.../io/ecocode/xml/XmlEcoCodeProfileTest.java | 2 +-
.../java/checks/AvoidSQLRequestInLoop.java | 58 ++++-----
.../fr/cnumr/java/checks/IncrementCheck.java | 1 -
.../NoFunctionCallWhenDeclaringForLoop.java | 122 ++++++++---------
.../UnnecessarilyAssignValuesToVariables.java | 6 +-
.../cnumr/java/MyJavaRulesDefinitionTest.java | 1 -
...idSpringRepositoryCallInLoopCheckTest.java | 2 +-
...oFunctionCallWhenDeclaringForLoopTest.java | 2 +-
.../php/checks/AvoidDoubleQuoteCheck.java | 5 +-
.../php/checks/AvoidFullSQLRequestCheck.java | 4 +-
.../checks/AvoidSQLRequestInLoopCheck.java | 101 +++++++-------
.../NoFunctionCallWhenDeclaringForLoop.java | 4 +-
.../python/checks/AvoidFullSQLRequest.java | 9 +-
.../AvoidGlobalVariableInFunctionCheck.java | 63 +++++++--
.../checks/AvoidTryCatchFinallyCheck.java | 2 -
.../NoFunctionCallWhenDeclaringForLoop.java | 4 -
37 files changed, 453 insertions(+), 356 deletions(-)
rename src/android-plugin/src/main/java/io/ecocode/java/checks/helpers/{CheckArgumentComplexType.java => CheckArgumentComplexTypeUtils.java} (95%)
diff --git a/.gitignore b/.gitignore
index 4572288da..7513da233 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,4 +26,4 @@ buildNumber.properties
.settings/
# IntelliJ IDEA settings
-.idea/
\ No newline at end of file
+.idea
\ No newline at end of file
diff --git a/README.md b/README.md
index 5a954c133..766e86078 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
---
-*ecoCode* is a collective project aiming at the reduction the environmental footprint of software at the code level. The goal of the project is to provide a list of static code analyzers to highlight code structures that may have a negative ecological impact: energy and resources over-consumption, "fatware", shortening terminals' lifespan, etc.
+*ecoCode* is a collective project aiming to reduce environmental footprint of software at the code level. The goal of the project is to provide a list of static code analyzers to highlight code structures that may have a negative ecological impact: energy and resources over-consumption, "fatware", shortening terminals' lifespan, etc.
ecoCode is based on evolving catalogs of [good practices](docs/rules), for various technologies. A SonarQube plugin then implement these catalogs as rules for scanning your projects.
diff --git a/src/.gitignore b/src/.gitignore
index f7a6afc7f..52789d918 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -6,3 +6,4 @@ target/
node/
*.iml
/lib/*.jar
+bin
\ No newline at end of file
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/JobCoalesceRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/JobCoalesceRule.java
index 7e9aae3e7..553135ccb 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/JobCoalesceRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/JobCoalesceRule.java
@@ -35,16 +35,18 @@
*/
@Rule(key = "EBAT003", name = "ecocodeJobCoalesce")
public class JobCoalesceRule extends IssuableSubscriptionVisitor {
+
+ private static final String ALARM_MANAGER_CLASS = "android.app.AlarmManager";
private final MethodMatchers alarmSchedulerMethodMatcher = MethodMatchers.or(
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("set").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setAlarmClock").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setAndAllowWhileIdle").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setExact").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setExactAndAllowWhileIdle").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setInexactRepeating").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setRepeating").withAnyParameters().build(),
- MethodMatchers.create().ofTypes("android.app.AlarmManager").names("setWindow").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("set").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setAlarmClock").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setAndAllowWhileIdle").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setExact").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setExactAndAllowWhileIdle").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setInexactRepeating").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setRepeating").withAnyParameters().build(),
+ MethodMatchers.create().ofTypes(ALARM_MANAGER_CLASS).names("setWindow").withAnyParameters().build(),
//ofAnyType is used because the method is forced to be overridden in a new class expending the abstract class AbstractThreadedSyncAdapter
MethodMatchers.create().ofAnyType().names("onPerformSync").withAnyParameters().build(),
//ofSubTypes is used because the method is from an abstract class
diff --git a/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/SensorCoalesceRule.java b/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/SensorCoalesceRule.java
index 5d9777fa3..090586391 100644
--- a/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/SensorCoalesceRule.java
+++ b/src/android-plugin/src/main/java/io/ecocode/java/checks/batch/SensorCoalesceRule.java
@@ -20,7 +20,7 @@
package io.ecocode.java.checks.batch;
import com.google.common.collect.ImmutableList;
-import io.ecocode.java.checks.helpers.CheckArgumentComplexType;
+import io.ecocode.java.checks.helpers.CheckArgumentComplexTypeUtils;
import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.semantic.MethodMatchers;
@@ -30,6 +30,7 @@
import org.sonar.plugins.java.api.tree.Tree;
import java.util.List;
+import java.util.Optional;
/**
* Check the call of the method "registerListener" of "android.hardware.SensorManager" with 4 parameters (the 4th one being the latency).
@@ -53,10 +54,9 @@ public List nodesToVisit() {
public void visitNode(Tree tree) {
if (tree.is(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree mit = (MethodInvocationTree) tree;
- if (sensorListenerMethodMatcher.matches(mit)) {
- if (!isFourthArgumentPositiveNumber(mit.arguments())) {
- reportIssue(mit, "Prefer using a reported latency on your SensorManager to reduce the power consumption of the app");
- }
+ if (sensorListenerMethodMatcher.matches(mit)
+ && !isFourthArgumentPositiveNumber(mit.arguments())) {
+ reportIssue(mit, "Prefer using a reported latency on your SensorManager to reduce the power consumption of the app");
}
}
}
@@ -74,13 +74,14 @@ private boolean isFourthArgumentPositiveNumber(Arguments arguments) {
ExpressionTree thirdArgument = arguments.get(3);
//Check 4th argument is a complex type (that needs to be managed)
while (thirdArgument.is(Tree.Kind.TYPE_CAST, Tree.Kind.MEMBER_SELECT, Tree.Kind.PARENTHESIZED_EXPRESSION)) {
- thirdArgument = (ExpressionTree) CheckArgumentComplexType.getChildExpression(thirdArgument);
+ thirdArgument = (ExpressionTree) CheckArgumentComplexTypeUtils.getChildExpression(thirdArgument);
}
- return thirdArgument.asConstant().isPresent()
+ Optional
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-bundle
- package
-
- copy
-
-
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- jar
- true
-
-
- ../lib
-
-
-
-
-
org.apache.maven.pluginsmaven-compiler-plugin
@@ -302,12 +276,31 @@
-
org.apache.maven.pluginsmaven-dependency-plugin2.10
+
+ copy-bundle
+ package
+
+ copy
+
+
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ jar
+ true
+
+
+ ../lib
+
+
+
copytest-compile
diff --git a/src/java-plugin/pom.xml b/src/java-plugin/pom.xml
index a63ad3b67..535a10fa0 100644
--- a/src/java-plugin/pom.xml
+++ b/src/java-plugin/pom.xml
@@ -86,31 +86,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-bundle
- package
-
- copy
-
-
-
-
- ${project.groupId}
- ${project.artifactId}
- ${project.version}
- jar
- true
-
-
- ../lib
-
-
-
- org.jacoco
@@ -132,16 +107,35 @@
-
org.apache.maven.pluginsmaven-dependency-plugin
+
+ copy-bundle
+ package
+
+ copy
+
+
+
+
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ jar
+ true
+
+
+ ../lib
+
+
+
copytest-compile
- copy
+ copy
diff --git a/src/php-plugin/pom.xml b/src/php-plugin/pom.xml
index 55c0832c6..2efa1b78f 100644
--- a/src/php-plugin/pom.xml
+++ b/src/php-plugin/pom.xml
@@ -55,7 +55,7 @@
copy-bundlepackage
- copy
+ copy
From 0ad827163c973a0deb701752c6249a88b6298d88 Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 9 Nov 2022 12:18:11 +0100
Subject: [PATCH 118/119] correction maven warn : duplicated dependency
---
src/android-plugin/pom.xml | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/android-plugin/pom.xml b/src/android-plugin/pom.xml
index ee87c568c..f1cb6ff4a 100644
--- a/src/android-plugin/pom.xml
+++ b/src/android-plugin/pom.xml
@@ -109,12 +109,6 @@
test
-
- commons-lang
- commons-lang
- 2.6
-
-
com.google.guavaguava
From 0996ae505a83fb452f17e6eb9f9382dfc0307fda Mon Sep 17 00:00:00 2001
From: dedece35
Date: Wed, 9 Nov 2022 12:19:27 +0100
Subject: [PATCH 119/119] correction maven warn : dependency-plugin without
version + delete useless 'java.version' block
---
src/pom.xml | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/pom.xml b/src/pom.xml
index 7cf401cd8..40822e5c8 100644
--- a/src/pom.xml
+++ b/src/pom.xml
@@ -186,12 +186,8 @@
org.apache.maven.plugins
- maven-compiler-plugin
- 3.10.1
-
-
- ${java.version}
-
+ maven-dependency-plugin
+ 3.3.0