diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/LLFirDesignatedBodyResolveTransformerForReturnTypeCalculator.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/LLFirDesignatedBodyResolveTransformerForReturnTypeCalculator.kt index 311570bf1bd..3a1f2d50ef4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/LLFirDesignatedBodyResolveTransformerForReturnTypeCalculator.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/element/builder/LLFirDesignatedBodyResolveTransformerForReturnTypeCalculator.kt @@ -75,8 +75,10 @@ private class LLFirDesignatedBodyResolveTransformerForReturnTypeCalculatorImpl( simpleFunction: FirSimpleFunction, data: ResolutionMode ): FirSimpleFunction { - simpleFunction.processCallable { - FirLazyBodiesCalculator.calculateLazyBodiesForFunction(it) + if (FirLazyBodiesCalculator.needCalculatingLazyBodyForFunction(simpleFunction)) { + simpleFunction.processCallable { + FirLazyBodiesCalculator.calculateLazyBodiesForFunction(it) + } } return super.transformSimpleFunction(simpleFunction, data) 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 c22ca2b0f71..9424bd6952c 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 @@ -37,9 +37,18 @@ internal object FirLazyBodiesCalculator { firFile.transform>(FirLazyBodiesCalculatorTransformer, persistentListOf()) } + private fun replaceValueParameterDefaultValues(valueParameters: List, newValueParameters: List) { + require(valueParameters.size == newValueParameters.size) + for ((valueParameter, newValueParameter) in valueParameters.zip(newValueParameters)) { + if (newValueParameter.defaultValue != null) { + valueParameter.replaceDefaultValue(newValueParameter.defaultValue) + } + } + } + fun calculateLazyBodiesForFunction(designation: FirDeclarationDesignation) { val simpleFunction = designation.declaration as FirSimpleFunction - if (simpleFunction.body !is FirLazyBlock) return + require(needCalculatingLazyBodyForFunction(simpleFunction)) val newFunction = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( session = simpleFunction.moduleData.session, scopeProvider = simpleFunction.moduleData.session.kotlinScopeProvider, @@ -49,13 +58,14 @@ internal object FirLazyBodiesCalculator { simpleFunction.apply { replaceBody(newFunction.body) replaceContractDescription(newFunction.contractDescription) + replaceValueParameterDefaultValues(valueParameters, newFunction.valueParameters) } } fun calculateLazyBodyForConstructor(designation: FirDeclarationDesignation) { val constructor = designation.declaration as FirConstructor require(constructor.psi is KtConstructor<*>) - require(constructor.body is FirLazyBlock || constructor.delegatedConstructor is FirLazyDelegatedConstructorCall) + require(needCalculatingLazyBodyForConstructor(constructor)) val newConstructor = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( session = constructor.moduleData.session, @@ -67,6 +77,7 @@ internal object FirLazyBodiesCalculator { constructor.apply { replaceBody(newConstructor.body) replaceDelegatedConstructor(newConstructor.delegatedConstructor) + replaceValueParameterDefaultValues(valueParameters, newConstructor.valueParameters) } } @@ -147,9 +158,15 @@ internal object FirLazyBodiesCalculator { } } + fun needCalculatingLazyBodyForConstructor(firConstructor: FirConstructor): Boolean = + needCalculatingLazyBodyForFunction(firConstructor) || firConstructor.delegatedConstructor is FirLazyDelegatedConstructorCall + + fun needCalculatingLazyBodyForFunction(firFunction: FirFunction): Boolean = + firFunction.body is FirLazyBlock || firFunction.valueParameters.any { it.defaultValue is FirLazyExpression } + fun needCalculatingLazyBodyForProperty(firProperty: FirProperty): Boolean = - firProperty.getter?.body is FirLazyBlock - || firProperty.setter?.body is FirLazyBlock + firProperty.getter?.let { needCalculatingLazyBodyForFunction(it) } == true + || firProperty.setter?.let { needCalculatingLazyBodyForFunction(it) } == true || firProperty.initializer is FirLazyExpression || (firProperty.delegate as? FirWrappedDelegateExpression)?.expression is FirLazyExpression || firProperty.getExplicitBackingField()?.initializer is FirLazyExpression @@ -179,7 +196,7 @@ private object FirLazyBodiesCalculatorTransformer : FirTransformer ): FirSimpleFunction { - if (simpleFunction.body is FirLazyBlock) { + if (FirLazyBodiesCalculator.needCalculatingLazyBodyForFunction(simpleFunction)) { val designation = FirDeclarationDesignation(data, simpleFunction) FirLazyBodiesCalculator.calculateLazyBodiesForFunction(designation) } @@ -190,7 +207,7 @@ private object FirLazyBodiesCalculatorTransformer : FirTransformer ): FirConstructor { - if (constructor.body is FirLazyBlock || constructor.delegatedConstructor is FirLazyDelegatedConstructorCall) { + if (FirLazyBodiesCalculator.needCalculatingLazyBodyForConstructor(constructor)) { val designation = FirDeclarationDesignation(data, constructor) FirLazyBodiesCalculator.calculateLazyBodyForConstructor(designation) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt index 9af0012e91d..25099487478 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt @@ -179,6 +179,10 @@ class FirJavaValueParameter @FirImplementationDetail constructor( override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) { } + override fun replaceDefaultValue(newDefaultValue: FirExpression?) { + error("Java value parameter cannot has default value") + } + override fun replaceGetter(newGetter: FirPropertyAccessor?) { } 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 a586cb78b2e..e7015528b52 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 @@ -586,10 +586,7 @@ open class RawFirBuilder( this.name = name symbol = FirValueParameterSymbol(name) defaultValue = if (hasDefaultValue()) { - disabledLazyMode { - // TODO build lazy initializers here - { this@toFirValueParameter.defaultValue }.toFirExpression("Should have default value") - } + buildOrLazyExpression(null, { { this@toFirValueParameter.defaultValue }.toFirExpression("Should have default value") }) } else null isCrossinline = hasModifier(CROSSINLINE_KEYWORD) isNoinline = hasModifier(NOINLINE_KEYWORD) 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 afb07076f89..aae1a985ef2 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 @@ -57,7 +57,7 @@ FILE: enums.kt } public? final? enum class PseudoInsn : R|kotlin/Enum| { - private constructor(signature: String = String(()V)): R|PseudoInsn| { + private constructor(signature: String = LAZY_EXPRESSION): R|PseudoInsn| { LAZY_super|> } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/namedArgument.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/namedArgument.lazyBodies.txt index ac0f4552e83..25cb048287a 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/namedArgument.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/namedArgument.lazyBodies.txt @@ -1,3 +1,3 @@ FILE: namedArgument.kt - public? final? fun foo(first: String = String(), second: Boolean = Boolean(true), third: Double = Double(3.1415)): R|kotlin/Unit| { LAZY_BLOCK } + public? final? fun foo(first: String = LAZY_EXPRESSION, second: Boolean = LAZY_EXPRESSION, third: Double = LAZY_EXPRESSION): R|kotlin/Unit| { LAZY_BLOCK } public? final? fun test(): R|kotlin/Unit| { LAZY_BLOCK } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt index 59fc36805f2..2acf77ed170 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt @@ -79,6 +79,8 @@ abstract class FirValueParameter : FirVariable(), FirControlFlowGraphOwner { abstract override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) + abstract fun replaceDefaultValue(newDefaultValue: FirExpression?) + abstract override fun transformTypeParameters(transformer: FirTransformer, data: D): FirValueParameter abstract override fun transformStatus(transformer: FirTransformer, data: D): FirValueParameter diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt index 2f933c77c82..b1bfb9cca74 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt @@ -195,4 +195,8 @@ internal class FirDefaultSetterValueParameter( override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) { controlFlowGraphReference = newControlFlowGraphReference } + + override fun replaceDefaultValue(newDefaultValue: FirExpression?) { + defaultValue = newDefaultValue + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt index e0e4faf8733..6298e44c2e5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt @@ -172,4 +172,8 @@ internal class FirValueParameterImpl( override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) { controlFlowGraphReference = newControlFlowGraphReference } + + override fun replaceDefaultValue(newDefaultValue: FirExpression?) { + defaultValue = newDefaultValue + } } 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 17386870a7c..35cc006e24c 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 @@ -393,7 +393,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild valueParameter.configure { +symbol("FirValueParameterSymbol") - +field("defaultValue", expression, nullable = true) + +field("defaultValue", expression, nullable = true, withReplace = true) +field("containingFunctionSymbol", functionSymbolType, "*").apply { withBindThis = false }