diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/types/Fe10IdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/types/Fe10IdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java index f4a591ca3c0..87f2a0e2097 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/types/Fe10IdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/types/Fe10IdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java @@ -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 { 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 9cb076cec51..980da44f273 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 @@ -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(firDeclaration) } diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/types/FirIdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/types/FirIdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java index bfbc471aa77..efbd1a78982 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/types/FirIdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/types/FirIdeNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/types/FirStandaloneNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/types/FirStandaloneNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java index e4516b9e620..a574b71e831 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/types/FirStandaloneNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/types/FirStandaloneNormalAnalysisSourceModuleTypeByDeclarationReturnTypeTestGenerated.java @@ -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 { diff --git a/analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt b/analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.kt new file mode 100644 index 00000000000..f7de284b9fe --- /dev/null +++ b/analysis/analysis-api/testData/types/byDeclarationReturnType/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/types/byDeclarationReturnType/anonymousFunction.txt b/analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.txt new file mode 100644 index 00000000000..df3b49579c6 --- /dev/null +++ b/analysis/analysis-api/testData/types/byDeclarationReturnType/anonymousFunction.txt @@ -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: [] +] diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index 64301d608ef..c82e0f6429e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -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 }