From 2131cb4fe077f0c1ef0b4957a740f9f6c391c079 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Mon, 7 Nov 2022 23:41:39 -0800 Subject: [PATCH] AA FIR: functional type for anonymous function ^KTIJ-17657 In progress --- ...ceModuleHLExpressionTypeTestGenerated.java | 6 ++++ .../components/KtFirExpressionTypeProvider.kt | 31 +++++++++++++------ ...ceModuleHLExpressionTypeTestGenerated.java | 6 ++++ ...ceModuleHLExpressionTypeTestGenerated.java | 6 ++++ ...ceModuleHLExpressionTypeTestGenerated.java | 6 ++++ .../expressionType/anonymousFunction.kt | 3 ++ .../expressionType/anonymousFunction.txt | 2 ++ 7 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt create mode 100644 analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index 14251d9986a..e71aab4ad2d 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/expressionTypeProvider/Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -46,6 +46,12 @@ public class Fe10IdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exte KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt"); + } + @Test @TestMetadata("arrayElement_arrayOfNulls.kt") public void testArrayElement_arrayOfNulls() throws Exception { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionTypeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionTypeProvider.kt index 1bb1adaf313..51f7ead7967 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionTypeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirExpressionTypeProvider.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.analysis.api.fir.utils.getReferencedElementType import org.jetbrains.kotlin.analysis.api.fir.utils.unwrap import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion 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 @@ -20,7 +19,6 @@ import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirPackageDirective import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isSuspend -import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.FirNamedReference @@ -31,6 +29,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract internal class KtFirExpressionTypeProvider( override val analysisSession: KtFirAnalysisSession, @@ -96,20 +96,33 @@ internal class KtFirExpressionTypeProvider( } override fun getReturnTypeForKtDeclaration(declaration: KtDeclaration): KtType { - val firDeclaration = when { - declaration is KtNamedFunction && declaration.name == null -> - declaration.getOrBuildFirOfType(firResolveSession).anonymousFunction - else -> - declaration.getOrBuildFirOfType(firResolveSession) - } + val firDeclaration = if (isAnonymousFunction(declaration)) + declaration.toFirAnonymousFunction() + else + declaration.getOrBuildFirOfType(firResolveSession) return firDeclaration.returnTypeRef.coneType.asKtType() } override fun getFunctionalTypeForKtFunction(declaration: KtFunction): KtType { - val firFunction = declaration.getOrBuildFirOfType(firResolveSession) + val firFunction = if (isAnonymousFunction(declaration)) + declaration.toFirAnonymousFunction() + else + declaration.getOrBuildFirOfType(firResolveSession) return firFunction.constructFunctionalType(firFunction.isSuspend).asKtType() } + @OptIn(ExperimentalContracts::class) + private fun isAnonymousFunction(ktDeclaration: KtDeclaration): Boolean { + contract { + returns(true) implies (ktDeclaration is KtNamedFunction) + } + return ktDeclaration is KtFunction && ktDeclaration.name == null + } + + private fun KtFunction.toFirAnonymousFunction(): FirAnonymousFunction { + return getOrBuildFirOfType(firResolveSession).anonymousFunction + } + override fun getExpectedType(expression: PsiElement): KtType? { val unwrapped = expression.unwrap() val expectedType = getExpectedTypeByReturnExpression(unwrapped) diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java index 00cadc808ac..61e51c96204 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -46,6 +46,12 @@ public class FirIdeDependentAnalysisSourceModuleHLExpressionTypeTestGenerated ex KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt"); + } + @Test @TestMetadata("arrayElement_arrayOfNulls.kt") public void testArrayElement_arrayOfNulls() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index 4fe8a5fa498..fcdfd274911 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/expressionTypeProvider/FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -46,6 +46,12 @@ public class FirIdeNormalAnalysisSourceModuleHLExpressionTypeTestGenerated exten KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt"); + } + @Test @TestMetadata("arrayElement_arrayOfNulls.kt") public void testArrayElement_arrayOfNulls() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java index 69472014480..d154b072e8c 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/expressionTypeProvider/FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerated.java @@ -46,6 +46,12 @@ public class FirStandaloneNormalAnalysisSourceModuleHLExpressionTypeTestGenerate KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("anonymousFunction.kt") + public void testAnonymousFunction() throws Exception { + runTest("analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt"); + } + @Test @TestMetadata("arrayElement_arrayOfNulls.kt") public void testArrayElement_arrayOfNulls() throws Exception { diff --git a/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt new file mode 100644 index 00000000000..8cc67081999 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.kt @@ -0,0 +1,3 @@ +fun foo() { + val f = fun(it: String) {} +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.txt b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.txt new file mode 100644 index 00000000000..495dff50d17 --- /dev/null +++ b/analysis/analysis-api/testData/components/expressionTypeProvider/expressionType/anonymousFunction.txt @@ -0,0 +1,2 @@ +expression: fun(it: String) {} +type: (kotlin.String) -> kotlin.Unit