[FIR] Add SYNTAX diagnostics for light tree
This commit is contained in:
committed by
TeamCityServer
parent
3e0eb06e3e
commit
7dedd04ed9
+47
-4
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.frontend.fir.handlers
|
package org.jetbrains.kotlin.test.frontend.fir.handlers
|
||||||
|
|
||||||
|
import com.intellij.lang.LighterASTNode
|
||||||
|
import com.intellij.openapi.util.Ref
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.TokenType
|
||||||
|
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory1
|
import org.jetbrains.kotlin.checkers.diagnostics.factories.DebugInfoDiagnosticFactory1
|
||||||
import org.jetbrains.kotlin.checkers.utils.TypeOfCall
|
import org.jetbrains.kotlin.checkers.utils.TypeOfCall
|
||||||
@@ -29,6 +33,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
@@ -108,11 +113,19 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
lightTreeEnabled: Boolean,
|
lightTreeEnabled: Boolean,
|
||||||
lightTreeComparingModeEnabled: Boolean
|
lightTreeComparingModeEnabled: Boolean
|
||||||
) {
|
) {
|
||||||
// TODO: support in light tree
|
val metaInfos = if (firFile.psi != null) {
|
||||||
val psiFile = firFile.psi ?: return
|
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).map {
|
||||||
val metaInfos = AnalyzingUtils.getSyntaxErrorRanges(psiFile).map {
|
FirErrors.SYNTAX.on(FirRealPsiSourceElement(it)).toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||||
FirErrors.SYNTAX.on(FirRealPsiSourceElement(it)).toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
}
|
||||||
|
} else {
|
||||||
|
val source = firFile.source ?: return
|
||||||
|
val errorNodes = LightTreeErrorsCollector(source.treeStructure).collectErrorNodes(source.lighterASTNode)
|
||||||
|
errorNodes.map { node ->
|
||||||
|
FirErrors.SYNTAX.on(node.toFirLightSourceElement(source.treeStructure))
|
||||||
|
.toMetaInfo(testFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globalMetadataInfoHandler.addMetadataInfosForFile(testFile, metaInfos)
|
globalMetadataInfoHandler.addMetadataInfosForFile(testFile, metaInfos)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,3 +300,33 @@ class PsiLightTreeMetaInfoProcessor(testServices: TestServices) : AbstractTwoAtt
|
|||||||
return FirDiagnosticsDirectives.USE_LIGHT_TREE !in module.directives
|
return FirDiagnosticsDirectives.USE_LIGHT_TREE !in module.directives
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class LightTreeErrorsCollector(private val tree: FlyweightCapableTreeStructure<LighterASTNode>) {
|
||||||
|
|
||||||
|
private fun LighterASTNode.getChildrenAsArray(): Array<out LighterASTNode?> {
|
||||||
|
val kidsRef = Ref<Array<LighterASTNode?>>()
|
||||||
|
return if (tree.getChildren(this, kidsRef) > 0) kidsRef.get() else emptyArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun LighterASTNode.forEachChildren(f: (LighterASTNode) -> Unit) {
|
||||||
|
val kidsArray = this.getChildrenAsArray()
|
||||||
|
for (kid in kidsArray) {
|
||||||
|
if (kid == null) break
|
||||||
|
val tokenType = kid.tokenType
|
||||||
|
if (KtTokens.COMMENTS.contains(tokenType) || tokenType == KtTokens.WHITE_SPACE || tokenType == KtTokens.SEMICOLON) continue
|
||||||
|
f(kid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun collectErrorNodes(node: LighterASTNode, acc: MutableList<LighterASTNode> = mutableListOf()): List<LighterASTNode> {
|
||||||
|
if (node.tokenType == TokenType.ERROR_ELEMENT) {
|
||||||
|
acc.add(node)
|
||||||
|
} else {
|
||||||
|
node.forEachChildren { child ->
|
||||||
|
collectErrorNodes(child, acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user