From e827f260e79dc9ebe03a0c2e5c74f807f252dddd Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 25 Oct 2023 11:21:41 +0200 Subject: [PATCH] [IR] Simplify `IrProperty?.isConst` check in interpreter --- .../org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt | 4 ++-- .../src/org/jetbrains/kotlin/ir/interpreter/Utils.kt | 3 +++ .../kotlin/ir/interpreter/checker/EvaluationMode.kt | 3 ++- .../ir/interpreter/checker/IrInterpreterCommonChecker.kt | 6 +++--- .../preprocessor/IrInterpreterConstGetterPreprocessor.kt | 3 ++- .../transformer/IrConstOnlyNecessaryTransformer.kt | 7 ++++--- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 2be95c5d0de..ace3ebe4777 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -378,12 +378,12 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal else -> callInterceptor.interceptJavaStaticField(expression) } } - field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.property?.isConst == true -> { + field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.property.isConst -> { callStack.pushCompoundInstruction(field.initializer?.expression) } expression.accessesTopLevelOrObjectField() -> { val propertyOwner = field.property - val isConst = propertyOwner?.isConst == true || + val isConst = propertyOwner.isConst || propertyOwner?.backingField?.initializer?.expression is IrConst<*> || propertyOwner?.parentClassOrNull?.hasAnnotation(compileTimeAnnotation) == true // check if object is marked as compile time verify(isConst) { "Cannot interpret get method on top level non const properties" } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 1d6bc6398ca..89c311113b6 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -367,3 +367,6 @@ internal val IrField.property: IrProperty? internal val IrCall.correspondingProperty: IrProperty? get() = this.symbol.owner.correspondingPropertySymbol?.owner + +internal val IrProperty?.isConst: Boolean + get() = this?.isConst == true \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt index 177603c64aa..38a51bc8797 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/EvaluationMode.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.interpreter.hasAnnotation import org.jetbrains.kotlin.ir.interpreter.intrinsicConstEvaluationAnnotation +import org.jetbrains.kotlin.ir.interpreter.isConst import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isString @@ -59,7 +60,7 @@ enum class EvaluationMode { ).map { IrBuiltIns.KOTLIN_INTERNAL_IR_FQN.child(Name.identifier(it)).asString() }.toSet() override fun canEvaluateFunction(function: IrFunction): Boolean { - if (function.property?.isConst == true) return true + if (function.property.isConst) return true val returnType = function.returnType if (!returnType.isPrimitiveType() && !returnType.isString() && !returnType.isUnsignedType()) return false diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrInterpreterCommonChecker.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrInterpreterCommonChecker.kt index 449a4bda603..23b8b7bef21 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrInterpreterCommonChecker.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrInterpreterCommonChecker.kt @@ -59,7 +59,7 @@ class IrInterpreterCommonChecker : IrInterpreterChecker { } private fun IrCall.isGetterToConstVal(): Boolean { - return correspondingProperty?.isConst == true + return correspondingProperty.isConst } override fun visitCall(expression: IrCall, data: IrInterpreterCheckerData): Boolean { @@ -189,8 +189,8 @@ class IrInterpreterCommonChecker : IrInterpreterChecker { // 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, data) == true - owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> { + expression.receiver == null -> property.isConst && owner.initializer?.accept(this, data) == true + owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property.isConst -> { val receiverComputable = (expression.receiver?.accept(this, data) ?: true) || expression.receiver.isAccessToNotNullableObject() val initializerComputable = owner.initializer?.accept(this, data) ?: false diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/preprocessor/IrInterpreterConstGetterPreprocessor.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/preprocessor/IrInterpreterConstGetterPreprocessor.kt index 6768987ce4e..b14b208ac08 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/preprocessor/IrInterpreterConstGetterPreprocessor.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/preprocessor/IrInterpreterConstGetterPreprocessor.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl import org.jetbrains.kotlin.ir.interpreter.correspondingProperty +import org.jetbrains.kotlin.ir.interpreter.isConst import org.jetbrains.kotlin.ir.interpreter.property import org.jetbrains.kotlin.ir.types.classOrFail @@ -64,6 +65,6 @@ class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor { fun IrField.hasConstantValue(): Boolean { val implicitConst = isFinal && isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && initializer != null - return implicitConst || property?.isConst == true + return implicitConst || property.isConst } } \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstOnlyNecessaryTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstOnlyNecessaryTransformer.kt index 1979e0b0096..1c299c79578 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstOnlyNecessaryTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/transformer/IrConstOnlyNecessaryTransformer.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode import org.jetbrains.kotlin.ir.interpreter.checker.IrInterpreterChecker +import org.jetbrains.kotlin.ir.interpreter.isConst import org.jetbrains.kotlin.ir.interpreter.property /** @@ -35,7 +36,7 @@ internal class IrConstOnlyNecessaryTransformer( interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions ) { override fun visitCall(expression: IrCall, data: Data): IrElement { - val isConstGetter = expression.symbol.owner.property?.isConst == true + val isConstGetter = expression.symbol.owner.property.isConst if (!data.inAnnotation && !isConstGetter) { expression.transformChildren(this, data) return expression @@ -44,7 +45,7 @@ internal class IrConstOnlyNecessaryTransformer( } override fun visitGetField(expression: IrGetField, data: Data): IrExpression { - val isConst = expression.symbol.owner.property?.isConst == true + val isConst = expression.symbol.owner.property.isConst if (!data.inAnnotation && !isConst) return expression return super.visitGetField(expression, data) } @@ -58,7 +59,7 @@ internal class IrConstOnlyNecessaryTransformer( } override fun visitField(declaration: IrField, data: Data): IrStatement { - val isConst = declaration.property?.isConst == true + val isConst = declaration.property.isConst if (!isConst) { declaration.transformChildren(this, data) return declaration