diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt index 77c81a10658..cc0af17c477 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrTreeBuildUtils.kt @@ -116,7 +116,11 @@ internal fun createTempClass(name: Name, origin: IrDeclarationOrigin = TEMP_CLAS internal fun IrFunction.createGetField(): IrExpression { val backingField = (this as IrSimpleFunction).correspondingPropertySymbol?.owner?.backingField!! val receiver = dispatchReceiverParameter ?: extensionReceiverParameter - return IrGetFieldImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, backingField.symbol, backingField.type, receiver?.createGetValue()) + return backingField.createGetField(receiver) +} + +internal fun IrField.createGetField(receiver: IrValueParameter? = null): IrGetField { + return IrGetFieldImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, this.symbol, this.type, receiver?.createGetValue()) } internal fun List.wrapWithBlockBody(): IrBlockBody { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt index 2a6e70bcd96..d4bd2ca799d 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrCompileTimeChecker.kt @@ -20,11 +20,10 @@ import org.jetbrains.kotlin.ir.util.statements import org.jetbrains.kotlin.ir.visitors.IrElementVisitor class IrCompileTimeChecker( - containingDeclaration: IrElement? = null, private val mode: EvaluationMode, private val interpreterConfiguration: IrInterpreterConfiguration, ) : IrElementVisitor { - private val visitedStack = mutableListOf().apply { if (containingDeclaration != null) add(containingDeclaration) } + private val visitedStack = mutableListOf() private inline fun IrElement.asVisited(crossinline block: () -> Boolean): Boolean { visitedStack += this @@ -189,22 +188,24 @@ class IrCompileTimeChecker( return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic && owner.isFinal && (owner.type.isPrimitiveType() || owner.type.isStringClassType()) } - return when { - // TODO fix later; used it here because java boolean resolves very strange, - // its type is flexible (so its not primitive) and there is no initializer at backing field - fqName == "java.lang.Boolean.FALSE" || fqName == "java.lang.Boolean.TRUE" -> true - isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true - expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true - owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> { - val receiverComputable = (expression.receiver?.accept(this, null) ?: true) - || expression.isAccessToNotNullableObject() - val initializerComputable = owner.initializer?.accept(this, null) ?: false - receiverComputable && initializerComputable - } - else -> { - val declarations = owner.parent.getInnerDeclarations() - val getter = declarations.filterIsInstance().singleOrNull { it == property }?.getter ?: return false - visitedStack.contains(getter) + return owner.asVisited { + when { + // TODO fix later; used it here because java boolean resolves very strange, + // its type is flexible (so its not primitive) and there is no initializer at backing field + fqName == "java.lang.Boolean.FALSE" || fqName == "java.lang.Boolean.TRUE" -> true + isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true + expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true + owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> { + val receiverComputable = (expression.receiver?.accept(this, null) ?: true) + || expression.isAccessToNotNullableObject() + val initializerComputable = owner.initializer?.accept(this, null) ?: false + receiverComputable && initializerComputable + } + else -> { + val declarations = owner.parent.getInnerDeclarations() + val getter = declarations.filterIsInstance().singleOrNull { it == property }?.getter ?: return@asVisited false + visitedStack.contains(getter) + } } } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstExpressionTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstExpressionTransformer.kt index 29c3bb4fe5c..9c490b42f72 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstExpressionTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstExpressionTransformer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode +import org.jetbrains.kotlin.ir.interpreter.createGetField import kotlin.math.max import kotlin.math.min @@ -40,7 +41,8 @@ internal class IrConstExpressionTransformer( val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true if (!isConst) return super.visitField(declaration, data) - if (expression.canBeInterpreted(declaration, interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) { + val getField = declaration.createGetField() + if (getField.canBeInterpreted(interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) { initializer.expression = expression.interpret(failAsError = true) } 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 08c6dfc1813..7d794c5a7ef 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 @@ -77,11 +77,10 @@ internal abstract class IrConstTransformer( } protected fun IrExpression.canBeInterpreted( - containingDeclaration: IrElement? = null, configuration: IrInterpreterConfiguration = interpreter.environment.configuration ): Boolean { return try { - this.accept(IrCompileTimeChecker(containingDeclaration, mode, configuration), null) || + this.accept(IrCompileTimeChecker(mode, configuration), null) || this.accept(IrCompileTimeNameChecker(mode), null) } catch (e: Throwable) { if (suppressExceptions) {