Skip to content

Commit

Permalink
feat: abstract ruletype enum with IRuleType (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinWitt authored Mar 25, 2022
1 parent 19edf5a commit 59667b5
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 27 deletions.
13 changes: 11 additions & 2 deletions src/main/java/sorald/cli/MineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
import sorald.event.collectors.MinerStatisticsCollector;
import sorald.event.models.ExecutionInfo;
import sorald.miner.MineSonarWarnings;
import sorald.rule.IRuleType;
import sorald.rule.Rule;
import sorald.rule.RuleType;
import sorald.rule.Rules;
import sorald.sonar.SonarRuleType;
import sorald.util.MavenUtils;

/** CLI Command for Sorald's mining functionality. */
Expand Down Expand Up @@ -49,10 +50,11 @@ class MineCommand extends BaseCommand {

@CommandLine.Option(
names = {Constants.ARG_RULE_TYPES},
converter = IRuleTypeConverter.class,
description =
"One or more types of rules to check for (use ',' to separate multiple types). Choices: ${COMPLETION-CANDIDATES}",
split = ",")
private List<RuleType> ruleTypes = new ArrayList<>();
private List<IRuleType> ruleTypes = new ArrayList<>();

@CommandLine.Option(
names = {Constants.ARG_HANDLED_RULES},
Expand Down Expand Up @@ -111,4 +113,11 @@ private void validateArgs() {
Constants.ARG_RESOLVE_CLASSPATH_FROM, source));
}
}

private static class IRuleTypeConverter implements CommandLine.ITypeConverter<IRuleType> {
@Override
public IRuleType convert(String value) {
return SonarRuleType.valueOf(value.toUpperCase());
}
}
}
10 changes: 10 additions & 0 deletions src/main/java/sorald/rule/IRuleType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package sorald.rule;

