Skip to content

Commit 2fb066e

Browse files
lunakolySpace
authored and
Space
committed
KT-47101: Fix companion supertypes
1 parent 4f52ab6 commit 2fb066e

File tree

8 files changed

+96
-11
lines changed

8 files changed

+96
-11
lines changed

analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt

+33-9
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
2424
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
2525
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
2626
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
27-
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
2827
import org.jetbrains.kotlin.fir.scopes.FirScope
2928
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
3029
import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer
4342
import org.jetbrains.kotlin.name.ClassId
4443
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
4544
import org.jetbrains.kotlin.utils.addIfNotNull
45+
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
4646

4747
class FirSupertypeResolverProcessor(session: FirSession, scopeSession: ScopeSession) :
4848
FirTransformerBasedResolveProcessor(session, scopeSession) {
@@ -169,19 +169,22 @@ private fun FirClassLikeDeclaration.typeParametersScope(): FirScope? {
169169
return FirMemberTypeParameterScope(this)
170170
}
171171

172-
private fun createOtherScopesForNestedClasses(
172+
private fun createOtherScopesForNestedClassesOrCompanion(
173173
klass: FirClass,
174174
session: FirSession,
175175
scopeSession: ScopeSession,
176-
supertypeComputationSession: SupertypeComputationSession
176+
supertypeComputationSession: SupertypeComputationSession,
177+
withCompanionScopes: Boolean,
177178
): Collection<FirScope> =
178179
mutableListOf<FirScope>().apply {
179180
// Note: from higher priority to lower priority
180181
// See also: BodyResolveContext.withScopesForClass
181182
addIfNotNull(session.nestedClassifierScope(klass))
182-
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
183-
for (companionObject in companionObjects) {
184-
addIfNotNull(session.nestedClassifierScope(companionObject))
183+
if (withCompanionScopes) {
184+
val companionObjects = klass.declarations.filterIsInstance<FirRegularClass>().filter { it.isCompanion }
185+
for (companionObject in companionObjects) {
186+
addIfNotNull(session.nestedClassifierScope(companionObject))
187+
}
185188
}
186189
lookupSuperTypes(
187190
klass,
@@ -240,13 +243,26 @@ open class FirSupertypeResolverVisitor(
240243

241244
private fun prepareScopeForNestedClasses(klass: FirClass): ScopePersistentList {
242245
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
243-
val scopes = prepareScopes(klass)
246+
calculateScopes(klass, true)
247+
}
248+
}
244249

245-
resolveAllSupertypes(klass, klass.superTypeRefs)
246-
scopes.pushAll(createOtherScopesForNestedClasses(klass, session, scopeSession, supertypeComputationSession))
250+
private fun prepareScopeForCompanion(klass: FirClass): ScopePersistentList {
251+
return supertypeComputationSession.getOrPutScopeForCompanion(klass) {
252+
calculateScopes(klass, false)
247253
}
248254
}
249255

256+
private fun calculateScopes(
257+
klass: FirClass,
258+
withCompanionScopes: Boolean,
259+
): PersistentList<FirScope> {
260+
resolveAllSupertypes(klass, klass.superTypeRefs)
261+
return prepareScopes(klass).pushAll(
262+
createOtherScopesForNestedClassesOrCompanion(klass, session, scopeSession, supertypeComputationSession, withCompanionScopes)
263+
)
264+
}
265+
250266
private fun resolveAllSupertypes(
251267
classLikeDeclaration: FirClassLikeDeclaration,
252268
supertypeRefs: List<FirTypeRef>,
@@ -285,6 +301,10 @@ open class FirSupertypeResolverVisitor(
285301
else -> scopeForLocalClass ?: return persistentListOf()
286302
}
287303
}
304+
classLikeDeclaration.safeAs<FirRegularClass>()?.isCompanion == true -> {
305+
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
306+
prepareScopeForCompanion(outerClassFir ?: return persistentListOf())
307+
}
288308
classId.isNestedClass -> {
289309
val outerClassFir = classId.outerClassId?.let(::getFirClassifierByFqName) as? FirRegularClass
290310
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
@@ -446,6 +466,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
446466
class SupertypeComputationSession {
447467
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
448468
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
469+
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
449470
val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
450471

451472
val supertypesSupplier: SupertypeSupplier = object : SupertypeSupplier() {
@@ -473,6 +494,9 @@ class SupertypeComputationSession {
473494
fun getOrPutScopeForNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
474495
scopesForNestedClassesMap.getOrPut(klass) { scope() }
475496

497+
fun getOrPutScopeForCompanion(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
498+
scopesForCompanionMap.getOrPut(klass) { scope() }
499+
476500
fun startComputingSupertypes(classLikeDeclaration: FirClassLikeDeclaration) {
477501
require(supertypeStatusMap[classLikeDeclaration] == null) {
478502
"Unexpected in startComputingSupertypes supertype status for $classLikeDeclaration: ${supertypeStatusMap[classLikeDeclaration]}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// FIR_IDENTICAL
2+
open class B
3+
4+
class A {
5+
companion object : B() { // Nested B should be invisible here but it's not
6+
class B
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package
2+
3+
public final class A {
4+
public constructor A()
5+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
6+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
7+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
8+
9+
public companion object Companion : B {
10+
private constructor Companion()
11+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
12+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
13+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
14+
15+
public final class B {
16+
public constructor B()
17+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
18+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
19+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
20+
}
21+
}
22+
}
23+
24+
public open class B {
25+
public constructor B()
26+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
27+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
28+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
29+
}

compiler/testData/diagnostics/tests/scopes/classHeader/companionObjectParents.fir.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ val bImpl: B.Companion.Interface
77
get() = null!!
88

99
interface A {
10-
companion object : <!CYCLIC_INHERITANCE_HIERARCHY!>Nested<!>(), <!CYCLIC_INHERITANCE_HIERARCHY!>Interface<!> by aImpl, <!CYCLIC_INHERITANCE_HIERARCHY!>I<Nested, Interface><!> {
10+
companion object : <!UNRESOLVED_REFERENCE!>Nested<!>(), <!UNRESOLVED_REFERENCE!>Interface<!> by aImpl, I<<!UNRESOLVED_REFERENCE!>Nested<!>, <!UNRESOLVED_REFERENCE!>Interface<!>> {
1111

1212
class Nested
1313

@@ -16,7 +16,7 @@ interface A {
1616
}
1717

1818
class B {
19-
companion object : <!CYCLIC_INHERITANCE_HIERARCHY!>Nested<!>(), <!CYCLIC_INHERITANCE_HIERARCHY!>Interface<!> by aImpl, <!CYCLIC_INHERITANCE_HIERARCHY!>I<Nested, Interface><!> {
19+
companion object : <!UNRESOLVED_REFERENCE!>Nested<!>(), <!UNRESOLVED_REFERENCE!>Interface<!> by aImpl, I<<!UNRESOLVED_REFERENCE!>Nested<!>, <!UNRESOLVED_REFERENCE!>Interface<!>> {
2020

2121
class Nested
2222

compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)