[JS] Support evaluation of const intrinsics for K2
#KT-56023 Fixed #KT-51582 Fixed
This commit is contained in:
@@ -30,11 +30,14 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
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.checker.EvaluationMode
|
||||||
import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
|
import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
|
||||||
import org.jetbrains.kotlin.ir.util.KotlinMangler
|
import org.jetbrains.kotlin.ir.util.KotlinMangler
|
||||||
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.platform.isJs
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class Fir2IrConverter(
|
class Fir2IrConverter(
|
||||||
@@ -418,10 +421,15 @@ class Fir2IrConverter(
|
|||||||
companion object {
|
companion object {
|
||||||
private fun evaluateConstants(irModuleFragment: IrModuleFragment) {
|
private fun evaluateConstants(irModuleFragment: IrModuleFragment) {
|
||||||
val firModuleDescriptor = irModuleFragment.descriptor as? FirModuleDescriptor
|
val firModuleDescriptor = irModuleFragment.descriptor as? FirModuleDescriptor
|
||||||
|
val targetPlatform = firModuleDescriptor?.platform
|
||||||
val languageVersionSettings = firModuleDescriptor?.session?.languageVersionSettings
|
val languageVersionSettings = firModuleDescriptor?.session?.languageVersionSettings
|
||||||
val intrinsicConstEvaluation = languageVersionSettings?.supportsFeature(LanguageFeature.IntrinsicConstEvaluation) == true
|
val intrinsicConstEvaluation = languageVersionSettings?.supportsFeature(LanguageFeature.IntrinsicConstEvaluation) == true
|
||||||
|
|
||||||
val interpreter = IrInterpreter(irModuleFragment.irBuiltins)
|
val configuration = IrInterpreterConfiguration(
|
||||||
|
printOnlyExceptionMessage = targetPlatform.isJs(),
|
||||||
|
treatFloatInSpecialWay = targetPlatform.isJs()
|
||||||
|
)
|
||||||
|
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
|
||||||
irModuleFragment.files.forEach {
|
irModuleFragment.files.forEach {
|
||||||
it.transformChildren(IrConstTransformer(interpreter, it, mode = mode), null)
|
it.transformChildren(IrConstTransformer(interpreter, it, mode = mode), null)
|
||||||
|
|||||||
+1
-1
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
|
|||||||
class ConstEvaluationLowering(
|
class ConstEvaluationLowering(
|
||||||
val context: CommonBackendContext,
|
val context: CommonBackendContext,
|
||||||
private val suppressErrors: Boolean = context.configuration.getBoolean(CommonConfigurationKeys.IGNORE_CONST_OPTIMIZATION_ERRORS),
|
private val suppressErrors: Boolean = context.configuration.getBoolean(CommonConfigurationKeys.IGNORE_CONST_OPTIMIZATION_ERRORS),
|
||||||
|
configuration: IrInterpreterConfiguration = IrInterpreterConfiguration(printOnlyExceptionMessage = true),
|
||||||
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||||
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||||
) : FileLoweringPass {
|
) : FileLoweringPass {
|
||||||
val configuration = IrInterpreterConfiguration(printOnlyExceptionMessage = true)
|
|
||||||
val interpreter = IrInterpreter(IrInterpreterEnvironment(context.irBuiltIns, configuration), emptyMap())
|
val interpreter = IrInterpreter(IrInterpreterEnvironment(context.irBuiltIns, configuration), emptyMap())
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
|
|||||||
+10
-2
@@ -151,13 +151,21 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val receiverType = irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type
|
val receiverType = irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type
|
||||||
val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
|
val argsType = (listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }).map {
|
||||||
|
// TODO: for consistency with current K/JS implementation Float constant should be treated as a Double (KT-35422)
|
||||||
|
if (environment.configuration.treatFloatInSpecialWay && it.isFloat()) irBuiltIns.doubleType else it
|
||||||
|
}
|
||||||
val argsValues = args.wrap(this, irFunction)
|
val argsValues = args.wrap(this, irFunction)
|
||||||
|
|
||||||
// TODO replace unary, binary, ternary functions with vararg
|
// TODO replace unary, binary, ternary functions with vararg
|
||||||
withExceptionHandler(environment) {
|
withExceptionHandler(environment) {
|
||||||
val result = when (argsType.size) {
|
val result = when (argsType.size) {
|
||||||
1 -> interpretUnaryFunction(methodName, argsType[0].getOnlyName(), argsValues[0])
|
1 -> when {
|
||||||
|
methodName == "toString" && environment.configuration.treatFloatInSpecialWay && (argsValues[0] is Double || argsValues[0] is Float) -> {
|
||||||
|
argsValues[0].specialToStringForJs()
|
||||||
|
}
|
||||||
|
else -> interpretUnaryFunction(methodName, argsType[0].getOnlyName(), argsValues[0])
|
||||||
|
}
|
||||||
2 -> when (methodName) {
|
2 -> when (methodName) {
|
||||||
"rangeTo" -> return calculateRangeTo(irFunction.returnType, args)
|
"rangeTo" -> return calculateRangeTo(irFunction.returnType, args)
|
||||||
else -> interpretBinaryFunction(
|
else -> interpretBinaryFunction(
|
||||||
|
|||||||
+22
-9
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.ir.interpreter
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.InterpreterError
|
import org.jetbrains.kotlin.ir.interpreter.exceptions.InterpreterError
|
||||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
||||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.verify
|
import org.jetbrains.kotlin.ir.interpreter.exceptions.verify
|
||||||
@@ -112,6 +114,19 @@ private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack)
|
|||||||
|
|
||||||
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
|
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
|
||||||
val callStack = environment.callStack
|
val callStack = environment.callStack
|
||||||
|
val irFunction = expression.symbol.owner
|
||||||
|
|
||||||
|
if (irFunction.name.asString() == "<get-name>" && expression.dispatchReceiver is IrGetEnumValue) {
|
||||||
|
// this optimization allow us to avoid creation of enum object when we try to interpret simple `name` call; see KT-53480
|
||||||
|
callStack.pushSimpleInstruction(expression)
|
||||||
|
callStack.pushSimpleInstruction(irFunction.dispatchReceiverParameter!!)
|
||||||
|
|
||||||
|
val enumEntry = (expression.dispatchReceiver as IrGetEnumValue).symbol.owner
|
||||||
|
callStack.pushState(enumEntry.toState(environment.irBuiltIns))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO do the same thing but for "KCallable.name" with "this" as receiver
|
||||||
|
|
||||||
val hasDefaults = (0 until expression.valueArgumentsCount).any { expression.getValueArgument(it) == null }
|
val hasDefaults = (0 until expression.valueArgumentsCount).any { expression.getValueArgument(it) == null }
|
||||||
if (hasDefaults) {
|
if (hasDefaults) {
|
||||||
environment.getCachedFunction(expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall)?.let {
|
environment.getCachedFunction(expression.symbol, fromDelegatingCall = expression is IrDelegatingConstructorCall)?.let {
|
||||||
@@ -166,7 +181,6 @@ private fun unfoldValueParameters(expression: IrFunctionAccessExpression, enviro
|
|||||||
).owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
).owner.createCall().apply { environment.irBuiltIns.copyArgs(expression, this) }
|
||||||
callStack.pushCompoundInstruction(callToDefault)
|
callStack.pushCompoundInstruction(callToDefault)
|
||||||
} else {
|
} else {
|
||||||
val irFunction = expression.symbol.owner
|
|
||||||
callStack.pushSimpleInstruction(expression)
|
callStack.pushSimpleInstruction(expression)
|
||||||
|
|
||||||
fun IrValueParameter.schedule(arg: IrExpression?) {
|
fun IrValueParameter.schedule(arg: IrExpression?) {
|
||||||
@@ -277,14 +291,6 @@ private fun unfoldGetEnumValue(expression: IrGetEnumValue, environment: IrInterp
|
|||||||
val callStack = environment.callStack
|
val callStack = environment.callStack
|
||||||
environment.mapOfEnums[expression.symbol]?.let { return callStack.pushState(it) }
|
environment.mapOfEnums[expression.symbol]?.let { return callStack.pushState(it) }
|
||||||
|
|
||||||
val frameOwner = callStack.currentFrameOwner
|
|
||||||
if (frameOwner is IrCall && frameOwner.dispatchReceiver is IrGetEnumValue && frameOwner.symbol.owner.name.asString() == "<get-name>") {
|
|
||||||
// this optimization allow us to avoid creation of enum object when we try to interpret simple `name` call; see KT-53480
|
|
||||||
val enumEntry = (frameOwner.dispatchReceiver as IrGetEnumValue).symbol.owner
|
|
||||||
callStack.pushState(enumEntry.toState(environment.irBuiltIns))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
callStack.pushSimpleInstruction(expression)
|
callStack.pushSimpleInstruction(expression)
|
||||||
val enumEntry = expression.symbol.owner
|
val enumEntry = expression.symbol.owner
|
||||||
val enumClass = enumEntry.symbol.owner.parentAsClass
|
val enumClass = enumEntry.symbol.owner.parentAsClass
|
||||||
@@ -389,6 +395,13 @@ private fun unfoldStringConcatenation(expression: IrStringConcatenation, environ
|
|||||||
// this callback is used to check the need for an explicit toString call
|
// this callback is used to check the need for an explicit toString call
|
||||||
val explicitToStringCheck = fun() {
|
val explicitToStringCheck = fun() {
|
||||||
when (val state = callStack.peekState()) {
|
when (val state = callStack.peekState()) {
|
||||||
|
is Primitive<*> -> {
|
||||||
|
// This block is not really needed, but this way it is easier to handle `toString` with `treatFloatInSpecialWay` enabled.
|
||||||
|
callStack.popState()
|
||||||
|
val toStringCall = IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, environment.irBuiltIns.memberToString)
|
||||||
|
callStack.pushSimpleInstruction(toStringCall)
|
||||||
|
callStack.pushState(state)
|
||||||
|
}
|
||||||
is Common -> {
|
is Common -> {
|
||||||
callStack.popState()
|
callStack.popState()
|
||||||
// TODO this check can be dropped after serialization introduction
|
// TODO this check can be dropped after serialization introduction
|
||||||
|
|||||||
@@ -293,6 +293,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
|
|
||||||
return callStack.pushCompoundInstruction(constructorCall)
|
return callStack.pushCompoundInstruction(constructorCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
callStack.pushState(expression.toPrimitive())
|
callStack.pushState(expression.toPrimitive())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -11,12 +11,14 @@ package org.jetbrains.kotlin.ir.interpreter
|
|||||||
* @param createNonCompileTimeObjects
|
* @param createNonCompileTimeObjects
|
||||||
* 'true' - interpreter will construct object and initialize its properties despite the fact it is not marked as compile time;
|
* 'true' - interpreter will construct object and initialize its properties despite the fact it is not marked as compile time;
|
||||||
* 'false' - interpreter will create a representation of empty object, that can be used to get const properties
|
* 'false' - interpreter will create a representation of empty object, that can be used to get const properties
|
||||||
|
* @param treatFloatInSpecialWay interpret float const as if it was a double and avoid `toFloat` evaluation if possible
|
||||||
*/
|
*/
|
||||||
// TODO maybe create some sort of builder
|
// TODO maybe create some sort of builder
|
||||||
class IrInterpreterConfiguration(
|
data class IrInterpreterConfiguration(
|
||||||
val maxStack: Int = 10_000,
|
val maxStack: Int = 10_000,
|
||||||
val maxCommands: Int = 1_000_000,
|
val maxCommands: Int = 1_000_000,
|
||||||
val createNonCompileTimeObjects: Boolean = false,
|
val createNonCompileTimeObjects: Boolean = false,
|
||||||
val printOnlyExceptionMessage: Boolean = false,
|
val printOnlyExceptionMessage: Boolean = false,
|
||||||
val collapseStackTraceFromJDK: Boolean = true,
|
val collapseStackTraceFromJDK: Boolean = true,
|
||||||
|
val treatFloatInSpecialWay: Boolean = false,
|
||||||
)
|
)
|
||||||
|
|||||||
+4
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||||
@@ -118,8 +119,9 @@ class IrInterpreterEnvironment(
|
|||||||
return when (state) {
|
return when (state) {
|
||||||
is Primitive<*> ->
|
is Primitive<*> ->
|
||||||
when {
|
when {
|
||||||
state.value == null -> state.value.toIrConst(type, start, end)
|
configuration.treatFloatInSpecialWay && state.value is Float -> IrConstImpl.float(start, end, type, state.value)
|
||||||
type.isPrimitiveType() || type.isString() -> state.value.toIrConst(type, start, end)
|
configuration.treatFloatInSpecialWay && state.value is Double -> IrConstImpl.double(start, end, type, state.value)
|
||||||
|
state.value == null || type.isPrimitiveType() || type.isString() -> state.value.toIrConst(type, start, end)
|
||||||
else -> original // TODO support for arrays
|
else -> original // TODO support for arrays
|
||||||
}
|
}
|
||||||
is ExceptionState -> {
|
is ExceptionState -> {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
import org.jetbrains.kotlin.utils.keysToMap
|
import org.jetbrains.kotlin.utils.keysToMap
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
val intrinsicConstEvaluationAnnotation = FqName("kotlin.internal.IntrinsicConstEvaluation")
|
val intrinsicConstEvaluationAnnotation = FqName("kotlin.internal.IntrinsicConstEvaluation")
|
||||||
val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation")
|
val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation")
|
||||||
@@ -131,7 +132,9 @@ fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
internal fun IrFunction.getCapitalizedFileName(): String {
|
||||||
|
return this.fileOrNull?.name?.replace(".kt", "Kt")?.capitalizeAsciiOnly() ?: "<UNKNOWN>"
|
||||||
|
}
|
||||||
|
|
||||||
internal fun IrClass.isSubclassOfThrowable(): Boolean {
|
internal fun IrClass.isSubclassOfThrowable(): Boolean {
|
||||||
return generateSequence(this) { irClass ->
|
return generateSequence(this) { irClass ->
|
||||||
@@ -314,6 +317,14 @@ internal fun State.unsignedToString(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Any?.specialToStringForJs(): String {
|
||||||
|
return when {
|
||||||
|
this is Float && !this.isInfinite() && floor(this) == this -> this.toInt().toString()
|
||||||
|
this is Double && !this.isInfinite() && floor(this) == this -> this.toLong().toString()
|
||||||
|
else -> this.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun IrEnumEntry.toState(irBuiltIns: IrBuiltIns): Common {
|
internal fun IrEnumEntry.toState(irBuiltIns: IrBuiltIns): Common {
|
||||||
val enumClass = this.symbol.owner.parentAsClass
|
val enumClass = this.symbol.owner.parentAsClass
|
||||||
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
|
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
|
||||||
|
|||||||
+11
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
|||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||||
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
|
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
|
||||||
import org.jetbrains.kotlin.ir.interpreter.fqName
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
import org.jetbrains.kotlin.ir.interpreter.isAccessToNotNullableObject
|
import org.jetbrains.kotlin.ir.interpreter.isAccessToNotNullableObject
|
||||||
@@ -18,7 +19,9 @@ import org.jetbrains.kotlin.ir.util.statements
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
class IrCompileTimeChecker(
|
class IrCompileTimeChecker(
|
||||||
containingDeclaration: IrElement? = null, private val mode: EvaluationMode = EvaluationMode.WITH_ANNOTATIONS
|
containingDeclaration: IrElement? = null,
|
||||||
|
private val mode: EvaluationMode = EvaluationMode.WITH_ANNOTATIONS,
|
||||||
|
private val interpreterConfiguration: IrInterpreterConfiguration,
|
||||||
) : IrElementVisitor<Boolean, Nothing?> {
|
) : IrElementVisitor<Boolean, Nothing?> {
|
||||||
private var contextExpression: IrCall? = null
|
private var contextExpression: IrCall? = null
|
||||||
private val visitedStack = mutableListOf<IrElement>().apply { if (containingDeclaration != null) add(containingDeclaration) }
|
private val visitedStack = mutableListOf<IrElement>().apply { if (containingDeclaration != null) add(containingDeclaration) }
|
||||||
@@ -67,6 +70,13 @@ class IrCompileTimeChecker(
|
|||||||
val owner = expression.symbol.owner
|
val owner = expression.symbol.owner
|
||||||
if (!mode.canEvaluateFunction(owner, expression)) return false
|
if (!mode.canEvaluateFunction(owner, expression)) return false
|
||||||
|
|
||||||
|
// We disable `toFloat` folding on K/JS till `toFloat` is fixed (KT-35422)
|
||||||
|
// This check must be placed here instead of CallInterceptor because we still
|
||||||
|
// want to evaluate (1) `const val` expressions and (2) values in annotations.
|
||||||
|
if (owner.name.asString() == "toFloat" && interpreterConfiguration.treatFloatInSpecialWay) {
|
||||||
|
return super.visitCall(expression, data)
|
||||||
|
}
|
||||||
|
|
||||||
return expression.saveContext {
|
return expression.saveContext {
|
||||||
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, null) ?: true
|
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, null) ?: true
|
||||||
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, null) ?: true
|
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, null) ?: true
|
||||||
|
|||||||
+10
-4
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||||
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||||
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
@@ -49,9 +50,12 @@ class IrConstTransformer(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.canBeInterpreted(containingDeclaration: IrElement? = null): Boolean {
|
private fun IrExpression.canBeInterpreted(
|
||||||
|
containingDeclaration: IrElement? = null,
|
||||||
|
configuration: IrInterpreterConfiguration = interpreter.environment.configuration
|
||||||
|
): Boolean {
|
||||||
return try {
|
return try {
|
||||||
this.accept(IrCompileTimeChecker(containingDeclaration, mode = mode), null)
|
this.accept(IrCompileTimeChecker(containingDeclaration, mode, configuration), null)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
if (suppressExceptions) {
|
if (suppressExceptions) {
|
||||||
return false
|
return false
|
||||||
@@ -87,7 +91,9 @@ class IrConstTransformer(
|
|||||||
val expression = initializer?.expression ?: return declaration
|
val expression = initializer?.expression ?: return declaration
|
||||||
if (expression is IrConst<*>) return declaration
|
if (expression is IrConst<*>) return declaration
|
||||||
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
|
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
|
||||||
if (isConst && expression.canBeInterpreted(declaration)) {
|
if (!isConst) return super.visitField(declaration)
|
||||||
|
|
||||||
|
if (expression.canBeInterpreted(declaration, interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||||
initializer.expression = expression.interpret(failAsError = true)
|
initializer.expression = expression.interpret(failAsError = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +135,7 @@ class IrConstTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression {
|
private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression {
|
||||||
if (this.canBeInterpreted()) {
|
if (this.canBeInterpreted(configuration = interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||||
return this.interpret(failAsError = true).convertToConstIfPossible(expectedType)
|
return this.interpret(failAsError = true).convertToConstIfPossible(expectedType)
|
||||||
} else if (this is IrConstructorCall) {
|
} else if (this is IrConstructorCall) {
|
||||||
transformAnnotation(this)
|
transformAnnotation(this)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Comp
|
|||||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
||||||
import org.jetbrains.kotlin.ir.types.isArray
|
import org.jetbrains.kotlin.ir.types.isArray
|
||||||
|
import org.jetbrains.kotlin.ir.types.isFloat
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
|
|
||||||
internal interface Proxy {
|
internal interface Proxy {
|
||||||
@@ -34,6 +35,8 @@ internal fun State.wrap(callInterceptor: CallInterceptor, remainArraysAsIs: Bool
|
|||||||
is Primitive<*> -> when {
|
is Primitive<*> -> when {
|
||||||
this.isNull() -> null
|
this.isNull() -> null
|
||||||
this.type.isArray() || this.type.isPrimitiveArray() -> if (remainArraysAsIs) this else this.value
|
this.type.isArray() || this.type.isPrimitiveArray() -> if (remainArraysAsIs) this else this.value
|
||||||
|
// TODO: for consistency with current K/JS implementation Float constant should be treated as a Double (KT-35422)
|
||||||
|
this.type.isFloat() && callInterceptor.environment.configuration.treatFloatInSpecialWay -> this.value.toString().toDouble()
|
||||||
else -> this.value
|
else -> this.value
|
||||||
}
|
}
|
||||||
is Common -> this.asProxy(callInterceptor, extendFrom)
|
is Common -> this.asProxy(callInterceptor, extendFrom)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND_K1: JS_IR
|
||||||
// IGNORE_BACKEND: JS_IR_ES6
|
// IGNORE_BACKEND_K1: JS_IR_ES6
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_K2: JS_IR, NATIVE
|
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
// IGNORE_BACKEND_K2: JS_IR
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (239.toByte().toString() != (239.toByte() as Byte?).toString()) return "byte failed"
|
if (239.toByte().toString() != (239.toByte() as Byte?).toString()) return "byte failed"
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
// `Boolean.equals(Boolean)` will not be evaluated in K1
|
// `Boolean.equals(Boolean)` will not be evaluated in K1
|
||||||
// IGNORE_BACKEND_K1: NATIVE
|
// IGNORE_BACKEND_K1: NATIVE
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = (-1).toByte()
|
const val minusOneVal = (-1).toByte()
|
||||||
const val oneVal = 1.toByte()
|
const val oneVal = 1.toByte()
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
// `Char.equals(Char)` will not be evaluated in K1
|
// `Char.equals(Char)` will not be evaluated in K1
|
||||||
// IGNORE_BACKEND_K1: NATIVE
|
// IGNORE_BACKEND_K1: NATIVE
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|||||||
+7
-3
@@ -1,12 +1,14 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = -1.0
|
const val minusOneVal = -1.0
|
||||||
const val oneVal = 1.0
|
const val oneVal = 1.0
|
||||||
const val twoVal = 2.0
|
const val twoVal = 2.0
|
||||||
const val threeVal = 3.0
|
const val threeVal = 3.0
|
||||||
const val fourVal = 4.0
|
const val fourVal = 4.0
|
||||||
|
const val oneAndAHalf = 1.5
|
||||||
|
|
||||||
const val byteVal = 2.toByte()
|
const val byteVal = 2.toByte()
|
||||||
const val shortVal = 2.toShort()
|
const val shortVal = 2.toShort()
|
||||||
@@ -87,6 +89,7 @@ const val equals4 = fourVal == twoVal
|
|||||||
|
|
||||||
const val toString1 = oneVal.toString()
|
const val toString1 = oneVal.toString()
|
||||||
const val toString2 = twoVal.toString()
|
const val toString2 = twoVal.toString()
|
||||||
|
const val toString3 = oneAndAHalf.toString()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (compareTo1 != -1) return "Fail 1.1"
|
if (compareTo1 != -1) return "Fail 1.1"
|
||||||
@@ -159,8 +162,9 @@ fun box(): String {
|
|||||||
if (equals3 != false) return "Fail 9.3"
|
if (equals3 != false) return "Fail 9.3"
|
||||||
if (equals4 != false) return "Fail 9.4"
|
if (equals4 != false) return "Fail 9.4"
|
||||||
|
|
||||||
if (toString1 != "1.0") return "Fail 10.1"
|
if (toString1 != "1.0" && toString1 != "1" /* JS */) return "Fail 10.1"
|
||||||
if (toString2 != "2.0") return "Fail 10.2"
|
if (toString2 != "2.0" && toString2 != "2" /* JS */) return "Fail 10.2"
|
||||||
|
if (toString3 != "1.5") return "Fail 10.3"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
+4
-3
@@ -12,8 +12,9 @@ const val name3 = EnumClass.anotherValue.name
|
|||||||
const val name4 = EnumClass.WITH_UNDERSCORE.name
|
const val name4 = EnumClass.WITH_UNDERSCORE.name
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (name2 != "VALUE") return "Fail 1"
|
if (EnumClass.OK.name != "OK") return "Fail 1"
|
||||||
if (name3 != "anotherValue") return "Fail 2"
|
if (name2 != "VALUE") return "Fail 2"
|
||||||
if (name4 != "WITH_UNDERSCORE") return "Fail 3"
|
if (name3 != "anotherValue") return "Fail 3"
|
||||||
|
if (name4 != "WITH_UNDERSCORE") return "Fail 4"
|
||||||
return name1
|
return name1
|
||||||
}
|
}
|
||||||
+7
-3
@@ -1,12 +1,14 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = -1.0f
|
const val minusOneVal = -1.0f
|
||||||
const val oneVal = 1.0f
|
const val oneVal = 1.0f
|
||||||
const val twoVal = 2.0f
|
const val twoVal = 2.0f
|
||||||
const val threeVal = 3.0f
|
const val threeVal = 3.0f
|
||||||
const val fourVal = 4.0f
|
const val fourVal = 4.0f
|
||||||
|
const val oneAndAHalf = 1.5f
|
||||||
|
|
||||||
const val byteVal = 2.toByte()
|
const val byteVal = 2.toByte()
|
||||||
const val shortVal = 2.toShort()
|
const val shortVal = 2.toShort()
|
||||||
@@ -87,6 +89,7 @@ const val equals4 = fourVal == twoVal
|
|||||||
|
|
||||||
const val toString1 = oneVal.toString()
|
const val toString1 = oneVal.toString()
|
||||||
const val toString2 = twoVal.toString()
|
const val toString2 = twoVal.toString()
|
||||||
|
const val toString3 = oneAndAHalf.toString()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (compareTo1 != -1) return "Fail 1.1"
|
if (compareTo1 != -1) return "Fail 1.1"
|
||||||
@@ -159,8 +162,9 @@ fun box(): String {
|
|||||||
if (equals3 != false) return "Fail 9.3"
|
if (equals3 != false) return "Fail 9.3"
|
||||||
if (equals4 != false) return "Fail 9.4"
|
if (equals4 != false) return "Fail 9.4"
|
||||||
|
|
||||||
if (toString1 != "1.0") return "Fail 10.1"
|
if (toString1 != "1.0" && toString1 != "1" /* JS */) return "Fail 10.1"
|
||||||
if (toString2 != "2.0") return "Fail 10.2"
|
if (toString2 != "2.0" && toString2 != "2" /* JS */) return "Fail 10.2"
|
||||||
|
if (toString3 != "1.5") return "Fail 10.3"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
// !LANGUAGE: +IntrinsicConstEvaluation
|
// !LANGUAGE: +IntrinsicConstEvaluation
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val flag = true
|
const val flag = true
|
||||||
const val value = 10
|
const val value = 10
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = -1
|
const val minusOneVal = -1
|
||||||
const val oneVal = 1
|
const val oneVal = 1
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = -1L
|
const val minusOneVal = -1L
|
||||||
const val oneVal = 1L
|
const val oneVal = 1L
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
// IGNORE_BACKEND_K1: JVM_IR, NATIVE
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JVM_IR, NATIVE, JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
const val minusOneVal = (-1).toShort()
|
const val minusOneVal = (-1).toShort()
|
||||||
const val oneVal = 1.toShort()
|
const val oneVal = 1.toShort()
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
const val code = '1'.code
|
const val code = '1'.code
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
|
||||||
const val someStr = "123"
|
const val someStr = "123"
|
||||||
const val otherStr = "other"
|
const val otherStr = "other"
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
const val byteVal: UByte = 1u
|
const val byteVal: UByte = 1u
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
// IGNORE_BACKEND_K1: JS_IR, JS_IR_ES6
|
||||||
|
|
||||||
|
const val toStringInConst = 1.0.toString()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (toStringInConst != "1") return "Fail 1"
|
||||||
|
if (1.0.toString() != toStringInConst) return "Fail 2"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
|
|
||||||
object K : Code("K")
|
object K : Code("K")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// TARGET_BACKEND: NATIVE
|
// TARGET_BACKEND: NATIVE
|
||||||
|
// TARGET_BACKEND: JS_IR
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
object Test {
|
object Test {
|
||||||
|
|||||||
+8
@@ -23,3 +23,11 @@ const val f1 = <!EVALUATED: `2`!>enumValues<EnumClass>().size<!>
|
|||||||
const val f2 = <!EVALUATED: `VALUE1`!>enumValueOf<EnumClass>("VALUE1").name<!>
|
const val f2 = <!EVALUATED: `VALUE1`!>enumValueOf<EnumClass>("VALUE1").name<!>
|
||||||
|
|
||||||
const val j1 = <!EVALUATED: `VALUE1, VALUE2`!>enumValues<EnumClass>().joinToString { it.name }<!>
|
const val j1 = <!EVALUATED: `VALUE1, VALUE2`!>enumValues<EnumClass>().joinToString { it.name }<!>
|
||||||
|
|
||||||
|
@CompileTimeCalculation
|
||||||
|
fun getEnumValue(flag: Boolean): EnumClass {
|
||||||
|
return if (flag) EnumClass.VALUE1 else EnumClass.VALUE2
|
||||||
|
}
|
||||||
|
|
||||||
|
const val conditional1 = <!EVALUATED: `VALUE1`!>getEnumValue(true).name<!>
|
||||||
|
const val conditional2 = <!EVALUATED: `VALUE2`!>getEnumValue(false).name<!>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
|
// IGNORE_BACKEND_K2: JS_IR
|
||||||
val test1 = 1
|
val test1 = 1
|
||||||
val test2 = -1
|
val test2 = -1
|
||||||
val test3 = true
|
val test3 = true
|
||||||
|
|||||||
+90
@@ -21043,6 +21043,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("jsIrToConst.kt")
|
||||||
|
public void testJsIrToConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/jsIrToConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt55912.kt")
|
@TestMetadata("kt55912.kt")
|
||||||
public void testKt55912() throws Exception {
|
public void testKt55912() throws Exception {
|
||||||
@@ -21055,6 +21061,18 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringConcatenationWithObject.kt")
|
||||||
|
public void testStringConcatenationWithObject() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisPlusString.kt")
|
||||||
|
public void testThisPlusString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@@ -21063,6 +21081,78 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("booleanOperations.kt")
|
||||||
|
public void testBooleanOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("byteOperations.kt")
|
||||||
|
public void testByteOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("charOperations.kt")
|
||||||
|
public void testCharOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("doubleOperations.kt")
|
||||||
|
public void testDoubleOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("floatOperations.kt")
|
||||||
|
public void testFloatOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ifConstVal.kt")
|
||||||
|
public void testIfConstVal() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("intOperations.kt")
|
||||||
|
public void testIntOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("longOperations.kt")
|
||||||
|
public void testLongOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("shortOperations.kt")
|
||||||
|
public void testShortOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stdlibConst.kt")
|
||||||
|
public void testStdlibConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringOperations.kt")
|
||||||
|
public void testStringOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unsignedConst.kt")
|
||||||
|
public void testUnsignedConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+90
@@ -21043,6 +21043,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("jsIrToConst.kt")
|
||||||
|
public void testJsIrToConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/jsIrToConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt55912.kt")
|
@TestMetadata("kt55912.kt")
|
||||||
public void testKt55912() throws Exception {
|
public void testKt55912() throws Exception {
|
||||||
@@ -21055,6 +21061,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringConcatenationWithObject.kt")
|
||||||
|
public void testStringConcatenationWithObject() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisPlusString.kt")
|
||||||
|
public void testThisPlusString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@@ -21063,6 +21081,78 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("booleanOperations.kt")
|
||||||
|
public void testBooleanOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("byteOperations.kt")
|
||||||
|
public void testByteOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("charOperations.kt")
|
||||||
|
public void testCharOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("doubleOperations.kt")
|
||||||
|
public void testDoubleOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("floatOperations.kt")
|
||||||
|
public void testFloatOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ifConstVal.kt")
|
||||||
|
public void testIfConstVal() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("intOperations.kt")
|
||||||
|
public void testIntOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("longOperations.kt")
|
||||||
|
public void testLongOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("shortOperations.kt")
|
||||||
|
public void testShortOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stdlibConst.kt")
|
||||||
|
public void testStdlibConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringOperations.kt")
|
||||||
|
public void testStringOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unsignedConst.kt")
|
||||||
|
public void testUnsignedConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+90
@@ -21043,6 +21043,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("jsIrToConst.kt")
|
||||||
|
public void testJsIrToConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/jsIrToConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("kt55912.kt")
|
@TestMetadata("kt55912.kt")
|
||||||
public void testKt55912() throws Exception {
|
public void testKt55912() throws Exception {
|
||||||
@@ -21055,6 +21061,18 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
|||||||
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringConcatenationWithObject.kt")
|
||||||
|
public void testStringConcatenationWithObject() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/stringConcatenationWithObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisPlusString.kt")
|
||||||
|
public void testThisPlusString() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/thisPlusString.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@@ -21063,6 +21081,78 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
|||||||
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
public void testAllFilesPresentInDumpIrAndCheck() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("booleanOperations.kt")
|
||||||
|
public void testBooleanOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/booleanOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("byteOperations.kt")
|
||||||
|
public void testByteOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/byteOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("charOperations.kt")
|
||||||
|
public void testCharOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/charOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("doubleOperations.kt")
|
||||||
|
public void testDoubleOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/doubleOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("floatOperations.kt")
|
||||||
|
public void testFloatOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/floatOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ifConstVal.kt")
|
||||||
|
public void testIfConstVal() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/ifConstVal.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("intOperations.kt")
|
||||||
|
public void testIntOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/intOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("longOperations.kt")
|
||||||
|
public void testLongOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/longOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("shortOperations.kt")
|
||||||
|
public void testShortOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/shortOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stdlibConst.kt")
|
||||||
|
public void testStdlibConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stdlibConst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("stringOperations.kt")
|
||||||
|
public void testStringOperations() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/stringOperations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("unsignedConst.kt")
|
||||||
|
public void testUnsignedConst() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_BACKEND_K2: JS_IR
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// EXPECTED_REACHABLE_NODES: 1378
|
// EXPECTED_REACHABLE_NODES: 1378
|
||||||
package foo
|
package foo
|
||||||
|
|||||||
Reference in New Issue
Block a user