diff --git a/backend/core/src/main/java/org/sonarsource/sonarlint/core/analysis/AnalysisService.java b/backend/core/src/main/java/org/sonarsource/sonarlint/core/analysis/AnalysisService.java index 7e58f7313a..c975dd3f89 100644 --- a/backend/core/src/main/java/org/sonarsource/sonarlint/core/analysis/AnalysisService.java +++ b/backend/core/src/main/java/org/sonarsource/sonarlint/core/analysis/AnalysisService.java @@ -418,18 +418,16 @@ private ServerActiveRule tryConvertDeprecatedKeys(String connectionId, ServerAct var ruleKeyPossiblyWithDeprecatedRepo = RuleKey.parse(possiblyDeprecatedActiveRuleFromStorage.getRuleKey()); var templateRuleKeyWithCorrectRepo = RuleKey.parse(ruleOrTemplateDefinition.getKey()); var ruleKey = new RuleKey(templateRuleKeyWithCorrectRepo.repository(), ruleKeyPossiblyWithDeprecatedRepo.rule()).toString(); - //TODO Replace empty list with proper one. return new ServerActiveRule(ruleKey, possiblyDeprecatedActiveRuleFromStorage.getSeverity(), possiblyDeprecatedActiveRuleFromStorage.getParams(), - ruleOrTemplateDefinition.getKey(), Collections.emptyList()); + ruleOrTemplateDefinition.getKey(), possiblyDeprecatedActiveRuleFromStorage.getOverriddenImpacts()); } else { ruleOrTemplateDefinition = rulesRepository.getRule(connectionId, possiblyDeprecatedActiveRuleFromStorage.getRuleKey()).orElse(null); if (ruleOrTemplateDefinition == null) { // The rule is not known among our loaded analyzers, so return it untouched, to let calling code take appropriate decision return possiblyDeprecatedActiveRuleFromStorage; } - //TODO Replace empty list with proper one. return new ServerActiveRule(ruleOrTemplateDefinition.getKey(), possiblyDeprecatedActiveRuleFromStorage.getSeverity(), possiblyDeprecatedActiveRuleFromStorage.getParams(), - null, Collections.emptyList()); + null, possiblyDeprecatedActiveRuleFromStorage.getOverriddenImpacts()); } } diff --git a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetails.java b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetails.java index 5793b5c619..99864e09c0 100644 --- a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetails.java +++ b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetails.java @@ -39,6 +39,7 @@ import org.sonarsource.sonarlint.core.commons.SoftwareQuality; import org.sonarsource.sonarlint.core.rule.extractor.SonarLintRuleDefinition; import org.sonarsource.sonarlint.core.rule.extractor.SonarLintRuleParamDefinition; +import org.sonarsource.sonarlint.core.serverapi.push.parsing.common.ImpactPayload; import org.sonarsource.sonarlint.core.serverapi.rules.ServerActiveRule; import org.sonarsource.sonarlint.core.serverapi.rules.ServerRule; @@ -54,14 +55,14 @@ public class RuleDetails { private final IssueSeverity defaultSeverity; private final RuleType type; private final CleanCodeAttribute cleanCodeAttribute; - private final Map defaultImpacts; + private final Map impacts; private final Collection params; private final String extendedDescription; private final Set educationPrincipleKeys; private final VulnerabilityProbability vulnerabilityProbability; public RuleDetails(String key, SonarLanguage language, String name, String htmlDescription, Map> descriptionSectionsByKey, - IssueSeverity defaultSeverity, RuleType type, @Nullable CleanCodeAttribute cleanCodeAttribute, Map defaultImpacts, + IssueSeverity defaultSeverity, RuleType type, @Nullable CleanCodeAttribute cleanCodeAttribute, Map impacts, @Nullable String extendedDescription, Collection params, Set educationPrincipleKeys, @Nullable VulnerabilityProbability vulnerabilityProbability) { this.key = key; @@ -72,7 +73,7 @@ public RuleDetails(String key, SonarLanguage language, String name, String htmlD this.defaultSeverity = defaultSeverity; this.type = type; this.cleanCodeAttribute = cleanCodeAttribute; - this.defaultImpacts = defaultImpacts; + this.impacts = impacts; this.params = params; this.extendedDescription = extendedDescription; this.educationPrincipleKeys = educationPrincipleKeys; @@ -147,11 +148,22 @@ public static RuleDetails merging(ServerActiveRule activeRuleFromStorage, Server serverRule.getSeverity(), templateRuleDefFromPlugin.getType(), cleanCodeAttribute, - defaultImpacts, + mergeImpacts(defaultImpacts, activeRuleFromStorage.getOverriddenImpacts()), serverRule.getHtmlNote(), Collections.emptyList(), templateRuleDefFromPlugin.getEducationPrincipleKeys(), templateRuleDefFromPlugin.getVulnerabilityProbability().orElse(null)); } + public static Map mergeImpacts(Map defaultImpacts, List overriddenImpacts) { + if (overriddenImpacts != null && !overriddenImpacts.isEmpty()) { + return overriddenImpacts.stream() + .collect(Collectors.toMap( + impact -> SoftwareQuality.valueOf(impact.getSoftwareQuality()), + impact -> ImpactSeverity.valueOf(impact.getSeverity()) + )); + } + return defaultImpacts; + } + public String getKey() { return key; } @@ -192,8 +204,8 @@ public Optional getCleanCodeAttribute() { return Optional.ofNullable(cleanCodeAttribute); } - public Map getDefaultImpacts() { - return defaultImpacts; + public Map getImpacts() { + return impacts; } public Collection getParams() { diff --git a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetailsAdapter.java b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetailsAdapter.java index 29d53ad5dd..081a0c1bc4 100644 --- a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetailsAdapter.java +++ b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RuleDetailsAdapter.java @@ -37,12 +37,6 @@ import org.sonarsource.sonarlint.core.analysis.api.TextEdit; import org.sonarsource.sonarlint.core.commons.RuleType; import org.sonarsource.sonarlint.core.commons.api.SonarLanguage; -import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.FileEditDto; -import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.IssueFlowDto; -import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.IssueLocationDto; -import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.QuickFixDto; -import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.TextEditDto; -import org.sonarsource.sonarlint.core.rpc.protocol.common.Either; import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.EffectiveRuleDetailsDto; import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.EffectiveRuleParamDto; import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.ImpactDto; @@ -53,8 +47,14 @@ import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.RuleNonContextualSectionDto; import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.RuleSplitDescriptionDto; import org.sonarsource.sonarlint.core.rpc.protocol.backend.rules.VulnerabilityProbability; +import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.FileEditDto; +import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.IssueFlowDto; +import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.IssueLocationDto; +import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.QuickFixDto; +import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.TextEditDto; import org.sonarsource.sonarlint.core.rpc.protocol.common.CleanCodeAttribute; import org.sonarsource.sonarlint.core.rpc.protocol.common.CleanCodeAttributeCategory; +import org.sonarsource.sonarlint.core.rpc.protocol.common.Either; import org.sonarsource.sonarlint.core.rpc.protocol.common.ImpactSeverity; import org.sonarsource.sonarlint.core.rpc.protocol.common.IssueSeverity; import org.sonarsource.sonarlint.core.rpc.protocol.common.Language; @@ -85,7 +85,7 @@ public static EffectiveRuleDetailsDto transform(RuleDetails ruleDetails, @Nullab adapt(ruleDetails.getType()), ruleDetails.getCleanCodeAttribute().map(RuleDetailsAdapter::adapt).orElse(null), ruleDetails.getCleanCodeAttribute().map(org.sonarsource.sonarlint.core.commons.CleanCodeAttribute::getAttributeCategory).map(RuleDetailsAdapter::adapt).orElse(null), - toDto(ruleDetails.getDefaultImpacts()), + toDto(ruleDetails.getImpacts()), transformDescriptions(ruleDetails, contextKey), transform(ruleDetails.getParams()), adapt(ruleDetails.getLanguage()), diff --git a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RulesService.java b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RulesService.java index 830fa58714..bc4c67c1a7 100644 --- a/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RulesService.java +++ b/backend/core/src/main/java/org/sonarsource/sonarlint/core/rules/RulesService.java @@ -230,19 +230,17 @@ private ServerActiveRule tryConvertDeprecatedKeys(ServerActiveRule possiblyDepre var ruleKeyPossiblyWithDeprecatedRepo = RuleKey.parse(possiblyDeprecatedActiveRuleFromStorage.getRuleKey()); var templateRuleKeyWithCorrectRepo = RuleKey.parse(ruleOrTemplateDefinition.get().getKey()); var ruleKey = new RuleKey(templateRuleKeyWithCorrectRepo.repository(), ruleKeyPossiblyWithDeprecatedRepo.rule()).toString(); - //TODO Replace empty list with proper one. return new ServerActiveRule(ruleKey, possiblyDeprecatedActiveRuleFromStorage.getSeverity(), possiblyDeprecatedActiveRuleFromStorage.getParams(), - ruleOrTemplateDefinition.get().getKey(), Collections.emptyList()); + ruleOrTemplateDefinition.get().getKey(), possiblyDeprecatedActiveRuleFromStorage.getOverriddenImpacts()); } else { ruleOrTemplateDefinition = rulesRepository.getRule(connectionId, possiblyDeprecatedActiveRuleFromStorage.getRuleKey()); if (ruleOrTemplateDefinition.isEmpty()) { // The rule is not known among our loaded analyzers, so return it untouched, to let calling code take appropriate decision return possiblyDeprecatedActiveRuleFromStorage; } - //TODO Replace empty list with proper one. return new ServerActiveRule(ruleOrTemplateDefinition.get().getKey(), possiblyDeprecatedActiveRuleFromStorage.getSeverity(), possiblyDeprecatedActiveRuleFromStorage.getParams(), - null, Collections.emptyList()); + null, possiblyDeprecatedActiveRuleFromStorage.getOverriddenImpacts()); } } @@ -425,7 +423,8 @@ public RuleDetailsForAnalysis getRuleDetailsForConnectedAnalysis(Binding binding } var ruleDefinition = ruleDefinitionOpt.get(); return new RuleDetailsForAnalysis(activeRule.getSeverity(), ruleDefinition.getType(), - ruleDefinition.getCleanCodeAttribute().orElse(CONVENTIONAL), ruleDefinition.getDefaultImpacts(), + ruleDefinition.getCleanCodeAttribute().orElse(CONVENTIONAL), + RuleDetails.mergeImpacts(ruleDefinition.getDefaultImpacts(), activeRule.getOverriddenImpacts()), ruleDefinition.getVulnerabilityProbability().orElse(null)); } diff --git a/backend/server-api/src/main/java/org/sonarsource/sonarlint/core/serverapi/rules/RulesApi.java b/backend/server-api/src/main/java/org/sonarsource/sonarlint/core/serverapi/rules/RulesApi.java index 8248dfecb5..d15b52b96d 100644 --- a/backend/server-api/src/main/java/org/sonarsource/sonarlint/core/serverapi/rules/RulesApi.java +++ b/backend/server-api/src/main/java/org/sonarsource/sonarlint/core/serverapi/rules/RulesApi.java @@ -29,6 +29,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.sonarsource.sonarlint.core.commons.CleanCodeAttribute; import org.sonarsource.sonarlint.core.commons.ImpactSeverity; import org.sonarsource.sonarlint.core.commons.IssueSeverity; @@ -40,6 +41,7 @@ import org.sonarsource.sonarlint.core.serverapi.ServerApiHelper; import org.sonarsource.sonarlint.core.serverapi.UrlUtils; import org.sonarsource.sonarlint.core.serverapi.proto.sonarqube.ws.Rules; +import org.sonarsource.sonarlint.core.serverapi.push.parsing.common.ImpactPayload; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; @@ -120,8 +122,9 @@ public Collection getAllActiveRules(String qualityProfileKey, IssueSeverity.valueOf(ar.getSeverity()), ar.getParamsList().stream().collect(toMap(Rules.Active.Param::getKey, Rules.Active.Param::getValue)), ruleTemplatesByRuleKey.get(ruleKey), - //TODO Pass the right value - Collections.emptyList())); + ar.getImpacts().getImpactsList().stream() + .map(impact -> new ImpactPayload(impact.getSoftwareQuality().toString(), impact.getSeverity().name())) + .collect(Collectors.toList()))); }, false, diff --git a/backend/server-api/src/main/proto/sonarqube/ws-rules.proto b/backend/server-api/src/main/proto/sonarqube/ws-rules.proto index a44c2429a3..04606ee1e3 100644 --- a/backend/server-api/src/main/proto/sonarqube/ws-rules.proto +++ b/backend/server-api/src/main/proto/sonarqube/ws-rules.proto @@ -95,9 +95,14 @@ message Active { optional string qProfile = 1; optional string severity = 3; repeated Param params = 5; + optional Impacts impacts = 9; message Param { optional string key = 1; optional string value = 2; } + + message Impacts{ + repeated sonarqube.ws.commons.Impact impacts = 1; + } }