[FIR] Reuse transformConst method to evaluate properties in Java world
#KT-57802
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
+12
-30
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user