Skip to content

Commit 6b6c8b1

Browse files
JAVASE-6 Restrict registration of S2259 to SQ Community Build
Restrict the loading of java:S2259 to SQCB to enable other plugins to provide an implementation S2259 for Java. Because the other plugin might declare java:S2259 as deprecated, the products might not be able to load a set of rules where java:S2259 is both implemented and deprecated. To avoid any further ambiguity, S2259 is now removed from the default quality profile.
1 parent b050a45 commit 6b6c8b1

File tree

8 files changed

+80
-9
lines changed

8 files changed

+80
-9
lines changed

its/ruling/src/test/java/org/sonar/java/it/JavaRulingTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static void prepare() throws Exception {
9696
List<String> extraNonDefaultRules = List.of("S3546", "S6374");
9797
ProfileGenerator.generate(ORCHESTRATOR, "Sonar Way", ImmutableMap.of(), new HashSet<>(), SUBSET_OF_ENABLED_RULES, result,
9898
extraNonDefaultRules);
99-
assertThat(result).hasSize(23); // ALL symbolic-execution rules
99+
assertThat(result).hasSize(22); // ALL symbolic-execution rules minus S2259 that has been deprecated
100100

101101
Path allRulesFolder = Paths.get("src/test/resources");
102102
effectiveDumpOldFolder = tmpDumpOldFolder.getRoot().toPath().toAbsolutePath();

java-symbolic-execution/java-symbolic-execution-plugin/src/main/java/org/sonar/java/se/plugin/JavaSECheckList.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package org.sonar.java.se.plugin;
1818

1919
import java.util.List;
20+
import java.util.Set;
21+
import java.util.function.Predicate;
2022
import org.sonar.java.se.checks.AllowXMLInclusionCheck;
2123
import org.sonar.java.se.checks.BooleanGratuitousExpressionsCheck;
2224
import org.sonar.java.se.checks.ConditionalUnreachableCodeCheck;
@@ -43,12 +45,24 @@
4345
import org.sonar.java.se.checks.XxeProcessingCheck;
4446

4547
public class JavaSECheckList {
48+
/**
49+
* A list of checks that can be overridden by other analyzers.
50+
*/
51+
public static final Set<Class<? extends SECheck>> OVERRIDABLE_CHECKS = Set.of(
52+
NullDereferenceCheck.class // S2259
53+
);
4654

4755
private JavaSECheckList(){
4856
// no need to instantiate
4957
}
5058

5159
public static List<Class<? extends SECheck>> getChecks() {
60+
return getStandaloneChecks().stream()
61+
.filter(Predicate.not(OVERRIDABLE_CHECKS::contains))
62+
.toList();
63+
}
64+
65+
public static List<Class<? extends SECheck>> getStandaloneChecks() {
5266
return List.of(
5367
// SEChecks ordered by ExplodedGraphWalker need
5468
NullDereferenceCheck.class,

java-symbolic-execution/java-symbolic-execution-plugin/src/main/java/org/sonar/java/se/plugin/JavaSECheckRegistrar.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@
1717
package org.sonar.java.se.plugin;
1818

1919
import java.util.ArrayList;
20+
import java.util.List;
2021
import java.util.Set;
22+
import org.sonar.api.SonarEdition;
23+
import org.sonar.api.SonarProduct;
2124
import org.sonar.api.SonarRuntime;
2225
import org.sonar.api.batch.rule.CheckFactory;
2326
import org.sonar.api.batch.rule.Checks;
2427
import org.sonar.api.ce.ComputeEngineSide;
2528
import org.sonar.api.scanner.ScannerSide;
2629
import org.sonar.api.server.ServerSide;
2730
import org.sonar.api.server.rule.RulesDefinition;
31+
import org.sonar.java.annotations.VisibleForTesting;
2832
import org.sonar.java.se.SymbolicExecutionVisitor;
2933
import org.sonar.java.se.checks.SECheck;
3034
import org.sonar.plugins.java.api.CheckRegistrar;
@@ -54,7 +58,7 @@ public void register(RegistrarContext registrarContext) {
5458

5559
@Override
5660
public void register(RegistrarContext registrarContext, CheckFactory checkFactory) {
57-
Checks<JavaCheck> checks = checkFactory.<JavaCheck>create(REPOSITORY_KEY).addAnnotatedChecks(JavaSECheckList.getChecks());
61+
Checks<JavaCheck> checks = checkFactory.<JavaCheck>create(REPOSITORY_KEY).addAnnotatedChecks(getChecks(runtime));
5862

5963
var seChecks = checks.all().stream()
6064
.filter(SECheck.class::isInstance)
@@ -71,11 +75,26 @@ public void register(RegistrarContext registrarContext, CheckFactory checkFactor
7175
public void customRulesDefinition(RulesDefinition.Context context, RulesDefinition.NewRepository javaRepository) {
7276
RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, SONAR_WAY_PATH, runtime);
7377

74-
ruleMetadataLoader.addRulesByAnnotatedClass(javaRepository, new ArrayList<>(JavaSECheckList.getChecks()));
78+
ruleMetadataLoader.addRulesByAnnotatedClass(javaRepository, new ArrayList<>(getChecks(runtime)));
7579

7680
setTemplates(javaRepository);
7781
}
7882

83+
@VisibleForTesting
84+
static List<Class<? extends SECheck>> getChecks(SonarRuntime runtime) {
85+
if (isStandaloneSymbolicExecutionPlugin(runtime)) {
86+
return JavaSECheckList.getStandaloneChecks();
87+
}
88+
return JavaSECheckList.getChecks();
89+
}
90+
91+
@VisibleForTesting
92+
static boolean isStandaloneSymbolicExecutionPlugin(SonarRuntime runtime) {
93+
return runtime != null &&
94+
runtime.getProduct() != SonarProduct.SONARLINT &&
95+
runtime.getEdition() == SonarEdition.COMMUNITY;
96+
}
97+
7998
private static void setTemplates(RulesDefinition.NewRepository repository) {
8099
RULE_TEMPLATES_KEY.forEach(ruleKey -> repository.rule(ruleKey).setTemplate(true));
81100
}

java-symbolic-execution/java-symbolic-execution-plugin/src/main/java/org/sonar/java/se/plugin/JavaSEProfileRegistrar.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.sonar.java.se.plugin;
1818

19+
import javax.annotation.Nullable;
1920
import org.sonar.plugins.java.api.ProfileRegistrar;
2021

2122
public class JavaSEProfileRegistrar implements ProfileRegistrar {
@@ -24,4 +25,9 @@ public class JavaSEProfileRegistrar implements ProfileRegistrar {
2425
public void register(RegistrarContext registrarContext) {
2526
registrarContext.registerDefaultQualityProfileRules(RulesList.getSonarWayRuleKeys());
2627
}
28+
29+
30+
String trigger_S2259(@Nullable Object parameter) {
31+
return parameter.toString();
32+
}
2733
}

java-symbolic-execution/java-symbolic-execution-plugin/src/main/java/org/sonar/java/se/plugin/RulesList.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public static List<RuleKey> getSonarWayRuleKeys() {
2929
"S2095",
3030
"S2189",
3131
"S2222",
32-
"S2259",
3332
"S2583",
3433
"S2589",
3534
"S2637",

java-symbolic-execution/java-symbolic-execution-plugin/src/test/java/org/sonar/java/se/plugin/JavaSECheckListTest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@
2323
class JavaSECheckListTest {
2424

2525
@Test
26-
void getChecks() {
27-
assertThat(JavaSECheckList.getChecks()).isNotNull().hasSize(23);
26+
void getChecks_returns_the_list_of_checks_that_cannot_be_overridden_by_other_plugins() {
27+
assertThat(JavaSECheckList.getChecks())
28+
.hasSize(22)
29+
.doesNotContainAnyElementsOf(JavaSECheckList.OVERRIDABLE_CHECKS);
30+
}
31+
32+
@Test
33+
void getStandaloneChecks_returns_the_full_list_of_checks() {
34+
assertThat(JavaSECheckList.getStandaloneChecks())
35+
.hasSize(23);
2836
}
2937

3038
}

java-symbolic-execution/java-symbolic-execution-plugin/src/test/java/org/sonar/java/se/plugin/JavaSECheckRegistrarTest.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,32 @@ void register_rules() {
6666
assertThat(context.testRuleKeys).isEmpty();
6767
}
6868

69+
@Test
70+
void is_only_in_standalone_mode_in_sqcb() {
71+
var sonarQubeCloud = SonarRuntimeImpl.forSonarQube(
72+
Version.parse("8.1"),
73+
SonarQubeSide.SERVER,
74+
SonarEdition.SONARCLOUD
75+
);
76+
assertThat(JavaSECheckRegistrar.isStandaloneSymbolicExecutionPlugin(sonarQubeCloud)).isFalse();
77+
var sonarQubeCommunityBuild = SonarRuntimeImpl.forSonarQube(
78+
Version.parse("25.1"),
79+
SonarQubeSide.SERVER,
80+
SonarEdition.COMMUNITY
81+
);
82+
assertThat(JavaSECheckRegistrar.isStandaloneSymbolicExecutionPlugin(sonarQubeCommunityBuild)).isTrue();
83+
var sonarQubeServerDeveloper = SonarRuntimeImpl.forSonarQube(
84+
Version.parse("2025.1"),
85+
SonarQubeSide.SERVER,
86+
SonarEdition.DEVELOPER
87+
);
88+
assertThat(JavaSECheckRegistrar.isStandaloneSymbolicExecutionPlugin(sonarQubeServerDeveloper)).isFalse();
89+
90+
var sonarQubeForIDE = SonarRuntimeImpl.forSonarLint(Version.parse("10.22.0.81232"));
91+
assertThat(JavaSECheckRegistrar.isStandaloneSymbolicExecutionPlugin(sonarQubeForIDE)).isFalse();
92+
}
93+
94+
6995
@Test
7096
void rules_definition() {
7197
SonarRuntime sonarRuntime = SonarRuntimeImpl.forSonarQube(Version.create(10, 2), SonarQubeSide.SERVER, SonarEdition.ENTERPRISE);
@@ -85,7 +111,7 @@ void rules_definition() {
85111
assertThat(repository.name()).isEqualTo("Sonar");
86112
assertThat(repository.language()).isEqualTo("java");
87113
List<RulesDefinition.Rule> rules = repository.rules();
88-
assertThat(rules).hasSize(23);
114+
assertThat(rules).hasSize(22);
89115

90116
var activeByDefault = rules.stream()
91117
.filter(k -> !rulesNotActiveByDefault.contains(k.key()))

java-symbolic-execution/java-symbolic-execution-plugin/src/test/java/org/sonar/java/se/plugin/JavaSEProfileRegistrarTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ void constructor() {
2828
JavaSEProfileRegistrar registrar = new JavaSEProfileRegistrar();
2929
TestProfileRegistrarContext context = new TestProfileRegistrarContext();
3030
registrar.register(context);
31-
assertThat(context.defaultQualityProfileRules).hasSize(21); // 2 are not in the default profile
31+
assertThat(context.defaultQualityProfileRules).hasSize(20); // 3 are not in the default profile
3232
}
33-
3433
}

0 commit comments

Comments
 (0)