From 2129938ef2dfd96fe91836fcb2811b19f188ce0b Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Fri, 19 May 2023 17:16:06 +0200 Subject: [PATCH] [IR] Properly handle interpretation errors if inside annotation class #KT-58923 --- .../IrConstExpressionTransformer.kt | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) 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 1d6e6e8f335..dc8f5a28014 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 @@ -6,12 +6,10 @@ package org.jetbrains.kotlin.ir.interpreter.transformer import org.jetbrains.kotlin.constant.EvaluatedConstTracker +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrField -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl @@ -32,9 +30,34 @@ internal class IrConstExpressionTransformer( onError: (IrFile, IrElement, IrErrorExpression) -> Unit, suppressExceptions: Boolean, ) : IrConstTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, onWarning, onError, suppressExceptions) { + private var inAnnotation: Boolean = false + + private inline fun visitAnnotationClass(crossinline block: () -> T): T { + val oldInAnnotation = inAnnotation + inAnnotation = true + try { + return block() + } finally { + inAnnotation = oldInAnnotation + } + } + + override fun visitFunction(declaration: IrFunction, data: Nothing?): IrStatement { + // It is useless to visit default accessor and if we do that we could render excess information for `IrGetField` + if (declaration.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) return declaration + return super.visitFunction(declaration, data) + } + + override fun visitClass(declaration: IrClass, data: Nothing?): IrStatement { + if (declaration.kind == ClassKind.ANNOTATION_CLASS) { + return visitAnnotationClass { super.visitClass(declaration, data) } + } + return super.visitClass(declaration, data) + } + override fun visitCall(expression: IrCall, data: Nothing?): IrElement { if (expression.canBeInterpreted()) { - return expression.interpret(failAsError = false) + return expression.interpret(failAsError = inAnnotation) } return super.visitCall(expression, data) } @@ -53,15 +76,9 @@ internal class IrConstExpressionTransformer( return super.visitField(declaration, data) } - override fun visitFunction(declaration: IrFunction, data: Nothing?): IrStatement { - // It is useless to visit default accessor and if we do that we could render excess information for `IrGetField` - if (declaration.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) return declaration - return super.visitFunction(declaration, data) - } - override fun visitGetField(expression: IrGetField, data: Nothing?): IrExpression { if (expression.canBeInterpreted()) { - return expression.interpret(failAsError = false) + return expression.interpret(failAsError = inAnnotation) } return super.visitGetField(expression, data) } @@ -71,7 +88,7 @@ internal class IrConstExpressionTransformer( this.startOffset, this.endOffset, expression.type, listOf(this@wrapInStringConcat) ) - fun IrExpression.wrapInToStringConcatAndInterpret(): IrExpression = wrapInStringConcat().interpret(failAsError = false) + fun IrExpression.wrapInToStringConcatAndInterpret(): IrExpression = wrapInStringConcat().interpret(failAsError = inAnnotation) fun IrExpression.getConstStringOrEmpty(): String = if (this is IrConst<*>) value.toString() else "" // If we have some complex expression in arguments (like some `IrComposite`) we will skip it,