[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.fir.FirSession
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.isExpect
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -43,7 +45,10 @@ class KotlinScopeProvider(
if (symbol is FirRegularClassSymbol) {
symbol.fir.scope(
substitutor(symbol, useSiteSuperType, useSiteSession),
useSiteSession, scopeSession, skipPrivateMembers = true, klass.classId
useSiteSession, scopeSession,
skipPrivateMembers = true,
classId = klass.classId,
isFromExpectClass = (klass as? FirRegularClass)?.isExpect == true
).let {
it as? FirTypeScope ?: error("$it is expected to be FirOverrideAwareScope")
}
@@ -85,7 +90,7 @@ class KotlinScopeProvider(
data class ConeSubstitutionScopeKey(
val classId: ClassId?, val substitutor: ConeSubstitutor
val classId: ClassId?, val isFromExpectClass: Boolean, val substitutor: ConeSubstitutor
) : ScopeSessionKey<FirClass<*>, FirClassSubstitutionScope>()
fun FirClass<*>.unsubstitutedScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope {
@@ -97,7 +102,8 @@ internal fun FirClass<*>.scope(
useSiteSession: FirSession,
scopeSession: ScopeSession,
skipPrivateMembers: Boolean,
classId: ClassId? = this.classId
classId: ClassId? = this.classId,
isFromExpectClass: Boolean = false
): FirTypeScope {
val basicScope = scopeProvider.getUseSiteMemberScope(
this, useSiteSession, scopeSession
@@ -105,8 +111,11 @@ internal fun FirClass<*>.scope(
if (substitutor == ConeSubstitutor.Empty) return basicScope
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,
private val substitutor: ConeSubstitutor,
private val skipPrivateMembers: Boolean,
private val derivedClassId: ClassId? = null
private val derivedClassId: ClassId? = null,
private val makeExpect: Boolean = false
) : FirTypeScope() {
private val fakeOverrideFunctions = mutableMapOf<FirFunctionSymbol<*>, FirFunctionSymbol<*>>()
@@ -143,7 +144,8 @@ class FirClassSubstitutionScope(
newReturnType,
newParameterTypes,
newTypeParameters as List<FirTypeParameter>,
derivedClassId
derivedClassId,
makeExpect
)
}
@@ -161,7 +163,7 @@ class FirClassSubstitutionScope(
}
return createFakeOverrideConstructor(
FirConstructorSymbol(original.callableId, overriddenSymbol = original),
session, constructor, newReturnType, newParameterTypes, newTypeParameters
session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect
).symbol
}
@@ -185,7 +187,8 @@ class FirClassSubstitutionScope(
newReceiverType,
newReturnType,
newTypeParameters as List<FirTypeParameter>,
derivedClassId
derivedClassId,
makeExpect
)
}
@@ -474,7 +477,8 @@ class FirClassSubstitutionScope(
baseConstructor: FirConstructor,
newReturnType: ConeKotlinType? = null,
newParameterTypes: List<ConeKotlinType?>? = null,
newTypeParameters: List<FirTypeParameterRef>? = null
newTypeParameters: List<FirTypeParameterRef>? = null,
isExpect: Boolean = baseConstructor.isExpect
): FirConstructor {
// 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
@@ -484,7 +488,7 @@ class FirClassSubstitutionScope(
origin = FirDeclarationOrigin.FakeOverride
returnTypeRef = baseConstructor.returnTypeRef.withReplacedReturnType(newReturnType)
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
status = baseConstructor.status
status = baseConstructor.status.withExpect(isExpect)
symbol = fakeOverrideSymbol
resolvePhase = baseConstructor.resolvePhase
configureAnnotationsAndParameters(session, baseConstructor, newParameterTypes)
@@ -8,42 +8,40 @@ FILE fqName:<root> fileName:/expectedEnumClass.kt
ENUM_ENTRY name:BAR
init: EXPRESSION_BODY
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>
SYNTHETIC_BODY kind=ENUM_VALUES
FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:<root>.MyEnum
FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<<root>.MyEnum> [expect]
FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:<root>.MyEnum [expect]
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 [fake_override]
FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum<E of kotlin.Enum>) returnType:kotlin.Any [expect,fake_override]
overridden:
protected final fun clone (): kotlin.Any declared in 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:
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>
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:
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>
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:
public final fun hashCode (): kotlin.Int declared in 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:
public open fun toString (): kotlin.String declared in 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]
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:
public final fun <get-name> (): kotlin.String declared in 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]
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:
public final fun <get-ordinal> (): kotlin.Int declared in kotlin.Enum
$this: VALUE_PARAMETER name:<this> type:kotlin.Enum<E of kotlin.Enum>