Skip to content

Commit

Permalink
SLI-1617 Add INFO and BLOCKER impact severity levels (#1179)
Browse files Browse the repository at this point in the history
  • Loading branch information
nquinquenel authored Sep 24, 2024
1 parent 1e31670 commit 3074b14
Show file tree
Hide file tree
Showing 18 changed files with 149 additions and 52 deletions.
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
sonarlint-core = "10.6.0.79030"
sonarlint-core = "10.6.0.79033"

sonar-java = "8.1.0.36477"
sonar-javascript = "10.15.0.27423"
Expand Down
28 changes: 21 additions & 7 deletions src/main/java/org/sonarlint/intellij/SonarLintIcons.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ object SonarLintIcons {
)

private val IMPACT_ICONS = mapOf(
ImpactSeverity.BLOCKER to getIcon("/images/impact/blocker.svg"),
ImpactSeverity.HIGH to getIcon("/images/impact/high.svg"),
ImpactSeverity.MEDIUM to getIcon("/images/impact/medium.svg"),
ImpactSeverity.LOW to getIcon("/images/impact/low.svg")
ImpactSeverity.LOW to getIcon("/images/impact/low.svg"),
ImpactSeverity.INFO to getIcon("/images/impact/info.svg")
)

private val TYPE_ICONS = mapOf(
Expand All @@ -110,15 +112,27 @@ object SonarLintIcons {
)

val backgroundColorsByImpact = mapOf(
ImpactSeverity.HIGH to JBColor(Color(180, 35, 24, 20), Color(180, 35, 24, 60)),
ImpactSeverity.MEDIUM to JBColor(Color(174, 122, 41, 20), Color(174, 122, 41, 60)),
ImpactSeverity.LOW to JBColor(Color(49, 108, 146, 20), Color(49, 108, 146, 60))
ImpactSeverity.BLOCKER to JBColor(Color(254, 228, 226), Color(128, 27, 20, 20)),
ImpactSeverity.HIGH to JBColor(Color(254, 243, 242), Color(253, 162, 155, 20)),
ImpactSeverity.MEDIUM to JBColor(Color(255, 240, 235), Color(254, 150, 75, 20)),
ImpactSeverity.LOW to JBColor(Color(252, 245, 228), Color(250, 220, 121, 20)),
ImpactSeverity.INFO to JBColor(Color(245, 251, 255), Color(143, 202, 234, 20))
)

val fontColorsByImpact = mapOf(
ImpactSeverity.HIGH to JBColor(Color(128, 27, 20), Color.LIGHT_GRAY),
ImpactSeverity.MEDIUM to JBColor(Color(140, 94, 30), Color.LIGHT_GRAY),
ImpactSeverity.LOW to JBColor(Color(49, 108, 146), Color.LIGHT_GRAY)
ImpactSeverity.BLOCKER to JBColor(Color(128, 27, 20), Color(249, 112, 102)),
ImpactSeverity.HIGH to JBColor(Color(180, 35, 24), Color(253, 162, 155)),
ImpactSeverity.MEDIUM to JBColor(Color(147, 55, 13), Color(254, 150, 75)),
ImpactSeverity.LOW to JBColor(Color(140, 94, 30), Color(250, 220, 121)),
ImpactSeverity.INFO to JBColor(Color(49, 107, 146), Color(143, 202, 234))
)

val borderColorsByImpact = mapOf(
ImpactSeverity.BLOCKER to JBColor(Color(128, 27, 20), Color(249, 112, 102)),
ImpactSeverity.HIGH to JBColor(Color(217, 44, 32), Color(253, 162, 155)),
ImpactSeverity.MEDIUM to JBColor(Color(254, 150, 75), Color(254, 150, 75)),
ImpactSeverity.LOW to JBColor(Color(250, 220, 121), Color(250, 220, 121)),
ImpactSeverity.INFO to JBColor(Color(143, 202, 234), Color(143, 202, 234))
)

private fun getIcon(path: String): Icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@
import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import org.sonarlint.intellij.SonarLintIcons;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;
import javax.swing.Icon;
import org.jetbrains.annotations.NotNull;
import org.sonarlint.intellij.SonarLintIcons;

public class SonarLintColorSettingsPage implements ColorSettingsPage {
private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[] {
new AttributesDescriptor("Blocker issue", SonarLintTextAttributes.BLOCKER),
new AttributesDescriptor("High impact issue", SonarLintTextAttributes.HIGH),
new AttributesDescriptor("Medium impact issue", SonarLintTextAttributes.MEDIUM),
new AttributesDescriptor("Low impact issue", SonarLintTextAttributes.LOW),
new AttributesDescriptor("Info issue", SonarLintTextAttributes.INFO),
new AttributesDescriptor("Old issue", SonarLintTextAttributes.OLD_CODE),
new AttributesDescriptor("Selected issue", SonarLintTextAttributes.SELECTED)
};
Expand All @@ -49,17 +51,7 @@ private static class DescriptorComparator implements Comparator<AttributesDescri
}
}

private static final Map<String, TextAttributesKey> ADDITIONAL_HIGHLIGHT_DESCRIPTORS;

static {
Arrays.sort(DESCRIPTORS, new DescriptorComparator());
// sort alphabetically by key
ADDITIONAL_HIGHLIGHT_DESCRIPTORS = new TreeMap<>();

for (AttributesDescriptor desc : DESCRIPTORS) {
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put(desc.getDisplayName(), desc.getKey());
}
}
private static final Map<String, TextAttributesKey> ADDITIONAL_HIGHLIGHT_DESCRIPTORS = new TreeMap<>();

@Nullable @Override public Icon getIcon() {
return SonarLintIcons.SONARLINT;
Expand Down Expand Up @@ -88,14 +80,25 @@ private static class DescriptorComparator implements Comparator<AttributesDescri
}

@Nullable @Override public Map<String, TextAttributesKey> getAdditionalHighlightingTagToDescriptorMap() {
if (ADDITIONAL_HIGHLIGHT_DESCRIPTORS.isEmpty()) {
// sort alphabetically by key
Arrays.sort(DESCRIPTORS, new DescriptorComparator());
for (AttributesDescriptor desc : DESCRIPTORS) {
ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put(desc.getDisplayName(), desc.getKey());
}
}
return ADDITIONAL_HIGHLIGHT_DESCRIPTORS;
}

@NotNull @Override public AttributesDescriptor[] getAttributeDescriptors() {
@NotNull
@Override
public AttributesDescriptor @NotNull [] getAttributeDescriptors() {
return DESCRIPTORS;
}

@NotNull @Override public ColorDescriptor[] getColorDescriptors() {
@NotNull
@Override
public ColorDescriptor @NotNull [] getColorDescriptors() {
return ColorDescriptor.EMPTY_ARRAY;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;

public class SonarLintTextAttributes {
public static final TextAttributesKey BLOCKER;
public static final TextAttributesKey HIGH;
public static final TextAttributesKey MEDIUM;
public static final TextAttributesKey LOW;
public static final TextAttributesKey INFO;
public static final TextAttributesKey OLD_CODE;
public static final TextAttributesKey SELECTED;

Expand All @@ -39,9 +41,11 @@ public class SonarLintTextAttributes {
/*
* Defaults should be consistent with SonarLintSeverity
*/
BLOCKER = createTextAttributesKey("SONARLINT_BLOCKER", SonarLintSeverity.BLOCKER.defaultTextAttributes());
HIGH = createTextAttributesKey("SONARLINT_HIGH", SonarLintSeverity.HIGH.defaultTextAttributes());
MEDIUM = createTextAttributesKey("SONARLINT_MEDIUM", SonarLintSeverity.MEDIUM.defaultTextAttributes());
LOW = createTextAttributesKey("SONARLINT_LOW", SonarLintSeverity.LOW.defaultTextAttributes());
INFO = createTextAttributesKey("SONARLINT_INFO", SonarLintSeverity.INFO.defaultTextAttributes());
OLD_CODE = createTextAttributesKey("SONARLINT_OLD_CODE", SonarLintSeverity.OLD_CODE.defaultTextAttributes());
SELECTED = createTextAttributesKey("SONARLINT_SELECTED");
DIFF_ADDITION = createTextAttributesKey("SONARLINT_DIFF_ADDITION", DiffColors.DIFF_INSERTED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,20 @@ static TextAttributesKey getTextAttrsKey(Project project, @Nullable ImpactSeveri

if (impact != null) {
return switch (impact) {
case BLOCKER -> SonarLintTextAttributes.BLOCKER;
case HIGH -> SonarLintTextAttributes.HIGH;
case LOW -> SonarLintTextAttributes.LOW;
case INFO -> SonarLintTextAttributes.INFO;
default -> SonarLintTextAttributes.MEDIUM;
};
}

if (severity != null) {
return switch (severity) {
case CRITICAL, BLOCKER -> SonarLintTextAttributes.HIGH;
case MINOR, INFO -> SonarLintTextAttributes.LOW;
case BLOCKER -> SonarLintTextAttributes.BLOCKER;
case CRITICAL -> SonarLintTextAttributes.HIGH;
case MINOR -> SonarLintTextAttributes.LOW;
case INFO -> SonarLintTextAttributes.INFO;
default -> SonarLintTextAttributes.MEDIUM;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import javax.swing.JButton
import javax.swing.JPanel
import javax.swing.SwingConstants
import org.sonarlint.intellij.SonarLintIcons
import org.sonarlint.intellij.SonarLintIcons.backgroundColorsByImpact
import org.sonarlint.intellij.SonarLintIcons.borderColorsByImpact
import org.sonarlint.intellij.actions.MarkAsResolvedAction.Companion.canBeMarkedAsResolved
import org.sonarlint.intellij.actions.MarkAsResolvedAction.Companion.openMarkAsResolvedDialogAsync
import org.sonarlint.intellij.actions.ReopenIssueAction.Companion.canBeReopened
Expand Down Expand Up @@ -211,7 +213,8 @@ class RuleHeaderPanel(private val parent: Disposable) : JBPanel<RuleHeaderPanel>
qualities.entries.forEach {
val cleanImpact = cleanCapitalized(it.value.label)
val cleanQuality = cleanCapitalized(it.key.label)
val qualityPanel = RoundedPanelWithBackgroundColor(SonarLintIcons.backgroundColorsByImpact[it.value]).apply {
val qualityPanel =
RoundedPanelWithBackgroundColor(backgroundColorsByImpact[it.value], borderColorsByImpact[it.value]).apply {
toolTipText = "Issues found for this rule will have a $cleanImpact impact on the $cleanQuality of your software."
}
qualityPanel.add(JBLabel(cleanCapitalized(it.key.toString())).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
*/
public class IssueTreeModelBuilder implements FindingTreeModelBuilder {
private static final List<IssueSeverity> SEVERITY_ORDER = List.of(BLOCKER, CRITICAL, MAJOR, MINOR, INFO);
private static final List<ImpactSeverity> IMPACT_ORDER = List.of(HIGH, MEDIUM, LOW);
private static final List<ImpactSeverity> IMPACT_ORDER = List.of(ImpactSeverity.BLOCKER, HIGH, MEDIUM, LOW, ImpactSeverity.INFO);
private static final Comparator<LiveIssue> ISSUE_COMPARATOR = new IssueComparator();

private final FindingTreeIndex index;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package org.sonarlint.intellij.util

import com.intellij.ui.IdeBorderFactory
import com.intellij.ui.JBColor
import com.intellij.util.ui.GraphicsUtil
import com.intellij.util.ui.JBInsets
Expand All @@ -29,21 +30,22 @@ import java.awt.Rectangle
import java.awt.geom.RoundRectangle2D
import javax.swing.JPanel

open class RoundedPanelWithBackgroundColor(private val color: JBColor? = null, private val cornerAngle: Float = 20f) : JPanel() {
open class RoundedPanelWithBackgroundColor(
backgroundColor: JBColor? = null,
borderColor: JBColor? = null,
private val cornerAngle: Float = 20f
) : JPanel() {

init {
isOpaque = false
cursor = Cursor.getDefaultCursor()
updateColors()
}

override fun updateUI() {
super.updateUI()
updateColors()
}

private fun updateColors() {
background = color
background = backgroundColor
borderColor?.let {
val customBorder = IdeBorderFactory.createRoundedBorder(cornerAngle.toInt(), 1)
customBorder.setColor(borderColor)
border = customBorder
}
}

override fun paintComponent(g: Graphics) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
import org.sonarsource.sonarlint.core.rpc.protocol.common.IssueSeverity;

public enum SonarLintSeverity {
BLOCKER(CodeInsightColors.WARNINGS_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WARNING),
HIGH(CodeInsightColors.WARNINGS_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WARNING),
MEDIUM(CodeInsightColors.WARNINGS_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WARNING),
LOW(CodeInsightColors.WARNINGS_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WEAK_WARNING),
INFO(CodeInsightColors.WARNINGS_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WEAK_WARNING),
OLD_CODE(CodeInsightColors.WEAK_WARNING_ATTRIBUTES, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, HighlightSeverity.WEAK_WARNING);

private static final Map<String, SonarLintSeverity> cache = Stream.of(values()).collect(Collectors.toMap(Enum::toString, Function.identity()));
Expand Down Expand Up @@ -66,8 +68,10 @@ public static SonarLintSeverity fromCoreSeverity(@Nullable ImpactSeverity impact
return cache.get(impact.toString());
}
return switch (severity) {
case BLOCKER, CRITICAL -> cache.get(ImpactSeverity.HIGH.toString());
case MINOR, INFO -> cache.get(ImpactSeverity.LOW.toString());
case BLOCKER -> cache.get(ImpactSeverity.BLOCKER.toString());
case CRITICAL -> cache.get(ImpactSeverity.HIGH.toString());
case MINOR -> cache.get(ImpactSeverity.LOW.toString());
case INFO -> cache.get(ImpactSeverity.INFO.toString());
default -> cache.get(ImpactSeverity.MEDIUM.toString());
};
}
Expand Down
24 changes: 24 additions & 0 deletions src/main/resources/images/impact/blocker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions src/main/resources/images/impact/high.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/main/resources/images/impact/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions src/main/resources/images/impact/low.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions src/main/resources/images/impact/medium.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/test/java/org/sonarlint/intellij/SonarLintIconsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package org.sonarlint.intellij
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.sonarlint.intellij.SonarLintIcons.hotspotTypeWithProbability
import org.sonarlint.intellij.SonarLintIcons.impact
import org.sonarlint.intellij.SonarLintIcons.severity
import org.sonarlint.intellij.SonarLintIcons.toDisabled
import org.sonarlint.intellij.SonarLintIcons.type
Expand All @@ -37,6 +38,13 @@ class SonarLintIconsTest {
}
}

@Test
fun testImpacts() {
for (value in org.sonarsource.sonarlint.core.client.utils.ImpactSeverity.values()) {
assertThat(impact(value)).isNotNull
}
}

@Test
fun testTypes() {
for (value in RuleType.values()) {
Expand Down
Loading

0 comments on commit 3074b14

Please sign in to comment.