diff --git a/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt b/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt new file mode 100644 index 00000000000..69f7b32f7e4 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt @@ -0,0 +1,19 @@ +abstract class Outer { + interface Nested { + fun bar() + } +} + +fun main() { + object : Outer() { + fun foo(n: Nested) { + n.bar() + } + } +} + +class Impl : Outer() { + fun foo(n: Nested) { + n.bar() + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.txt b/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.txt new file mode 100644 index 00000000000..f43cf4820ed --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.txt @@ -0,0 +1,35 @@ +FILE: typesFromSuperClasses.kt + public abstract class Outer : R|kotlin/Any| { + public constructor(): R|Outer| { + super() + } + + public abstract interface Nested : R|kotlin/Any| { + public abstract fun bar(): R|kotlin/Unit| + + } + + } + public final fun main(): R|kotlin/Unit| { + object : R|Outer| { + private constructor(): R|anonymous| { + super() + } + + public[local] final fun foo(n: R|Outer.Nested|): R|kotlin/Unit| { + R|/n|.R|/Outer.Nested.bar|() + } + + } + + } + public final class Impl : R|Outer| { + public constructor(): R|Impl| { + super() + } + + public final fun foo(n: R|Outer.Nested|): R|kotlin/Unit| { + R|/n|.R|/Outer.Nested.bar|() + } + + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 4dffb60f89f..ecdd1972bcd 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -1481,6 +1481,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { public void testImplicitInLocalClasses() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt"); } + + @TestMetadata("typesFromSuperClasses.kt") + public void testTypesFromSuperClasses() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt"); + } } @TestMetadata("compiler/fir/analysis-tests/testData/resolve/multifile") diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 8c775499204..f3e8892e674 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1481,6 +1481,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos public void testImplicitInLocalClasses() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt"); } + + @TestMetadata("typesFromSuperClasses.kt") + public void testTypesFromSuperClasses() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt"); + } } @TestMetadata("compiler/fir/analysis-tests/testData/resolve/multifile") diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 45198f78d93..f327054453d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -57,7 +57,6 @@ fun > F.runSupertypeResolvePhaseForLocalClass( localClassesNavigationInfo: LocalClassesNavigationInfo, ): F { val supertypeComputationSession = SupertypeComputationSession() - val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession) val supertypeResolverVisitor = FirSupertypeResolverVisitor( session, supertypeComputationSession, scopeSession, FirImmutableCompositeScope(ImmutableList.ofAll(currentScopeList)), @@ -67,6 +66,7 @@ fun > F.runSupertypeResolvePhaseForLocalClass( this.accept(supertypeResolverVisitor) supertypeComputationSession.breakLoops(session) + val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession) return this.transform(applySupertypesTransformer, null).single } @@ -84,17 +84,27 @@ private class FirApplySupertypesTransformer( } override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult { - if (regularClass.superTypeRefs.any { it !is FirResolvedTypeRef }) { - val supertypeRefs = getResolvedSupertypeRefs(regularClass) - - // TODO: Replace with an immutable version or transformer - regularClass.replaceSuperTypeRefs(supertypeRefs) - regularClass.replaceResolvePhase(FirResolvePhase.SUPER_TYPES) - } + applyResolvedSupertypesToClass(regularClass) return (regularClass.transformChildren(this, null) as FirRegularClass).compose() } + private fun applyResolvedSupertypesToClass(firClass: FirClass<*>) { + if (firClass.superTypeRefs.any { it !is FirResolvedTypeRef }) { + val supertypeRefs = getResolvedSupertypeRefs(firClass) + + // TODO: Replace with an immutable version or transformer + firClass.replaceSuperTypeRefs(supertypeRefs) + firClass.replaceResolvePhase(FirResolvePhase.SUPER_TYPES) + } + } + + override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Nothing?): CompositeTransformResult { + applyResolvedSupertypesToClass(anonymousObject) + + return super.transformAnonymousObject(anonymousObject, data) + } + private fun getResolvedSupertypeRefs(classLikeDeclaration: FirClassLikeDeclaration<*>): List { val status = supertypeComputationSession.getSupertypesComputationStatus(classLikeDeclaration) require(status is SupertypeComputationStatus.Computed) { @@ -253,6 +263,11 @@ private class FirSupertypeResolverVisitor( regularClass.acceptChildren(this) } + override fun visitAnonymousObject(anonymousObject: FirAnonymousObject) { + resolveSpecificClassLikeSupertypes(anonymousObject, anonymousObject.superTypeRefs) + anonymousObject.acceptChildren(this) + } + fun resolveSpecificClassLikeSupertypes( classLikeDeclaration: FirClassLikeDeclaration<*>, supertypeRefs: List