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");
|
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
|
@Test
|
||||||
@TestMetadata("companionObjectParents.kt")
|
@TestMetadata("companionObjectParents.kt")
|
||||||
public void testCompanionObjectParents() throws Exception {
|
public void testCompanionObjectParents() throws Exception {
|
||||||
|
|||||||
+6
@@ -25710,6 +25710,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
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
|
@Test
|
||||||
@TestMetadata("companionObjectParents.kt")
|
@TestMetadata("companionObjectParents.kt")
|
||||||
public void testCompanionObjectParents() throws Exception {
|
public void testCompanionObjectParents() throws Exception {
|
||||||
|
|||||||
+6
@@ -25710,6 +25710,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
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
|
@Test
|
||||||
@TestMetadata("companionObjectParents.kt")
|
@TestMetadata("companionObjectParents.kt")
|
||||||
public void testCompanionObjectParents() throws Exception {
|
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.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
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.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
||||||
import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope
|
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.name.ClassId
|
||||||
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) :
|
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) :
|
||||||
FirTransformerBasedResolveProcessor(session, scopeSession) {
|
FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||||
@@ -169,19 +169,22 @@ private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? {
|
|||||||
return FirMemberTypeParameterScope(this)
|
return FirMemberTypeParameterScope(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createOtherScopesForNestedClasses(
|
private fun createOtherScopesForNestedClassesOrCompanion(
|
||||||
klass: FirClass,
|
klass: FirClass,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
supertypeComputationSession: SupertypeComputationSession
|
supertypeComputationSession: SupertypeComputationSession,
|
||||||
|
withCompanionScopes: Boolean,
|
||||||
): Collection<FirScope> =
|
): Collection<FirScope> =
|
||||||
mutableListOf<FirScope>().apply {
|
mutableListOf<FirScope>().apply {
|
||||||
// Note: from higher priority to lower priority
|
// Note: from higher priority to lower priority
|
||||||
// See also: BodyResolveContext.withScopesForClass
|
// See also: BodyResolveContext.withScopesForClass
|
||||||
addIfNotNull(session.nestedClassifierScope(klass))
|
addIfNotNull(session.nestedClassifierScope(klass))
|
||||||
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
|
if (withCompanionScopes) {
|
||||||
for (companionObject in companionObjects) {
|
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
|
||||||
addIfNotNull(session.nestedClassifierScope(companionObject))
|
for (companionObject in companionObjects) {
|
||||||
|
addIfNotNull(session.nestedClassifierScope(companionObject))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lookupSuperTypes(
|
lookupSuperTypes(
|
||||||
klass,
|
klass,
|
||||||
@@ -240,13 +243,26 @@ open class FirSupertypeResolverVisitor(
|
|||||||
|
|
||||||
private fun prepareScopeForNestedClasses(klass: FirClass): ScopePersistentList {
|
private fun prepareScopeForNestedClasses(klass: FirClass): ScopePersistentList {
|
||||||
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
|
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
|
||||||
val scopes = prepareScopes(klass)
|
calculateScopes(klass, true)
|
||||||
|
|
||||||
resolveAllSupertypes(klass, klass.superTypeRefs)
|
|
||||||
scopes.pushAll(createOtherScopesForNestedClasses(klass, session, scopeSession, supertypeComputationSession))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
private fun resolveAllSupertypes(
|
||||||
classLikeDeclaration: FirClassLikeDeclaration,
|
classLikeDeclaration: FirClassLikeDeclaration,
|
||||||
supertypeRefs: List<FirTypeRef>,
|
supertypeRefs: List<FirTypeRef>,
|
||||||
@@ -285,6 +301,10 @@ open class FirSupertypeResolverVisitor(
|
|||||||
else -> scopeForLocalClass ?: return persistentListOf()
|
else -> scopeForLocalClass ?: return persistentListOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
classLikeDeclaration.safeAs<FirRegularClass>()?.isCompanion == true -> {
|
||||||
|
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
|
||||||
|
prepareScopeForCompanion(outerClassFir ?: return persistentListOf())
|
||||||
|
}
|
||||||
classId.isNestedClass -> {
|
classId.isNestedClass -> {
|
||||||
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
|
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
|
||||||
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
|
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
|
||||||
@@ -446,6 +466,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
|
|||||||
class SupertypeComputationSession {
|
class SupertypeComputationSession {
|
||||||
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
||||||
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||||
|
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||||
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
||||||
|
|
||||||
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
|
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
|
||||||
@@ -473,6 +494,9 @@ class SupertypeComputationSession {
|
|||||||
fun getOrPutScopeForNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
fun getOrPutScopeForNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||||
scopesForNestedClassesMap.getOrPut(klass) { scope() }
|
scopesForNestedClassesMap.getOrPut(klass) { scope() }
|
||||||
|
|
||||||
|
fun getOrPutScopeForCompanion(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||||
|
scopesForCompanionMap.getOrPut(klass) { scope() }
|
||||||
|
|
||||||
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration) {
|
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration) {
|
||||||
require(supertypeStatusMap[classLikeDeclaration] == null) {
|
require(supertypeStatusMap[classLikeDeclaration] == null) {
|
||||||
"Unexpected in startComputingSupertypes supertype status for $classLikeDeclaration: ${supertypeStatusMap[classLikeDeclaration]}"
|
"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!!
|
get() = null!!
|
||||||
|
|
||||||
interface A {
|
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
|
class Nested
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ interface A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class B {
|
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
|
class Nested
|
||||||
|
|
||||||
|
|||||||
Generated
+6
@@ -25722,6 +25722,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/scopes/classHeader/classParents.kt");
|
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
|
@Test
|
||||||
@TestMetadata("companionObjectParents.kt")
|
@TestMetadata("companionObjectParents.kt")
|
||||||
public void testCompanionObjectParents() throws Exception {
|
public void testCompanionObjectParents() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user