diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 6a99cc7d239..ae1ae195cd5 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -397,21 +397,21 @@ class DeclarationsConverter( val isLocal = isClassLocal(classNode) { getParent() } return withChildClassName(className, isLocal) { - withCapturedTypeParameters { - val status = FirDeclarationStatusImpl( - if (isLocal) Visibilities.Local else modifiers.getVisibility(), - modifiers.getModality(isClassOrObject = true) - ).apply { - isExpect = modifiers.hasExpect() - isActual = modifiers.hasActual() - isInner = modifiers.isInner() - isCompanion = modifiers.isCompanion() && classKind == ClassKind.OBJECT - isData = modifiers.isDataClass() - isInline = modifiers.isInlineClass() - isFun = modifiers.isFunctionalInterface() - isExternal = modifiers.hasExternal() - } + val status = FirDeclarationStatusImpl( + if (isLocal) Visibilities.Local else modifiers.getVisibility(), + modifiers.getModality(isClassOrObject = true) + ).apply { + isExpect = modifiers.hasExpect() + isActual = modifiers.hasActual() + isInner = modifiers.isInner() + isCompanion = modifiers.isCompanion() && classKind == ClassKind.OBJECT + isData = modifiers.isDataClass() + isInline = modifiers.isInlineClass() + isFun = modifiers.isFunctionalInterface() + isExternal = modifiers.hasExternal() + } + withCapturedTypeParameters(status.isInner, firTypeParameters) { buildRegularClass { source = classNode.toFirSourceElement() moduleData = baseModuleData @@ -424,9 +424,9 @@ class DeclarationsConverter( annotations += modifiers.annotations typeParameters += firTypeParameters - if (!status.isInner) clearCapturedTypeParameters() - typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } } - addCapturedTypeParameters(firTypeParameters) + context.applyToActualCapturedTypeParameters(true) { + typeParameters += buildOuterClassTypeParameterRef { symbol = it } + } val selfType = classNode.toDelegatedSelfType(this) registerSelfType(selfType) @@ -554,7 +554,9 @@ class DeclarationsConverter( classKind = ClassKind.OBJECT scopeProvider = baseScopeProvider symbol = FirAnonymousObjectSymbol() - typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { this.symbol = it } } + context.applyToActualCapturedTypeParameters(false) { + typeParameters += buildOuterClassTypeParameterRef { this.symbol = it } + } val delegatedSelfType = objectLiteral.toDelegatedSelfType(this) registerSelfType(delegatedSelfType) @@ -1059,9 +1061,8 @@ class DeclarationsConverter( receiverTypeRef = receiverType symbol = FirPropertySymbol(callableIdForName(propertyName)) dispatchReceiverType = currentDispatchReceiverType() - withCapturedTypeParameters { + withCapturedTypeParameters(true, firTypeParameters) { typeParameters += firTypeParameters - addCapturedTypeParameters(firTypeParameters) val delegateBuilder = delegateExpression?.let { FirWrappedDelegateExpressionBuilder().apply { @@ -1419,11 +1420,14 @@ class DeclarationsConverter( context.firFunctionTargets += target annotations += modifiers.annotations - withCapturedTypeParameters { - if (this is FirSimpleFunctionBuilder) { - typeParameters += firTypeParameters - addCapturedTypeParameters(typeParameters) - } + val actualTypeParameters = if (this is FirSimpleFunctionBuilder) { + typeParameters += firTypeParameters + typeParameters + } else { + listOf() + } + + withCapturedTypeParameters(true, actualTypeParameters) { valueParametersList?.let { list -> valueParameters += convertValueParameters(list).map { it.firValueParameter } } val hasContractEffectList = outerContractDescription != null 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 883f5819d16..16d3a3ba257 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 @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.name.CallableId +import org.jetbrains.kotlin.name.LocalCallableIdConstructor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -839,9 +840,8 @@ open class RawFirBuilder( isFun = classOrObject.hasModifier(FUN_KEYWORD) isExternal = classOrObject.hasModifier(EXTERNAL_KEYWORD) } - withCapturedTypeParameters { - if (!status.isInner) context.capturedTypeParameters = context.capturedTypeParameters.clear() + withCapturedTypeParameters(status.isInner, listOf()) { buildRegularClass { source = classOrObject.toFirSourceElement() moduleData = baseModuleData @@ -854,9 +854,14 @@ open class RawFirBuilder( classOrObject.extractAnnotationsTo(this) classOrObject.extractTypeParametersTo(this) - typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } } - addCapturedTypeParameters(typeParameters.take(classOrObject.typeParameters.size)) + context.applyToActualCapturedTypeParameters(true) { + typeParameters += buildOuterClassTypeParameterRef { symbol = it } + } + context.pushFirTypeParameters( + status.isInner, + typeParameters.subList(0, classOrObject.typeParameters.size) + ) val delegatedSelfType = classOrObject.toDelegatedSelfType(this) registerSelfType(delegatedSelfType) @@ -925,6 +930,8 @@ open class RawFirBuilder( classOrObject.hasExpectModifier() ) } + + context.popFirTypeParameters() } } }.also { @@ -943,7 +950,9 @@ open class RawFirBuilder( classKind = ClassKind.OBJECT scopeProvider = baseScopeProvider symbol = FirAnonymousObjectSymbol() - typeParameters += context.capturedTypeParameters.map { buildOuterClassTypeParameterRef { symbol = it } } + context.applyToActualCapturedTypeParameters(false) { + typeParameters += buildOuterClassTypeParameterRef { symbol = it } + } val delegatedSelfType = objectDeclaration.toDelegatedSelfType(this) registerSelfType(delegatedSelfType) objectDeclaration.extractAnnotationsTo(this) @@ -1046,8 +1055,11 @@ open class RawFirBuilder( for (valueParameter in function.valueParameters) { valueParameters += valueParameter.convert() } - withCapturedTypeParameters { - if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters) + val actualTypeParameters = if (this is FirSimpleFunctionBuilder) + this.typeParameters + else + listOf() + withCapturedTypeParameters(true, actualTypeParameters) { val outerContractDescription = function.obtainContractDescription() val bodyWithContractDescription = function.buildFirBody() this.body = bodyWithContractDescription.first @@ -1310,8 +1322,7 @@ open class RawFirBuilder( symbol = FirPropertySymbol(callableIdForName(propertyName)) dispatchReceiverType = currentDispatchReceiverType() extractTypeParametersTo(this) - withCapturedTypeParameters { - addCapturedTypeParameters(this.typeParameters) + withCapturedTypeParameters(true, this.typeParameters) { val delegateBuilder = if (hasDelegate()) { FirWrappedDelegateExpressionBuilder().apply { source = diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 45721ed379e..e08b7ca34b6 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -90,24 +90,15 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte context.dispatchReceiverTypesStack.add(selfType.type as ConeClassLikeType) } - inline fun withCapturedTypeParameters(block: () -> T): T { - val previous = context.capturedTypeParameters + inline fun withCapturedTypeParameters(status: Boolean, currentFirTypeParameters: List, block: () -> T): T { + context.pushFirTypeParameters(status, currentFirTypeParameters) return try { block() } finally { - context.capturedTypeParameters = previous + context.popFirTypeParameters() } } - fun addCapturedTypeParameters(typeParameters: List) { - context.capturedTypeParameters = - context.capturedTypeParameters.addAll(0, typeParameters.map { typeParameter -> typeParameter.symbol }) - } - - fun clearCapturedTypeParameters() { - context.capturedTypeParameters = context.capturedTypeParameters.clear() - } - fun callableIdForName(name: Name, local: Boolean = false) = when { local -> { diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt index 8d35e8bb7b0..50229d473d2 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Context.kt @@ -5,15 +5,14 @@ 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.FirSourceElementKind +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -28,9 +27,36 @@ class Context { val calleeNamesForLambda = mutableListOf() val firLabels = mutableListOf() val firLoopTargets = mutableListOf() - var capturedTypeParameters = persistentListOf() + val capturedTypeParameters = mutableListOf() val arraySetArgument = mutableMapOf() var forcedElementSourceKind: FirSourceElementKind? = null val dispatchReceiverTypesStack = mutableListOf() + + fun pushFirTypeParameters(notNested: Boolean, parameters: List) { + capturedTypeParameters.add(StatusFirTypeParameterSymbolList(notNested, parameters.map { it.symbol })) + } + + fun popFirTypeParameters() { + val list = capturedTypeParameters + list.removeAt(list.lastIndex) + } + + inline fun applyToActualCapturedTypeParameters(ignoreLastLevel: Boolean, action: (FirTypeParameterSymbol) -> Unit) { + for (index in capturedTypeParameters.lastIndex downTo 0) { + val element = capturedTypeParameters[index] + + if (index < capturedTypeParameters.lastIndex || !ignoreLastLevel) { + for (capturedTypeParameter in element.list) { + action(capturedTypeParameter) + } + } + + if (!element.notNested) { + break + } + } + } + + data class StatusFirTypeParameterSymbolList(val notNested: Boolean, val list: List = listOf()) } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index 23035352624..85af69d020a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -89,9 +89,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( check(classOrObject is KtClassOrObject) withChildClassName(classOrObject.nameAsSafeName, false) { - withCapturedTypeParameters { - if (!parent.isInner) context.capturedTypeParameters = context.capturedTypeParameters.clear() - addCapturedTypeParameters(parent.typeParameters.take(classOrObject.typeParameters.size)) + withCapturedTypeParameters(parent.isInner, parent.typeParameters.subList(0, classOrObject.typeParameters.size)) { registerSelfType(classOrObject.toDelegatedSelfType(parent)) return moveNext(iterator, parent) }