public interface IRuleType {

/**
* Returns the name of the rule type. A rule type is a category of rules, such as "Bug",
* "Vulnerability".
*/
String getName();
}
2 changes: 1 addition & 1 deletion src/main/java/sorald/rule/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface Rule {
String getName();

/** @return The type of this rule. */
RuleType getType();
IRuleType getType();

/**
* Create a rule based on the key.
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/sorald/rule/RuleType.java

This file was deleted.

8 changes: 4 additions & 4 deletions src/main/java/sorald/rule/Rules.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static Collection<Rule> getAllRules() {
* @param types Types to filter rules by.
* @return All rules with any of the given types.
*/
public static Collection<Rule> getRulesByType(RuleType... types) {
public static Collection<Rule> getRulesByType(IRuleType... types) {
var ruleTypes = Set.of(types);
return getAllRules().stream()
.filter(rule -> ruleTypes.contains(rule.getType()))
Expand All @@ -40,15 +40,15 @@ public static Collection<Rule> getRulesByType(RuleType... types) {
* @param types Types to filter rules by.
* @return All rules with any of the given types.
*/
public static Collection<Rule> getRulesByType(Collection<RuleType> types) {
return getRulesByType(types.toArray(RuleType[]::new));
public static Collection<Rule> getRulesByType(Collection<IRuleType> types) {
return getRulesByType(types.toArray(IRuleType[]::new));
}

/**
* Infer which rules to use based on rule types specified (or left unspecified) on the command
* line.
*/
public static List<Rule> inferRules(List<RuleType> ruleTypes, boolean handledRules) {
public static List<Rule> inferRules(List<IRuleType> ruleTypes, boolean handledRules) {
List<Rule> rules =
List.copyOf(
ruleTypes.isEmpty()
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/sorald/sonar/SonarRule.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import java.util.Objects;
import org.sonarsource.sonarlint.core.rule.extractor.SonarLintRuleDefinition;
import sorald.rule.IRuleType;
import sorald.rule.Rule;
import sorald.rule.RuleType;

public class SonarRule implements Rule {
private final String key;
private final String name;
private final RuleType type;
private final IRuleType type;

private static final String SONAR_JAVA_PREFIX = "java:";

Expand All @@ -18,7 +18,7 @@ public SonarRule(String key) {
SonarLintRuleDefinition ruleDefinition =
SonarLintEngine.getAllRulesDefinitionsByKey().get(withLanguage(key));
this.name = ruleDefinition.getName();
this.type = RuleType.valueOf(ruleDefinition.getType());
this.type = SonarRuleType.valueOf(ruleDefinition.getType());
}

private static String withoutLanguage(String ruleKey) {
Expand Down Expand Up @@ -46,7 +46,7 @@ public String getName() {
}

@Override
public RuleType getType() {
public IRuleType getType() {
return type;
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/sorald/sonar/SonarRuleType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sorald.sonar;

import sorald.rule.IRuleType;

/** Enumeration of Sonar rule types */
public enum SonarRuleType implements IRuleType {
BUG("Bug"),
VULNERABILITY("Vulnerability"),
CODE_SMELL("Code_Smell"),
SECURITY_HOTSPOT("Security_Hotspot");

private final String name;

SonarRuleType(String name) {
this.name = name;
}

@Override
public String getName() {
return name;
}
}
7 changes: 4 additions & 3 deletions src/test/java/sorald/miner/WarningMinerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
import sorald.cli.SoraldVersionProvider;
import sorald.event.StatsMetadataKeys;
import sorald.processor.CastArithmeticOperandProcessor;
import sorald.rule.IRuleType;
import sorald.rule.Rule;
import sorald.rule.RuleType;
import sorald.rule.Rules;
import sorald.sonar.SonarRuleType;

public class WarningMinerTest {

Expand Down Expand Up @@ -83,7 +84,7 @@ public void test_onlyMineRepairableViolations() throws Exception {
*/
@Test
public void warningsMiner_onlyScansForGivenTypes_whenRuleTypesGiven() throws Exception {
Set<RuleType> ruleTypes = Set.of(RuleType.VULNERABILITY, RuleType.CODE_SMELL);
Set<IRuleType> ruleTypes = Set.of(SonarRuleType.VULNERABILITY, SonarRuleType.CODE_SMELL);

File outputFile = File.createTempFile("warnings", null);
File temp = Files.createTempDirectory("tempDir").toFile();
Expand All @@ -93,7 +94,7 @@ public void warningsMiner_onlyScansForGivenTypes_whenRuleTypesGiven() throws Exc
outputFile.getPath(),
temp.getPath(),
Constants.ARG_RULE_TYPES,
ruleTypes.stream().map(RuleType::name).collect(Collectors.joining(",")));
ruleTypes.stream().map(IRuleType::getName).collect(Collectors.joining(",")));

List<String> expectedChecks =
Rules.getRulesByType(ruleTypes).stream()
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/sorald/sonar/SonarRulesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@
import java.util.List;
import org.junit.jupiter.api.Test;
import sorald.Processors;
import sorald.rule.IRuleType;
import sorald.rule.Rule;
import sorald.rule.RuleType;
import sorald.rule.Rules;

class SonarRulesTest {
@Test
void getRulesByType_subsetOfRulesShouldHaveCorrectRuleType() {
// arrange
List<RuleType> ruleTypes = List.of(RuleType.VULNERABILITY);
List<IRuleType> ruleTypes = List.of(SonarRuleType.VULNERABILITY);

// act
Collection<Rule> rules = Rules.getRulesByType(ruleTypes);

// assert
rules.forEach(rule -> assertThat(rule.getType(), equalTo(RuleType.VULNERABILITY)));
rules.forEach(rule -> assertThat(rule.getType(), equalTo(SonarRuleType.VULNERABILITY)));
}

@Test
void inferRules_subsetOfRulesShouldHaveACorrespondingProcessor() {
// arrange
List<RuleType> ruleTypes = List.of();
List<IRuleType> ruleTypes = List.of();
boolean handledRules = true;

// act
Expand Down

0 comments on commit 59667b5

Please sign in to comment.