[FIR] Take class expect flag into account in its substitution scope

This commit is contained in:
Mikhail Glukhikh
2020-06-24 17:04:21 +03:00
parent c1609ed490
commit fcabd02fe8
3 changed files with 35 additions and 24 deletions
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.scopes
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.classId import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.declarations.isExpect
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -43,7 +45,10 @@ class KotlinScopeProvider(
if (symbol is FirRegularClassSymbol) { if (symbol is FirRegularClassSymbol) {
symbol.fir.scope( symbol.fir.scope(
substitutor(symbol, useSiteSuperType, useSiteSession), substitutor(symbol, useSiteSuperType, useSiteSession),
useSiteSession, scopeSession, skipPrivateMembers = true, klass.classId useSiteSession, scopeSession,
skipPrivateMembers = true,
classId = klass.classId,
isFromExpectClass = (klass as? FirRegularClass)?.isExpect == true
).let { ).let {
it as? FirTypeScope ?: error("$it is expected to be FirOverrideAwareScope") it as? FirTypeScope ?: error("$it is expected to be FirOverrideAwareScope")
} }
@@ -85,7 +90,7 @@ class KotlinScopeProvider(
data class ConeSubstitutionScopeKey( data class ConeSubstitutionScopeKey(
val classId: ClassId?, val substitutor: ConeSubstitutor val classId: ClassId?, val isFromExpectClass: Boolean, val substitutor: ConeSubstitutor
) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>() ) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope { fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
@@ -97,7 +102,8 @@ internal fun FirClass<*>.scope(
useSiteSession: FirSession, useSiteSession: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,
skipPrivateMembers: Boolean, skipPrivateMembers: Boolean,
classId: ClassId? = this.classId classId: ClassId? = this.classId,
isFromExpectClass: Boolean = false
): FirTypeScope { ): FirTypeScope {
val basicScope = scopeProvider.getUseSiteMemberScope( val basicScope = scopeProvider.getUseSiteMemberScope(
this, useSiteSession, scopeSession this, useSiteSession, scopeSession
@@ -105,8 +111,11 @@ internal fun FirClass<*>.scope(
if (substitutor == ConeSubstitutor.Empty) return basicScope if (substitutor == ConeSubstitutor.Empty) return basicScope
return scopeSession.getOrBuild( return scopeSession.getOrBuild(
this, ConeSubstitutionScopeKey(classId, substitutor) this, ConeSubstitutionScopeKey(classId, isFromExpectClass, substitutor)
) { ) {
FirClassSubstitutionScope(useSiteSession, basicScope, scopeSession, substitutor, skipPrivateMembers, classId) FirClassSubstitutionScope(
useSiteSession, basicScope, scopeSession, substitutor,
skipPrivateMembers, classId, makeExpect = isFromExpectClass
)
} }
} }
@@ -40,7 +40,8 @@ class FirClassSubstitutionScope(
scopeSession: ScopeSession, scopeSession: ScopeSession,
private val substitutor: ConeSubstitutor, private val substitutor: ConeSubstitutor,
private val skipPrivateMembers: Boolean, private val skipPrivateMembers: Boolean,
private val derivedClassId: ClassId? = null private val derivedClassId: ClassId? = null,
private val makeExpect: Boolean = false
) : FirTypeScope() { ) : FirTypeScope() {
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>() private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
@@ -143,7 +144,8 @@ class FirClassSubstitutionScope(
newReturnType, newReturnType,
newParameterTypes, newParameterTypes,
newTypeParameters as List<FirTypeParameter>, newTypeParameters as List<FirTypeParameter>,
derivedClassId derivedClassId,
makeExpect
) )
} }
@@ -161,7 +163,7 @@ class FirClassSubstitutionScope(
} }
return createFakeOverrideConstructor( return createFakeOverrideConstructor(
FirConstructorSymbol(original.callableId, overriddenSymbol = original), FirConstructorSymbol(original.callableId, overriddenSymbol = original),
session, constructor, newReturnType, newParameterTypes, newTypeParameters session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect
).symbol ).symbol
} }
@@ -185,7 +187,8 @@ class FirClassSubstitutionScope(
newReceiverType, newReceiverType,
newReturnType, newReturnType,
newTypeParameters as List<FirTypeParameter>, newTypeParameters as List<FirTypeParameter>,
derivedClassId derivedClassId,
makeExpect
) )
} }
@@ -474,7 +477,8 @@ class FirClassSubstitutionScope(
baseConstructor: FirConstructor, baseConstructor: FirConstructor,
newReturnType: ConeKotlinType? = null, newReturnType: ConeKotlinType? = null,
newParameterTypes: List<ConeKotlinType?>? = null, newParameterTypes: List<ConeKotlinType?>? = null,
newTypeParameters: List<FirTypeParameterRef>? = null newTypeParameters: List<FirTypeParameterRef>? = null,
isExpect: Boolean = baseConstructor.isExpect
): FirConstructor { ): FirConstructor {
// TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl // TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl
// As second alternative, we can invent some light-weight kind of FirRegularClass // As second alternative, we can invent some light-weight kind of FirRegularClass
@@ -484,7 +488,7 @@ class FirClassSubstitutionScope(
origin = FirDeclarationOrigin.FakeOverride origin = FirDeclarationOrigin.FakeOverride
returnTypeRef = baseConstructor.returnTypeRef.withReplacedReturnType(newReturnType) returnTypeRef = baseConstructor.returnTypeRef.withReplacedReturnType(newReturnType)
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null) receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
status = baseConstructor.status status = baseConstructor.status.withExpect(isExpect)
symbol = fakeOverrideSymbol symbol = fakeOverrideSymbol
resolvePhase = baseConstructor.resolvePhase resolvePhase = baseConstructor.resolvePhase
configureAnnotationsAndParameters(session, baseConstructor, newParameterTypes) configureAnnotationsAndParameters(session, baseConstructor, newParameterTypes)
@@ -8,42 +8,40 @@ FILE fqName:<root> fileName:/expectedEnumClass.kt
ENUM_ENTRY name:BAR ENUM_ENTRY name:BAR
init: EXPRESSION_BODY init: EXPRESSION_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> () [primary,expect] declared in <root>.MyEnum' ENUM_CONSTRUCTOR_CALL 'private constructor <init> () [primary,expect] declared in <root>.MyEnum'
FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.MyEnum> FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.MyEnum> [expect]
SYNTHETIC_BODY kind=ENUM_VALUES FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:<root>.MyEnum [expect]
FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:<root>.MyEnum
VALUE_PARAMETER name:value index:0 type:kotlin.String VALUE_PARAMETER name:value index:0 type:kotlin.String
SYNTHETIC_BODY kind=ENUM_VALUEOF FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Any [expect,fake_override]
FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Any [fake_override]
overridden: overridden:
protected final fun clone (): kotlin.Any declared in kotlin.Enum protected final fun clone (): kotlin.Any declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
FUN FAKE_OVERRIDE name:compareTo visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>, other:<root>.MyEnum) returnType:kotlin.Int [fake_override,operator] FUN FAKE_OVERRIDE name:compareTo visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>, other:<root>.MyEnum) returnType:kotlin.Int [expect,fake_override]
overridden: overridden:
public final fun compareTo (other: E of kotlin.Enum): kotlin.Int [operator] declared in kotlin.Enum public final fun compareTo (other: E of kotlin.Enum): kotlin.Int [operator] declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
VALUE_PARAMETER name:other index:0 type:<root>.MyEnum VALUE_PARAMETER name:other index:0 type:<root>.MyEnum
FUN FAKE_OVERRIDE name:equals visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] FUN FAKE_OVERRIDE name:equals visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>, other:kotlin.Any?) returnType:kotlin.Boolean [expect,fake_override]
overridden: overridden:
public final fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Enum public final fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
VALUE_PARAMETER name:other index:0 type:kotlin.Any? VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Int [fake_override] FUN FAKE_OVERRIDE name:hashCode visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Int [expect,fake_override]
overridden: overridden:
public final fun hashCode (): kotlin.Int declared in kotlin.Enum public final fun hashCode (): kotlin.Int declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.String [fake_override] FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.String [expect,fake_override]
overridden: overridden:
public open fun toString (): kotlin.String declared in kotlin.Enum public open fun toString (): kotlin.String declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [expect,fake_override,val]
FUN FAKE_OVERRIDE name:<get-name> visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.String [fake_override] FUN FAKE_OVERRIDE name:<get-name> visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.String [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] correspondingProperty: PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [expect,fake_override,val]
overridden: overridden:
public final fun <get-name> (): kotlin.String declared in kotlin.Enum public final fun <get-name> (): kotlin.String declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>
PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [expect,fake_override,val]
FUN FAKE_OVERRIDE name:<get-ordinal> visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Int [fake_override] FUN FAKE_OVERRIDE name:<get-ordinal> visibility:public modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Int [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] correspondingProperty: PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [expect,fake_override,val]
overridden: overridden:
public final fun <get-ordinal> (): kotlin.Int declared in kotlin.Enum public final fun <get-ordinal> (): kotlin.Int declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum> $this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>