FIR: Fix type resolution for anonymous objects
^KT-39050 Fixed
This commit is contained in:
+19
@@ -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()
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FILE: typesFromSuperClasses.kt
|
||||
public abstract class Outer : R|kotlin/Any| {
|
||||
public constructor(): R|Outer| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
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<R|Outer|>()
|
||||
}
|
||||
|
||||
public[local] final fun foo(n: R|Outer.Nested|): R|kotlin/Unit| {
|
||||
R|<local>/n|.R|/Outer.Nested.bar|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public final class Impl : R|Outer| {
|
||||
public constructor(): R|Impl| {
|
||||
super<R|Outer|>()
|
||||
}
|
||||
|
||||
public final fun foo(n: R|Outer.Nested|): R|kotlin/Unit| {
|
||||
R|<local>/n|.R|/Outer.Nested.bar|()
|
||||
}
|
||||
|
||||
}
|
||||
Generated
+5
@@ -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")
|
||||
|
||||
+5
@@ -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")
|
||||
|
||||
+23
-8
@@ -57,7 +57,6 @@ fun <F : FirClass<F>> 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 : FirClass<F>> F.runSupertypeResolvePhaseForLocalClass(
|
||||
this.accept(supertypeResolverVisitor)
|
||||
supertypeComputationSession.breakLoops(session)
|
||||
|
||||
val applySupertypesTransformer = FirApplySupertypesTransformer(supertypeComputationSession)
|
||||
return this.transform<F, Nothing?>(applySupertypesTransformer, null).single
|
||||
}
|
||||
|
||||
@@ -84,17 +84,27 @@ private class FirApplySupertypesTransformer(
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
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<FirStatement> {
|
||||
applyResolvedSupertypesToClass(anonymousObject)
|
||||
|
||||
return super.transformAnonymousObject(anonymousObject, data)
|
||||
}
|
||||
|
||||
private fun getResolvedSupertypeRefs(classLikeDeclaration: FirClassLikeDeclaration<*>): List<FirTypeRef> {
|
||||
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<FirTypeRef>
|
||||
|
||||
Reference in New Issue
Block a user