Fix DEBUG_INFO_CALL positioning in FIR
This commit is contained in:
+37
-20
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||
@@ -180,6 +181,31 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
Renderers.renderCallInfo(fqName, getTypeOfCall(reference, resolvedSymbol))
|
||||
}
|
||||
|
||||
private fun DebugInfoDiagnosticFactory1.getPositionedElement(sourceElement: FirSourceElement): FirSourceElement {
|
||||
return if (this === DebugInfoDiagnosticFactory1.CALL
|
||||
&& sourceElement.elementType == KtNodeTypes.DOT_QUALIFIED_EXPRESSION
|
||||
) {
|
||||
if (sourceElement is FirPsiSourceElement<*>) {
|
||||
val psi = (sourceElement.psi as KtDotQualifiedExpression).selectorExpression
|
||||
psi?.let { FirRealPsiSourceElement(it) } ?: sourceElement
|
||||
} else {
|
||||
val tree = sourceElement.treeStructure
|
||||
val selector = tree.selector(sourceElement.lighterASTNode)
|
||||
if (selector == null) {
|
||||
sourceElement
|
||||
} else {
|
||||
val startDelta = tree.getStartOffset(selector) - tree.getStartOffset(sourceElement.lighterASTNode)
|
||||
val endDelta = tree.getEndOffset(selector) - tree.getEndOffset(sourceElement.lighterASTNode)
|
||||
FirLightSourceElement(
|
||||
selector, sourceElement.startOffset + startDelta, sourceElement.endOffset + endDelta, tree
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sourceElement
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun DebugInfoDiagnosticFactory1.createDebugInfoDiagnostic(
|
||||
element: FirElement,
|
||||
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>,
|
||||
@@ -187,31 +213,22 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
||||
): FirDiagnosticWithParameters1<FirSourceElement, String>? {
|
||||
val sourceElement = element.source ?: return null
|
||||
if (sourceElement.kind !in allowedKindsForDebugInfo) return null
|
||||
|
||||
// Lambda argument is always (?) duplicated by function literal
|
||||
// Block expression is always (?) duplicated by single block expression
|
||||
if (sourceElement.elementType == KtNodeTypes.LAMBDA_ARGUMENT || sourceElement.elementType == KtNodeTypes.BLOCK) return null
|
||||
if (diagnosedRangesToDiagnosticNames[sourceElement.startOffset..sourceElement.endOffset]?.contains(this.name) != true) return null
|
||||
// Unfortunately I had to repeat positioning strategy logic here
|
||||
// (we need to check diagnostic range before applying it)
|
||||
val positionedElement = getPositionedElement(sourceElement)
|
||||
if (diagnosedRangesToDiagnosticNames[positionedElement.startOffset..positionedElement.endOffset]?.contains(this.name) != true) {
|
||||
return null
|
||||
}
|
||||
|
||||
val argumentText = argument()
|
||||
return when (sourceElement) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
||||
sourceElement,
|
||||
argumentText,
|
||||
severity,
|
||||
FirDiagnosticFactory1(
|
||||
name,
|
||||
severity,
|
||||
)
|
||||
)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
||||
sourceElement,
|
||||
argumentText,
|
||||
severity,
|
||||
FirDiagnosticFactory1<FirSourceElement, PsiElement, String>(
|
||||
name,
|
||||
severity
|
||||
)
|
||||
)
|
||||
val factory = FirDiagnosticFactory1<FirPsiSourceElement<PsiElement>, PsiElement, String>(name, severity)
|
||||
return when (positionedElement) {
|
||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user