[IR] Replace mutable property in const transformer with data class

This commit is contained in:
Ivan Kylchik
2023-06-07 18:51:12 +02:00
committed by Space Team
parent 0e2b348fa0
commit 3ce61f988f
6 changed files with 42 additions and 45 deletions
@@ -30,7 +30,9 @@ internal abstract class IrConstAnnotationTransformer(
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit, onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
onError: (IrFile, IrElement, IrErrorExpression) -> Unit, onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
suppressExceptions: Boolean, suppressExceptions: Boolean,
) : IrConstTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions) { ) : IrConstTransformer(
interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) {
protected fun transformAnnotations(annotationContainer: IrAnnotationContainer) { protected fun transformAnnotations(annotationContainer: IrAnnotationContainer) {
annotationContainer.annotations.forEach { annotation -> annotationContainer.annotations.forEach { annotation ->
transformAnnotation(annotation) transformAnnotation(annotation)
@@ -26,13 +26,15 @@ internal class IrConstDeclarationAnnotationTransformer(
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit, onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
onError: (IrFile, IrElement, IrErrorExpression) -> Unit, onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
suppressExceptions: Boolean, suppressExceptions: Boolean,
) : IrConstAnnotationTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions) { ) : IrConstAnnotationTransformer(
override fun visitFile(declaration: IrFile, data: Nothing?): IrFile { interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) {
override fun visitFile(declaration: IrFile, data: Data): IrFile {
transformAnnotations(declaration) transformAnnotations(declaration)
return super.visitFile(declaration, data) return super.visitFile(declaration, data)
} }
override fun visitDeclaration(declaration: IrDeclarationBase, data: Nothing?): IrStatement { override fun visitDeclaration(declaration: IrDeclarationBase, data: Data): IrStatement {
transformAnnotations(declaration) transformAnnotations(declaration)
return super.visitDeclaration(declaration, data) return super.visitDeclaration(declaration, data)
} }
@@ -31,40 +31,30 @@ internal abstract class IrConstExpressionTransformer(
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit, onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
onError: (IrFile, IrElement, IrErrorExpression) -> Unit, onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
suppressExceptions: Boolean, suppressExceptions: Boolean,
) : IrConstTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions) { ) : IrConstTransformer(
protected var inAnnotation: Boolean = false interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) {
private inline fun <T> visitAnnotationClass(crossinline block: () -> T): T { override fun visitFunction(declaration: IrFunction, data: Data): IrStatement {
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` // 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 if (declaration.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) return declaration
return super.visitFunction(declaration, data) return super.visitFunction(declaration, data)
} }
override fun visitClass(declaration: IrClass, data: Nothing?): IrStatement { override fun visitClass(declaration: IrClass, data: Data): IrStatement {
if (declaration.kind == ClassKind.ANNOTATION_CLASS) { if (declaration.kind == ClassKind.ANNOTATION_CLASS) {
return visitAnnotationClass { super.visitClass(declaration, data) } return super.visitClass(declaration, data.copy(inAnnotation = true))
} }
return super.visitClass(declaration, data) return super.visitClass(declaration, data)
} }
override fun visitCall(expression: IrCall, data: Nothing?): IrElement { override fun visitCall(expression: IrCall, data: Data): IrElement {
if (expression.canBeInterpreted()) { if (expression.canBeInterpreted()) {
return expression.interpret(failAsError = inAnnotation) return expression.interpret(failAsError = data.inAnnotation)
} }
return super.visitCall(expression, data) return super.visitCall(expression, data)
} }
override fun visitField(declaration: IrField, data: Nothing?): IrStatement { override fun visitField(declaration: IrField, data: Data): IrStatement {
val initializer = declaration.initializer val initializer = declaration.initializer
val expression = initializer?.expression ?: return declaration val expression = initializer?.expression ?: return declaration
val getField = declaration.createGetField() val getField = declaration.createGetField()
@@ -76,19 +66,19 @@ internal abstract class IrConstExpressionTransformer(
return super.visitField(declaration, data) return super.visitField(declaration, data)
} }
override fun visitGetField(expression: IrGetField, data: Nothing?): IrExpression { override fun visitGetField(expression: IrGetField, data: Data): IrExpression {
if (expression.canBeInterpreted()) { if (expression.canBeInterpreted()) {
return expression.interpret(failAsError = inAnnotation) return expression.interpret(failAsError = data.inAnnotation)
} }
return super.visitGetField(expression, data) return super.visitGetField(expression, data)
} }
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): IrExpression { override fun visitStringConcatenation(expression: IrStringConcatenation, data: Data): IrExpression {
fun IrExpression.wrapInStringConcat(): IrExpression = IrStringConcatenationImpl( fun IrExpression.wrapInStringConcat(): IrExpression = IrStringConcatenationImpl(
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 = inAnnotation) fun IrExpression.wrapInToStringConcatAndInterpret(): IrExpression = wrapInStringConcat().interpret(failAsError = data.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,
@@ -34,33 +34,33 @@ internal class IrConstOnlyNecessaryTransformer(
) : IrConstExpressionTransformer( ) : IrConstExpressionTransformer(
interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) { ) {
override fun visitCall(expression: IrCall, data: Nothing?): IrElement { override fun visitCall(expression: IrCall, data: Data): IrElement {
val isConstGetter = (expression.symbol.owner as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isConst == true val isConstGetter = (expression.symbol.owner as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isConst == true
if (!inAnnotation && !isConstGetter) { if (!data.inAnnotation && !isConstGetter) {
expression.transformChildren(this, null) expression.transformChildren(this, data)
return expression return expression
} }
return super.visitCall(expression, data) return super.visitCall(expression, data)
} }
override fun visitGetField(expression: IrGetField, data: Nothing?): IrExpression { override fun visitGetField(expression: IrGetField, data: Data): IrExpression {
val isConst = expression.symbol.owner.correspondingPropertySymbol?.owner?.isConst == true val isConst = expression.symbol.owner.correspondingPropertySymbol?.owner?.isConst == true
if (!inAnnotation && !isConst) return expression if (!data.inAnnotation && !isConst) return expression
return super.visitGetField(expression, data) return super.visitGetField(expression, data)
} }
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): IrExpression { override fun visitStringConcatenation(expression: IrStringConcatenation, data: Data): IrExpression {
if (!inAnnotation) { if (!data.inAnnotation) {
expression.transformChildren(this, null) expression.transformChildren(this, data)
return expression return expression
} }
return super.visitStringConcatenation(expression, data) return super.visitStringConcatenation(expression, data)
} }
override fun visitField(declaration: IrField, data: Nothing?): IrStatement { override fun visitField(declaration: IrField, data: Data): IrStatement {
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
if (!isConst) { if (!isConst) {
declaration.transformChildren(this, null) declaration.transformChildren(this, data)
return declaration return declaration
} }
@@ -39,17 +39,17 @@ fun IrFile.transformConst(
val irConstExpressionTransformer = IrConstOnlyNecessaryTransformer( val irConstExpressionTransformer = IrConstOnlyNecessaryTransformer(
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) )
preprocessedFile.transform(irConstExpressionTransformer, null) preprocessedFile.transform(irConstExpressionTransformer, IrConstTransformer.Data())
val irConstDeclarationAnnotationTransformer = IrConstDeclarationAnnotationTransformer( val irConstDeclarationAnnotationTransformer = IrConstDeclarationAnnotationTransformer(
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) )
preprocessedFile.transform(irConstDeclarationAnnotationTransformer, null) preprocessedFile.transform(irConstDeclarationAnnotationTransformer, IrConstTransformer.Data())
val irConstTypeAnnotationTransformer = IrConstTypeAnnotationTransformer( val irConstTypeAnnotationTransformer = IrConstTypeAnnotationTransformer(
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) )
preprocessedFile.transform(irConstTypeAnnotationTransformer, null) preprocessedFile.transform(irConstTypeAnnotationTransformer, IrConstTransformer.Data())
} }
fun IrFile.runConstOptimizations( fun IrFile.runConstOptimizations(
@@ -65,7 +65,7 @@ fun IrFile.runConstOptimizations(
val irConstExpressionTransformer = IrConstAllTransformer( val irConstExpressionTransformer = IrConstAllTransformer(
interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
) )
this.transform(irConstExpressionTransformer, null) this.transform(irConstExpressionTransformer, IrConstTransformer.Data())
} }
fun IrFile.preprocessForConstTransformer( fun IrFile.preprocessForConstTransformer(
@@ -91,7 +91,9 @@ internal abstract class IrConstTransformer(
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,
private val suppressExceptions: Boolean, private val suppressExceptions: Boolean,
) : IrElementTransformer<Nothing?> { ) : IrElementTransformer<IrConstTransformer.Data> {
internal data class Data(val inAnnotation: Boolean = false)
private fun IrExpression.warningIfError(original: IrExpression): IrExpression { private fun IrExpression.warningIfError(original: IrExpression): IrExpression {
if (this is IrErrorExpression) { if (this is IrErrorExpression) {
onWarning(irFile, original, this) onWarning(irFile, original, this)
@@ -28,10 +28,11 @@ internal class IrConstTypeAnnotationTransformer(
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit, onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
onError: (IrFile, IrElement, IrErrorExpression) -> Unit, onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
suppressExceptions: Boolean, suppressExceptions: Boolean,
) : IrConstAnnotationTransformer(interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions), ) : IrConstAnnotationTransformer(
IrTypeTransformerVoid<Nothing?> { interpreter, irFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
), IrTypeTransformerVoid<IrConstTransformer.Data> {
override fun <Type : IrType?> transformType(container: IrElement, type: Type, data: Nothing?): Type { override fun <Type : IrType?> transformType(container: IrElement, type: Type, data: Data): Type {
if (type == null) return type if (type == null) return type
transformAnnotations(type) transformAnnotations(type)