From fb2485f83c3bb6062132f3ef79e7d73a4d64af2a Mon Sep 17 00:00:00 2001 From: Egor Kulikov Date: Fri, 2 Dec 2022 03:12:51 +0000 Subject: [PATCH] [FIR] Make constructor delegate lazy in RawFirBuilder Fifth step for ^KT-52615 Merge-request: KT-MR-7860 Merged-by: Egor Kulikov --- .../lazy/resolve/FirLazyBodiesCalculator.kt | 29 +++-- .../RawFirNonLocalDeclarationBuilder.kt | 80 ++++++++++-- .../lazyResolve/annotationParameters.txt | 26 ++-- .../classes/classWithTypeParameters.txt | 16 +-- .../classes/functionInValueClass.txt | 26 ++-- .../lazyResolve/secondaryConstructor.txt | 65 ++-------- .../java/declarations/FirJavaConstructor.kt | 4 + .../kotlin/fir/builder/RawFirBuilder.kt | 119 ++++++++++++------ .../declarations/annotation.lazyBodies.txt | 4 +- .../constructorInObject.lazyBodies.txt | 4 +- ...ccessorsContractDescription.lazyBodies.txt | 4 +- .../declarations/derivedClass.lazyBodies.txt | 4 +- .../declarations/enums.lazyBodies.txt | 4 +- .../declarations/enums2.lazyBodies.txt | 2 +- .../declarations/nestedClass.lazyBodies.txt | 4 +- ...rTypRefInPrimaryConstructor.lazyBodies.txt | 2 +- ...pRefInPrimaryConsturctorVal.lazyBodies.txt | 2 +- ...ypRefInSecondaryConstructor.lazyBodies.txt | 4 +- .../noPrimaryConstructor.lazyBodies.txt | 7 +- .../expressions/annotated.lazyBodies.txt | 2 +- .../expressions/arrayAccess.lazyBodies.txt | 2 +- .../expressions/calls.lazyBodies.txt | 2 +- .../collectionLiterals.lazyBodies.txt | 6 +- .../expressions/destructuring.lazyBodies.txt | 2 +- .../rawBuilder/expressions/for.lazyBodies.txt | 2 +- .../expressions/init.lazyBodies.txt | 2 +- .../expressions/lambda.lazyBodies.txt | 2 +- .../expressions/unary.lazyBodies.txt | 4 +- .../kotlin/fir/declarations/FirConstructor.kt | 2 + .../declarations/impl/FirConstructorImpl.kt | 4 + .../impl/FirPrimaryConstructor.kt | 4 + .../FirLazyDelegatedConstructorCallBuilder.kt | 61 +++++++++ .../impl/FirLazyDelegatedConstructorCall.kt | 72 +++++++++++ .../kotlin/fir/renderer/FirRenderer.kt | 17 ++- .../fir/tree/generator/BuilderConfigurator.kt | 2 +- .../generator/ImplementationConfigurator.kt | 29 +++++ .../fir/tree/generator/NodeConfigurator.kt | 2 +- 37 files changed, 436 insertions(+), 187 deletions(-) create mode 100644 compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirLazyDelegatedConstructorCallBuilder.kt create mode 100644 compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirLazyDelegatedConstructorCall.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt index 067dec7349b..c22ca2b0f71 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/FirLazyBodiesCalculator.kt @@ -11,11 +11,13 @@ import kotlinx.collections.immutable.toPersistentList import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesignation import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock +import org.jetbrains.kotlin.fir.expressions.impl.FirLazyDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.impl.FirLazyExpression import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider @@ -50,20 +52,21 @@ internal object FirLazyBodiesCalculator { } } - fun calculateLazyBodyForSecondaryConstructor(designation: FirDeclarationDesignation) { - val secondaryConstructor = designation.declaration as FirConstructor - require(!secondaryConstructor.isPrimary) - if (secondaryConstructor.body !is FirLazyBlock) return + fun calculateLazyBodyForConstructor(designation: FirDeclarationDesignation) { + val constructor = designation.declaration as FirConstructor + require(constructor.psi is KtConstructor<*>) + require(constructor.body is FirLazyBlock || constructor.delegatedConstructor is FirLazyDelegatedConstructorCall) - val newFunction = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = secondaryConstructor.moduleData.session, - scopeProvider = secondaryConstructor.moduleData.session.kotlinScopeProvider, + val newConstructor = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = constructor.moduleData.session, + scopeProvider = constructor.moduleData.session.kotlinScopeProvider, designation = designation, - rootNonLocalDeclaration = secondaryConstructor.psi as KtSecondaryConstructor, - ) as FirSimpleFunction + rootNonLocalDeclaration = constructor.psi as KtConstructor<*>, + ) as FirConstructor - secondaryConstructor.apply { - replaceBody(newFunction.body) + constructor.apply { + replaceBody(newConstructor.body) + replaceDelegatedConstructor(newConstructor.delegatedConstructor) } } @@ -187,9 +190,9 @@ private object FirLazyBodiesCalculatorTransformer : FirTransformer ): FirConstructor { - if (constructor.body is FirLazyBlock) { + if (constructor.body is FirLazyBlock || constructor.delegatedConstructor is FirLazyDelegatedConstructorCall) { val designation = FirDeclarationDesignation(data, constructor) - FirLazyBodiesCalculator.calculateLazyBodyForSecondaryConstructor(designation) + FirLazyBodiesCalculator.calculateLazyBodyForConstructor(designation) } return constructor } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index d47288c78b3..0c82c5f8bdf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -16,19 +16,20 @@ import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.psi import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull internal class RawFirNonLocalDeclarationBuilder private constructor( session: FirSession, baseScopeProvider: FirScopeProvider, - private val originalDeclarationIfParamertized: FirTypeParameterRefsOwner?, + private val originalDeclaration: FirDeclaration, private val declarationToBuild: KtDeclaration, private val functionsToRebind: Set? = null, private val replacementApplier: RawFirReplacement.Applier? = null @@ -45,7 +46,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( val builder = RawFirNonLocalDeclarationBuilder( session = session, baseScopeProvider = scopeProvider, - originalDeclarationIfParamertized = designation.declaration as? FirTypeParameterRefsOwner, + originalDeclaration = designation.declaration, declarationToBuild = rootNonLocalDeclaration, replacementApplier = replacementApplier ) @@ -62,7 +63,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( rootNonLocalDeclaration: KtDeclaration, ): FirDeclaration { val functionsToRebind = when (val originalDeclaration = designation.declaration) { - is FirSimpleFunction -> setOf(originalDeclaration) + is FirFunction -> setOf(originalDeclaration) is FirProperty -> setOfNotNull(originalDeclaration.getter, originalDeclaration.setter) else -> null } @@ -70,7 +71,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( val builder = RawFirNonLocalDeclarationBuilder( session = session, baseScopeProvider = scopeProvider, - originalDeclarationIfParamertized = designation.declaration as? FirTypeParameterRefsOwner, + originalDeclaration = designation.declaration, declarationToBuild = rootNonLocalDeclaration, functionsToRebind = functionsToRebind, ) @@ -89,8 +90,8 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( declarationSource: KtSourceElement?, currentFirTypeParameters: List ) { - if (originalDeclarationIfParamertized != null && declarationSource?.psi == originalDeclarationIfParamertized.psi) { - super.addCapturedTypeParameters(status, declarationSource, originalDeclarationIfParamertized.typeParameters) + if (originalDeclaration is FirTypeParameterRefsOwner && declarationSource?.psi == originalDeclaration.psi) { + super.addCapturedTypeParameters(status, declarationSource, originalDeclaration.typeParameters) } else { super.addCapturedTypeParameters(status, declarationSource, currentFirTypeParameters) } @@ -132,6 +133,55 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( ) } + private fun extractContructorConversionParams( + classOrObject: KtClassOrObject, + constructor: KtConstructor<*> + ): ConstructorConversionParams { + val typeParameters = mutableListOf() + context.appendOuterTypeParameters(ignoreLastLevel = false, typeParameters) + val containingClass = this.containingClass ?: buildErrorWithAttachment("Constructor outside of class") { + withPsiEntry("constructor", constructor) + } + val selfType = classOrObject.toDelegatedSelfType(typeParameters, containingClass.symbol) + val superTypeCallEntry = classOrObject.superTypeListEntries.firstIsInstanceOrNull() + return ConstructorConversionParams(superTypeCallEntry, selfType, typeParameters) + } + + override fun visitSecondaryConstructor(constructor: KtSecondaryConstructor, data: Unit?): FirElement { + val classOrObject = constructor.getContainingClassOrObject() + val params = extractContructorConversionParams(classOrObject, constructor) + val delegatedTypeRef = (originalDeclaration as FirConstructor).delegatedConstructor?.constructedTypeRef + ?: buildErrorWithAttachment("Secondary constructor without delegated call") { + withPsiEntry("constructor", constructor) + } + return constructor.toFirConstructor( + delegatedTypeRef, + params.selfType, + classOrObject, + params.typeParameters, + ) + } + + override fun visitPrimaryConstructor(constructor: KtPrimaryConstructor, data: Unit?): FirElement { + val classOrObject = constructor.getContainingClassOrObject() + val params = extractContructorConversionParams(classOrObject, constructor) + val firConstructor = originalDeclaration as FirConstructor + val calleeReference = firConstructor.delegatedConstructor?.calleeReference as FirSuperReference? + val newConstructor = constructor.toFirConstructor( + params.superTypeCallEntry, + firConstructor.delegatedConstructor?.constructedTypeRef, + params.selfType, + classOrObject, + params.typeParameters, + firConstructor.delegatedConstructor == null, + copyConstructedTypeRefWithImplicitSource = false, + ) + if (calleeReference != null) { + (newConstructor.delegatedConstructor?.calleeReference as? FirSuperReference)?.replaceSuperTypeRef(calleeReference.superTypeRef) + } + return newConstructor + } + override fun visitEnumEntry(enumEntry: KtEnumEntry, data: Unit?): FirElement { val owner = containingClass ?: buildErrorWithAttachment("Enum entry outside of class") { withPsiEntry("enumEntry", enumEntry) @@ -158,6 +208,14 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( val ownerTypeArgumentsCount = containingClass?.typeParameters?.size visitor.convertProperty(declarationToBuild, ownerSymbol, ownerTypeArgumentsCount) } + is KtConstructor<*> -> { + if (containingClass == null) { + // Constructor outside of class, syntax error, we should not do anything + originalDeclaration + } else { + visitor.convertElement(declarationToBuild) + } + } else -> visitor.convertElement(declarationToBuild) } as FirDeclaration } @@ -182,5 +240,11 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( private fun PsiElement?.toDelegatedSelfType(firClass: FirRegularClass): FirResolvedTypeRef = toDelegatedSelfType(firClass.typeParameters, firClass.symbol) + + private data class ConstructorConversionParams( + val superTypeCallEntry: KtSuperTypeCallEntry?, + val selfType: FirTypeRef, + val typeParameters: List, + ) } diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt index 6ae721d8e79..08d092b7f8d 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/annotationParameters.txt @@ -19,7 +19,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -57,7 +57,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -95,7 +95,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -133,7 +133,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -171,7 +171,7 @@ FILE: annotationParameters.kt } public? final? [RAW_FIR] annotation class Anno : R|kotlin/Annotation| { public? [RAW_FIR] [ContainingClassKey=Anno] constructor([RAW_FIR] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -209,7 +209,7 @@ FILE: annotationParameters.kt } public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -247,7 +247,7 @@ FILE: annotationParameters.kt } public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -285,7 +285,7 @@ FILE: annotationParameters.kt } public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -323,7 +323,7 @@ FILE: annotationParameters.kt } public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -362,7 +362,7 @@ FILE: annotationParameters.kt } public? final? [COMPILER_REQUIRED_ANNOTATIONS] annotation class Anno : R|kotlin/Annotation| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=Anno] constructor([COMPILER_REQUIRED_ANNOTATIONS] [CorrespondingProperty=/Anno.args] args: A.X): R|Anno| { - super() + LAZY_super } public? final? [COMPILER_REQUIRED_ANNOTATIONS] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -401,7 +401,7 @@ FILE: annotationParameters.kt } public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: ): R|Anno| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -440,7 +440,7 @@ FILE: annotationParameters.kt } public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: ): R|Anno| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| @@ -479,7 +479,7 @@ FILE: annotationParameters.kt } public final [SUPER_TYPES] annotation class Anno : R|kotlin/Annotation| { public [STATUS] [ContainingClassKey=Anno] constructor([STATUS] [CorrespondingProperty=/Anno.args] args: ): R|Anno| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val args: A.X = R|/args| diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt index 6315170838c..3b60177061a 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classes/classWithTypeParameters.txt @@ -3,7 +3,7 @@ RAW_FIR: FILE: classWithTypeParameters.kt public? final? [RAW_FIR] class ResolveMe<[RAW_FIR] T : Int, [RAW_FIR] K> : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=ResolveMe] constructor<[RAW_FIR] T : Int, [RAW_FIR] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -12,7 +12,7 @@ IMPORTS: FILE: classWithTypeParameters.kt public? final? [RAW_FIR] class ResolveMe<[RAW_FIR] T : Int, [RAW_FIR] K> : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=ResolveMe] constructor<[RAW_FIR] T : Int, [RAW_FIR] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -21,7 +21,7 @@ COMPILER_REQUIRED_ANNOTATIONS: FILE: classWithTypeParameters.kt public? final? [COMPILER_REQUIRED_ANNOTATIONS] class ResolveMe<[COMPILER_REQUIRED_ANNOTATIONS] T : Int, [COMPILER_REQUIRED_ANNOTATIONS] K> : R|kotlin/Any| { public? [COMPILER_REQUIRED_ANNOTATIONS] [ContainingClassKey=ResolveMe] constructor<[COMPILER_REQUIRED_ANNOTATIONS] T : Int, [COMPILER_REQUIRED_ANNOTATIONS] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -30,7 +30,7 @@ COMPANION_GENERATION: FILE: classWithTypeParameters.kt public? final? [COMPANION_GENERATION] class ResolveMe<[COMPANION_GENERATION] T : Int, [COMPANION_GENERATION] K> : R|kotlin/Any| { public? [COMPANION_GENERATION] [ContainingClassKey=ResolveMe] constructor<[COMPANION_GENERATION] T : Int, [COMPANION_GENERATION] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -39,7 +39,7 @@ SUPER_TYPES: FILE: classWithTypeParameters.kt public? final? [SUPER_TYPES] class ResolveMe<[SUPER_TYPES] T : Int, [SUPER_TYPES] K> : R|kotlin/Any| { public? [SUPER_TYPES] [ContainingClassKey=ResolveMe] constructor<[SUPER_TYPES] T : Int, [SUPER_TYPES] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -48,7 +48,7 @@ TYPES: FILE: classWithTypeParameters.kt public? final? [TYPES] class ResolveMe<[TYPES] T : R|kotlin/Int|, [TYPES] K> : R|kotlin/Any| { public? [TYPES] [ContainingClassKey=ResolveMe] constructor<[TYPES] T : R|kotlin/Int|, [TYPES] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -57,7 +57,7 @@ STATUS: FILE: classWithTypeParameters.kt public final [STATUS] class ResolveMe<[STATUS] T : R|kotlin/Int|, [STATUS] K> : R|kotlin/Any| { public [STATUS] [ContainingClassKey=ResolveMe] constructor<[STATUS] T : R|kotlin/Int|, [STATUS] K>(): R|ResolveMe| { - super() + LAZY_super } } @@ -66,7 +66,7 @@ ARGUMENTS_OF_ANNOTATIONS: FILE: classWithTypeParameters.kt public final [ARGUMENTS_OF_ANNOTATIONS] class ResolveMe<[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K> : R|kotlin/Any| { public [ARGUMENTS_OF_ANNOTATIONS] [ContainingClassKey=ResolveMe] constructor<[ARGUMENTS_OF_ANNOTATIONS] T : R|kotlin/Int|, [ARGUMENTS_OF_ANNOTATIONS] K>(): R|ResolveMe| { - super() + LAZY_super } } diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt b/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt index 7ebc32afa6e..2c9477c20e4 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/classes/functionInValueClass.txt @@ -3,7 +3,7 @@ RAW_FIR: FILE: functionInValueClass.kt @JvmInline() public? final? inline [RAW_FIR] class Value : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=Value] constructor([RAW_FIR] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -17,7 +17,7 @@ IMPORTS: FILE: functionInValueClass.kt @JvmInline() public? final? inline [RAW_FIR] class Value : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=Value] constructor([RAW_FIR] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -31,7 +31,7 @@ COMPILER_REQUIRED_ANNOTATIONS: FILE: functionInValueClass.kt @JvmInline() public? final? inline [RAW_FIR] class Value : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=Value] constructor([RAW_FIR] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -45,7 +45,7 @@ COMPANION_GENERATION: FILE: functionInValueClass.kt @JvmInline() public? final? inline [RAW_FIR] class Value : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=Value] constructor([RAW_FIR] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -59,7 +59,7 @@ SUPER_TYPES: FILE: functionInValueClass.kt @JvmInline() public? final? inline [RAW_FIR] class Value : R|kotlin/Any| { public? [RAW_FIR] [ContainingClassKey=Value] constructor([RAW_FIR] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [RAW_FIR] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -73,7 +73,7 @@ TYPES: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public? final? inline [SUPER_TYPES] class Value : R|kotlin/Any| { public? [SUPER_TYPES] [ContainingClassKey=Value] constructor([SUPER_TYPES] [CorrespondingProperty=/Value.value] value: Int): R|Value| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -87,7 +87,7 @@ STATUS: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [SUPER_TYPES] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public? [TYPES] [ContainingClassKey=Value] constructor([TYPES] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -101,7 +101,7 @@ ARGUMENTS_OF_ANNOTATIONS: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [SUPER_TYPES] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public? [TYPES] [ContainingClassKey=Value] constructor([TYPES] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -115,7 +115,7 @@ CONTRACTS: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [SUPER_TYPES] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public? [TYPES] [ContainingClassKey=Value] constructor([TYPES] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public? final? [SUPER_TYPES] [IsFromPrimaryConstructor=true] val value: Int = R|/value| @@ -130,7 +130,7 @@ IMPLICIT_TYPES_BODY_RESOLVE: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| @@ -145,7 +145,7 @@ ANNOTATIONS_ARGUMENTS_MAPPING: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| @@ -160,7 +160,7 @@ EXPECT_ACTUAL_MATCHING: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| @@ -175,7 +175,7 @@ BODY_RESOLVE: FILE: functionInValueClass.kt @R|kotlin/jvm/JvmInline|() public final inline [STATUS] [FirValueClassRepresentationKey=InlineClassRepresentation(underlyingPropertyName=value, underlyingType=kotlin/Int)] class Value : R|kotlin/Any| { public [STATUS] [ContainingClassKey=Value] constructor([STATUS] [CorrespondingProperty=/Value.value] value: R|kotlin/Int|): R|Value| { - super() + LAZY_super } public final [STATUS] [IsFromPrimaryConstructor=true] val value: R|kotlin/Int| = R|/value| diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt b/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt index 83a27dcc6ec..3d5a7c5c9b0 100644 --- a/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt +++ b/analysis/low-level-api-fir/testdata/lazyResolve/secondaryConstructor.txt @@ -4,10 +4,7 @@ FILE: secondaryConstructor.kt public? final? [RAW_FIR] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -16,10 +13,7 @@ FILE: secondaryConstructor.kt public? final? [RAW_FIR] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -28,10 +22,7 @@ FILE: secondaryConstructor.kt public? final? [COMPILER_REQUIRED_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -40,10 +31,7 @@ FILE: secondaryConstructor.kt public? final? [COMPANION_GENERATION] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -52,10 +40,7 @@ FILE: secondaryConstructor.kt public? final? [SUPER_TYPES] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -64,10 +49,7 @@ FILE: secondaryConstructor.kt public? final? [TYPES] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -76,10 +58,7 @@ FILE: secondaryConstructor.kt public final [STATUS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -88,10 +67,7 @@ FILE: secondaryConstructor.kt public final [ARGUMENTS_OF_ANNOTATIONS] fun resolveMe(): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -102,10 +78,7 @@ FILE: secondaryConstructor.kt } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -116,10 +89,7 @@ FILE: secondaryConstructor.kt } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -130,10 +100,7 @@ FILE: secondaryConstructor.kt } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -144,10 +111,7 @@ FILE: secondaryConstructor.kt } public? final? [RAW_FIR] fun receive([RAW_FIR] value: A): R|kotlin/Unit| { LAZY_BLOCK } public? final? [RAW_FIR] class A : R|kotlin/Any| { - public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public? [RAW_FIR] [ContainingClassKey=A] constructor([RAW_FIR] x: Int): R|A| { LAZY_BLOCK } } @@ -159,10 +123,7 @@ FILE: secondaryConstructor.kt public final [CONTRACTS] fun receive([CONTRACTS] value: R|A|): R|kotlin/Unit| { } public final [STATUS] class A : R|kotlin/Any| { - public [STATUS] [ContainingClassKey=A] constructor([STATUS] x: R|kotlin/Int|): R|A| { - super() - [RAW_FIR] lval a: = x# - } + public [STATUS] [ContainingClassKey=A] constructor([STATUS] x: R|kotlin/Int|): R|A| { LAZY_BLOCK } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt index a3a63ad3973..b63db055afa 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt @@ -133,6 +133,10 @@ class FirJavaConstructor @FirImplementationDetail constructor( valueParameters += newValueParameters } + override fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?) { + error("Delegated constructor cannot be replaced for FirJavaConstructor") + } + override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) {} override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) { 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 5ab57421841..58ee64bedd0 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 @@ -188,6 +188,29 @@ open class RawFirBuilder( return buildOrLazy(buildBlock, ::buildLazyBlock) } + private inline fun buildOrLazyDelegatedConstructorCall( + isThis: Boolean, + constructedTypeRef: FirTypeRef, + buildCall: () -> FirDelegatedConstructorCall + ): FirDelegatedConstructorCall { + return buildOrLazy(buildCall, { + buildLazyDelegatedConstructorCall { + this.isThis = isThis + this.constructedTypeRef = constructedTypeRef + calleeReference = if (isThis) { + buildExplicitThisReference { + source = null + } + } else { + buildExplicitSuperReference { + source = null + superTypeRef = constructedTypeRef + } + } + } + }) + } + open fun convertElement(element: KtElement): FirElement? = element.accept(this@Visitor, Unit) @@ -206,7 +229,8 @@ open class RawFirBuilder( defaultTypeRef: FirTypeRef? = null, valueParameterDeclaration: ValueParameterDeclaration, additionalAnnotations: List = emptyList() - ): FirValueParameter = valueParameter.toFirValueParameter(defaultTypeRef, functionSymbol, valueParameterDeclaration, additionalAnnotations) + ): FirValueParameter = + valueParameter.toFirValueParameter(defaultTypeRef, functionSymbol, valueParameterDeclaration, additionalAnnotations) private fun KtTypeReference?.toFirOrImplicitType(): FirTypeRef = convertSafe() ?: buildImplicitTypeRef { @@ -291,14 +315,12 @@ open class RawFirBuilder( ): FirDeclaration { return when (this) { is KtSecondaryConstructor -> { - disabledLazyMode { - toFirConstructor( - delegatedSuperType, - delegatedSelfType, - owner, - ownerTypeParameters - ) - } + toFirConstructor( + if (isDelegatedCallToThis()) delegatedSelfType else delegatedSuperType, + delegatedSelfType, + owner, + ownerTypeParameters, + ) } is KtEnumEntry -> { val primaryConstructor = owner.primaryConstructor @@ -890,11 +912,12 @@ open class RawFirBuilder( if (primaryConstructor != null || (this !is KtClass || !this.isInterface()) && shouldGenerateImplicitPrimaryConstructor) { val firPrimaryConstructor = primaryConstructor.toFirConstructor( superTypeCallEntry, - delegatedSuperTypeRef!!, + delegatedSuperTypeRef, delegatedSelfTypeRef ?: delegatedSuperTypeRef!!, owner = this, containerTypeParameters, containingClassIsExpectClass, + copyConstructedTypeRefWithImplicitSource = true, ) container.declarations += firPrimaryConstructor } @@ -902,27 +925,49 @@ open class RawFirBuilder( return delegatedSuperTypeRef!! to delegateFieldsMap.takeIf { it.isNotEmpty() } } - private fun KtPrimaryConstructor?.toFirConstructor( + /** + * @param delegatedSuperTypeRef can be null if containingClassIsExpectClass is true + */ + protected fun KtPrimaryConstructor?.toFirConstructor( superTypeCallEntry: KtSuperTypeCallEntry?, - delegatedSuperTypeRef: FirTypeRef, + delegatedSuperTypeRef: FirTypeRef?, delegatedSelfTypeRef: FirTypeRef, owner: KtClassOrObject, ownerTypeParameters: List, containingClassIsExpectClass: Boolean, + copyConstructedTypeRefWithImplicitSource: Boolean, ): FirConstructor { val constructorCall = superTypeCallEntry?.toFirSourceElement() val constructorSource = this?.toFirSourceElement() ?: owner.toKtPsiSourceElement(KtFakeSourceElementKind.ImplicitConstructor) - val firDelegatedCall = if (containingClassIsExpectClass) null else buildDelegatedConstructorCall { - source = constructorCall ?: constructorSource.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall) - constructedTypeRef = delegatedSuperTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef) - isThis = false - calleeReference = buildExplicitSuperReference { - source = superTypeCallEntry?.calleeExpression?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall) - ?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall) - superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + val firDelegatedCall = if (containingClassIsExpectClass) null else { + val constructedTypeRef = if (copyConstructedTypeRefWithImplicitSource) { + delegatedSuperTypeRef!!.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef) + } else { + delegatedSuperTypeRef!! } - superTypeCallEntry?.extractArgumentsTo(this) + val delegatedConstructorCall = { + buildDelegatedConstructorCall { + source = constructorCall ?: constructorSource.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall) + this.constructedTypeRef = constructedTypeRef + isThis = false + calleeReference = buildExplicitSuperReference { + source = + superTypeCallEntry?.calleeExpression?.toFirSourceElement(KtFakeSourceElementKind.DelegatingConstructorCall) + ?: this@buildDelegatedConstructorCall.source?.fakeElement(KtFakeSourceElementKind.DelegatingConstructorCall) + superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + } + superTypeCallEntry?.extractArgumentsTo(this) + } + } + if (this == null && owner !is KtEnumEntry) { + // primary constructor without body + delegatedConstructorCall() + } else buildOrLazyDelegatedConstructorCall( + isThis = false, + constructedTypeRef, + delegatedConstructorCall, + ) } // See DescriptorUtils#getDefaultConstructorVisibility in core.descriptors @@ -1003,7 +1048,7 @@ open class RawFirBuilder( } } - private fun convertScript(script: KtScript, containingFile: FirFileBuilder,): FirScript { + private fun convertScript(script: KtScript, containingFile: FirFileBuilder): FirScript { return buildScript { source = script.toFirSourceElement() moduleData = baseModuleData @@ -1086,7 +1131,8 @@ open class RawFirBuilder( delegatedEntrySelfType, owner = ktEnumEntry, typeParameters, - containingClassIsExpectClass + containingClassIsExpectClass, + copyConstructedTypeRefWithImplicitSource = true, ) // Use ANONYMOUS_OBJECT_NAME for the owner class id for enum entry declarations (see KT-42351) withChildClassName(SpecialNames.ANONYMOUS, forceLocalContext = true, isExpect = false) { @@ -1541,9 +1587,9 @@ open class RawFirBuilder( } } - private fun KtSecondaryConstructor.toFirConstructor( - delegatedSuperTypeRef: FirTypeRef, - delegatedSelfTypeRef: FirTypeRef, + protected fun KtSecondaryConstructor.toFirConstructor( + delegatedTypeRef: FirTypeRef, + selfTypeRef: FirTypeRef, owner: KtClassOrObject, ownerTypeParameters: List ): FirConstructor { @@ -1552,7 +1598,7 @@ open class RawFirBuilder( source = this@toFirConstructor.toFirSourceElement() moduleData = baseModuleData origin = FirDeclarationOrigin.Source - returnTypeRef = delegatedSelfTypeRef + returnTypeRef = selfTypeRef val explicitVisibility = visibility status = FirDeclarationStatusImpl(explicitVisibility, Modality.FINAL).apply { isExpect = hasExpectModifier() || this@RawFirBuilder.context.containerIsExpect @@ -1563,10 +1609,12 @@ open class RawFirBuilder( } dispatchReceiverType = owner.obtainDispatchReceiverForConstructor() symbol = FirConstructorSymbol(callableIdForClassConstructor()) - delegatedConstructor = getDelegationCall().convert( - delegatedSuperTypeRef, - delegatedSelfTypeRef, - ) + delegatedConstructor = buildOrLazyDelegatedConstructorCall( + isThis = isDelegatedCallToThis(), + constructedTypeRef = delegatedTypeRef, + ) { + getDelegationCall().convert(delegatedTypeRef) + } this@RawFirBuilder.context.firFunctionTargets += target extractAnnotationsTo(this) typeParameters += constructorTypeParametersFromConstructedClass(ownerTypeParameters) @@ -1583,8 +1631,7 @@ open class RawFirBuilder( } private fun KtConstructorDelegationCall.convert( - delegatedSuperTypeRef: FirTypeRef, - delegatedSelfTypeRef: FirTypeRef, + delegatedType: FirTypeRef, ): FirDelegatedConstructorCall { val isThis = isCallToThis //|| (isImplicit && hasPrimaryConstructor) val source = if (isImplicit) { @@ -1592,10 +1639,6 @@ open class RawFirBuilder( } else { this.toFirSourceElement() } - val delegatedType = when { - isThis -> delegatedSelfTypeRef - else -> delegatedSuperTypeRef - } return buildDelegatedConstructorCall { this.source = source constructedTypeRef = delegatedType.copyWithNewSourceKind(KtFakeSourceElementKind.ImplicitTypeRef) @@ -1619,7 +1662,7 @@ open class RawFirBuilder( } private fun KtDeclarationWithInitializer.toInitializerExpression() = - runIf (hasInitializer()) { + runIf(hasInitializer()) { buildOrLazyExpression(initializer?.toFirSourceElement()) { initializer.toFirExpression("Should have initializer") } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.lazyBodies.txt index d4597cc2897..c0c487e46ec 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.lazyBodies.txt @@ -13,14 +13,14 @@ FILE: annotation.kt } @base() public? final? class correct : R|kotlin/Any| { public? constructor(@base() x: Int): R|correct| { - super() + LAZY_super } @base() public? final? val x: Int = R|/x| public? get(): Int @base() public? constructor(): R|correct| { - this(IntegerLiteral(0)) + LAZY_this } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.lazyBodies.txt index 410d67a1b7f..f7316df65eb 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: constructorInObject.kt public? final? object A : R|kotlin/Any| { public? constructor(): R|A| { - super() + LAZY_super } init { LAZY_BLOCK } @@ -30,7 +30,7 @@ FILE: constructorInObject.kt public? final? companion object Companion : R|kotlin/Any| { public? constructor(): R|C.Companion| { - super() + LAZY_super } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/propertyAccessorsContractDescription.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/propertyAccessorsContractDescription.lazyBodies.txt index 2c7e49b7cd4..5882f5f9b08 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/propertyAccessorsContractDescription.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/propertyAccessorsContractDescription.lazyBodies.txt @@ -15,7 +15,7 @@ FILE: propertyAccessorsContractDescription.kt } public? final? class AnotherClass : R|kotlin/Any| { public? constructor(multiplier: Int): R|AnotherClass| { - super() + LAZY_super } public? final? var anotherInt: Int = LAZY_EXPRESSION @@ -33,7 +33,7 @@ FILE: propertyAccessorsContractDescription.kt } public? final? class SomeClass : R|kotlin/Any| { public? constructor(multiplier: Int?): R|SomeClass| { - super() + LAZY_super } public? final? var someInt: Int = LAZY_EXPRESSION diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.lazyBodies.txt index ba56e828eff..0ac7180f6d5 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: derivedClass.kt public? open class Base : R|kotlin/Any| { public? constructor(x: T): R|Base| { - super() + LAZY_super } public? final? val x: T = R|/x| @@ -10,7 +10,7 @@ FILE: derivedClass.kt } public? final? class Derived : Base { public? constructor(x: T): R|Derived| { - super>(x#) + LAZY_super> } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.lazyBodies.txt index b88962957a9..afb07076f89 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.lazyBodies.txt @@ -19,7 +19,7 @@ FILE: enums.kt } public? final? enum class Planet : R|kotlin/Enum| { private constructor(m: Double, r: Double): R|Planet| { - super|>() + LAZY_super|> } public? final? val m: Double = R|/m| @@ -58,7 +58,7 @@ FILE: enums.kt } public? final? enum class PseudoInsn : R|kotlin/Enum| { private constructor(signature: String = String(()V)): R|PseudoInsn| { - super|>() + LAZY_super|> } public? final? val signature: String = R|/signature| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.lazyBodies.txt index 0b03bcfbe89..344f6672fec 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.lazyBodies.txt @@ -15,7 +15,7 @@ FILE: enums2.kt } public? final? enum class SomeEnum : R|kotlin/Enum| { private constructor(x: Some): R|SomeEnum| { - super|>() + LAZY_super|> } public? final? val x: Some = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.lazyBodies.txt index 95071a2c119..82efe43a8bf 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: nestedClass.kt public? abstract class Base : R|kotlin/Any| { public? constructor(s: String): R|Base| { - super() + LAZY_super } public? final? val s: String = R|/s| @@ -15,7 +15,7 @@ FILE: nestedClass.kt public? final? class Derived : Base { public? constructor(s: String): R|Outer.Derived| { - super(s#) + LAZY_super } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConstructor.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConstructor.lazyBodies.txt index 02116acf56c..b5274869644 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConstructor.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConstructor.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: noParameterTypRefInPrimaryConstructor.kt public? final? class X : R|kotlin/Any| { public? constructor(x: ): R|X| { - super() + LAZY_super } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConsturctorVal.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConsturctorVal.lazyBodies.txt index cef20d4cedb..43ba303a06f 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConsturctorVal.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInPrimaryConsturctorVal.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: noParameterTypRefInPrimaryConsturctorVal.kt public? final? class X : R|kotlin/Any| { public? constructor(x: ): R|X| { - super() + LAZY_super } public? final? val x: = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInSecondaryConstructor.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInSecondaryConstructor.lazyBodies.txt index a60fb3a2908..c3f2b35bedc 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInSecondaryConstructor.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noParameterType/noParameterTypRefInSecondaryConstructor.lazyBodies.txt @@ -1,7 +1,5 @@ FILE: noParameterTypRefInSecondaryConstructor.kt public? final? class C : R|kotlin/Any| { - public? constructor(x: ): R|C| { - super() - } + public? constructor(x: ): R|C| { LAZY_BLOCK } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.lazyBodies.txt index ff9575ff5ef..b5bda65a8a0 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.lazyBodies.txt @@ -3,13 +3,10 @@ FILE: noPrimaryConstructor.kt public? final? val x: String public? get(): String - public? constructor(x: String): R|NoPrimary| { - super() - this#.x# = x# - } + public? constructor(x: String): R|NoPrimary| { LAZY_BLOCK } public? constructor(): R|NoPrimary| { - this(String()) + LAZY_this } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.lazyBodies.txt index b3c4fec3283..027f59869a1 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.lazyBodies.txt @@ -8,7 +8,7 @@ FILE: annotated.kt public? final? fun foo(arg: Int): Int { LAZY_BLOCK } public? final? data class Two : R|kotlin/Any| { public? constructor(x: Int, y: Int): R|Two| { - super() + LAZY_super } public? final? val x: Int = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.lazyBodies.txt index d49f63d3ce9..47578ab8665 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.lazyBodies.txt @@ -4,7 +4,7 @@ FILE: arrayAccess.kt public? final? fun foo(): { LAZY_BLOCK } public? final? class Wrapper : R|kotlin/Any| { public? constructor(v: IntArray): R|Wrapper| { - super() + LAZY_super } public? final? val v: IntArray = R|/v| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.lazyBodies.txt index 5c8391a0ae7..5dfac3080c3 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.lazyBodies.txt @@ -4,7 +4,7 @@ FILE: calls.kt public? final? fun testRegular(): Int { LAZY_BLOCK } public? final? class My : R|kotlin/Any| { public? constructor(x: Int): R|My| { - super() + LAZY_super } public? final? var x: Int = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.lazyBodies.txt index 41bb97c524b..28b30fcbf46 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: collectionLiterals.kt public? final? annotation class Ann1 : R|kotlin/Annotation| { public? constructor(arr: IntArray): R|Ann1| { - super() + LAZY_super } public? final? val arr: IntArray = R|/arr| @@ -10,7 +10,7 @@ FILE: collectionLiterals.kt } public? final? annotation class Ann2 : R|kotlin/Annotation| { public? constructor(arr: DoubleArray): R|Ann2| { - super() + LAZY_super } public? final? val arr: DoubleArray = R|/arr| @@ -19,7 +19,7 @@ FILE: collectionLiterals.kt } public? final? annotation class Ann3 : R|kotlin/Annotation| { public? constructor(arr: Array): R|Ann3| { - super() + LAZY_super } public? final? val arr: Array = R|/arr| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.lazyBodies.txt index 3e478c47f88..5f1d2cc9603 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: destructuring.kt public? final? data class Some : R|kotlin/Any| { public? constructor(first: Int, second: Double, third: String): R|Some| { - super() + LAZY_super } public? final? val first: Int = R|/first| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.lazyBodies.txt index 7cd142a462a..3aa25b05eef 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.lazyBodies.txt @@ -4,7 +4,7 @@ FILE: for.kt public? final? fun bar(list: List): R|kotlin/Unit| { LAZY_BLOCK } public? final? data class Some : R|kotlin/Any| { public? constructor(x: Int, y: Int): R|Some| { - super() + LAZY_super } public? final? val x: Int = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/init.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/init.lazyBodies.txt index 78995de4031..4e3d776fcdc 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/init.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/init.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: init.kt public? final? class WithInit : R|kotlin/Any| { public? constructor(x: Int): R|WithInit| { - super() + LAZY_super } public? final? val x: Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.lazyBodies.txt index 056f6daf1a7..d2b0bf58651 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.lazyBodies.txt @@ -1,7 +1,7 @@ FILE: lambda.kt public? final? data class Tuple : R|kotlin/Any| { public? constructor(x: Int, y: Int): R|Tuple| { - super() + LAZY_super } public? final? val x: Int = R|/x| diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.lazyBodies.txt index e7181687c20..27d679817d9 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.lazyBodies.txt @@ -2,7 +2,7 @@ FILE: unary.kt public? final? fun test(): R|kotlin/Unit| { LAZY_BLOCK } public? final? class X : R|kotlin/Any| { public? constructor(i: Int): R|X| { - super() + LAZY_super } public? final? val i: Int = R|/i| @@ -13,7 +13,7 @@ FILE: unary.kt public? final? fun test3(arr: Array): R|kotlin/Unit| { LAZY_BLOCK } public? final? class Y : R|kotlin/Any| { public? constructor(arr: Array): R|Y| { - super() + LAZY_super } public? final? val arr: Array = R|/arr| diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt index 9d07822ae77..9e3bda3915b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt @@ -65,6 +65,8 @@ abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner { abstract override fun replaceValueParameters(newValueParameters: List) + abstract fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?) + abstract override fun replaceBody(newBody: FirBlock?) abstract override fun transformTypeParameters(transformer: FirTransformer, data: D): FirConstructor diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt index f4824d8ed93..0a06e8ebf74 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt @@ -159,6 +159,10 @@ internal class FirConstructorImpl( valueParameters.addAll(newValueParameters) } + override fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?) { + delegatedConstructor = newDelegatedConstructor + } + override fun replaceBody(newBody: FirBlock?) { body = newBody } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt index 39060aae511..eae6815e6d4 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt @@ -160,6 +160,10 @@ class FirPrimaryConstructor @FirImplementationDetail constructor( valueParameters.addAll(newValueParameters) } + override fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?) { + delegatedConstructor = newDelegatedConstructor + } + override fun replaceBody(newBody: FirBlock?) { body = newBody } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirLazyDelegatedConstructorCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirLazyDelegatedConstructorCallBuilder.kt new file mode 100644 index 00000000000..209dba4b529 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirLazyDelegatedConstructorCallBuilder.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.expressions.builder + +import kotlin.contracts.* +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirImplementationDetail +import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder +import org.jetbrains.kotlin.fir.builder.FirBuilderDsl +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirArgumentList +import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.impl.FirLazyDelegatedConstructorCall +import org.jetbrains.kotlin.fir.references.FirReference +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +@FirBuilderDsl +class FirLazyDelegatedConstructorCallBuilder : FirAnnotationContainerBuilder { + lateinit var constructedTypeRef: FirTypeRef + lateinit var calleeReference: FirReference + var isThis: Boolean by kotlin.properties.Delegates.notNull() + + @OptIn(FirImplementationDetail::class) + override fun build(): FirDelegatedConstructorCall { + return FirLazyDelegatedConstructorCall( + constructedTypeRef, + calleeReference, + isThis, + ) + } + + @Deprecated("Modification of 'source' has no impact for FirLazyDelegatedConstructorCallBuilder", level = DeprecationLevel.HIDDEN) + override var source: KtSourceElement? + get() = throw IllegalStateException() + set(_) { + throw IllegalStateException() + } + + @Deprecated("Modification of 'annotations' has no impact for FirLazyDelegatedConstructorCallBuilder", level = DeprecationLevel.HIDDEN) + override val annotations: MutableList = mutableListOf() +} + +@OptIn(ExperimentalContracts::class) +inline fun buildLazyDelegatedConstructorCall(init: FirLazyDelegatedConstructorCallBuilder.() -> Unit): FirDelegatedConstructorCall { + contract { + callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) + } + return FirLazyDelegatedConstructorCallBuilder().apply(init).build() +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirLazyDelegatedConstructorCall.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirLazyDelegatedConstructorCall.kt new file mode 100644 index 00000000000..682f9f1f506 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirLazyDelegatedConstructorCall.kt @@ -0,0 +1,72 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.expressions.impl + +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirImplementationDetail +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirArgumentList +import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.references.FirReference +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +class FirLazyDelegatedConstructorCall @FirImplementationDetail constructor( + override var constructedTypeRef: FirTypeRef, + override var calleeReference: FirReference, + override val isThis: Boolean, +) : FirDelegatedConstructorCall() { + override val source: KtSourceElement? get() = error("FirLazyDelegatedConstructorCall should be calculated before accessing") + override val annotations: List get() = error("FirLazyDelegatedConstructorCall should be calculated before accessing") + override val argumentList: FirArgumentList get() = error("FirLazyDelegatedConstructorCall should be calculated before accessing") + override val contextReceiverArguments: List get() = error("FirLazyDelegatedConstructorCall should be calculated before accessing") + override val dispatchReceiver: FirExpression get() = error("FirLazyDelegatedConstructorCall should be calculated before accessing") + override val isSuper: Boolean get() = !isThis + + override fun acceptChildren(visitor: FirVisitor, data: D) { + constructedTypeRef.accept(visitor, data) + calleeReference.accept(visitor, data) + } + + override fun transformChildren(transformer: FirTransformer, data: D): FirLazyDelegatedConstructorCall { + constructedTypeRef = constructedTypeRef.transform(transformer, data) + transformCalleeReference(transformer, data) + return this + } + + override fun transformAnnotations(transformer: FirTransformer, data: D): FirLazyDelegatedConstructorCall { + return this + } + + override fun transformDispatchReceiver(transformer: FirTransformer, data: D): FirLazyDelegatedConstructorCall { + return this + } + + override fun transformCalleeReference(transformer: FirTransformer, data: D): FirLazyDelegatedConstructorCall { + calleeReference = calleeReference.transform(transformer, data) + return this + } + + override fun replaceArgumentList(newArgumentList: FirArgumentList) {} + + override fun replaceContextReceiverArguments(newContextReceiverArguments: List) {} + + override fun replaceConstructedTypeRef(newConstructedTypeRef: FirTypeRef) { + constructedTypeRef = newConstructedTypeRef + } + + override fun replaceCalleeReference(newCalleeReference: FirReference) { + calleeReference = newCalleeReference + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index b7e3f721cb5..9aaf3db99bb 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -654,10 +654,15 @@ class FirRenderer( } override fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall) { - val dispatchReceiver = delegatedConstructorCall.dispatchReceiver - if (dispatchReceiver !is FirNoReceiverExpression) { - dispatchReceiver.accept(this) - print(".") + if (delegatedConstructorCall !is FirLazyDelegatedConstructorCall) { + val dispatchReceiver = delegatedConstructorCall.dispatchReceiver + if (dispatchReceiver !is FirNoReceiverExpression) { + dispatchReceiver.accept(this) + print(".") + } + } + if (delegatedConstructorCall is FirLazyDelegatedConstructorCall) { + print("LAZY_") } if (delegatedConstructorCall.isSuper) { print("super<") @@ -666,7 +671,9 @@ class FirRenderer( } delegatedConstructorCall.constructedTypeRef.accept(this) print(">") - visitCall(delegatedConstructorCall) + if (delegatedConstructorCall !is FirLazyDelegatedConstructorCall) { + visitCall(delegatedConstructorCall) + } } override fun visitTypeRef(typeRef: FirTypeRef) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index 9b921ee7ede..0fd658beb1e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -190,7 +190,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree defaultNull("label") } - builder(delegatedConstructorCall) { + builder(delegatedConstructorCall, type = "FirDelegatedConstructorCallImpl") { parents += callBuilder default("argumentList") { value = "FirEmptyArgumentList" diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 57a282b4045..ac18f61c6a9 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -128,6 +128,35 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() useTypes(explicitThisReferenceType, explicitSuperReferenceType) } + impl(delegatedConstructorCall, "FirLazyDelegatedConstructorCall") { + val error = """error("FirLazyDelegatedConstructorCall should be calculated before accessing")""" + default("source") { + value = error + withGetter = true + } + default("annotations") { + value = error + withGetter = true + } + default("argumentList") { + value = error + withGetter = true + } + default("contextReceiverArguments") { + value = error + withGetter = true + } + default("dispatchReceiver") { + value = error + withGetter = true + } + default("isSuper") { + value = "!isThis" + withGetter = true + } + publicImplementation() + } + impl(expression, "FirElseIfTrueCondition") { defaultTypeRefWithSource("FirImplicitBooleanTypeRef") useTypes(implicitBooleanTypeRefType) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index fe8ef26c65a..17386870a7c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -379,7 +379,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild constructor.configure { +annotations +symbol("FirConstructorSymbol") - +field("delegatedConstructor", delegatedConstructorCall, nullable = true).withTransform() + +field("delegatedConstructor", delegatedConstructorCall, nullable = true, withReplace = true).withTransform() +body(nullable = true) +booleanField("isPrimary") }