Skip to content

Commit

Permalink
suppress error highlighting if error intersects template string argument
Browse files Browse the repository at this point in the history
  • Loading branch information
undeadcat committed Aug 31, 2017
1 parent 27bb538 commit 0adff04
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package com.intellij.StyledComponents
import com.intellij.lang.javascript.JSTokenTypes
import com.intellij.lang.javascript.psi.JSLiteralExpression
import com.intellij.lang.javascript.psi.ecma6.JSStringTemplateExpression
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.TextRange
import com.intellij.util.ArrayUtil
import com.intellij.util.containers.ContainerUtil
import java.util.ArrayList

val INJECTED_FILE_RANGES_KEY = Key<List<TextRange>?>("INJECTED_FILE_RANGES_KEY")
private val EXTERNAL_FRAGMENT = "EXTERNAL_FRAGMENT"

fun getInjectionPlaces(myQuotedLiteral: JSLiteralExpression): List<StringPlace> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.intellij.StyledComponents

import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter
import com.intellij.codeInsight.highlighting.HighlightErrorFilter
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiFile

class InterpolationArgumentsErrorFilter : HighlightErrorFilter(), HighlightInfoFilter {
override fun shouldHighlightErrorElement(element: PsiErrorElement): Boolean {
val acceptedRanges = element.containingFile.getUserData(INJECTED_FILE_RANGES_KEY)
if (acceptedRanges == null) {
return true
}
return acceptedRanges.any { range -> range.contains(element.textRange) }
}

override fun accept(highlightInfo: HighlightInfo, file: PsiFile?): Boolean {
val acceptedRanges = file?.getUserData(INJECTED_FILE_RANGES_KEY)
if (acceptedRanges == null) {
return true
}
if (highlightInfo.severity === HighlightSeverity.WARNING
|| highlightInfo.severity === HighlightSeverity.WEAK_WARNING
|| highlightInfo.severity === HighlightSeverity.ERROR) {
return acceptedRanges.any { range ->
highlightInfo.startOffset > range.startOffset
&& highlightInfo.endOffset < range.endOffset
}
}
return true
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import com.intellij.lang.injection.MultiHostInjector
import com.intellij.lang.injection.MultiHostRegistrar
import com.intellij.lang.javascript.psi.JSExpression
import com.intellij.lang.javascript.psi.ecma6.JSStringTemplateExpression
import com.intellij.openapi.util.Pair
import com.intellij.openapi.util.TextRange
import com.intellij.patterns.ElementPattern
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.injected.MultiHostRegistrarImpl
import com.intellij.psi.impl.source.tree.injected.Place
import org.jetbrains.plugins.less.LESSLanguage

class StyledComponentsInjector : MultiHostInjector {
Expand Down Expand Up @@ -40,11 +45,22 @@ class StyledComponentsInjector : MultiHostInjector {
registrar.addPlace(thePrefix, theSuffix, injectionHost, range)
}
registrar.doneInjecting()
val result = getInjectionResult(registrar) ?: return
val injectedFile = result.second
val injectedFileRanges = result.first.map { TextRange(it.range.startOffset, it.range.endOffset - it.suffix.length) }

if (injectedFileRanges.size > 1) {
injectedFile.putUserData(INJECTED_FILE_RANGES_KEY, injectedFileRanges)
}
}
}

private fun getInjectionResult(registrar: MultiHostRegistrar): Pair<Place, PsiFile>? {
val result = (registrar as MultiHostRegistrarImpl).result
return if (result == null || result.isEmpty()) null
else result[result.size - 1]
}
data class PlaceInfo(val elementPattern: ElementPattern<JSStringTemplateExpression>,
val prefix: String? = null,
val suffix: String? = null)

}
2 changes: 2 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@

<extensions defaultExtensionNs="com.intellij">
<multiHostInjector implementation="com.intellij.StyledComponents.StyledComponentsInjector"/>
<highlightErrorFilter implementation="com.intellij.StyledComponents.InterpolationArgumentsErrorFilter"/>
<daemon.highlightInfoFilter implementation="com.intellij.StyledComponents.InterpolationArgumentsErrorFilter"/>
</extensions>
</idea-plugin>
43 changes: 43 additions & 0 deletions src/test/HighlightingTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import com.intellij.psi.css.inspections.invalid.CssInvalidPropertyValueInspection
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase

class HighlightingTest : LightCodeInsightFixtureTestCase() {

fun testWithoutArguments_ErrorsHighlighted() {
myFixture.enableInspections(CssInvalidPropertyValueInspection::class.java)
doTest("var someCss = css`div {\n" +
" color:<error descr=\"a term expected\"> </error>{}\n" +
"<error descr=\"Unexpected terms\">}</error>;`")
}

fun testErrorSurroundsInterpolationArgument_NotHighlighted() {
myFixture.enableInspections(CssInvalidPropertyValueInspection::class.java)
doTest("var someCss = css`\n" +
"//should not highlight\n" +
"withArgument{\n" +
" border: 5px \${foobar} red;\n" +
"},\n" +
"//should highlight\n" +
"withoutArgument {\n" +
" border: 5px<error> foobar-not-acceptable red</error>;\n" +
"};;`")
}

fun testErrorAdjacentToInterpolationArgument_NotHighlighted() {
doTest("var styledSomething = styled.something`\n" +
" perspective: 1000px;\n" +
" \${value}\n" +
" \${anotherValue}\n" +
"`\n" +
"const Triangle = styled.span`\n" +
" \${({ right }) => (right ? 'right: 0;' : 'left: 0;')}\n" +
"`")
}

private fun doTest(expected: String) {
myFixture.setCaresAboutInjection(false)
myFixture.configureByText("dummy.es6", expected)
myFixture.testHighlighting(true, false, true)
}

}
Binary file modified webstorm-styled-components.zip
Binary file not shown.

0 comments on commit 0adff04

Please sign in to comment.