KT-47101: Fix companion supertypes
This commit is contained in:
+6
@@ -25710,6 +25710,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionNestedVsOuter.kt")
|
||||
public void testCompanionNestedVsOuter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/companionNestedVsOuter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObjectParents.kt")
|
||||
public void testCompanionObjectParents() throws Exception {
|
||||
|
||||
+6
@@ -25710,6 +25710,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionNestedVsOuter.kt")
|
||||
public void testCompanionNestedVsOuter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/companionNestedVsOuter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObjectParents.kt")
|
||||
public void testCompanionObjectParents() throws Exception {
|
||||
|
||||
+6
@@ -25710,6 +25710,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionNestedVsOuter.kt")
|
||||
public void testCompanionNestedVsOuter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/companionNestedVsOuter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObjectParents.kt")
|
||||
public void testCompanionObjectParents() throws Exception {
|
||||
|
||||
+34
-10
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
||||
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
||||
import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope
|
||||
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) :
|
||||
FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
@@ -169,19 +169,22 @@ private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? {
|
||||
return FirMemberTypeParameterScope(this)
|
||||
}
|
||||
|
||||
private fun createOtherScopesForNestedClasses(
|
||||
private fun createOtherScopesForNestedClassesOrCompanion(
|
||||
klass: FirClass,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
supertypeComputationSession: SupertypeComputationSession
|
||||
supertypeComputationSession: SupertypeComputationSession,
|
||||
withCompanionScopes: Boolean,
|
||||
): Collection<FirScope> =
|
||||
mutableListOf<FirScope>().apply {
|
||||
// Note: from higher priority to lower priority
|
||||
// See also: BodyResolveContext.withScopesForClass
|
||||
addIfNotNull(session.nestedClassifierScope(klass))
|
||||
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
|
||||
for (companionObject in companionObjects) {
|
||||
addIfNotNull(session.nestedClassifierScope(companionObject))
|
||||
if (withCompanionScopes) {
|
||||
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
|
||||
for (companionObject in companionObjects) {
|
||||
addIfNotNull(session.nestedClassifierScope(companionObject))
|
||||
}
|
||||
}
|
||||
lookupSuperTypes(
|
||||
klass,
|
||||
@@ -240,13 +243,26 @@ open class FirSupertypeResolverVisitor(
|
||||
|
||||
private fun prepareScopeForNestedClasses(klass: FirClass): ScopePersistentList {
|
||||
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
|
||||
val scopes = prepareScopes(klass)
|
||||
|
||||
resolveAllSupertypes(klass, klass.superTypeRefs)
|
||||
scopes.pushAll(createOtherScopesForNestedClasses(klass, session, scopeSession, supertypeComputationSession))
|
||||
calculateScopes(klass, true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareScopeForCompanion(klass: FirClass): ScopePersistentList {
|
||||
return supertypeComputationSession.getOrPutScopeForCompanion(klass) {
|
||||
calculateScopes(klass, false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateScopes(
|
||||
klass: FirClass,
|
||||
withCompanionScopes: Boolean,
|
||||
): PersistentList<FirScope> {
|
||||
resolveAllSupertypes(klass, klass.superTypeRefs)
|
||||
return prepareScopes(klass).pushAll(
|
||||
createOtherScopesForNestedClassesOrCompanion(klass, session, scopeSession, supertypeComputationSession, withCompanionScopes)
|
||||
)
|
||||
}
|
||||
|
||||
private fun resolveAllSupertypes(
|
||||
classLikeDeclaration: FirClassLikeDeclaration,
|
||||
supertypeRefs: List<FirTypeRef>,
|
||||
@@ -285,6 +301,10 @@ open class FirSupertypeResolverVisitor(
|
||||
else -> scopeForLocalClass ?: return persistentListOf()
|
||||
}
|
||||
}
|
||||
classLikeDeclaration.safeAs<FirRegularClass>()?.isCompanion == true -> {
|
||||
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
|
||||
prepareScopeForCompanion(outerClassFir ?: return persistentListOf())
|
||||
}
|
||||
classId.isNestedClass -> {
|
||||
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
|
||||
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
|
||||
@@ -446,6 +466,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
|
||||
class SupertypeComputationSession {
|
||||
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
||||
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
||||
|
||||
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
|
||||
@@ -473,6 +494,9 @@ class SupertypeComputationSession {
|
||||
fun getOrPutScopeForNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||
scopesForNestedClassesMap.getOrPut(klass) { scope() }
|
||||
|
||||
fun getOrPutScopeForCompanion(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||
scopesForCompanionMap.getOrPut(klass) { scope() }
|
||||
|
||||
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration) {
|
||||
require(supertypeStatusMap[classLikeDeclaration] == null) {
|
||||
"Unexpected in startComputingSupertypes supertype status for $classLikeDeclaration: ${supertypeStatusMap[classLikeDeclaration]}"
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// FIR_IDENTICAL
|
||||
open class B
|
||||
|
||||
class A {
|
||||
companion object : B() { // Nested B should be invisible here but it's not
|
||||
class B
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public companion object Companion : B {
|
||||
private constructor Companion()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class B {
|
||||
public constructor B()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public open class B {
|
||||
public constructor B()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ val bImpl: B.Companion.Interface
|
||||
get() = null!!
|
||||
|
||||
interface A {
|
||||
companion object : <!CYCLIC_INHERITANCE_HIERARCHY!>Nested<!>(), <!CYCLIC_INHERITANCE_HIERARCHY!>Interface<!> by aImpl, <!CYCLIC_INHERITANCE_HIERARCHY!>I<Nested, Interface><!> {
|
||||
companion object : <!UNRESOLVED_REFERENCE!>Nested<!>(), <!UNRESOLVED_REFERENCE!>Interface<!> by aImpl, I<<!UNRESOLVED_REFERENCE!>Nested<!>, <!UNRESOLVED_REFERENCE!>Interface<!>> {
|
||||
|
||||
class Nested
|
||||
|
||||
@@ -16,7 +16,7 @@ interface A {
|
||||
}
|
||||
|
||||
class B {
|
||||
companion object : <!CYCLIC_INHERITANCE_HIERARCHY!>Nested<!>(), <!CYCLIC_INHERITANCE_HIERARCHY!>Interface<!> by aImpl, <!CYCLIC_INHERITANCE_HIERARCHY!>I<Nested, Interface><!> {
|
||||
companion object : <!UNRESOLVED_REFERENCE!>Nested<!>(), <!UNRESOLVED_REFERENCE!>Interface<!> by aImpl, I<<!UNRESOLVED_REFERENCE!>Nested<!>, <!UNRESOLVED_REFERENCE!>Interface<!>> {
|
||||
|
||||
class Nested
|
||||
|
||||
|
||||
Generated
+6
@@ -25722,6 +25722,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionNestedVsOuter.kt")
|
||||
public void testCompanionNestedVsOuter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/companionNestedVsOuter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObjectParents.kt")
|
||||
public void testCompanionObjectParents() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user