[AA] delegate to resolveToFirSymbol to avoid decompilation

`getReturnTypeForKtDeclaration` is called by UAST on probably compiled declarations.
In order to avoid redundant decompilation + building raw FIR + resolve,
let's delegate to deserialized FIR which is already prepared in stubs

Fixes KTIJ-24810

When `findSourceNonLocalFirDeclaration` is called on non-physical property accessor e.g.,
during completion, then traverse tree should allow drilling into FirProperty;
otherwise, no FIR would be found
This commit is contained in:
Anna Kozlova
2023-06-06 11:12:46 +02:00
committed by Space Team
parent 16644c1a3b
commit 09f4f0af66
7 changed files with 42 additions and 5 deletions
@@ -46,6 +46,12 @@ public class Fe10IdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGen
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test @Test
@TestMetadata("localClassType.kt") @TestMetadata("localClassType.kt")
public void testLocalClassType() throws Exception { public void testLocalClassType() throws Exception {
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirOfType import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirOfType
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -34,6 +35,9 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.applyIf import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
internal class KtFirExpressionTypeProvider( internal class KtFirExpressionTypeProvider(
override val analysisSession: KtFirAnalysisSession, override val analysisSession: KtFirAnalysisSession,
@@ -120,12 +124,13 @@ internal class KtFirExpressionTypeProvider(
} }
override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType { override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType {
val firDeclaration = if (isAnonymousFunction(declaration)) val firDeclaration = if (declaration is KtParameter && declaration.ownerFunction == null) {
declaration.toFirAnonymousFunction()
else
declaration.getOrBuildFir(firResolveSession) declaration.getOrBuildFir(firResolveSession)
} else {
declaration.resolveToFirSymbol(firResolveSession, FirResolvePhase.TYPES).fir
}
return when (firDeclaration) { return when (firDeclaration) {
is FirCallableDeclaration -> firDeclaration.returnTypeRef.coneType.asKtType() is FirCallableDeclaration -> firDeclaration.symbol.resolvedReturnType.asKtType()
is FirFunctionTypeParameter -> firDeclaration.returnTypeRef.coneType.asKtType() is FirFunctionTypeParameter -> firDeclaration.returnTypeRef.coneType.asKtType()
else -> unexpectedElementError<FirElement>(firDeclaration) else -> unexpectedElementError<FirElement>(firDeclaration)
} }
@@ -46,6 +46,12 @@ public class FirIdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGene
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test @Test
@TestMetadata("localClassType.kt") @TestMetadata("localClassType.kt")
public void testLocalClassType() throws Exception { public void testLocalClassType() throws Exception {
@@ -46,6 +46,12 @@ public class FirStandaloneNormalAnalysisSourceModuleTypeByDeclarationReturnTypeT
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/types/byDeclarationReturnType"), Pattern.compile("^(.+)\\.kt$"), null, true);
} }
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test @Test
@TestMetadata("localClassType.kt") @TestMetadata("localClassType.kt")
public void testLocalClassType() throws Exception { public void testLocalClassType() throws Exception {
@@ -0,0 +1,3 @@
fun foo() {
val f = fun<caret>(it: String) {}
}
@@ -0,0 +1,11 @@
annotationsList: []
classId: kotlin/Unit
classSymbol: KtNamedClassOrObjectSymbol(kotlin/Unit)
nullability: NON_NULLABLE
ownTypeArguments: []
qualifiers: [
qualifier:
name: Unit
symbol: KtNamedClassOrObjectSymbol(kotlin/Unit)
typeArguments: []
]
@@ -73,7 +73,7 @@ internal fun KtElement.findSourceByTraversingWholeTree(
val isDeclaration = this is KtDeclaration val isDeclaration = this is KtDeclaration
return FirElementFinder.findElementIn( return FirElementFinder.findElementIn(
firFile, firFile,
canGoInside = { it is FirRegularClass || it is FirScript || it is FirFunction }, canGoInside = { it is FirRegularClass || it is FirScript || it is FirFunction || it is FirProperty },
predicate = { firDeclaration -> predicate = { firDeclaration ->
firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration
} }