From ec39cd3d3182dabf3d031de001c8087707f3cf7e Mon Sep 17 00:00:00 2001 From: "simon.ogorodnik" Date: Thu, 9 Apr 2020 22:18:03 +0300 Subject: [PATCH] [FIR] Use captured, constructed class type parameters in RawFirBuilder --- .../kotlin/fir/builder/BaseFirBuilder.kt | 36 +++- .../jetbrains/kotlin/fir/builder/Context.kt | 3 + .../kotlin/fir/builder/RawFirBuilder.kt | 197 +++++++++++------- 3 files changed, 154 insertions(+), 82 deletions(-) diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 013e590ea91..6733aa5b4c5 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -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(val baseSession: FirSession, val context: Conte } } + inline fun withCapturedTypeParameters(block: () -> T): T { + val previous = context.capturedTypeParameters + val result = block() + context.capturedTypeParameters = previous + return result + } + + fun addCapturedTypeParameters(typeParameters: List) { + 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(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 { + fun typeParametersFromSelfType( + delegatedSelfTypeRef: FirTypeRef + ): List { return delegatedSelfTypeRef.coneTypeSafe() ?.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): List { + 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) diff --git a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/Context.kt b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/Context.kt index 17a49116ff1..d027de24f94 100644 --- a/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/Context.kt +++ b/compiler/fir/raw-fir/fir-common/src/org/jetbrains/kotlin/fir/builder/Context.kt @@ -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 { val firFunctionCalls = mutableListOf() val firLabels = mutableListOf() val firLoopTargets = mutableListOf() + var capturedTypeParameters = persistentListOf() val arraySetArgument = mutableMapOf() } \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 0c99276005e..215a2d0a84e 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -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 ): 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 ): 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 ): 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(), - ) - 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(), + ) + 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() } - 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 ): 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) }