[AA] calculate ktType based on symbols when possible

then, for compiled code deserialized fir would be used instead of building
decompiled text and consequence building and resolving of raw fir;

type for ktTypeReference from compiled code is called e.g., by UAST inspections
when they check annotations of the called function parameters
This commit is contained in:
Anna Kozlova
2023-05-26 16:59:14 +02:00
committed by Space Team
parent d7fd2471b8
commit 1d5c080dd8
19 changed files with 261 additions and 1 deletions
@@ -46,6 +46,48 @@ public class Fe10IdeNormalAnalysisSourceModuleTypeReferenceTestGenerated extends
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeProvider/typeReference"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationEntry.kt")
public void testAnnotationEntry() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntry.kt");
}
@Test
@TestMetadata("annotationEntryOnParameter.kt")
public void testAnnotationEntryOnParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntryOnParameter.kt");
}
@Test
@TestMetadata("annotationOnFunction.kt")
public void testAnnotationOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationOnFunction.kt");
}
@Test
@TestMetadata("functionReceiver.kt")
public void testFunctionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReceiver.kt");
}
@Test
@TestMetadata("functionReturn.kt")
public void testFunctionReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReturn.kt");
}
@Test
@TestMetadata("propertyReceiver.kt")
public void testPropertyReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReceiver.kt");
}
@Test
@TestMetadata("propertyReturn.kt")
public void testPropertyReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReturn.kt");
}
@Test
@TestMetadata("starProjection.kt")
public void testStarProjection() throws Exception {
@@ -20,15 +20,21 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbolOfTypeSafe
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker.isCompatible
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -38,8 +44,16 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
import org.jetbrains.kotlin.psi.KtDoubleColonExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.CaptureStatus
@@ -94,7 +108,29 @@ internal class KtFirTypeProvider(
}
override fun getKtType(ktTypeReference: KtTypeReference): KtType {
return when (val fir = ktTypeReference.getOrBuildFir(firResolveSession)) {
val parent = ktTypeReference.parent
val fir = when {
parent is KtParameter && parent.ownerFunction != null && parent.typeReference === ktTypeReference -> parent.resolveToFirSymbolOfTypeSafe<FirValueParameterSymbol>(
firResolveSession, FirResolvePhase.TYPES
)?.fir?.returnTypeRef
parent is KtCallableDeclaration && (parent is KtNamedFunction || parent is KtProperty) && (parent.receiverTypeReference === ktTypeReference || parent.typeReference === ktTypeReference) -> {
val firCallable = parent.resolveToFirSymbolOfTypeSafe<FirCallableSymbol<*>>(
firResolveSession, FirResolvePhase.TYPES
)?.fir
if (parent.receiverTypeReference === ktTypeReference) firCallable?.receiverParameter?.typeRef else firCallable?.returnTypeRef
}
parent is KtConstructorCalleeExpression && parent.parent is KtAnnotationEntry -> {
val firDeclaration = getFirDeclaration(parent.parent as KtAnnotationEntry, ktTypeReference)
if (firDeclaration != null) {
firDeclaration.annotations.find { it.realPsi === parent.parent }?.annotationTypeRef
?: (firDeclaration as? FirProperty)?.backingField?.annotations?.find { it.realPsi === parent.parent }?.annotationTypeRef
} else {
ktTypeReference.getOrBuildFir(firResolveSession)
}
}
else -> ktTypeReference.getOrBuildFir(firResolveSession)
}
return when (fir) {
is FirResolvedTypeRef -> fir.coneType.asKtType()
is FirDelegatedConstructorCall -> fir.constructedTypeRef.coneType.asKtType()
is FirTypeProjectionWithVariance -> {
@@ -107,6 +143,26 @@ internal class KtFirTypeProvider(
}
}
private fun getFirDeclaration(annotationEntry: KtAnnotationEntry, ktTypeReference: KtTypeReference): FirMemberDeclaration? {
if (annotationEntry.typeReference !== ktTypeReference) return null
val declaration = annotationEntry.parent?.parent as? KtNamedDeclaration ?: return null
return when {
declaration is KtClassOrObject -> declaration.resolveToFirSymbolOfTypeSafe<FirClassLikeSymbol<*>>(
firResolveSession, FirResolvePhase.TYPES
)?.fir
declaration is KtParameter && declaration.ownerFunction != null ->
declaration.resolveToFirSymbolOfTypeSafe<FirValueParameterSymbol>(
firResolveSession, FirResolvePhase.TYPES
)?.fir
declaration is KtCallableDeclaration && (declaration is KtNamedFunction || declaration is KtProperty) -> {
declaration.resolveToFirSymbolOfTypeSafe<FirCallableSymbol<*>>(
firResolveSession, FirResolvePhase.TYPES
)?.fir
}
else -> return null
}
}
override fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType? {
return when (val fir = expression.getOrBuildFir(firResolveSession)) {
is FirGetClassCall ->
@@ -46,6 +46,48 @@ public class FirIdeDependentAnalysisSourceModuleTypeReferenceTestGenerated exten
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeProvider/typeReference"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationEntry.kt")
public void testAnnotationEntry() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntry.kt");
}
@Test
@TestMetadata("annotationEntryOnParameter.kt")
public void testAnnotationEntryOnParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntryOnParameter.kt");
}
@Test
@TestMetadata("annotationOnFunction.kt")
public void testAnnotationOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationOnFunction.kt");
}
@Test
@TestMetadata("functionReceiver.kt")
public void testFunctionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReceiver.kt");
}
@Test
@TestMetadata("functionReturn.kt")
public void testFunctionReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReturn.kt");
}
@Test
@TestMetadata("propertyReceiver.kt")
public void testPropertyReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReceiver.kt");
}
@Test
@TestMetadata("propertyReturn.kt")
public void testPropertyReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReturn.kt");
}
@Test
@TestMetadata("starProjection.kt")
public void testStarProjection() throws Exception {
@@ -46,6 +46,48 @@ public class FirIdeNormalAnalysisSourceModuleTypeReferenceTestGenerated extends
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeProvider/typeReference"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationEntry.kt")
public void testAnnotationEntry() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntry.kt");
}
@Test
@TestMetadata("annotationEntryOnParameter.kt")
public void testAnnotationEntryOnParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntryOnParameter.kt");
}
@Test
@TestMetadata("annotationOnFunction.kt")
public void testAnnotationOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationOnFunction.kt");
}
@Test
@TestMetadata("functionReceiver.kt")
public void testFunctionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReceiver.kt");
}
@Test
@TestMetadata("functionReturn.kt")
public void testFunctionReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReturn.kt");
}
@Test
@TestMetadata("propertyReceiver.kt")
public void testPropertyReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReceiver.kt");
}
@Test
@TestMetadata("propertyReturn.kt")
public void testPropertyReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReturn.kt");
}
@Test
@TestMetadata("starProjection.kt")
public void testStarProjection() throws Exception {
@@ -46,6 +46,48 @@ public class FirStandaloneNormalAnalysisSourceModuleTypeReferenceTestGenerated e
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/typeProvider/typeReference"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationEntry.kt")
public void testAnnotationEntry() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntry.kt");
}
@Test
@TestMetadata("annotationEntryOnParameter.kt")
public void testAnnotationEntryOnParameter() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationEntryOnParameter.kt");
}
@Test
@TestMetadata("annotationOnFunction.kt")
public void testAnnotationOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/annotationOnFunction.kt");
}
@Test
@TestMetadata("functionReceiver.kt")
public void testFunctionReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReceiver.kt");
}
@Test
@TestMetadata("functionReturn.kt")
public void testFunctionReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/functionReturn.kt");
}
@Test
@TestMetadata("propertyReceiver.kt")
public void testPropertyReceiver() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReceiver.kt");
}
@Test
@TestMetadata("propertyReturn.kt")
public void testPropertyReturn() throws Exception {
runTest("analysis/analysis-api/testData/components/typeProvider/typeReference/propertyReturn.kt");
}
@Test
@TestMetadata("starProjection.kt")
public void testStarProjection() throws Exception {
@@ -0,0 +1,4 @@
annotation class Anno
@An<caret>no
class Sub
@@ -0,0 +1,2 @@
expression: Anno
ktType: Anno
@@ -0,0 +1,3 @@
annotation class Anno
fun f(@An<caret>no p: String) {}
@@ -0,0 +1,2 @@
expression: Anno
ktType: Anno
@@ -0,0 +1,3 @@
annotation class Anno
@An<caret>no
fun f() {}
@@ -0,0 +1,2 @@
expression: Anno
ktType: Anno
@@ -0,0 +1,3 @@
class Foo {}
fun F<caret>oo.f(): Boolean = false
@@ -0,0 +1,2 @@
expression: Foo
ktType: Foo
@@ -0,0 +1,3 @@
class Foo {}
fun Foo.f(): Boo<caret>lean = false
@@ -0,0 +1,2 @@
expression: Boolean
ktType: kotlin.Boolean
@@ -0,0 +1,3 @@
class Foo {}
var F<caret>oo.f: Boolean = false
@@ -0,0 +1,2 @@
expression: Foo
ktType: Foo
@@ -0,0 +1,3 @@
class Foo {}
var Foo.f: B<caret>oolean = false
@@ -0,0 +1,2 @@
expression: Boolean
ktType: kotlin.Boolean