[FIR] Use captured, constructed class type parameters in RawFirBuilder
This commit is contained in:
+33
-3
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.builder
|
||||
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import kotlinx.collections.immutable.mutate
|
||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
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) =
|
||||
when {
|
||||
local -> CallableId(name)
|
||||
@@ -146,17 +159,34 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
fun T?.toDelegatedSelfType(firObject: FirAnonymousObjectBuilder): FirResolvedTypeRef {
|
||||
return buildResolvedTypeRef {
|
||||
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>()
|
||||
?.typeArguments
|
||||
?.map { ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol).fir }
|
||||
?.map {
|
||||
buildConstructedClassTypeParameterRef {
|
||||
symbol = ((it as ConeTypeParameterType).lookupTag.symbol as FirTypeParameterSymbol)
|
||||
}
|
||||
}
|
||||
?: 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 {
|
||||
label = context.firLabels.pop()
|
||||
val target = FirLoopTarget(label?.name)
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.builder
|
||||
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import org.jetbrains.kotlin.fir.FirFunctionTarget
|
||||
import org.jetbrains.kotlin.fir.FirLabel
|
||||
import org.jetbrains.kotlin.fir.FirLoopTarget
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
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.FqName
|
||||
|
||||
@@ -22,5 +24,6 @@ class Context<T> {
|
||||
val firFunctionCalls = mutableListOf<FirFunctionCallBuilder>()
|
||||
val firLabels = mutableListOf<FirLabel>()
|
||||
val firLoopTargets = mutableListOf<FirLoopTarget>()
|
||||
var capturedTypeParameters = persistentListOf<FirTypeParameterSymbol>()
|
||||
val arraySetArgument = mutableMapOf<T, FirExpression>()
|
||||
}
|
||||
+118
-79
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.builder
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
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.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -156,8 +158,11 @@ class RawFirBuilder(
|
||||
convert()
|
||||
|
||||
private fun KtDeclaration.toFirDeclaration(
|
||||
delegatedSuperType: FirTypeRef, delegatedSelfType: FirResolvedTypeRef,
|
||||
owner: KtClassOrObject, ownerClassBuilder: FirClassBuilder, hasPrimaryConstructor: Boolean,
|
||||
delegatedSuperType: FirTypeRef,
|
||||
delegatedSelfType: FirResolvedTypeRef,
|
||||
owner: KtClassOrObject,
|
||||
ownerClassBuilder: FirClassBuilder, hasPrimaryConstructor: Boolean,
|
||||
ownerTypeParameters: List<FirTypeParameterRef>
|
||||
): FirDeclaration {
|
||||
return when (this) {
|
||||
is KtSecondaryConstructor -> {
|
||||
@@ -166,6 +171,7 @@ class RawFirBuilder(
|
||||
delegatedSelfType,
|
||||
owner,
|
||||
hasPrimaryConstructor,
|
||||
ownerTypeParameters
|
||||
)
|
||||
}
|
||||
is KtEnumEntry -> {
|
||||
@@ -408,6 +414,7 @@ class RawFirBuilder(
|
||||
delegatedSelfTypeRef: FirTypeRef?,
|
||||
delegatedEnumSuperTypeRef: FirTypeRef?,
|
||||
classKind: ClassKind,
|
||||
containerTypeParameters: List<FirTypeParameterRef>
|
||||
): FirTypeRef {
|
||||
var superTypeCallEntry: KtSuperTypeCallEntry? = null
|
||||
var delegatedSuperTypeRef: FirTypeRef? = null
|
||||
@@ -475,6 +482,7 @@ class RawFirBuilder(
|
||||
delegatedSuperTypeRef,
|
||||
delegatedSelfTypeRef ?: delegatedSuperTypeRef,
|
||||
owner = this,
|
||||
containerTypeParameters
|
||||
)
|
||||
container.declarations += firPrimaryConstructor
|
||||
return delegatedSuperTypeRef
|
||||
@@ -485,6 +493,7 @@ class RawFirBuilder(
|
||||
delegatedSuperTypeRef: FirTypeRef,
|
||||
delegatedSelfTypeRef: FirTypeRef,
|
||||
owner: KtClassOrObject,
|
||||
ownerTypeParameters: List<FirTypeParameterRef>
|
||||
): FirConstructor {
|
||||
val constructorCallee = superTypeCallEntry?.calleeExpression?.toFirSourceElement()
|
||||
val constructorSource = (this ?: owner).toFirSourceElement()
|
||||
@@ -519,7 +528,7 @@ class RawFirBuilder(
|
||||
this.status = status
|
||||
symbol = FirConstructorSymbol(callableIdForClassConstructor())
|
||||
delegatedConstructor = firDelegatedCall
|
||||
typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
|
||||
this@toFirConstructor?.extractAnnotationsTo(this)
|
||||
this@toFirConstructor?.extractValueParametersTo(this)
|
||||
}
|
||||
@@ -592,6 +601,7 @@ class RawFirBuilder(
|
||||
correctedEnumSelfTypeRef,
|
||||
delegatedEntrySelfType,
|
||||
owner = ktEnumEntry,
|
||||
typeParameters
|
||||
)
|
||||
for (declaration in ktEnumEntry.declarations) {
|
||||
declarations += declaration.toFirDeclaration(
|
||||
@@ -600,6 +610,7 @@ class RawFirBuilder(
|
||||
ktEnumEntry,
|
||||
ownerClassBuilder = this,
|
||||
hasPrimaryConstructor = true,
|
||||
ownerTypeParameters = emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -631,61 +642,72 @@ class RawFirBuilder(
|
||||
isData = (classOrObject as? KtClass)?.isData() == true
|
||||
isInline = classOrObject.hasModifier(INLINE_KEYWORD)
|
||||
}
|
||||
val classBuilder = if (status.modality == Modality.SEALED) FirSealedClassBuilder() else FirClassImplBuilder()
|
||||
classBuilder.apply {
|
||||
source = classOrObject.toFirSourceElement()
|
||||
session = baseSession
|
||||
name = classOrObject.nameAsSafeName
|
||||
this.status = status
|
||||
this.classKind = classKind
|
||||
scopeProvider = baseScopeProvider
|
||||
symbol = FirRegularClassSymbol(context.currentClassId)
|
||||
withCapturedTypeParameters {
|
||||
if (!status.isInner) context.capturedTypeParameters = context.capturedTypeParameters.clear()
|
||||
|
||||
classOrObject.extractAnnotationsTo(this)
|
||||
classOrObject.extractTypeParametersTo(this)
|
||||
val classBuilder = if (status.modality == Modality.SEALED) FirSealedClassBuilder() else FirClassImplBuilder()
|
||||
classBuilder.apply {
|
||||
source = classOrObject.toFirSourceElement()
|
||||
session = baseSession
|
||||
name = classOrObject.nameAsSafeName
|
||||
this.status = status
|
||||
this.classKind = classKind
|
||||
scopeProvider = baseScopeProvider
|
||||
symbol = FirRegularClassSymbol(context.currentClassId)
|
||||
|
||||
val delegatedSelfType = classOrObject.toDelegatedSelfType(this)
|
||||
val delegatedSuperType = classOrObject.extractSuperTypeListEntriesTo(this, delegatedSelfType, null, classKind)
|
||||
classOrObject.extractAnnotationsTo(this)
|
||||
classOrObject.extractTypeParametersTo(this)
|
||||
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
|
||||
|
||||
val primaryConstructor = classOrObject.primaryConstructor
|
||||
val firPrimaryConstructor = declarations.firstOrNull() as? FirConstructor
|
||||
if (primaryConstructor != null && firPrimaryConstructor != null) {
|
||||
primaryConstructor.valueParameters.zip(
|
||||
firPrimaryConstructor.valueParameters
|
||||
).forEach { (ktParameter, firParameter) ->
|
||||
if (ktParameter.hasValOrVar()) {
|
||||
addDeclaration(ktParameter.toFirProperty(firParameter))
|
||||
addCapturedTypeParameters(typeParameters.take(classOrObject.typeParameters.size))
|
||||
|
||||
val delegatedSelfType = classOrObject.toDelegatedSelfType(this)
|
||||
val delegatedSuperType =
|
||||
classOrObject.extractSuperTypeListEntriesTo(this, delegatedSelfType, null, classKind, typeParameters)
|
||||
|
||||
val primaryConstructor = classOrObject.primaryConstructor
|
||||
val firPrimaryConstructor = declarations.firstOrNull() as? FirConstructor
|
||||
if (primaryConstructor != null && firPrimaryConstructor != null) {
|
||||
primaryConstructor.valueParameters.zip(
|
||||
firPrimaryConstructor.valueParameters
|
||||
).forEach { (ktParameter, firParameter) ->
|
||||
if (ktParameter.hasValOrVar()) {
|
||||
addDeclaration(ktParameter.toFirProperty(firParameter))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (declaration in classOrObject.declarations) {
|
||||
addDeclaration(
|
||||
declaration.toFirDeclaration(
|
||||
delegatedSuperType, delegatedSelfType, classOrObject, classBuilder,
|
||||
hasPrimaryConstructor = primaryConstructor != null,
|
||||
),
|
||||
)
|
||||
}
|
||||
for (declaration in classOrObject.declarations) {
|
||||
addDeclaration(
|
||||
declaration.toFirDeclaration(
|
||||
delegatedSuperType,
|
||||
delegatedSelfType,
|
||||
classOrObject,
|
||||
classBuilder, hasPrimaryConstructor = primaryConstructor != null,
|
||||
typeParameters
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if (classOrObject.hasModifier(DATA_KEYWORD) && firPrimaryConstructor != null) {
|
||||
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
||||
declarations.filterIsInstance<FirProperty>(),
|
||||
)
|
||||
zippedParameters.generateComponentFunctions(
|
||||
baseSession, this, context.packageFqName, context.className, firPrimaryConstructor,
|
||||
)
|
||||
zippedParameters.generateCopyFunction(
|
||||
baseSession, classOrObject, this, context.packageFqName, context.className, firPrimaryConstructor,
|
||||
)
|
||||
// TODO: equals, hashCode, toString
|
||||
}
|
||||
if (classOrObject.hasModifier(DATA_KEYWORD) && firPrimaryConstructor != null) {
|
||||
val zippedParameters = classOrObject.primaryConstructorParameters.zip(
|
||||
declarations.filterIsInstance<FirProperty>(),
|
||||
)
|
||||
zippedParameters.generateComponentFunctions(
|
||||
baseSession, this, context.packageFqName, context.className, firPrimaryConstructor,
|
||||
)
|
||||
zippedParameters.generateCopyFunction(
|
||||
baseSession, classOrObject, this, context.packageFqName, context.className, firPrimaryConstructor,
|
||||
)
|
||||
// TODO: equals, hashCode, toString
|
||||
}
|
||||
|
||||
if (classOrObject.hasModifier(ENUM_KEYWORD)) {
|
||||
generateValuesFunction(baseSession, context.packageFqName, context.className)
|
||||
generateValueOfFunction(baseSession, context.packageFqName, context.className)
|
||||
}
|
||||
}.build()
|
||||
if (classOrObject.hasModifier(ENUM_KEYWORD)) {
|
||||
generateValuesFunction(baseSession, context.packageFqName, context.className)
|
||||
generateValueOfFunction(baseSession, context.packageFqName, context.className)
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,11 +720,19 @@ class RawFirBuilder(
|
||||
classKind = ClassKind.OBJECT
|
||||
scopeProvider = baseScopeProvider
|
||||
symbol = FirAnonymousObjectSymbol()
|
||||
typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } }
|
||||
val delegatedSelfType = objectDeclaration.toDelegatedSelfType(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
|
||||
|
||||
|
||||
for (declaration in objectDeclaration.declarations) {
|
||||
declarations += declaration.toFirDeclaration(
|
||||
delegatedSuperType,
|
||||
@@ -710,6 +740,7 @@ class RawFirBuilder(
|
||||
owner = objectDeclaration,
|
||||
ownerClassBuilder = this,
|
||||
hasPrimaryConstructor = false,
|
||||
ownerTypeParameters = emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -789,7 +820,10 @@ class RawFirBuilder(
|
||||
for (valueParameter in function.valueParameters) {
|
||||
valueParameters += valueParameter.convert<FirValueParameter>()
|
||||
}
|
||||
body = function.buildFirBody()
|
||||
withCapturedTypeParameters {
|
||||
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
|
||||
body = function.buildFirBody()
|
||||
}
|
||||
context.firFunctionTargets.removeLast()
|
||||
}.build().also {
|
||||
target.bind(it)
|
||||
@@ -884,6 +918,7 @@ class RawFirBuilder(
|
||||
delegatedSelfTypeRef: FirTypeRef,
|
||||
owner: KtClassOrObject,
|
||||
hasPrimaryConstructor: Boolean,
|
||||
ownerTypeParameters: List<FirTypeParameterRef>
|
||||
): FirConstructor {
|
||||
val target = FirFunctionTarget(labelName = null, isLambda = false)
|
||||
return buildConstructor {
|
||||
@@ -906,7 +941,7 @@ class RawFirBuilder(
|
||||
)
|
||||
this@RawFirBuilder.context.firFunctionTargets += target
|
||||
extractAnnotationsTo(this)
|
||||
typeParameters += typeParametersFromSelfType(delegatedSelfTypeRef)
|
||||
typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters)
|
||||
extractValueParametersTo(this)
|
||||
body = buildFirBody()
|
||||
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
||||
@@ -952,6 +987,7 @@ class RawFirBuilder(
|
||||
returnTypeRef = propertyType
|
||||
name = propertyName
|
||||
this.isVar = isVar
|
||||
|
||||
initializer = propertyInitializer
|
||||
|
||||
if (this@toFirProperty.isLocal) {
|
||||
@@ -974,35 +1010,38 @@ class RawFirBuilder(
|
||||
isLocal = false
|
||||
receiverTypeRef = receiverTypeReference.convertSafe()
|
||||
symbol = FirPropertySymbol(callableIdForName(propertyName))
|
||||
val delegateBuilder = if (hasDelegate()) {
|
||||
FirWrappedDelegateExpressionBuilder().apply {
|
||||
source = if (stubMode) null else delegateExpression?.toFirSourceElement()
|
||||
expression = { delegateExpression }.toFirExpression("Should have delegate")
|
||||
}
|
||||
} else null
|
||||
status = FirDeclarationStatusImpl(visibility, modality).apply {
|
||||
isExpect = hasExpectModifier()
|
||||
isActual = hasActualModifier()
|
||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||
isConst = hasModifier(CONST_KEYWORD)
|
||||
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||
}
|
||||
extractTypeParametersTo(this)
|
||||
withCapturedTypeParameters {
|
||||
addCapturedTypeParameters(this.typeParameters)
|
||||
val delegateBuilder = if (hasDelegate()) {
|
||||
FirWrappedDelegateExpressionBuilder().apply {
|
||||
source = if (stubMode) null else delegateExpression?.toFirSourceElement()
|
||||
expression = { delegateExpression }.toFirExpression("Should have delegate")
|
||||
}
|
||||
} else null
|
||||
status = FirDeclarationStatusImpl(visibility, modality).apply {
|
||||
isExpect = hasExpectModifier()
|
||||
isActual = hasActualModifier()
|
||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||
isConst = hasModifier(CONST_KEYWORD)
|
||||
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||
}
|
||||
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||
setter = if (isVar) {
|
||||
this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||
} else null
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||
setter = if (isVar) {
|
||||
this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||
} else null
|
||||
|
||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
ownerClassBuilder,
|
||||
baseSession,
|
||||
isExtension = receiverTypeReference != null,
|
||||
stubMode,
|
||||
receiver
|
||||
)
|
||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
ownerClassBuilder,
|
||||
baseSession,
|
||||
isExtension = receiverTypeReference != null,
|
||||
stubMode,
|
||||
receiver
|
||||
)
|
||||
}
|
||||
}
|
||||
extractAnnotationsTo(this)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user