[FIR] Don't force calculation of return type in substitution scope
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
FILE: implicitTypeInFakeOverride.kt
|
||||||
|
public final fun <K> extract(x: R|Out<K>|): R|T| {
|
||||||
|
^extract R|<local>/x|.R|/Out.get|()
|
||||||
|
}
|
||||||
|
public final class Out<out T> : R|kotlin/Any| {
|
||||||
|
public constructor<out T>(x: R|T|): R|Out<T>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val x: R|T| = R|<local>/x|
|
||||||
|
public get(): R|T|
|
||||||
|
|
||||||
|
public final fun get(): R|T| {
|
||||||
|
^get this@R|/Out|.R|/Out.x|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.scopes
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataKey
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataRegistry
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
|
||||||
|
abstract class FakeOverrideTypeCalculator {
|
||||||
|
abstract fun computeReturnType(declaration: FirTypedDeclaration): ConeKotlinType?
|
||||||
|
|
||||||
|
class DoNothing : FakeOverrideTypeCalculator() {
|
||||||
|
override fun computeReturnType(declaration: FirTypedDeclaration): ConeKotlinType? {
|
||||||
|
return declaration.returnTypeRef.coneTypeSafe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ForcedFakeOverrideTypeCalculator : FakeOverrideTypeCalculator() {
|
||||||
|
override fun computeReturnType(declaration: FirTypedDeclaration): ConeKotlinType {
|
||||||
|
declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let { return it }
|
||||||
|
val (substitutor, baseSymbol) = declaration.attributes.fakeOverrideSubstitution ?: error("")
|
||||||
|
val baseDeclaration = baseSymbol.fir as FirTypedDeclaration
|
||||||
|
val returnType = computeReturnType(baseDeclaration)
|
||||||
|
declaration.attributes.fakeOverrideSubstitution = null
|
||||||
|
return substitutor.substituteOrSelf(returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
object FakeOverrideSubstitutionKey : FirDeclarationDataKey()
|
||||||
|
|
||||||
|
var FirDeclarationAttributes.fakeOverrideSubstitution: FakeOverrideSubstitution? by FirDeclarationDataRegistry.attributesAccessor(
|
||||||
|
FakeOverrideSubstitutionKey
|
||||||
|
)
|
||||||
|
|
||||||
|
data class FakeOverrideSubstitution(
|
||||||
|
val substitutor: ConeSubstitutor,
|
||||||
|
val baseSymbol: AbstractFirBasedSymbol<*>
|
||||||
|
)
|
||||||
+31
-16
@@ -13,12 +13,14 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
import org.jetbrains.kotlin.fir.resolve.substitution.chain
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
class FirClassSubstitutionScope(
|
class FirClassSubstitutionScope(
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
@@ -126,13 +128,13 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||||
|
|
||||||
val (newTypeParameters, newReceiverType, newReturnType, newSubstitutor) = createSubstitutedData(member)
|
val (newTypeParameters, newReceiverType, newReturnType, newSubstitutor, fakeOverrideSubstitution) = createSubstitutedData(member)
|
||||||
val newParameterTypes = member.valueParameters.map {
|
val newParameterTypes = member.valueParameters.map {
|
||||||
it.returnTypeRef.coneType.substitute(newSubstitutor)
|
it.returnTypeRef.coneType.substitute(newSubstitutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } &&
|
if (newReceiverType == null && newReturnType == null && newParameterTypes.all { it == null } &&
|
||||||
newTypeParameters === member.typeParameters) {
|
newTypeParameters === member.typeParameters && fakeOverrideSubstitution == null) {
|
||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +152,8 @@ class FirClassSubstitutionScope(
|
|||||||
newParameterTypes,
|
newParameterTypes,
|
||||||
newTypeParameters as List<FirTypeParameter>,
|
newTypeParameters as List<FirTypeParameter>,
|
||||||
derivedClassId,
|
derivedClassId,
|
||||||
makeExpect
|
makeExpect,
|
||||||
|
fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +161,7 @@ class FirClassSubstitutionScope(
|
|||||||
if (substitutor == ConeSubstitutor.Empty) return original
|
if (substitutor == ConeSubstitutor.Empty) return original
|
||||||
val constructor = original.fir
|
val constructor = original.fir
|
||||||
|
|
||||||
val (newTypeParameters, _, newReturnType, newSubstitutor) = createSubstitutedData(constructor)
|
val (newTypeParameters, _, newReturnType, newSubstitutor, fakeOverrideSubstitution) = createSubstitutedData(constructor)
|
||||||
val newParameterTypes = constructor.valueParameters.map {
|
val newParameterTypes = constructor.valueParameters.map {
|
||||||
it.returnTypeRef.coneType.substitute(newSubstitutor)
|
it.returnTypeRef.coneType.substitute(newSubstitutor)
|
||||||
}
|
}
|
||||||
@@ -168,7 +171,7 @@ class FirClassSubstitutionScope(
|
|||||||
}
|
}
|
||||||
return FirFakeOverrideGenerator.createFakeOverrideConstructor(
|
return FirFakeOverrideGenerator.createFakeOverrideConstructor(
|
||||||
FirConstructorSymbol(original.callableId, overriddenSymbol = original),
|
FirConstructorSymbol(original.callableId, overriddenSymbol = original),
|
||||||
session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect
|
session, constructor, newReturnType, newParameterTypes, newTypeParameters, makeExpect, fakeOverrideSubstitution
|
||||||
).symbol
|
).symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +180,7 @@ class FirClassSubstitutionScope(
|
|||||||
val member = original.fir
|
val member = original.fir
|
||||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||||
|
|
||||||
val (newTypeParameters, newReceiverType, newReturnType, _) = createSubstitutedData(member)
|
val (newTypeParameters, newReceiverType, newReturnType, _, fakeOverrideSubstitution) = createSubstitutedData(member)
|
||||||
if (newReceiverType == null &&
|
if (newReceiverType == null &&
|
||||||
newReturnType == null && newTypeParameters === member.typeParameters
|
newReturnType == null && newTypeParameters === member.typeParameters
|
||||||
) {
|
) {
|
||||||
@@ -193,7 +196,8 @@ class FirClassSubstitutionScope(
|
|||||||
newReturnType,
|
newReturnType,
|
||||||
newTypeParameters as List<FirTypeParameter>,
|
newTypeParameters as List<FirTypeParameter>,
|
||||||
derivedClassId,
|
derivedClassId,
|
||||||
makeExpect
|
makeExpect,
|
||||||
|
fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +205,8 @@ class FirClassSubstitutionScope(
|
|||||||
val typeParameters: List<FirTypeParameterRef>,
|
val typeParameters: List<FirTypeParameterRef>,
|
||||||
val receiverType: ConeKotlinType?,
|
val receiverType: ConeKotlinType?,
|
||||||
val returnType: ConeKotlinType?,
|
val returnType: ConeKotlinType?,
|
||||||
val substitutor: ConeSubstitutor
|
val substitutor: ConeSubstitutor,
|
||||||
|
val fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData {
|
private fun createSubstitutedData(member: FirCallableMemberDeclaration<*>): SubstitutedData {
|
||||||
@@ -214,9 +219,10 @@ class FirClassSubstitutionScope(
|
|||||||
val receiverType = member.receiverTypeRef?.coneType
|
val receiverType = member.receiverTypeRef?.coneType
|
||||||
val newReceiverType = receiverType?.substitute(substitutor)
|
val newReceiverType = receiverType?.substitute(substitutor)
|
||||||
|
|
||||||
val returnType = member.returnTypeRef.coneType
|
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
val newReturnType = returnType.substitute(substitutor)
|
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, member.symbol) }
|
||||||
return SubstitutedData(newTypeParameters, newReceiverType, newReturnType, substitutor)
|
val newReturnType = returnType?.substitute(substitutor)
|
||||||
|
return SubstitutedData(newTypeParameters, newReceiverType, newReturnType, substitutor, fakeOverrideSubstitution)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
private fun createFakeOverrideField(original: FirFieldSymbol): FirFieldSymbol {
|
||||||
@@ -224,8 +230,9 @@ class FirClassSubstitutionScope(
|
|||||||
val member = original.fir
|
val member = original.fir
|
||||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||||
|
|
||||||
val returnType = member.returnTypeRef.coneType
|
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
val newReturnType = returnType.substitute() ?: return original
|
// TODO: do we have fields with implicit type?
|
||||||
|
val newReturnType = returnType?.substitute() ?: return original
|
||||||
|
|
||||||
return FirFakeOverrideGenerator.createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
|
return FirFakeOverrideGenerator.createFakeOverrideField(session, member, original, newReturnType, derivedClassId)
|
||||||
}
|
}
|
||||||
@@ -235,8 +242,9 @@ class FirClassSubstitutionScope(
|
|||||||
val member = original.fir as FirSyntheticProperty
|
val member = original.fir as FirSyntheticProperty
|
||||||
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
|
||||||
|
|
||||||
val returnType = member.returnTypeRef.coneType
|
val returnType = member.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
val newReturnType = returnType.substitute()
|
val fakeOverrideSubstitution = runIf(returnType == null) { FakeOverrideSubstitution(substitutor, original) }
|
||||||
|
val newReturnType = returnType?.substitute()
|
||||||
|
|
||||||
val newParameterTypes = member.getter.valueParameters.map {
|
val newParameterTypes = member.getter.valueParameters.map {
|
||||||
it.returnTypeRef.coneType.substitute()
|
it.returnTypeRef.coneType.substitute()
|
||||||
@@ -246,7 +254,14 @@ class FirClassSubstitutionScope(
|
|||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
|
|
||||||
return FirFakeOverrideGenerator.createFakeOverrideAccessor(session, member, original, newReturnType, newParameterTypes)
|
return FirFakeOverrideGenerator.createFakeOverrideAccessor(
|
||||||
|
session,
|
||||||
|
member,
|
||||||
|
original,
|
||||||
|
newReturnType,
|
||||||
|
newParameterTypes,
|
||||||
|
fakeOverrideSubstitution
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
|||||||
+107
-36
@@ -16,12 +16,16 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
|
||||||
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
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FakeOverrideSubstitution
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
object FirFakeOverrideGenerator {
|
object FirFakeOverrideGenerator {
|
||||||
fun createFakeOverrideFunction(
|
fun createFakeOverrideFunction(
|
||||||
@@ -33,14 +37,16 @@ object FirFakeOverrideGenerator {
|
|||||||
newParameterTypes: List<ConeKotlinType?>? = null,
|
newParameterTypes: List<ConeKotlinType?>? = null,
|
||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
derivedClassId: ClassId? = null,
|
derivedClassId: ClassId? = null,
|
||||||
isExpect: Boolean = baseFunction.isExpect
|
isExpect: Boolean = baseFunction.isExpect,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||||
): FirNamedFunctionSymbol {
|
): FirNamedFunctionSymbol {
|
||||||
val symbol = FirNamedFunctionSymbol(
|
val symbol = FirNamedFunctionSymbol(
|
||||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseFunction.name),
|
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseFunction.name),
|
||||||
isFakeOverride = true, overriddenSymbol = baseSymbol
|
isFakeOverride = true, overriddenSymbol = baseSymbol
|
||||||
)
|
)
|
||||||
createFakeOverrideFunction(
|
createFakeOverrideFunction(
|
||||||
symbol, session, baseFunction, newReceiverType, newReturnType, newParameterTypes, newTypeParameters, isExpect
|
symbol, session, baseFunction, newReceiverType, newReturnType,
|
||||||
|
newParameterTypes, newTypeParameters, isExpect, fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
@@ -54,6 +60,7 @@ object FirFakeOverrideGenerator {
|
|||||||
newParameterTypes: List<ConeKotlinType?>?,
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
newTypeParameters: List<FirTypeParameter>?,
|
newTypeParameters: List<FirTypeParameter>?,
|
||||||
isExpect: Boolean = baseFunction.isExpect,
|
isExpect: Boolean = baseFunction.isExpect,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?,
|
||||||
): FirSimpleFunction {
|
): FirSimpleFunction {
|
||||||
// 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
|
||||||
@@ -66,7 +73,8 @@ object FirFakeOverrideGenerator {
|
|||||||
newParameterTypes,
|
newParameterTypes,
|
||||||
newTypeParameters,
|
newTypeParameters,
|
||||||
newReceiverType,
|
newReceiverType,
|
||||||
newReturnType
|
newReturnType,
|
||||||
|
fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +90,7 @@ object FirFakeOverrideGenerator {
|
|||||||
newReturnType: ConeKotlinType? = null,
|
newReturnType: ConeKotlinType? = null,
|
||||||
newModality: Modality? = null,
|
newModality: Modality? = null,
|
||||||
newVisibility: Visibility? = null,
|
newVisibility: Visibility? = null,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||||
): FirSimpleFunction {
|
): FirSimpleFunction {
|
||||||
return buildSimpleFunction {
|
return buildSimpleFunction {
|
||||||
source = baseFunction.source
|
source = baseFunction.source
|
||||||
@@ -93,7 +102,8 @@ object FirFakeOverrideGenerator {
|
|||||||
resolvePhase = baseFunction.resolvePhase
|
resolvePhase = baseFunction.resolvePhase
|
||||||
|
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
session, baseFunction, newParameterTypes, newTypeParameters, newReceiverType, newReturnType
|
session, baseFunction, newParameterTypes,
|
||||||
|
newTypeParameters, newReceiverType, newReturnType, fakeOverrideSubstitution
|
||||||
).filterIsInstance<FirTypeParameter>()
|
).filterIsInstance<FirTypeParameter>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +115,8 @@ object FirFakeOverrideGenerator {
|
|||||||
newReturnType: ConeKotlinType?,
|
newReturnType: ConeKotlinType?,
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
newTypeParameters: List<FirTypeParameterRef>?,
|
newTypeParameters: List<FirTypeParameterRef>?,
|
||||||
isExpect: Boolean
|
isExpect: Boolean,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
): 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
|
||||||
@@ -119,7 +130,7 @@ object FirFakeOverrideGenerator {
|
|||||||
resolvePhase = baseConstructor.resolvePhase
|
resolvePhase = baseConstructor.resolvePhase
|
||||||
|
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType
|
session, baseConstructor, newParameterTypes, newTypeParameters, newReceiverType = null, newReturnType, fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,11 +141,19 @@ object FirFakeOverrideGenerator {
|
|||||||
newParameterTypes: List<ConeKotlinType?>?,
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
newTypeParameters: List<FirTypeParameterRef>?,
|
newTypeParameters: List<FirTypeParameterRef>?,
|
||||||
newReceiverType: ConeKotlinType?,
|
newReceiverType: ConeKotlinType?,
|
||||||
newReturnType: ConeKotlinType?
|
newReturnType: ConeKotlinType?,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
): List<FirTypeParameterRef> {
|
): List<FirTypeParameterRef> {
|
||||||
return when {
|
return when {
|
||||||
baseFunction.typeParameters.isEmpty() -> {
|
baseFunction.typeParameters.isEmpty() -> {
|
||||||
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
configureAnnotationsAndSignature(
|
||||||
|
session,
|
||||||
|
baseFunction,
|
||||||
|
newParameterTypes,
|
||||||
|
newReceiverType,
|
||||||
|
newReturnType,
|
||||||
|
fakeOverrideSubstitution
|
||||||
|
)
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
newTypeParameters == null -> {
|
newTypeParameters == null -> {
|
||||||
@@ -144,14 +163,33 @@ object FirFakeOverrideGenerator {
|
|||||||
val copiedParameterTypes = baseFunction.valueParameters.map {
|
val copiedParameterTypes = baseFunction.valueParameters.map {
|
||||||
substitutor.substituteOrNull(it.returnTypeRef.coneType)
|
substitutor.substituteOrNull(it.returnTypeRef.coneType)
|
||||||
}
|
}
|
||||||
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
|
val symbol = baseFunction.symbol
|
||||||
|
val (copiedReceiverType, possibleReturnType) = substituteReceiverAndReturnType(
|
||||||
baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor
|
baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor
|
||||||
)
|
)
|
||||||
configureAnnotationsAndSignature(session, baseFunction, copiedParameterTypes, copiedReceiverType, copiedReturnType)
|
val (copiedReturnType, newFakeOverrideSubstitution) = when (possibleReturnType) {
|
||||||
|
is Maybe.Value -> possibleReturnType.value to null
|
||||||
|
else -> null to FakeOverrideSubstitution(substitutor, symbol)
|
||||||
|
}
|
||||||
|
configureAnnotationsAndSignature(
|
||||||
|
session,
|
||||||
|
baseFunction,
|
||||||
|
copiedParameterTypes,
|
||||||
|
copiedReceiverType,
|
||||||
|
copiedReturnType,
|
||||||
|
newFakeOverrideSubstitution
|
||||||
|
)
|
||||||
copiedTypeParameters
|
copiedTypeParameters
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
configureAnnotationsAndSignature(session, baseFunction, newParameterTypes, newReceiverType, newReturnType)
|
configureAnnotationsAndSignature(
|
||||||
|
session,
|
||||||
|
baseFunction,
|
||||||
|
newParameterTypes,
|
||||||
|
newReceiverType,
|
||||||
|
newReturnType,
|
||||||
|
fakeOverrideSubstitution
|
||||||
|
)
|
||||||
newTypeParameters
|
newTypeParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,10 +200,22 @@ object FirFakeOverrideGenerator {
|
|||||||
baseFunction: FirFunction<*>,
|
baseFunction: FirFunction<*>,
|
||||||
newParameterTypes: List<ConeKotlinType?>?,
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
newReceiverType: ConeKotlinType?,
|
newReceiverType: ConeKotlinType?,
|
||||||
newReturnType: ConeKotlinType?
|
newReturnType: ConeKotlinType?,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
) {
|
) {
|
||||||
annotations += baseFunction.annotations
|
annotations += baseFunction.annotations
|
||||||
returnTypeRef = replaceReturnTypeIfResolved(baseFunction, newReturnType)
|
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val fakeOverrideSubstitution = fakeOverrideSubstitution ?: runIf(baseFunction.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
FakeOverrideSubstitution(ConeSubstitutor.Empty, baseFunction.symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fakeOverrideSubstitution != null) {
|
||||||
|
returnTypeRef = buildImplicitTypeRef()
|
||||||
|
attributes.fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||||
|
} else {
|
||||||
|
returnTypeRef = baseFunction.returnTypeRef.withReplacedReturnType(newReturnType)
|
||||||
|
}
|
||||||
|
|
||||||
if (this is FirSimpleFunctionBuilder) {
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
receiverTypeRef = baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
receiverTypeRef = baseFunction.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
||||||
@@ -181,14 +231,6 @@ object FirFakeOverrideGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceReturnTypeIfResolved(
|
|
||||||
base: FirCallableDeclaration<*>,
|
|
||||||
newReturnType: ConeKotlinType?
|
|
||||||
): FirTypeRef = if (base.returnTypeRef is FirResolvedTypeRef)
|
|
||||||
base.returnTypeRef.withReplacedConeType(newReturnType)
|
|
||||||
else
|
|
||||||
base.returnTypeRef
|
|
||||||
|
|
||||||
fun createFakeOverrideProperty(
|
fun createFakeOverrideProperty(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
baseProperty: FirProperty,
|
baseProperty: FirProperty,
|
||||||
@@ -197,7 +239,8 @@ object FirFakeOverrideGenerator {
|
|||||||
newReturnType: ConeKotlinType? = null,
|
newReturnType: ConeKotlinType? = null,
|
||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
derivedClassId: ClassId? = null,
|
derivedClassId: ClassId? = null,
|
||||||
isExpect: Boolean = baseProperty.isExpect
|
isExpect: Boolean = baseProperty.isExpect,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||||
): FirPropertySymbol {
|
): FirPropertySymbol {
|
||||||
val symbol = FirPropertySymbol(
|
val symbol = FirPropertySymbol(
|
||||||
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseProperty.name),
|
CallableId(derivedClassId ?: baseSymbol.callableId.classId!!, baseProperty.name),
|
||||||
@@ -205,7 +248,8 @@ object FirFakeOverrideGenerator {
|
|||||||
)
|
)
|
||||||
createCopyForFirProperty(
|
createCopyForFirProperty(
|
||||||
symbol, baseProperty, session, isExpect,
|
symbol, baseProperty, session, isExpect,
|
||||||
newTypeParameters, newReceiverType, newReturnType
|
newTypeParameters, newReceiverType, newReturnType,
|
||||||
|
fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
@@ -220,6 +264,7 @@ object FirFakeOverrideGenerator {
|
|||||||
newReturnType: ConeKotlinType? = null,
|
newReturnType: ConeKotlinType? = null,
|
||||||
newModality: Modality? = null,
|
newModality: Modality? = null,
|
||||||
newVisibility: Visibility? = null,
|
newVisibility: Visibility? = null,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution? = null
|
||||||
): FirProperty {
|
): FirProperty {
|
||||||
return buildProperty {
|
return buildProperty {
|
||||||
source = baseProperty.source
|
source = baseProperty.source
|
||||||
@@ -236,7 +281,8 @@ object FirFakeOverrideGenerator {
|
|||||||
baseProperty,
|
baseProperty,
|
||||||
newTypeParameters,
|
newTypeParameters,
|
||||||
newReceiverType,
|
newReceiverType,
|
||||||
newReturnType
|
newReturnType,
|
||||||
|
fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,25 +291,30 @@ object FirFakeOverrideGenerator {
|
|||||||
baseProperty: FirProperty,
|
baseProperty: FirProperty,
|
||||||
newTypeParameters: List<FirTypeParameter>?,
|
newTypeParameters: List<FirTypeParameter>?,
|
||||||
newReceiverType: ConeKotlinType?,
|
newReceiverType: ConeKotlinType?,
|
||||||
newReturnType: ConeKotlinType?
|
newReturnType: ConeKotlinType?,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
): List<FirTypeParameter> {
|
): List<FirTypeParameter> {
|
||||||
return when {
|
return when {
|
||||||
baseProperty.typeParameters.isEmpty() -> {
|
baseProperty.typeParameters.isEmpty() -> {
|
||||||
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType)
|
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType, fakeOverrideSubstitution)
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
newTypeParameters == null -> {
|
newTypeParameters == null -> {
|
||||||
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
|
val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor(
|
||||||
baseProperty, ConeSubstitutor.Empty
|
baseProperty, ConeSubstitutor.Empty
|
||||||
)
|
)
|
||||||
val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType(
|
val (copiedReceiverType, possibleReturnType) = substituteReceiverAndReturnType(
|
||||||
baseProperty, newReceiverType, newReturnType, substitutor
|
baseProperty, newReceiverType, newReturnType, substitutor
|
||||||
)
|
)
|
||||||
configureAnnotationsAndSignature(baseProperty, copiedReceiverType, copiedReturnType)
|
val (copiedReturnType, newFakeOverrideSubstitution) = when (possibleReturnType) {
|
||||||
|
is Maybe.Value -> possibleReturnType.value to null
|
||||||
|
else -> null to FakeOverrideSubstitution(substitutor, baseProperty.symbol)
|
||||||
|
}
|
||||||
|
configureAnnotationsAndSignature(baseProperty, copiedReceiverType, copiedReturnType, newFakeOverrideSubstitution)
|
||||||
copiedTypeParameters.filterIsInstance<FirTypeParameter>()
|
copiedTypeParameters.filterIsInstance<FirTypeParameter>()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType)
|
configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType, fakeOverrideSubstitution)
|
||||||
newTypeParameters
|
newTypeParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,27 +325,40 @@ object FirFakeOverrideGenerator {
|
|||||||
newReceiverType: ConeKotlinType?,
|
newReceiverType: ConeKotlinType?,
|
||||||
newReturnType: ConeKotlinType?,
|
newReturnType: ConeKotlinType?,
|
||||||
substitutor: ConeSubstitutor
|
substitutor: ConeSubstitutor
|
||||||
): Pair<ConeKotlinType?, ConeKotlinType?> {
|
): Pair<ConeKotlinType?, Maybe<ConeKotlinType?>> {
|
||||||
val copiedReceiverType = newReceiverType?.let {
|
val copiedReceiverType = newReceiverType?.let {
|
||||||
substitutor.substituteOrNull(it)
|
substitutor.substituteOrNull(it)
|
||||||
} ?: baseCallable.receiverTypeRef?.let {
|
} ?: baseCallable.receiverTypeRef?.let {
|
||||||
substitutor.substituteOrNull(it.coneType)
|
substitutor.substituteOrNull(it.coneType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val copiedReturnType = newReturnType?.let {
|
val copiedReturnType = newReturnType?.let {
|
||||||
substitutor.substituteOrNull(it)
|
substitutor.substituteOrNull(it)
|
||||||
} ?: baseCallable.returnTypeRef.let {
|
} ?: baseCallable.returnTypeRef.let {
|
||||||
substitutor.substituteOrNull(it.coneType)
|
val coneType = baseCallable.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: return copiedReceiverType to Maybe.Nothing
|
||||||
|
substitutor.substituteOrNull(coneType)
|
||||||
}
|
}
|
||||||
return copiedReceiverType to copiedReturnType
|
return copiedReceiverType to Maybe.Value(copiedReturnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirPropertyBuilder.configureAnnotationsAndSignature(
|
private fun FirPropertyBuilder.configureAnnotationsAndSignature(
|
||||||
baseProperty: FirProperty,
|
baseProperty: FirProperty,
|
||||||
newReceiverType: ConeKotlinType?,
|
newReceiverType: ConeKotlinType?,
|
||||||
newReturnType: ConeKotlinType?
|
newReturnType: ConeKotlinType?,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
) {
|
) {
|
||||||
annotations += baseProperty.annotations
|
annotations += baseProperty.annotations
|
||||||
returnTypeRef = replaceReturnTypeIfResolved(baseProperty, newReturnType)
|
|
||||||
|
@Suppress("NAME_SHADOWING")
|
||||||
|
val fakeOverrideSubstitution = fakeOverrideSubstitution ?: runIf(baseProperty.returnTypeRef is FirImplicitTypeRef) {
|
||||||
|
FakeOverrideSubstitution(ConeSubstitutor.Empty, baseProperty.symbol)
|
||||||
|
}
|
||||||
|
if (fakeOverrideSubstitution != null) {
|
||||||
|
returnTypeRef = buildImplicitTypeRef()
|
||||||
|
attributes.fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||||
|
} else {
|
||||||
|
returnTypeRef = baseProperty.returnTypeRef.withReplacedReturnType(newReturnType)
|
||||||
|
}
|
||||||
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +393,8 @@ object FirFakeOverrideGenerator {
|
|||||||
baseProperty: FirSyntheticProperty,
|
baseProperty: FirSyntheticProperty,
|
||||||
baseSymbol: FirAccessorSymbol,
|
baseSymbol: FirAccessorSymbol,
|
||||||
newReturnType: ConeKotlinType?,
|
newReturnType: ConeKotlinType?,
|
||||||
newParameterTypes: List<ConeKotlinType?>?
|
newParameterTypes: List<ConeKotlinType?>?,
|
||||||
|
fakeOverrideSubstitution: FakeOverrideSubstitution?
|
||||||
): FirAccessorSymbol {
|
): FirAccessorSymbol {
|
||||||
val functionSymbol = FirNamedFunctionSymbol(baseSymbol.accessorId)
|
val functionSymbol = FirNamedFunctionSymbol(baseSymbol.accessorId)
|
||||||
val function = createFakeOverrideFunction(
|
val function = createFakeOverrideFunction(
|
||||||
@@ -339,7 +404,8 @@ object FirFakeOverrideGenerator {
|
|||||||
newReceiverType = null,
|
newReceiverType = null,
|
||||||
newReturnType,
|
newReturnType,
|
||||||
newParameterTypes,
|
newParameterTypes,
|
||||||
newTypeParameters = null
|
newTypeParameters = null,
|
||||||
|
fakeOverrideSubstitution = fakeOverrideSubstitution
|
||||||
)
|
)
|
||||||
return buildSyntheticProperty {
|
return buildSyntheticProperty {
|
||||||
this.session = session
|
this.session = session
|
||||||
@@ -417,4 +483,9 @@ object FirFakeOverrideGenerator {
|
|||||||
ChainedSubstitutor(substitutor, additionalSubstitutor)
|
ChainedSubstitutor(substitutor, additionalSubstitutor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class Maybe<out A> {
|
||||||
|
class Value<out A>(val value: A) : Maybe<A>()
|
||||||
|
object Nothing : Maybe<kotlin.Nothing>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
@@ -39,6 +39,11 @@ object FirDeclarationDataRegistry : TypeRegistry<FirDeclarationDataKey, Any>() {
|
|||||||
return DeclarationDataAccessor(generateNullableAccessor(kClass), kClass)
|
return DeclarationDataAccessor(generateNullableAccessor(kClass), kClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <K : FirDeclarationDataKey, V : Any> attributesAccessor(key: K): ReadWriteProperty<FirDeclarationAttributes, V?> {
|
||||||
|
val kClass = key::class
|
||||||
|
return AttributeDataAccessor(generateNullableAccessor(kClass), kClass)
|
||||||
|
}
|
||||||
|
|
||||||
private class DeclarationDataAccessor<V : Any>(
|
private class DeclarationDataAccessor<V : Any>(
|
||||||
val dataAccessor: NullableArrayMapAccessor<FirDeclarationDataKey, Any, V>,
|
val dataAccessor: NullableArrayMapAccessor<FirDeclarationDataKey, Any, V>,
|
||||||
val key: KClass<out FirDeclarationDataKey>
|
val key: KClass<out FirDeclarationDataKey>
|
||||||
@@ -51,4 +56,17 @@ object FirDeclarationDataRegistry : TypeRegistry<FirDeclarationDataKey, Any>() {
|
|||||||
thisRef.attributes[key] = value
|
thisRef.attributes[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AttributeDataAccessor<V : Any>(
|
||||||
|
val dataAccessor: NullableArrayMapAccessor<FirDeclarationDataKey, Any, V>,
|
||||||
|
val key: KClass<out FirDeclarationDataKey>
|
||||||
|
) : ReadWriteProperty<FirDeclarationAttributes, V?> {
|
||||||
|
override fun getValue(thisRef: FirDeclarationAttributes, property: KProperty<*>): V? {
|
||||||
|
return dataAccessor.getValue(thisRef, property)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: FirDeclarationAttributes, property: KProperty<*>, value: V?) {
|
||||||
|
thisRef[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user