KT-60957 [Analysis API] Properly handle source PSI for implicit invoke calls in KtFirReferenceShortener
For implicit invoke operator calls, there are two instances of `FirResolvedNamedReference`. One of them references `invoke` function and cannot be used to analyze the property access, and the second one has `source == null`. Luckily, the parent of the second reference is `FirPropertyAccessExpression`, which has the correct source ^KT-60957 Fixed
This commit is contained in:
+14
-1
@@ -985,7 +985,7 @@ private class ElementsToShortenCollector(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
||||||
val propertyReferenceExpression = (firPropertyAccess.psi as? KtDotQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression ?: return
|
val propertyReferenceExpression = firPropertyAccess.correspondingNameReference ?: return
|
||||||
if (!propertyReferenceExpression.textRange.intersects(selection)) return
|
if (!propertyReferenceExpression.textRange.intersects(selection)) return
|
||||||
|
|
||||||
val qualifiedProperty = propertyReferenceExpression.getQualifiedElement() as? KtDotQualifiedExpression ?: return
|
val qualifiedProperty = propertyReferenceExpression.getQualifiedElement() as? KtDotQualifiedExpression ?: return
|
||||||
@@ -1014,6 +1014,19 @@ private class ElementsToShortenCollector(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val FirPropertyAccessExpression.correspondingNameReference: KtNameReferenceExpression?
|
||||||
|
get() {
|
||||||
|
val nameReference = when (val sourcePsi = psi) {
|
||||||
|
// usual `foo.bar.baz` case
|
||||||
|
is KtDotQualifiedExpression -> sourcePsi.selectorExpression
|
||||||
|
|
||||||
|
// short `foo` case, or implicit invoke call like `foo.bar.baz()`
|
||||||
|
else -> sourcePsi
|
||||||
|
}
|
||||||
|
|
||||||
|
return nameReference as? KtNameReferenceExpression
|
||||||
|
}
|
||||||
|
|
||||||
private val FirPropertyAccessExpression.referencedSymbol: FirVariableSymbol<*>?
|
private val FirPropertyAccessExpression.referencedSymbol: FirVariableSymbol<*>?
|
||||||
get() = (calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol<*>
|
get() = (calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol<*>
|
||||||
|
|
||||||
|
|||||||
+6
@@ -460,6 +460,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variableAssignment_plusOperator.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variableAssignment_plusOperator.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("variable_invokeOperator.kt")
|
||||||
|
public void testVariable_invokeOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variable_invokeOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses")
|
@TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+6
@@ -460,6 +460,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera
|
|||||||
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variableAssignment_plusOperator.kt");
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variableAssignment_plusOperator.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("variable_invokeOperator.kt")
|
||||||
|
public void testVariable_invokeOperator() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/variable_invokeOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses")
|
@TestMetadata("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClasses")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// FILE: main.kt
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun usage() {
|
||||||
|
<expr>dependency.foo()</expr>
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: dependency.kt
|
||||||
|
package dependency
|
||||||
|
|
||||||
|
var foo: Foo = Foo()
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
operator fun invoke() {}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
Before shortening: dependency.foo()
|
||||||
|
with DO_NOT_SHORTEN:
|
||||||
|
with SHORTEN_IF_ALREADY_IMPORTED:
|
||||||
|
with SHORTEN_AND_IMPORT:
|
||||||
|
[qualifier] dependency.foo()
|
||||||
|
with SHORTEN_AND_STAR_IMPORT:
|
||||||
|
[qualifier] dependency.foo()
|
||||||
Reference in New Issue
Block a user