[IR] Properly handle interpretation errors if inside annotation class
#KT-58923
This commit is contained in:
+30
-13
@@ -6,12 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.ir.interpreter.transformer
|
package org.jetbrains.kotlin.ir.interpreter.transformer
|
||||||
|
|
||||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
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.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
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.expressions.*
|
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.IrStringConcatenationImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl
|
||||||
@@ -32,9 +30,34 @@ internal class IrConstExpressionTransformer(
|
|||||||
onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||||
suppressExceptions: Boolean,
|
suppressExceptions: Boolean,
|
||||||
) : IrConstTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, onWarning, onError, suppressExceptions) {
|
) : IrConstTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, onWarning, onError, suppressExceptions) {
|
||||||
|
private var inAnnotation: Boolean = false
|
||||||
|
|
||||||
|
private inline fun <T> 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 {
|
override fun visitCall(expression: IrCall, data: Nothing?): IrElement {
|
||||||
if (expression.canBeInterpreted()) {
|
if (expression.canBeInterpreted()) {
|
||||||
return expression.interpret(failAsError = false)
|
return expression.interpret(failAsError = inAnnotation)
|
||||||
}
|
}
|
||||||
return super.visitCall(expression, data)
|
return super.visitCall(expression, data)
|
||||||
}
|
}
|
||||||
@@ -53,15 +76,9 @@ internal class IrConstExpressionTransformer(
|
|||||||
return super.visitField(declaration, data)
|
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 {
|
override fun visitGetField(expression: IrGetField, data: Nothing?): IrExpression {
|
||||||
if (expression.canBeInterpreted()) {
|
if (expression.canBeInterpreted()) {
|
||||||
return expression.interpret(failAsError = false)
|
return expression.interpret(failAsError = inAnnotation)
|
||||||
}
|
}
|
||||||
return super.visitGetField(expression, data)
|
return super.visitGetField(expression, data)
|
||||||
}
|
}
|
||||||
@@ -71,7 +88,7 @@ internal class IrConstExpressionTransformer(
|
|||||||
this.startOffset, this.endOffset, expression.type, listOf(this@wrapInStringConcat)
|
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 ""
|
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,
|
// If we have some complex expression in arguments (like some `IrComposite`) we will skip it,
|
||||||
|
|||||||
Reference in New Issue
Block a user