Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,33 @@
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameterInfo;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType;
import com.github._1c_syntax.bsl.sonar.BSLCommunityProperties;
import com.github._1c_syntax.utils.StringInterner;
import com.google.common.reflect.ClassPath;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.commonmark.ext.autolink.AutolinkExtension;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import org.sonar.api.config.Configuration;
import org.sonar.api.issue.impact.Severity;
import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.rules.CleanCodeAttribute;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
import org.springframework.core.annotation.AnnotationUtils;

import javax.annotation.CheckForNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand All @@ -58,10 +65,13 @@ public class BSLLanguageServerRuleDefinition implements RulesDefinition {

public static final String REPOSITORY_KEY = "bsl-language-server";
public static final String PARAMETERS_TAG_NAME = "parameters";
private static final String REPOSITORY_NAME = "BSL Language Server";
public static final String REPOSITORY_NAME = "BSL Language Server";

private static final Map<DiagnosticSeverity, String> SEVERITY_MAP = createDiagnosticSeverityMap();
private static final Map<DiagnosticType, RuleType> RULE_TYPE_MAP = createRuleTypeMap();
public static final Map<DiagnosticSeverity, String> OLD_SEVERITY_MAP = createOldDiagnosticSeverityMap();
public static final Map<DiagnosticType, RuleType> RULE_TYPE_MAP = createRuleTypeMap();
public static final Map<DiagnosticTag, CleanCodeAttribute> CLEAN_CODE_ATTRIBUTE_MAP = createCleanCodeAttributeMap();

public static final Map<DiagnosticTag, Pair<SoftwareQuality, Severity>> IMPACTS_MAP = createImpactsMap();

private final Configuration config;
private final Parser markdownParser;
Expand Down Expand Up @@ -124,7 +134,7 @@ private void setUpNewRule(NewRule newRule) {
.setName(diagnosticInfo.getName())
.setHtmlDescription(getHtmlDescription(diagnosticInfo.getDescription()))
.setType(RULE_TYPE_MAP.get(diagnosticInfo.getType()))
.setSeverity(SEVERITY_MAP.get(diagnosticInfo.getSeverity()))
.setSeverity(OLD_SEVERITY_MAP.get(diagnosticInfo.getSeverity())) // "старая" серьезность, на всю диагностику
.setActivatedByDefault(diagnosticInfo.isActivatedByDefault())
;

Expand All @@ -142,6 +152,19 @@ private void setUpNewRule(NewRule newRule) {
newRule.addTags(tagsName);
}

// установим атрибут clean code
// переводим теги в соответствующий атрибут, сортируем и берем первый из списка
// пока так
diagnosticInfo.getTags().stream()
.map(CLEAN_CODE_ATTRIBUTE_MAP::get)
.distinct()
.sorted()
.findFirst()
.ifPresent(newRule::setCleanCodeAttribute);

// заполним влияние
computeImpact(diagnosticInfo.getTags()).forEach(newRule::addDefaultImpact);
Comment thread
theshadowco marked this conversation as resolved.

if (diagnosticInfo.getExtraMinForComplexity() > 0) {
newRule.setDebtRemediationFunction(
newRule.debtRemediationFunctions().linearWithOffset(
Expand Down Expand Up @@ -186,6 +209,18 @@ private Language createDiagnosticLanguage() {
return Language.valueOf(diagnosticLanguageCode.toUpperCase(Locale.ENGLISH));
}

private static Map<SoftwareQuality, Severity> computeImpact(List<DiagnosticTag> tags) {
Map<SoftwareQuality, Severity> map = new HashMap<>();
tags.forEach((DiagnosticTag tag) -> {
var impact = IMPACTS_MAP.get(tag);
var value = map.get(impact.getLeft());
if (value == null || impact.getRight().compareTo(value) > 0) {
map.put(impact.getLeft(), impact.getRight());
}
});
return map;
}

@CheckForNull
private static RuleParamType getRuleParamType(Class<?> type) {

Expand All @@ -206,15 +241,15 @@ private static RuleParamType getRuleParamType(Class<?> type) {
return ruleParamType;
}

private static Map<DiagnosticSeverity, String> createDiagnosticSeverityMap() {
private static Map<DiagnosticSeverity, String> createOldDiagnosticSeverityMap() {
Map<DiagnosticSeverity, String> map = new EnumMap<>(DiagnosticSeverity.class);
map.put(DiagnosticSeverity.INFO, org.sonar.api.rule.Severity.INFO);
map.put(DiagnosticSeverity.MINOR, org.sonar.api.rule.Severity.MINOR);
map.put(DiagnosticSeverity.MAJOR, org.sonar.api.rule.Severity.MAJOR);
map.put(DiagnosticSeverity.CRITICAL, org.sonar.api.rule.Severity.CRITICAL);
map.put(DiagnosticSeverity.BLOCKER, org.sonar.api.rule.Severity.BLOCKER);

return map;
return Collections.unmodifiableMap(map);
}

private static Map<DiagnosticType, RuleType> createRuleTypeMap() {
Expand All @@ -224,7 +259,45 @@ private static Map<DiagnosticType, RuleType> createRuleTypeMap() {
map.put(DiagnosticType.VULNERABILITY, RuleType.VULNERABILITY);
map.put(DiagnosticType.SECURITY_HOTSPOT, RuleType.SECURITY_HOTSPOT);

return map;
return Collections.unmodifiableMap(map);
}

private static Map<DiagnosticTag, CleanCodeAttribute> createCleanCodeAttributeMap() {
Map<DiagnosticTag, CleanCodeAttribute> map = new EnumMap<>(DiagnosticTag.class);
map.put(DiagnosticTag.BADPRACTICE, CleanCodeAttribute.FOCUSED);
map.put(DiagnosticTag.BRAINOVERLOAD, CleanCodeAttribute.CLEAR);
map.put(DiagnosticTag.ERROR, CleanCodeAttribute.LOGICAL);
map.put(DiagnosticTag.CLUMSY, CleanCodeAttribute.CLEAR);
map.put(DiagnosticTag.DEPRECATED, CleanCodeAttribute.MODULAR);
map.put(DiagnosticTag.DESIGN, CleanCodeAttribute.MODULAR);
map.put(DiagnosticTag.LOCALIZE, CleanCodeAttribute.CONVENTIONAL);
map.put(DiagnosticTag.LOCKINOS, CleanCodeAttribute.LOGICAL);
map.put(DiagnosticTag.PERFORMANCE, CleanCodeAttribute.EFFICIENT);
map.put(DiagnosticTag.SQL, CleanCodeAttribute.EFFICIENT);
map.put(DiagnosticTag.STANDARD, CleanCodeAttribute.CONVENTIONAL);
map.put(DiagnosticTag.SUSPICIOUS, CleanCodeAttribute.LOGICAL);
map.put(DiagnosticTag.UNPREDICTABLE, CleanCodeAttribute.LOGICAL);
map.put(DiagnosticTag.UNUSED, CleanCodeAttribute.LOGICAL);
return Collections.unmodifiableMap(map);
}

private static Map<DiagnosticTag, Pair<SoftwareQuality, Severity>> createImpactsMap() {
Map<DiagnosticTag, Pair<SoftwareQuality, Severity>> map = new EnumMap<>(DiagnosticTag.class);
map.put(DiagnosticTag.BADPRACTICE, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM));
map.put(DiagnosticTag.BRAINOVERLOAD, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.LOW));
map.put(DiagnosticTag.ERROR, Pair.of(SoftwareQuality.RELIABILITY, Severity.HIGH));
map.put(DiagnosticTag.CLUMSY, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.LOW));
map.put(DiagnosticTag.DEPRECATED, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM));
map.put(DiagnosticTag.DESIGN, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM));
map.put(DiagnosticTag.LOCALIZE, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.LOW));
map.put(DiagnosticTag.LOCKINOS, Pair.of(SoftwareQuality.RELIABILITY, Severity.LOW));
map.put(DiagnosticTag.PERFORMANCE, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.MEDIUM));
map.put(DiagnosticTag.SQL, Pair.of(SoftwareQuality.RELIABILITY, Severity.HIGH));
map.put(DiagnosticTag.STANDARD, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.LOW));
map.put(DiagnosticTag.SUSPICIOUS, Pair.of(SoftwareQuality.RELIABILITY, Severity.LOW));
map.put(DiagnosticTag.UNPREDICTABLE, Pair.of(SoftwareQuality.RELIABILITY, Severity.MEDIUM));
map.put(DiagnosticTag.UNUSED, Pair.of(SoftwareQuality.MAINTAINABILITY, Severity.INFO));
return Collections.unmodifiableMap(map);
}

