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, useSiteSession: FirSession,
scopeSession: ScopeSession scopeSession: ScopeSession
) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) { ) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) {
val implicitCompanionScope: FirScope? = val implicitCompanionScopes: List<FirScope> = run {
(boundSymbol.fir as? FirRegularClass)?.companionObject?.buildUseSiteMemberScope(useSiteSession, scopeSession) 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( class ImplicitExtensionReceiverValue(
@@ -95,8 +95,8 @@ class FirTowerResolver(
) )
} }
if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) { if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) {
val implicitCompanionScope = implicitDispatchReceiverValue.implicitCompanionScope val implicitCompanionScopes = implicitDispatchReceiverValue.implicitCompanionScopes
if (implicitCompanionScope != null) { for (implicitCompanionScope in implicitCompanionScopes) {
// Extension in companion // Extension in companion
// class My { // class My {
// companion object { fun My.foo() {} } // companion object { fun My.foo() {} }
@@ -184,8 +184,8 @@ class FirTowerResolver(
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++) towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++)
} }
if (implicitReceiverValue is ImplicitDispatchReceiverValue) { if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
val implicitCompanionScope = implicitReceiverValue.implicitCompanionScope val implicitCompanionScopes = implicitReceiverValue.implicitCompanionScopes
if (implicitCompanionScope != null) { for (implicitCompanionScope in implicitCompanionScopes) {
// Companion scope bound to implicit receiver scope // Companion scope bound to implicit receiver scope
// class Outer { // class Outer {
// companion object { val x = 0 } // companion object { val x = 0 }
@@ -19,6 +19,12 @@ open class Protected {
protected fun bar() {} protected fun bar() {}
} }
protected companion object {
fun fromCompanion() {}
protected fun protectedFromCompanion() {}
}
} }
class Derived : Protected() { class Derived : Protected() {
@@ -26,9 +32,12 @@ class Derived : Protected() {
bar() bar()
Nested().foo() Nested().foo()
Nested().<!INAPPLICABLE_CANDIDATE!>bar<!>() // hidden Nested().<!INAPPLICABLE_CANDIDATE!>bar<!>() // hidden
fromCompanion()
<!INAPPLICABLE_CANDIDATE!>protectedFromCompanion<!>()
} }
class NestedDerived : Nested() { private class NestedDerived : Nested() {
fun use() { fun use() {
bar() 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 final class Derived : R|Protected| {
public constructor(): R|Derived| { public constructor(): R|Derived| {
@@ -47,9 +60,11 @@ FILE: protectedVisibility.kt
this@R|/Protected|.R|/Protected.bar|() this@R|/Protected|.R|/Protected.bar|()
R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|() R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
R|/Protected.Nested.Nested|().<Inapplicable(HIDDEN): [/Protected.Nested.bar]>#() 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| { public constructor(): R|Derived.NestedDerived| {
super<R|Protected.Nested|>() super<R|Protected.Nested|>()
} }