[FIR] Reuse transformConst method to evaluate properties in Java world

#KT-57802
This commit is contained in:
Ivan Kylchik
2023-06-26 16:56:19 +02:00
committed by Space Team
parent 4d9b4dd27f
commit bf6f241d4a
2 changed files with 32 additions and 50 deletions
@@ -46,7 +46,6 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode 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.interpreter.transformer.transformConst
import org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder import org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorPublicSymbolImpl
@@ -546,29 +545,12 @@ class Fir2IrConverter(
val interpreter = IrInterpreter(IrInterpreterEnvironment(irModuleFragment.irBuiltins, configuration)) val interpreter = IrInterpreter(IrInterpreterEnvironment(irModuleFragment.irBuiltins, configuration))
val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS
components.session.javaElementFinder?.propertyEvaluator = eval@{ firProperty -> components.session.javaElementFinder?.propertyEvaluator = { it.evaluate(components, interpreter, mode) }
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()
}
val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(fir2IrConfiguration.diagnosticReporter, languageVersionSettings) val ktDiagnosticReporter = KtDiagnosticReporterWithImplicitIrBasedContext(fir2IrConfiguration.diagnosticReporter, languageVersionSettings)
irModuleFragment.files.forEach { irModuleFragment.files.forEach {
it.transformConst( it.transformConst(
it,
interpreter, interpreter,
mode, mode,
fir2IrConfiguration.evaluatedConstTracker, 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 // TODO: drop this function in favor of using [IrModuleDescriptor::shouldSeeInternalsOf] in FakeOverrideBuilder KT-61384
fun friendModulesMap(session: FirSession) = mapOf( fun friendModulesMap(session: FirSession) = mapOf(
session.moduleData.name.asStringStripSpecialMarkers() to session.moduleData.friendDependencies.map { session.moduleData.name.asStringStripSpecialMarkers() to session.moduleData.friendDependencies.map {
@@ -31,7 +31,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun IrFile.transformConst( fun IrElement.transformConst(
irFile: IrFile,
interpreter: IrInterpreter, interpreter: IrInterpreter,
mode: EvaluationMode, mode: EvaluationMode,
evaluatedConstTracker: EvaluatedConstTracker? = null, evaluatedConstTracker: EvaluatedConstTracker? = null,
@@ -39,22 +40,23 @@ fun IrFile.transformConst(
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> }, onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
suppressExceptions: Boolean = false, suppressExceptions: Boolean = false,
) { ): IrElement {
val checker = IrInterpreterCommonChecker() val checker = IrInterpreterCommonChecker()
val irConstExpressionTransformer = IrConstOnlyNecessaryTransformer( 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( 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( 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( fun IrFile.runConstOptimizations(
@@ -75,24 +77,6 @@ fun IrFile.runConstOptimizations(
preprocessedFile.transform(irConstExpressionTransformer, IrConstTransformer.Data()) 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( private fun IrFile.preprocessForConstTransformer(
interpreter: IrInterpreter, interpreter: IrInterpreter,
mode: EvaluationMode, mode: EvaluationMode,
@@ -104,10 +88,8 @@ private fun IrFile.preprocessForConstTransformer(
return preprocessedFile return preprocessedFile
} }
// Note: We are using `IrElementTransformer` here instead of `IrElementTransformerVoid` to avoid conflicts with `IrTypeVisitorVoid` internal abstract class IrConstTransformer(
// that is used later in `IrConstTypeAnnotationTransformer`. private val interpreter: IrInterpreter,
abstract class IrConstTransformer(
protected val interpreter: IrInterpreter,
private val irFile: IrFile, private val irFile: IrFile,
private val mode: EvaluationMode, private val mode: EvaluationMode,
private val checker: IrInterpreterChecker, private val checker: IrInterpreterChecker,