[FIR] Use captured, constructed class type parameters in RawFirBuilder

This commit is contained in:
simon.ogorodnik
2020-04-09 22:18:03 +03:00
parent f174893009
commit ec39cd3d31
3 changed files with 154 additions and 82 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.builder package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import kotlinx.collections.immutable.mutate
import org.jetbrains.kotlin.KtNodeTypes.* import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -68,6 +69,18 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
} }
} }
inline fun <T> withCapturedTypeParameters(block: () -> T): T {
val previous = context.capturedTypeParameters
val result = block()
context.capturedTypeParameters = previous
return result
}
fun addCapturedTypeParameters(typeParameters: List<FirTypeParameterRef>) {
context.capturedTypeParameters =
context.capturedTypeParameters.addAll(0, typeParameters.map { typeParameter -> typeParameter.symbol })
}
fun callableIdForName(name: Name, local: Boolean = false) = fun callableIdForName(name: Name, local: Boolean = false) =
when { when {
local -> CallableId(name) local -> CallableId(name)
@@ -146,17 +159,34 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
fun T?.toDelegatedSelfType(firObject: FirAnonymousObjectBuilder): FirResolvedTypeRef { fun T?.toDelegatedSelfType(firObject: FirAnonymousObjectBuilder): FirResolvedTypeRef {
return buildResolvedTypeRef { return buildResolvedTypeRef {
source = this@toDelegatedSelfType?.toFirSourceElement() source = this@toDelegatedSelfType?.toFirSourceElement()
type = ConeClassLikeTypeImpl(firObject.symbol.toLookupTag(), emptyArray(), false) type = ConeClassLikeTypeImpl(
firObject.symbol.toLookupTag(),
firObject.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false
)
} }
} }
fun typeParametersFromSelfType(delegatedSelfTypeRef: FirTypeRef): List<FirTypeParameter> { fun typeParametersFromSelfType(
delegatedSelfTypeRef: FirTypeRef
): List<FirTypeParameterRef> {
return delegatedSelfTypeRef.coneTypeSafe<ConeKotlinType>() return delegatedSelfTypeRef.coneTypeSafe<ConeKotlinType>()
?.typeArguments ?.typeArguments
?.map { ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol).fir } ?.map {
buildConstructedClassTypeParameterRef {
symbol = ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol)
}
}
?: emptyList() ?: emptyList()
} }
fun constructorTypeParametersFromConstructedClass(ownerTypeParameters: List<FirTypeParameterRef>): List<FirTypeParameterRef> {
return ownerTypeParameters.mapNotNull {
val declaredTypeParameter = (it as? FirTypeParameter) ?: return@mapNotNull null
buildConstructedClassTypeParameterRef { symbol = declaredTypeParameter.symbol }
}
}
fun FirLoopBuilder.configure(generateBlock: () -> FirBlock): FirLoop { fun FirLoopBuilder.configure(generateBlock: () -> FirBlock): FirLoop {
label = context.firLabels.pop() label = context.firLabels.pop()
val target = FirLoopTarget(label?.name) val target = FirLoopTarget(label?.name)
@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.fir.builder package org.jetbrains.kotlin.fir.builder
import kotlinx.collections.immutable.persistentListOf
import org.jetbrains.kotlin.fir.FirFunctionTarget import org.jetbrains.kotlin.fir.FirFunctionTarget
import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirLabel
import org.jetbrains.kotlin.fir.FirLoopTarget import org.jetbrains.kotlin.fir.FirLoopTarget
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.builder.FirFunctionCallBuilder import org.jetbrains.kotlin.fir.expressions.builder.FirFunctionCallBuilder
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -22,5 +24,6 @@ class Context<T> {
val firFunctionCalls = mutableListOf<FirFunctionCallBuilder>() val firFunctionCalls = mutableListOf<FirFunctionCallBuilder>()
val firLabels = mutableListOf<FirLabel>() val firLabels = mutableListOf<FirLabel>()
val firLoopTargets = mutableListOf<FirLoopTarget>() val firLoopTargets = mutableListOf<FirLoopTarget>()
var capturedTypeParameters = persistentListOf<FirTypeParameterSymbol>()
val arraySetArgument = mutableMapOf<T, FirExpression>() val arraySetArgument = mutableMapOf<T, FirExpression>()
} }
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.mutate
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -156,8 +158,11 @@ class RawFirBuilder(
convert() convert()
private fun KtDeclaration.toFirDeclaration( private fun KtDeclaration.toFirDeclaration(
delegatedSuperType: FirTypeRef, delegatedSelfType: FirResolvedTypeRef, delegatedSuperType: FirTypeRef,
owner: KtClassOrObject, ownerClassBuilder: FirClassBuilder, hasPrimaryConstructor: Boolean, delegatedSelfType: FirResolvedTypeRef,
owner: KtClassOrObject,
ownerClassBuilder: FirClassBuilder, hasPrimaryConstructor: Boolean,
ownerTypeParameters: List<FirTypeParameterRef>
): FirDeclaration { ): FirDeclaration {
return when (this) { return when (this) {
is KtSecondaryConstructor -> { is KtSecondaryConstructor -> {
@@ -166,6 +171,7 @@ class RawFirBuilder(
delegatedSelfType, delegatedSelfType,
owner, owner,
hasPrimaryConstructor, hasPrimaryConstructor,
ownerTypeParameters
) )
} }
is KtEnumEntry -> { is KtEnumEntry -> {
@@ -408,6 +414,7 @@ class RawFirBuilder(
delegatedSelfTypeRef: FirTypeRef?, delegatedSelfTypeRef: FirTypeRef?,
delegatedEnumSuperTypeRef: FirTypeRef?, delegatedEnumSuperTypeRef: FirTypeRef?,
classKind: ClassKind, classKind: ClassKind,
containerTypeParameters: List<FirTypeParameterRef>
): FirTypeRef { ): FirTypeRef {
var superTypeCallEntry: KtSuperTypeCallEntry? = null var superTypeCallEntry: KtSuperTypeCallEntry? = null
var delegatedSuperTypeRef: FirTypeRef? = null var delegatedSuperTypeRef: FirTypeRef? = null
@@ -475,6 +482,7 @@ class RawFirBuilder(
delegatedSuperTypeRef, delegatedSuperTypeRef,
delegatedSelfTypeRef ?: delegatedSuperTypeRef, delegatedSelfTypeRef ?: delegatedSuperTypeRef,
owner = this, owner = this,
containerTypeParameters
) )
container.declarations += firPrimaryConstructor container.declarations += firPrimaryConstructor
return delegatedSuperTypeRef return delegatedSuperTypeRef
@@ -485,6 +493,7 @@ class RawFirBuilder(
delegatedSuperTypeRef: FirTypeRef, delegatedSuperTypeRef: FirTypeRef,
delegatedSelfTypeRef: FirTypeRef, delegatedSelfTypeRef: FirTypeRef,
owner: KtClassOrObject, owner: KtClassOrObject,
ownerTypeParameters: List<FirTypeParameterRef>
): FirConstructor { ): FirConstructor {
val constructorCallee = superTypeCallEntry?.calleeExpression?.toFirSourceElement() val constructorCallee = superTypeCallEntry?.calleeExpression?.toFirSourceElement()
val constructorSource = (this ?: owner).toFirSourceElement() val constructorSource = (this ?: owner).toFirSourceElement()
@@ -519,7 +528,7 @@ class RawFirBuilder(
this.status = status this.status = status
symbol = FirConstructorSymbol(callableIdForClassConstructor()) symbol = FirConstructorSymbol(callableIdForClassConstructor())
delegatedConstructor = firDelegatedCall delegatedConstructor = firDelegatedCall
typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
this@toFirConstructor?.extractAnnotationsTo(this) this@toFirConstructor?.extractAnnotationsTo(this)
this@toFirConstructor?.extractValueParametersTo(this) this@toFirConstructor?.extractValueParametersTo(this)
} }
@@ -592,6 +601,7 @@ class RawFirBuilder(
correctedEnumSelfTypeRef, correctedEnumSelfTypeRef,
delegatedEntrySelfType, delegatedEntrySelfType,
owner = ktEnumEntry, owner = ktEnumEntry,
typeParameters
) )
for (declaration in ktEnumEntry.declarations) { for (declaration in ktEnumEntry.declarations) {
declarations += declaration.toFirDeclaration( declarations += declaration.toFirDeclaration(
@@ -600,6 +610,7 @@ class RawFirBuilder(
ktEnumEntry, ktEnumEntry,
ownerClassBuilder = this, ownerClassBuilder = this,
hasPrimaryConstructor = true, hasPrimaryConstructor = true,
ownerTypeParameters = emptyList()
) )
} }
} }
@@ -631,6 +642,9 @@ class RawFirBuilder(
isData = (classOrObject as? KtClass)?.isData() == true isData = (classOrObject as? KtClass)?.isData() == true
isInline = classOrObject.hasModifier(INLINE_KEYWORD) isInline = classOrObject.hasModifier(INLINE_KEYWORD)
} }
withCapturedTypeParameters {
if (!status.isInner) context.capturedTypeParameters = context.capturedTypeParameters.clear()
val classBuilder = if (status.modality == Modality.SEALED) FirSealedClassBuilder() else FirClassImplBuilder() val classBuilder = if (status.modality == Modality.SEALED) FirSealedClassBuilder() else FirClassImplBuilder()
classBuilder.apply { classBuilder.apply {
source = classOrObject.toFirSourceElement() source = classOrObject.toFirSourceElement()
@@ -643,9 +657,13 @@ class RawFirBuilder(
classOrObject.extractAnnotationsTo(this) classOrObject.extractAnnotationsTo(this)
classOrObject.extractTypeParametersTo(this) classOrObject.extractTypeParametersTo(this)
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
addCapturedTypeParameters(typeParameters.take(classOrObject.typeParameters.size))
val delegatedSelfType = classOrObject.toDelegatedSelfType(this) val delegatedSelfType = classOrObject.toDelegatedSelfType(this)
val delegatedSuperType = classOrObject.extractSuperTypeListEntriesTo(this, delegatedSelfType, null, classKind) val delegatedSuperType =
classOrObject.extractSuperTypeListEntriesTo(this, delegatedSelfType, null, classKind, typeParameters)
val primaryConstructor = classOrObject.primaryConstructor val primaryConstructor = classOrObject.primaryConstructor
val firPrimaryConstructor = declarations.firstOrNull() as? FirConstructor val firPrimaryConstructor = declarations.firstOrNull() as? FirConstructor
@@ -662,8 +680,11 @@ class RawFirBuilder(
for (declaration in classOrObject.declarations) { for (declaration in classOrObject.declarations) {
addDeclaration( addDeclaration(
declaration.toFirDeclaration( declaration.toFirDeclaration(
delegatedSuperType, delegatedSelfType, classOrObject, classBuilder, delegatedSuperType,
hasPrimaryConstructor = primaryConstructor != null, delegatedSelfType,
classOrObject,
classBuilder, hasPrimaryConstructor = primaryConstructor != null,
typeParameters
), ),
) )
} }
@@ -688,6 +709,7 @@ class RawFirBuilder(
}.build() }.build()
} }
} }
}
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Unit): FirElement { override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression, data: Unit): FirElement {
val objectDeclaration = expression.objectDeclaration val objectDeclaration = expression.objectDeclaration
@@ -698,11 +720,19 @@ class RawFirBuilder(
classKind = ClassKind.OBJECT classKind = ClassKind.OBJECT
scopeProvider = baseScopeProvider scopeProvider = baseScopeProvider
symbol = FirAnonymousObjectSymbol() symbol = FirAnonymousObjectSymbol()
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
val delegatedSelfType = objectDeclaration.toDelegatedSelfType(this) val delegatedSelfType = objectDeclaration.toDelegatedSelfType(this)
objectDeclaration.extractAnnotationsTo(this) objectDeclaration.extractAnnotationsTo(this)
val delegatedSuperType = objectDeclaration.extractSuperTypeListEntriesTo(this, delegatedSelfType, null, ClassKind.CLASS) val delegatedSuperType = objectDeclaration.extractSuperTypeListEntriesTo(
this,
delegatedSelfType,
null,
ClassKind.CLASS,
containerTypeParameters = emptyList()
)
typeRef = delegatedSelfType typeRef = delegatedSelfType
for (declaration in objectDeclaration.declarations) { for (declaration in objectDeclaration.declarations) {
declarations += declaration.toFirDeclaration( declarations += declaration.toFirDeclaration(
delegatedSuperType, delegatedSuperType,
@@ -710,6 +740,7 @@ class RawFirBuilder(
owner = objectDeclaration, owner = objectDeclaration,
ownerClassBuilder = this, ownerClassBuilder = this,
hasPrimaryConstructor = false, hasPrimaryConstructor = false,
ownerTypeParameters = emptyList()
) )
} }
} }
@@ -789,7 +820,10 @@ class RawFirBuilder(
for (valueParameter in function.valueParameters) { for (valueParameter in function.valueParameters) {
valueParameters += valueParameter.convert<FirValueParameter>() valueParameters += valueParameter.convert<FirValueParameter>()
} }
withCapturedTypeParameters {
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
body = function.buildFirBody() body = function.buildFirBody()
}
context.firFunctionTargets.removeLast() context.firFunctionTargets.removeLast()
}.build().also { }.build().also {
target.bind(it) target.bind(it)
@@ -884,6 +918,7 @@ class RawFirBuilder(
delegatedSelfTypeRef: FirTypeRef, delegatedSelfTypeRef: FirTypeRef,
owner: KtClassOrObject, owner: KtClassOrObject,
hasPrimaryConstructor: Boolean, hasPrimaryConstructor: Boolean,
ownerTypeParameters: List<FirTypeParameterRef>
): FirConstructor { ): FirConstructor {
val target = FirFunctionTarget(labelName = null, isLambda = false) val target = FirFunctionTarget(labelName = null, isLambda = false)
return buildConstructor { return buildConstructor {
@@ -906,7 +941,7 @@ class RawFirBuilder(
) )
this@RawFirBuilder.context.firFunctionTargets += target this@RawFirBuilder.context.firFunctionTargets += target
extractAnnotationsTo(this) extractAnnotationsTo(this)
typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef) typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
extractValueParametersTo(this) extractValueParametersTo(this)
body = buildFirBody() body = buildFirBody()
this@RawFirBuilder.context.firFunctionTargets.removeLast() this@RawFirBuilder.context.firFunctionTargets.removeLast()
@@ -952,6 +987,7 @@ class RawFirBuilder(
returnTypeRef = propertyType returnTypeRef = propertyType
name = propertyName name = propertyName
this.isVar = isVar this.isVar = isVar
initializer = propertyInitializer initializer = propertyInitializer
if (this@toFirProperty.isLocal) { if (this@toFirProperty.isLocal) {
@@ -974,6 +1010,9 @@ class RawFirBuilder(
isLocal = false isLocal = false
receiverTypeRef = receiverTypeReference.convertSafe() receiverTypeRef = receiverTypeReference.convertSafe()
symbol = FirPropertySymbol(callableIdForName(propertyName)) symbol = FirPropertySymbol(callableIdForName(propertyName))
extractTypeParametersTo(this)
withCapturedTypeParameters {
addCapturedTypeParameters(this.typeParameters)
val delegateBuilder = if (hasDelegate()) { val delegateBuilder = if (hasDelegate()) {
FirWrappedDelegateExpressionBuilder().apply { FirWrappedDelegateExpressionBuilder().apply {
source = if (stubMode) null else delegateExpression?.toFirSourceElement() source = if (stubMode) null else delegateExpression?.toFirSourceElement()
@@ -987,7 +1026,6 @@ class RawFirBuilder(
isConst = hasModifier(CONST_KEYWORD) isConst = hasModifier(CONST_KEYWORD)
isLateInit = hasModifier(LATEINIT_KEYWORD) isLateInit = hasModifier(LATEINIT_KEYWORD)
} }
extractTypeParametersTo(this)
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true) getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
setter = if (isVar) { setter = if (isVar) {
@@ -1004,6 +1042,7 @@ class RawFirBuilder(
receiver receiver
) )
} }
}
extractAnnotationsTo(this) extractAnnotationsTo(this)
} }
} }