Fix DEBUG_INFO_CALL positioning in FIR
This commit is contained in:
+1
-1
@@ -466,7 +466,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.defaultValue(node: Lig
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.selector(node: LighterASTNode): LighterASTNode? {
|
fun FlyweightCapableTreeStructure<LighterASTNode>.selector(node: LighterASTNode): LighterASTNode? {
|
||||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||||
getChildren(node, childrenRef)
|
getChildren(node, childrenRef)
|
||||||
val children = childrenRef.get() ?: return null
|
val children = childrenRef.get() ?: return null
|
||||||
|
|||||||
+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.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitorVoid
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||||
@@ -180,6 +181,31 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
Renderers.renderCallInfo(fqName, getTypeOfCall(reference, resolvedSymbol))
|
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(
|
private inline fun DebugInfoDiagnosticFactory1.createDebugInfoDiagnostic(
|
||||||
element: FirElement,
|
element: FirElement,
|
||||||
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>,
|
diagnosedRangesToDiagnosticNames: Map<IntRange, Set<String>>,
|
||||||
@@ -187,31 +213,22 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
): FirDiagnosticWithParameters1<FirSourceElement, String>? {
|
): FirDiagnosticWithParameters1<FirSourceElement, String>? {
|
||||||
val sourceElement = element.source ?: return null
|
val sourceElement = element.source ?: return null
|
||||||
if (sourceElement.kind !in allowedKindsForDebugInfo) return null
|
if (sourceElement.kind !in allowedKindsForDebugInfo) return null
|
||||||
|
|
||||||
// Lambda argument is always (?) duplicated by function literal
|
// Lambda argument is always (?) duplicated by function literal
|
||||||
// Block expression is always (?) duplicated by single block expression
|
// Block expression is always (?) duplicated by single block expression
|
||||||
if (sourceElement.elementType == KtNodeTypes.LAMBDA_ARGUMENT || sourceElement.elementType == KtNodeTypes.BLOCK) return null
|
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()
|
val argumentText = argument()
|
||||||
return when (sourceElement) {
|
val factory = FirDiagnosticFactory1<FirPsiSourceElement<PsiElement>, PsiElement, String>(name, severity)
|
||||||
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(
|
return when (positionedElement) {
|
||||||
sourceElement,
|
is FirPsiSourceElement<*> -> FirPsiDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||||
argumentText,
|
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(positionedElement, argumentText, severity, factory)
|
||||||
severity,
|
|
||||||
FirDiagnosticFactory1(
|
|
||||||
name,
|
|
||||||
severity,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
is FirLightSourceElement -> FirLightDiagnosticWithParameters1(
|
|
||||||
sourceElement,
|
|
||||||
argumentText,
|
|
||||||
severity,
|
|
||||||
FirDiagnosticFactory1<FirSourceElement, PsiElement, String>(
|
|
||||||
name,
|
|
||||||
severity
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-15
@@ -10,11 +10,11 @@ fun case1(case: Case1) {
|
|||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: boo; typeCall: extension function")!>boo(1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: boo; typeCall: extension function")!>boo(1)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(1)<!>
|
||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: boo; typeCall: extension function")!>boo(x = 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: boo; typeCall: extension function")!>boo(x = 1)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(x = 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(x = 1)<!>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ fun case2(case: Case2) {
|
|||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case2.boo; typeCall: function")!>boo(1, 2)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case2.boo; typeCall: function")!>boo(1, 2)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(1, 2)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(1, 2)<!>
|
||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case2.boo; typeCall: function")!>boo(x = 1, y = 2)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case2.boo; typeCall: function")!>boo(x = 1, y = 2)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(x = 1, y = 2)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(x = 1, y = 2)<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
@@ -52,11 +52,11 @@ fun case3(case: Case3) {
|
|||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case3.boo; typeCall: function")!>boo(1, 2)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case3.boo; typeCall: function")!>boo(1, 2)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(1, 2)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(1, 2)<!>
|
||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case3.boo; typeCall: function")!>boo(x = 1, y = 2)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case3.boo; typeCall: function")!>boo(x = 1, y = 2)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.boo(x = 1, y = 2)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.boo(x = 1, y = 2)<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 4
|
// TESTCASE NUMBER: 4
|
||||||
@@ -71,11 +71,11 @@ fun case4(case: Case4) {
|
|||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>plus(1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>plus(1)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.plus(1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.plus(1)<!>
|
||||||
//to (1.1)
|
//to (1.1)
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>plus(x = 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>plus(x = 1)<!>
|
||||||
//(1.1) return type is String
|
//(1.1) return type is String
|
||||||
case.plus(x = 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.plus(x = 1)<!>
|
||||||
//as operator call case + 1
|
//as operator call case + 1
|
||||||
//to (1.1)
|
//to (1.1)
|
||||||
<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>case+1<!>
|
<!DEBUG_INFO_CALL("fqName: Case4.plus; typeCall: operator function")!>case+1<!>
|
||||||
@@ -91,7 +91,7 @@ class Case5 {
|
|||||||
|
|
||||||
fun case(list: List<Int>) {
|
fun case(list: List<Int>) {
|
||||||
list.<!DEBUG_INFO_CALL("fqName: Case5.foo; typeCall: extension function")!>foo(1)<!>
|
list.<!DEBUG_INFO_CALL("fqName: Case5.foo; typeCall: extension function")!>foo(1)<!>
|
||||||
list.foo(1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>list.foo(1)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ class Case6 {
|
|||||||
|
|
||||||
fun case(list: List<Int>) {
|
fun case(list: List<Int>) {
|
||||||
list.<!DEBUG_INFO_CALL("fqName: Case6.foo; typeCall: extension function")!>foo(1)<!>
|
list.<!DEBUG_INFO_CALL("fqName: Case6.foo; typeCall: extension function")!>foo(1)<!>
|
||||||
list.foo(1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>list.foo(1)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ class Case7 {
|
|||||||
|
|
||||||
fun case(list: List<Short>) {
|
fun case(list: List<Short>) {
|
||||||
list.<!DEBUG_INFO_CALL("fqName: Case7.foo; typeCall: extension function")!>foo(1, 1)<!>
|
list.<!DEBUG_INFO_CALL("fqName: Case7.foo; typeCall: extension function")!>foo(1, 1)<!>
|
||||||
list.foo(1, 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>list.foo(1, 1)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ class Case8() {
|
|||||||
|
|
||||||
fun testcase8(case: Case8) {
|
fun testcase8(case: Case8) {
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case8.foo; typeCall: function")!>foo(1, 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case8.foo; typeCall: function")!>foo(1, 1)<!>
|
||||||
case.foo(1, 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.foo(1, 1)<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 9
|
// TESTCASE NUMBER: 9
|
||||||
@@ -138,7 +138,7 @@ class Case9() {
|
|||||||
|
|
||||||
fun testcase9(case: Case9) {
|
fun testcase9(case: Case9) {
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case9.xoo; typeCall: function")!>xoo(1, 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case9.xoo; typeCall: function")!>xoo(1, 1)<!>
|
||||||
case.xoo(1, 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.xoo(1, 1)<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 10
|
// TESTCASE NUMBER: 10
|
||||||
@@ -149,7 +149,7 @@ class Case10() {
|
|||||||
|
|
||||||
fun testcase10(case: Case10) {
|
fun testcase10(case: Case10) {
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case10.xoo; typeCall: function")!>xoo(1, 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case10.xoo; typeCall: function")!>xoo(1, 1)<!>
|
||||||
case.<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>xoo(1, 1)<!>
|
case.xoo(1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 11
|
// TESTCASE NUMBER: 11
|
||||||
@@ -160,5 +160,5 @@ class Case11() {
|
|||||||
|
|
||||||
fun testcase11(case: Case11) {
|
fun testcase11(case: Case11) {
|
||||||
case.<!DEBUG_INFO_CALL("fqName: Case11.xoo; typeCall: function")!>xoo(1, 1)<!>
|
case.<!DEBUG_INFO_CALL("fqName: Case11.xoo; typeCall: function")!>xoo(1, 1)<!>
|
||||||
case.xoo(1, 1)
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>case.xoo(1, 1)<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user