Skip to content
Open
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
@@ -0,0 +1,49 @@
package net.sjrx.intellij.plugins.systemdunitfiles.annotators

import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.Annotator
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import net.sjrx.intellij.plugins.systemdunitfiles.psi.UnitFileProperty
import net.sjrx.intellij.plugins.systemdunitfiles.psi.UnitFileSectionType
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.SemanticDataRepository
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.fileClass
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.GrammarOptionValue
import net.sjrx.intellij.plugins.systemdunitfiles.settings.ExperimentalSettings

/**
* Debug aid (#467): while the experimental grammar engine is enabled, mark the KEY of every option
* whose value is validated by that engine (a [GrammarOptionValue]), so it is obvious at a glance
* which keys exercise the new parse() path versus the original SyntacticMatch/SemanticMatch one.
*
* Does nothing when the flag is off, so it has no effect for normal users.
*/
class GrammarEngineKeyAnnotator : Annotator {

override fun annotate(element: PsiElement, holder: AnnotationHolder) {
if (element !is UnitFileProperty) return
if (!ExperimentalSettings.getInstance(element.project).state.useGrammarParseEngine) return

val section = PsiTreeUtil.getParentOfType(element, UnitFileSectionType::class.java) ?: return
val fileClass = element.containingFile.fileClass()
val validator = SemanticDataRepository.instance.getOptionValidator(fileClass, section.sectionName, element.key)

if (validator is GrammarOptionValue) {
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
.range(element.keyNode.psi)
.textAttributes(NEW_ENGINE_KEY)
.create()
}
}

companion object {
// Layered on top of the normal key color; METADATA gives a distinct, theme-aware tint.
val NEW_ENGINE_KEY: TextAttributesKey = TextAttributesKey.createTextAttributesKey(
"SYSTEMD_UNIT_FILE_NEW_GRAMMAR_ENGINE_KEY",
DefaultLanguageHighlighterColors.METADATA,
)
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<annotator language="Unit File (systemd)" implementationClass="net.sjrx.intellij.plugins.systemdunitfiles.annotators.LineContinuationCharacterFollowedByWhitespaceAnnotator"/>
<annotator language="Unit File (systemd)" implementationClass="net.sjrx.intellij.plugins.systemdunitfiles.annotators.PropertyIsNotInSectionAnnotator"/>
<annotator language="Unit File (systemd)" implementationClass="net.sjrx.intellij.plugins.systemdunitfiles.annotators.PidFileOptionWarning"/>
<annotator language="Unit File (systemd)" implementationClass="net.sjrx.intellij.plugins.systemdunitfiles.annotators.GrammarEngineKeyAnnotator"/>
<localInspection implementationClass="net.sjrx.intellij.plugins.systemdunitfiles.inspections.UnknownKeyInSectionInspection"
groupPath="Unit files (systemd)" language="Unit File (systemd)"
shortName="UnknownKeyInSection" displayName="Unknown option in section"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package net.sjrx.intellij.plugins.systemdunitfiles.annotators

import com.intellij.lang.annotation.HighlightSeverity
import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest
import net.sjrx.intellij.plugins.systemdunitfiles.settings.ExperimentalSettings
import org.junit.Test

class GrammarEngineKeyAnnotatorTest : AbstractUnitFileTest() {

// The light-test project is shared across classes, so don't leak the opt-in.
override fun tearDown() {
try {
ExperimentalSettings.getInstance(project).state.useGrammarParseEngine = false
} finally {
super.tearDown()
}
}

private fun markedKey(highlights: List<com.intellij.codeInsight.daemon.impl.HighlightInfo>, key: String) =
highlights.any { it.severity == HighlightSeverity.INFORMATION && it.text == key }

@Test
fun testGrammarBackedKeyIsMarkedWhenFlagOn() {
ExperimentalSettings.getInstance(project).state.useGrammarParseEngine = true
// RestrictAddressFamilies is validated by a GrammarOptionValue; PrivateTmp's value is not.
setupFileInEditor("file.service", "[Service]\nRestrictAddressFamilies=AF_INET\n")

val highlights = myFixture.doHighlighting()
assertTrue(markedKey(highlights, "RestrictAddressFamilies"))
}

@Test
fun testNotMarkedWhenFlagOff() {
setupFileInEditor("file.service", "[Service]\nRestrictAddressFamilies=AF_INET\n")

val highlights = myFixture.doHighlighting()
assertFalse(markedKey(highlights, "RestrictAddressFamilies"))
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.sjrx.intellij.plugins.systemdunitfiles.inspections

import com.intellij.lang.annotation.HighlightSeverity
import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest
import net.sjrx.intellij.plugins.systemdunitfiles.settings.ExperimentalSettings
import org.junit.Test
Expand Down Expand Up @@ -42,7 +43,7 @@ class GrammarParseEngineInspectionTest : AbstractUnitFileTest() {
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)

assertSize(0, myFixture.doHighlighting())
assertSize(0, myFixture.doHighlighting().filter { it.severity != HighlightSeverity.INFORMATION })
}

@Test
Expand All @@ -61,7 +62,7 @@ class GrammarParseEngineInspectionTest : AbstractUnitFileTest() {
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)

assertSize(3, myFixture.doHighlighting())
assertSize(3, myFixture.doHighlighting().filter { it.severity != HighlightSeverity.INFORMATION })
}

@Test
Expand All @@ -76,6 +77,6 @@ class GrammarParseEngineInspectionTest : AbstractUnitFileTest() {
setupFileInEditor("file.service", file)
enableInspection(InvalidValueInspection::class.java)

assertSize(0, myFixture.doHighlighting())
assertSize(0, myFixture.doHighlighting().filter { it.severity != HighlightSeverity.INFORMATION })
}
}
Loading