From 990f23a11b4243973ad90c2d282b6755594c9bd0 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 10 May 2023 10:49:11 +0200 Subject: [PATCH] [LL FIR] FirLazyBodiesCalculator: covert non-public api to private functions ^KT-56550 --- .../lazy/resolve/FirLazyBodiesCalculator.kt | 346 +++++++++--------- 1 file changed, 178 insertions(+), 168 deletions(-) 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 a01b07a9e86..cc5a62597c4 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 @@ -61,159 +61,164 @@ internal object FirLazyBodiesCalculator { FirLazyAnnotationTransformerData(firElement.moduleData.session, FirLazyAnnotationTransformerScope.COMPILER_ONLY) ) } - - 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 calculateLazyArgumentsForAnnotation(annotationCall: FirAnnotationCall, session: FirSession) { - require(needCalculatingAnnotationCall(annotationCall)) - val builder = RawFirBuilder(session, baseScopeProvider = session.kotlinScopeProvider) - val newAnnotationCall = builder.buildAnnotationCall(annotationCall.psi as KtAnnotationEntry) - annotationCall.replaceArgumentList(newAnnotationCall.argumentList) - } - - fun calculateLazyBodiesForFunction(designation: FirDesignation) { - val simpleFunction = designation.target as FirSimpleFunction - require(needCalculatingLazyBodyForFunction(simpleFunction)) - val newFunction = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = simpleFunction.moduleData.session, - scopeProvider = simpleFunction.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = simpleFunction.psi as KtNamedFunction, - ) as FirSimpleFunction - simpleFunction.apply { - replaceBody(newFunction.body) - replaceContractDescription(newFunction.contractDescription) - replaceValueParameterDefaultValues(valueParameters, newFunction.valueParameters) - } - } - - fun calculateLazyBodyForConstructor(designation: FirDesignation) { - val constructor = designation.target as FirConstructor - require(needCalculatingLazyBodyForConstructor(constructor)) - - val newConstructor = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = constructor.moduleData.session, - scopeProvider = constructor.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = constructor.psi as KtDeclaration, - ) as FirConstructor - - constructor.apply { - replaceBody(newConstructor.body) - replaceContractDescription(newConstructor.contractDescription) - replaceDelegatedConstructor(newConstructor.delegatedConstructor) - replaceValueParameterDefaultValues(valueParameters, newConstructor.valueParameters) - } - } - - fun calculateLazyBodyForProperty(designation: FirDesignation) { - val firProperty = designation.target as FirProperty - if (!needCalculatingLazyBodyForProperty(firProperty)) return - - val newProperty = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = firProperty.moduleData.session, - scopeProvider = firProperty.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = firProperty.psi as KtProperty - ) as FirProperty - - firProperty.getter?.takeIf { it.body is FirLazyBlock }?.let { getter -> - val newGetter = newProperty.getter!! - getter.replaceBody(newGetter.body) - getter.replaceContractDescription(newGetter.contractDescription) - } - - firProperty.setter?.takeIf { it.body is FirLazyBlock }?.let { setter -> - val newSetter = newProperty.setter!! - setter.replaceBody(newSetter.body) - setter.replaceContractDescription(newSetter.contractDescription) - } - - if (firProperty.initializer is FirLazyExpression) { - firProperty.replaceInitializer(newProperty.initializer) - } - - firProperty.getExplicitBackingField()?.takeIf { it.initializer is FirLazyExpression }?.let { backingField -> - val newInitializer = newProperty.getExplicitBackingField()?.initializer - backingField.replaceInitializer(newInitializer) - } - - val delegate = firProperty.delegate as? FirWrappedDelegateExpression - val delegateExpression = delegate?.expression - if (delegateExpression is FirLazyExpression) { - val newDelegate = newProperty.delegate as? FirWrappedDelegateExpression - check(newDelegate != null) { "Invalid replacement delegate" } - delegate.replaceExpression(newDelegate.expression) - delegate.replaceDelegateProvider(newDelegate.delegateProvider) - } - } - - fun calculateLazyInitializerForEnumEntry(designation: FirDesignation) { - val enumEntry = designation.target as FirEnumEntry - require(enumEntry.initializer is FirLazyExpression) - val newEntry = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = enumEntry.moduleData.session, - scopeProvider = enumEntry.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = enumEntry.psi as KtEnumEntry, - ) as FirEnumEntry - enumEntry.apply { - replaceInitializer(newEntry.initializer) - } - } - - fun calculateLazyBodyForAnonymousInitializer(designation: FirDesignation) { - val initializer = designation.target as FirAnonymousInitializer - require(initializer.body is FirLazyBlock) - val newInitializer = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = initializer.moduleData.session, - scopeProvider = initializer.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = initializer.psi as KtAnonymousInitializer, - ) as FirAnonymousInitializer - initializer.apply { - replaceBody(newInitializer.body) - } - } - - fun calculateLazyBodiesForField(designation: FirDesignation) { - val field = designation.target as FirField - require(field.initializer is FirLazyExpression) - val newField = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( - session = field.moduleData.session, - scopeProvider = field.moduleData.session.kotlinScopeProvider, - designation = designation, - rootNonLocalDeclaration = designation.path.last().psi as KtClassOrObject, - ) as FirField - field.apply { - replaceInitializer(newField.initializer) - } - } - - 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?.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 - - fun needCalculatingAnnotationCall(firAnnotationCall: FirAnnotationCall): Boolean = - firAnnotationCall.argumentList.arguments.any { it is FirLazyExpression } } +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) + } + } +} + +private fun calculateLazyArgumentsForAnnotation(annotationCall: FirAnnotationCall, session: FirSession) { + require(needCalculatingAnnotationCall(annotationCall)) + val builder = RawFirBuilder(session, baseScopeProvider = session.kotlinScopeProvider) + val newAnnotationCall = builder.buildAnnotationCall(annotationCall.psi as KtAnnotationEntry) + annotationCall.replaceArgumentList(newAnnotationCall.argumentList) +} + +private fun calculateLazyBodiesForFunction(designation: FirDesignation) { + val simpleFunction = designation.target as FirSimpleFunction + require(needCalculatingLazyBodyForFunction(simpleFunction)) + val newFunction = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = simpleFunction.moduleData.session, + scopeProvider = simpleFunction.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = simpleFunction.psi as KtNamedFunction, + ) as FirSimpleFunction + + simpleFunction.apply { + replaceBody(newFunction.body) + replaceContractDescription(newFunction.contractDescription) + replaceValueParameterDefaultValues(valueParameters, newFunction.valueParameters) + } +} + +private fun calculateLazyBodyForConstructor(designation: FirDesignation) { + val constructor = designation.target as FirConstructor + require(needCalculatingLazyBodyForConstructor(constructor)) + + val newConstructor = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = constructor.moduleData.session, + scopeProvider = constructor.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = constructor.psi as KtDeclaration, + ) as FirConstructor + + constructor.apply { + replaceBody(newConstructor.body) + replaceContractDescription(newConstructor.contractDescription) + replaceDelegatedConstructor(newConstructor.delegatedConstructor) + replaceValueParameterDefaultValues(valueParameters, newConstructor.valueParameters) + } +} + +private fun calculateLazyBodyForProperty(designation: FirDesignation) { + val firProperty = designation.target as FirProperty + if (!needCalculatingLazyBodyForProperty(firProperty)) return + + val newProperty = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = firProperty.moduleData.session, + scopeProvider = firProperty.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = firProperty.psi as KtProperty + ) as FirProperty + + firProperty.getter?.takeIf { it.body is FirLazyBlock }?.let { getter -> + val newGetter = newProperty.getter!! + getter.replaceBody(newGetter.body) + getter.replaceContractDescription(newGetter.contractDescription) + } + + firProperty.setter?.takeIf { it.body is FirLazyBlock }?.let { setter -> + val newSetter = newProperty.setter!! + setter.replaceBody(newSetter.body) + setter.replaceContractDescription(newSetter.contractDescription) + } + + if (firProperty.initializer is FirLazyExpression) { + firProperty.replaceInitializer(newProperty.initializer) + } + + firProperty.getExplicitBackingField()?.takeIf { it.initializer is FirLazyExpression }?.let { backingField -> + val newInitializer = newProperty.getExplicitBackingField()?.initializer + backingField.replaceInitializer(newInitializer) + } + + val delegate = firProperty.delegate as? FirWrappedDelegateExpression + val delegateExpression = delegate?.expression + if (delegateExpression is FirLazyExpression) { + val newDelegate = newProperty.delegate as? FirWrappedDelegateExpression + check(newDelegate != null) { "Invalid replacement delegate" } + delegate.replaceExpression(newDelegate.expression) + delegate.replaceDelegateProvider(newDelegate.delegateProvider) + } +} + +private fun calculateLazyInitializerForEnumEntry(designation: FirDesignation) { + val enumEntry = designation.target as FirEnumEntry + require(enumEntry.initializer is FirLazyExpression) + + val newEntry = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = enumEntry.moduleData.session, + scopeProvider = enumEntry.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = enumEntry.psi as KtEnumEntry, + ) as FirEnumEntry + + enumEntry.apply { + replaceInitializer(newEntry.initializer) + } +} + +private fun calculateLazyBodyForAnonymousInitializer(designation: FirDesignation) { + val initializer = designation.target as FirAnonymousInitializer + require(initializer.body is FirLazyBlock) + + val newInitializer = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = initializer.moduleData.session, + scopeProvider = initializer.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = initializer.psi as KtAnonymousInitializer, + ) as FirAnonymousInitializer + + initializer.apply { + replaceBody(newInitializer.body) + } +} + +private fun needCalculatingLazyBodyForConstructor(firConstructor: FirConstructor): Boolean = + needCalculatingLazyBodyForFunction(firConstructor) || firConstructor.delegatedConstructor is FirLazyDelegatedConstructorCall + +private fun calculateLazyBodiesForField(designation: FirDesignation) { + val field = designation.target as FirField + require(field.initializer is FirLazyExpression) + val newField = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( + session = field.moduleData.session, + scopeProvider = field.moduleData.session.kotlinScopeProvider, + designation = designation, + rootNonLocalDeclaration = designation.path.last().psi as KtClassOrObject, + ) as FirField + field.apply { + replaceInitializer(newField.initializer) + } +} + +private fun needCalculatingLazyBodyForFunction(firFunction: FirFunction): Boolean = + firFunction.body is FirLazyBlock || firFunction.valueParameters.any { it.defaultValue is FirLazyExpression } + +private fun needCalculatingLazyBodyForProperty(firProperty: FirProperty): Boolean = + 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 + +private fun needCalculatingAnnotationCall(firAnnotationCall: FirAnnotationCall): Boolean = + firAnnotationCall.argumentList.arguments.any { it is FirLazyExpression } + private enum class FirLazyAnnotationTransformerScope { ALL_ANNOTATIONS, COMPILER_ONLY; @@ -221,7 +226,7 @@ private enum class FirLazyAnnotationTransformerScope { private data class FirLazyAnnotationTransformerData( val session: FirSession, - val compilerAnnotationsOnly: FirLazyAnnotationTransformerScope = FirLazyAnnotationTransformerScope.ALL_ANNOTATIONS + val compilerAnnotationsOnly: FirLazyAnnotationTransformerScope = FirLazyAnnotationTransformerScope.ALL_ANNOTATIONS, ) private object FirLazyAnnotationTransformer : FirTransformer() { @@ -255,16 +260,17 @@ private object FirLazyAnnotationTransformer : FirTransformer): FirStatement { if (field.initializer is FirLazyExpression) { val designation = FirDesignation(data, field) - FirLazyBodiesCalculator.calculateLazyBodiesForField(designation) + calculateLazyBodiesForField(designation) } + return field } override fun transformSimpleFunction( simpleFunction: FirSimpleFunction, - data: PersistentList + data: PersistentList, ): FirSimpleFunction { - if (FirLazyBodiesCalculator.needCalculatingLazyBodyForFunction(simpleFunction)) { + if (needCalculatingLazyBodyForFunction(simpleFunction)) { val designation = FirDesignation(data, simpleFunction) - FirLazyBodiesCalculator.calculateLazyBodiesForFunction(designation) + calculateLazyBodiesForFunction(designation) } return simpleFunction @@ -344,20 +354,20 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer + data: PersistentList, ): FirConstructor { - if (FirLazyBodiesCalculator.needCalculatingLazyBodyForConstructor(constructor)) { + if (needCalculatingLazyBodyForConstructor(constructor)) { val designation = FirDesignation(data, constructor) - FirLazyBodiesCalculator.calculateLazyBodyForConstructor(designation) + calculateLazyBodyForConstructor(designation) } return constructor } override fun transformProperty(property: FirProperty, data: PersistentList): FirProperty { - if (FirLazyBodiesCalculator.needCalculatingLazyBodyForProperty(property)) { + if (needCalculatingLazyBodyForProperty(property)) { val designation = FirDesignation(data, property) - FirLazyBodiesCalculator.calculateLazyBodyForProperty(designation) + calculateLazyBodyForProperty(designation) } return property @@ -370,18 +380,18 @@ private abstract class FirLazyBodiesCalculatorTransformer : FirTransformer): FirStatement { if (enumEntry.initializer is FirLazyExpression) { val designation = FirDesignation(data, enumEntry) - FirLazyBodiesCalculator.calculateLazyInitializerForEnumEntry(designation) + calculateLazyInitializerForEnumEntry(designation) } return enumEntry } override fun transformAnonymousInitializer( - anonymousInitializer: FirAnonymousInitializer, data: PersistentList + anonymousInitializer: FirAnonymousInitializer, data: PersistentList, ): FirAnonymousInitializer { if (anonymousInitializer.body is FirLazyBlock) { val designation = FirDesignation(data, anonymousInitializer) - FirLazyBodiesCalculator.calculateLazyBodyForAnonymousInitializer(designation) + calculateLazyBodyForAnonymousInitializer(designation) } return anonymousInitializer