From bf6f241d4a8a2fe29d8b5846c8e7784dbff7453a Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Mon, 26 Jun 2023 16:56:19 +0200 Subject: [PATCH] [FIR] Reuse `transformConst` method to evaluate properties in Java world #KT-57802 --- .../kotlin/fir/backend/Fir2IrConverter.kt | 40 +++++++++--------- .../transformer/IrConstTransformer.kt | 42 ++++++------------- 2 files changed, 32 insertions(+), 50 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index f191ca16e5f..9e9c1d47479 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -46,7 +46,6 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode -import org.jetbrains.kotlin.ir.interpreter.transformer.evaluate import org.jetbrains.kotlin.ir.interpreter.transformer.transformConst import org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl @@ -546,29 +545,12 @@ class Fir2IrConverter( val interpreter = IrInterpreter(IrInterpreterEnvironment(irModuleFragment.irBuiltins, configuration)) val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS - components.session.javaElementFinder?.propertyEvaluator = eval@{ firProperty -> - val irProperty = components.declarationStorage.getCachedIrProperty(firProperty, fakeOverrideOwnerLookupTag = null) ?: return@eval null - - fun IrProperty.tryToGetConst(): IrConst<*>? { - return (backingField?.initializer?.expression as? IrConst<*>) - } - - irProperty.tryToGetConst()?.let { return@eval it.value.toString() } - val irFile = irProperty.fileOrNull ?: return@eval null - // Note: can't evaluate all expressions in given file, because we can accidentally get recursive processing and - // second call of `Fir2IrLazyField.initializer` will return null - val evaluated = irProperty.evaluate( - irFile, interpreter, mode, - evaluatedConstTracker = fir2IrConfiguration.evaluatedConstTracker, - inlineConstTracker = fir2IrConfiguration.inlineConstTracker, - ) - - return@eval evaluated?.tryToGetConst()?.value?.toString() - } + components.session.javaElementFinder?.propertyEvaluator = { it.evaluate(components, interpreter, mode) } val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(fir2IrConfiguration.diagnosticReporter, languageVersionSettings) irModuleFragment.files.forEach { it.transformConst( + it, interpreter, mode, fir2IrConfiguration.evaluatedConstTracker, @@ -582,6 +564,24 @@ class Fir2IrConverter( } } + private fun FirProperty.evaluate(components: Fir2IrComponents, interpreter: IrInterpreter, mode: EvaluationMode): String? { + val irProperty = components.declarationStorage.getCachedIrProperty(this, fakeOverrideOwnerLookupTag = null) ?: return null + + fun IrProperty.tryToGetConst(): IrConst<*>? = (backingField?.initializer?.expression as? IrConst<*>) + irProperty.tryToGetConst()?.let { return it.value.toString() } + + val irFile = irProperty.fileOrNull ?: return null + // Note: can't evaluate all expressions in given file, because we can accidentally get recursive processing and + // second call of `Fir2IrLazyField.initializer` will return null + val evaluated = irProperty.transformConst( + irFile, interpreter, mode, + evaluatedConstTracker = components.configuration.evaluatedConstTracker, + inlineConstTracker = components.configuration.inlineConstTracker, + ) + + return (evaluated as? IrProperty)?.tryToGetConst()?.value?.toString() + } + // TODO: drop this function in favor of using [IrModuleDescriptor::shouldSeeInternalsOf] in FakeOverrideBuilder KT-61384 fun friendModulesMap(session: FirSession) = mapOf( session.moduleData.name.asStringStripSpecialMarkers() to session.moduleData.friendDependencies.map { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstTransformer.kt index 2d21b8cba5a..c5333f885d4 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstTransformer.kt @@ -31,7 +31,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -fun IrFile.transformConst( +fun IrElement.transformConst( + irFile: IrFile, interpreter: IrInterpreter, mode: EvaluationMode, evaluatedConstTracker: EvaluatedConstTracker? = null, @@ -39,22 +40,23 @@ fun IrFile.transformConst( onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, suppressExceptions: Boolean = false, -) { +): IrElement { val checker = IrInterpreterCommonChecker() val irConstExpressionTransformer = IrConstOnlyNecessaryTransformer( - interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions + interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions ) - this.transform(irConstExpressionTransformer, IrConstTransformer.Data()) val irConstDeclarationAnnotationTransformer = IrConstDeclarationAnnotationTransformer( - interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions + interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions ) - this.transform(irConstDeclarationAnnotationTransformer, IrConstTransformer.Data()) val irConstTypeAnnotationTransformer = IrConstTypeAnnotationTransformer( - interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions + interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions ) - this.transform(irConstTypeAnnotationTransformer, IrConstTransformer.Data()) + + return this.transform(irConstExpressionTransformer, IrConstTransformer.Data()) + .transform(irConstDeclarationAnnotationTransformer, IrConstTransformer.Data()) + .transform(irConstTypeAnnotationTransformer, IrConstTransformer.Data()) } fun IrFile.runConstOptimizations( @@ -75,24 +77,6 @@ fun IrFile.runConstOptimizations( preprocessedFile.transform(irConstExpressionTransformer, IrConstTransformer.Data()) } -// TODO simplify -fun IrProperty.evaluate( - irFile: IrFile, - interpreter: IrInterpreter, - mode: EvaluationMode, - evaluatedConstTracker: EvaluatedConstTracker? = null, - inlineConstTracker: InlineConstTracker? = null, - onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, - onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, - suppressExceptions: Boolean = false, -): IrProperty? { - val checker = IrInterpreterCommonChecker() - val irConstExpressionTransformer = IrConstAllTransformer( - interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions - ) - return this.transform(irConstExpressionTransformer, IrConstTransformer.Data()) as? IrProperty -} - private fun IrFile.preprocessForConstTransformer( interpreter: IrInterpreter, mode: EvaluationMode, @@ -104,10 +88,8 @@ private fun IrFile.preprocessForConstTransformer( return preprocessedFile } -// Note: We are using `IrElementTransformer` here instead of `IrElementTransformerVoid` to avoid conflicts with `IrTypeVisitorVoid` -// that is used later in `IrConstTypeAnnotationTransformer`. -abstract class IrConstTransformer( - protected val interpreter: IrInterpreter, +internal abstract class IrConstTransformer( + private val interpreter: IrInterpreter, private val irFile: IrFile, private val mode: EvaluationMode, private val checker: IrInterpreterChecker,