FIR tower resolve: make companion members accessible from derived classes

This commit is contained in:
Mikhail Glukhikh
2019-11-18 13:53:36 +03:00
parent 802ed9b502
commit 7dea06d2a7
4 changed files with 38 additions and 8 deletions
@@ -89,8 +89,14 @@ class ImplicitDispatchReceiverValue(
useSiteSession: FirSession,
scopeSession: ScopeSession
) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) {
val implicitCompanionScope: FirScope? =
(boundSymbol.fir as? FirRegularClass)?.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)
val implicitCompanionScopes: List<FirScope> = run {
val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList()
listOfNotNull(klass.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)) +
lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull {
val superClass = (it as? ConeClassType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass
superClass?.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession)
}
}
}
class ImplicitExtensionReceiverValue(
@@ -95,8 +95,8 @@ class FirTowerResolver(
)
}
if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) {
val implicitCompanionScope = implicitDispatchReceiverValue.implicitCompanionScope
if (implicitCompanionScope != null) {
val implicitCompanionScopes = implicitDispatchReceiverValue.implicitCompanionScopes
for (implicitCompanionScope in implicitCompanionScopes) {
// Extension in companion
// class My {
// companion object { fun My.foo() {} }
@@ -184,8 +184,8 @@ class FirTowerResolver(
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++)
}
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
val implicitCompanionScope = implicitReceiverValue.implicitCompanionScope
if (implicitCompanionScope != null) {
val implicitCompanionScopes = implicitReceiverValue.implicitCompanionScopes
for (implicitCompanionScope in implicitCompanionScopes) {
// Companion scope bound to implicit receiver scope
// class Outer {
// companion object { val x = 0 }
@@ -19,6 +19,12 @@ open class Protected {
protected fun bar() {}
}
protected companion object {
fun fromCompanion() {}
protected fun protectedFromCompanion() {}
}
}
class Derived : Protected() {
@@ -26,9 +32,12 @@ class Derived : Protected() {
bar()
Nested().foo()
Nested().<!INAPPLICABLE_CANDIDATE!>bar<!>() // hidden
fromCompanion()
<!INAPPLICABLE_CANDIDATE!>protectedFromCompanion<!>()
}
class NestedDerived : Nested() {
private class NestedDerived : Nested() {
fun use() {
bar()
}
@@ -37,6 +37,19 @@ FILE: protectedVisibility.kt
}
protected final companion object Companion : R|kotlin/Any| {
private constructor(): R|Protected.Companion| {
super<R|kotlin/Any|>()
}
public final fun fromCompanion(): R|kotlin/Unit| {
}
protected final fun protectedFromCompanion(): R|kotlin/Unit| {
}
}
}
public final class Derived : R|Protected| {
public constructor(): R|Derived| {
@@ -47,9 +60,11 @@ FILE: protectedVisibility.kt
this@R|/Protected|.R|/Protected.bar|()
R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
R|/Protected.Nested.Nested|().<Inapplicable(HIDDEN): [/Protected.Nested.bar]>#()
this@R|/Protected.Companion|.R|/Protected.Companion.fromCompanion|()
<Inapplicable(HIDDEN): [/Protected.Companion.protectedFromCompanion]>#()
}
public final class NestedDerived : R|Protected.Nested| {
private final class NestedDerived : R|Protected.Nested| {
public constructor(): R|Derived.NestedDerived| {
super<R|Protected.Nested|>()
}