[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);
}
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test
@TestMetadata("localClassType.kt")
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.getOrBuildFirOfType
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.fir.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -34,6 +35,9 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import kotlin.contracts.ExperimentalContracts
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(
override val analysisSession: KtFirAnalysisSession,
@@ -120,12 +124,13 @@ internal class KtFirExpressionTypeProvider(
}
override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType {
val firDeclaration = if (isAnonymousFunction(declaration))
declaration.toFirAnonymousFunction()
else
val firDeclaration = if (declaration is KtParameter && declaration.ownerFunction == null) {
declaration.getOrBuildFir(firResolveSession)
} else {
declaration.resolveToFirSymbol(firResolveSession, FirResolvePhase.TYPES).fir
}
return when (firDeclaration) {
is FirCallableDeclaration -> firDeclaration.returnTypeRef.coneType.asKtType()
is FirCallableDeclaration -> firDeclaration.symbol.resolvedReturnType.asKtType()
is FirFunctionTypeParameter -> firDeclaration.returnTypeRef.coneType.asKtType()
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);
}
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test
@TestMetadata("localClassType.kt")
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);
}
@Test
@TestMetadata("anonymousFunction.kt")
public void testAnonymousFunction() throws Exception {
runTest("analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt");
}
@Test
@TestMetadata("localClassType.kt")
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
return FirElementFinder.findElementIn(
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 ->
firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration
}