@SneakyThrows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
*/
package com.github._1c_syntax.bsl.sonar.language;

import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType;
import org.junit.jupiter.api.Test;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.server.rule.RulesDefinition;

import java.util.Arrays;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -63,4 +67,32 @@ void testCheckTagParameters() {
.count()
).isZero();
}

@Test
void smokyAllTags() {
var tags = Arrays.stream(DiagnosticTag.values()).toList();
assertThat(BSLLanguageServerRuleDefinition.IMPACTS_MAP.keySet())
.hasSize(tags.size())
.containsAll(tags);

assertThat(BSLLanguageServerRuleDefinition.CLEAN_CODE_ATTRIBUTE_MAP.keySet())
.hasSize(tags.size())
.containsAll(tags);
}

@Test
void smokyAllTypes() {
var types = Arrays.stream(DiagnosticType.values()).toList();
assertThat(BSLLanguageServerRuleDefinition.RULE_TYPE_MAP.keySet())
.hasSize(types.size())
.containsAll(types);
}

@Test
void smokyAllSeverity() {
var severities = Arrays.stream(DiagnosticSeverity.values()).toList();
assertThat(BSLLanguageServerRuleDefinition.OLD_SEVERITY_MAP.keySet())
.hasSize(severities.size())
.containsAll(severities);
}
}