KT-47101: Fix companion supertypes

This commit is contained in:
Nikolay Lunyak
2021-11-15 13:22:38 +00:00
committed by Space
parent 4f52ab6ba1
commit 2fb066e261
8 changed files with 97 additions and 12 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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]}"
@@ -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
}
}
@@ -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
}
@@ -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
@@ -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 {