Support FirDiagnostic.isValid properly
Diagnostic is considered valid in this commit if it's reported on a syntactically non-erroneous element without erroneous last child
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ sealed class FirDiagnostic<out E : FirSourceElement> : Diagnostic {
|
||||
get() = factory.getTextRanges(this)
|
||||
|
||||
override val isValid: Boolean
|
||||
get() = true
|
||||
get() = factory.isValid(this)
|
||||
}
|
||||
|
||||
sealed class FirSimpleDiagnostic<out E : FirSourceElement> : FirDiagnostic<E>() {
|
||||
|
||||
+5
@@ -29,6 +29,11 @@ sealed class AbstractFirDiagnosticFactory<out E : FirSourceElement, D : FirDiagn
|
||||
|
||||
fun getTextRanges(diagnostic: FirDiagnostic<*>): List<TextRange> =
|
||||
positioningStrategy.markDiagnostic(diagnostic)
|
||||
|
||||
fun isValid(diagnostic: FirDiagnostic<*>): Boolean {
|
||||
val element = diagnostic.element
|
||||
return positioningStrategy.isValid(element.lighterASTNode, element.treeStructure)
|
||||
}
|
||||
}
|
||||
|
||||
class FirDiagnosticFactory0<E : FirSourceElement, P : PsiElement>(
|
||||
|
||||
+27
-1
@@ -6,9 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.lang.LighterASTNode
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.TokenType
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE
|
||||
|
||||
open class LightTreePositioningStrategy {
|
||||
open fun markDiagnostic(diagnostic: FirDiagnostic<*>): List<TextRange> {
|
||||
@@ -20,6 +24,10 @@ open class LightTreePositioningStrategy {
|
||||
return markElement(node, tree)
|
||||
}
|
||||
|
||||
open fun isValid(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
|
||||
return !hasSyntaxErrors(node, tree)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DEFAULT = LightTreePositioningStrategies.DEFAULT
|
||||
}
|
||||
@@ -32,3 +40,21 @@ fun markElement(node: LighterASTNode, tree: FlyweightCapableTreeStructure<Lighte
|
||||
fun markRange(from: LighterASTNode, to: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): List<TextRange> {
|
||||
return listOf(TextRange(tree.getStartOffset(from), tree.getEndOffset(to)))
|
||||
}
|
||||
|
||||
private val DOC_AND_COMMENT_TOKENS = setOf(
|
||||
WHITE_SPACE, KtTokens.IDENTIFIER,
|
||||
KtTokens.EOL_COMMENT, KtTokens.BLOCK_COMMENT, KtTokens.SHEBANG_COMMENT, KtTokens.DOC_COMMENT
|
||||
)
|
||||
|
||||
private fun hasSyntaxErrors(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
|
||||
if (node.tokenType == TokenType.ERROR_ELEMENT) return true
|
||||
|
||||
val childrenRef = Ref<Array<LighterASTNode>>()
|
||||
tree.getChildren(node, childrenRef)
|
||||
val children = childrenRef.get()
|
||||
return children.lastOrNull {
|
||||
val tokenType = it.tokenType
|
||||
tokenType !is KtSingleValueToken && tokenType !in DOC_AND_COMMENT_TOKENS
|
||||
}?.let { hasSyntaxErrors(it, tree) } == true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user