[IR] Separate IrConstTransformer into two distinct classes
The first one `IrConstExpressionTransformer` is responsible for transforming ordinary expressions and the second one `IrConstAnnotationTransformer` is responsible for annotations. #KT-57812
This commit is contained in:
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.transformConst
|
||||
import org.jetbrains.kotlin.ir.util.KotlinMangler
|
||||
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
@@ -431,12 +431,7 @@ class Fir2IrConverter(
|
||||
val interpreter = IrInterpreter(IrInterpreterEnvironment(irModuleFragment.irBuiltins, configuration))
|
||||
val mode = if (intrinsicConstEvaluation) EvaluationMode.ONLY_INTRINSIC_CONST else EvaluationMode.ONLY_BUILTINS
|
||||
irModuleFragment.files.forEach {
|
||||
val transformer = IrConstTransformer(
|
||||
interpreter, it,
|
||||
mode = mode,
|
||||
evaluatedConstTracker = fir2IrConfiguration.evaluatedConstTracker
|
||||
)
|
||||
it.transformChildren(transformer, null)
|
||||
it.transformConst(interpreter, mode = mode, evaluatedConstTracker = fir2IrConfiguration.evaluatedConstTracker)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-7
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.transformConst
|
||||
|
||||
class ConstEvaluationLowering(
|
||||
val context: CommonBackendContext,
|
||||
@@ -28,13 +28,9 @@ class ConstEvaluationLowering(
|
||||
private val evaluatedConstTracker = context.configuration[CommonConfigurationKeys.EVALUATED_CONST_TRACKER]
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
val transformer = IrConstTransformer(
|
||||
interpreter, irFile,
|
||||
mode = EvaluationMode.ONLY_INTRINSIC_CONST,
|
||||
evaluatedConstTracker,
|
||||
onWarning, onError, suppressErrors
|
||||
irFile.transformConst(
|
||||
interpreter, mode = EvaluationMode.ONLY_INTRINSIC_CONST, evaluatedConstTracker, onWarning, onError, suppressErrors
|
||||
)
|
||||
irFile.transformChildren(transformer, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.checker
|
||||
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
|
||||
internal class IrConstAnnotationTransformer(
|
||||
interpreter: IrInterpreter,
|
||||
irFile: IrFile,
|
||||
mode: EvaluationMode,
|
||||
evaluatedConstTracker: EvaluatedConstTracker?,
|
||||
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
suppressExceptions: Boolean,
|
||||
) : IrConstTransformer(interpreter, irFile, mode, evaluatedConstTracker, onWarning, onError, suppressExceptions) {
|
||||
override fun visitField(declaration: IrField): IrStatement {
|
||||
transformAnnotations(declaration)
|
||||
return super.visitField(declaration)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement {
|
||||
transformAnnotations(declaration)
|
||||
return super.visitDeclaration(declaration)
|
||||
}
|
||||
|
||||
private fun transformAnnotations(annotationContainer: IrAnnotationContainer) {
|
||||
annotationContainer.annotations.forEach { annotation ->
|
||||
transformAnnotation(annotation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformAnnotation(annotation: IrConstructorCall) {
|
||||
for (i in 0 until annotation.valueArgumentsCount) {
|
||||
val arg = annotation.getValueArgument(i) ?: continue
|
||||
when (arg) {
|
||||
is IrVararg -> annotation.putValueArgument(i, arg.transformVarArg())
|
||||
else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrVararg.transformVarArg(): IrVararg {
|
||||
if (elements.isEmpty()) return this
|
||||
val newIrVararg = IrVarargImpl(this.startOffset, this.endOffset, this.type, this.varargElementType)
|
||||
for (element in this.elements) {
|
||||
when (val arg = (element as? IrSpreadElement)?.expression ?: element) {
|
||||
is IrVararg -> arg.transformVarArg().elements.forEach { newIrVararg.addElement(it) }
|
||||
is IrExpression -> newIrVararg.addElement(arg.transformSingleArg(this.varargElementType))
|
||||
else -> newIrVararg.addElement(arg)
|
||||
}
|
||||
}
|
||||
return newIrVararg
|
||||
}
|
||||
|
||||
private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression {
|
||||
if (this.canBeInterpreted(configuration = interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||
return this.interpret(failAsError = true).convertToConstIfPossible(expectedType)
|
||||
} else if (this is IrConstructorCall) {
|
||||
transformAnnotation(this)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun IrExpression.convertToConstIfPossible(type: IrType): IrExpression {
|
||||
return when {
|
||||
this !is IrConst<*> || type is IrErrorType -> this
|
||||
type.isArray() -> this.convertToConstIfPossible((type as IrSimpleType).arguments.single().typeOrNull!!)
|
||||
type.isPrimitiveArray() -> this.convertToConstIfPossible(this.type)
|
||||
else -> this.value.toIrConst(type, this.startOffset, this.endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.checker
|
||||
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
internal class IrConstExpressionTransformer(
|
||||
interpreter: IrInterpreter,
|
||||
irFile: IrFile,
|
||||
mode: EvaluationMode,
|
||||
evaluatedConstTracker: EvaluatedConstTracker?,
|
||||
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
suppressExceptions: Boolean,
|
||||
) : IrConstTransformer(interpreter, irFile, mode, evaluatedConstTracker, onWarning, onError, suppressExceptions) {
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
if (expression.canBeInterpreted()) {
|
||||
return expression.interpret(failAsError = false)
|
||||
}
|
||||
return super.visitCall(expression)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField): IrStatement {
|
||||
val initializer = declaration.initializer
|
||||
val expression = initializer?.expression ?: return declaration
|
||||
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
|
||||
if (!isConst) return super.visitField(declaration)
|
||||
|
||||
if (expression.canBeInterpreted(declaration, interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||
initializer.expression = expression.interpret(failAsError = true)
|
||||
}
|
||||
|
||||
return super.visitField(declaration)
|
||||
}
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression {
|
||||
fun IrExpression.wrapInStringConcat(): IrExpression = IrStringConcatenationImpl(
|
||||
this.startOffset, this.endOffset, expression.type, listOf(this@wrapInStringConcat)
|
||||
)
|
||||
|
||||
fun IrExpression.wrapInToStringConcatAndInterpret(): IrExpression = wrapInStringConcat().interpret(failAsError = false)
|
||||
|
||||
// here `StringBuilder`'s list is used to optimize memory, everything works without it
|
||||
val folded = mutableListOf<IrExpression>()
|
||||
val buildersList = mutableListOf<StringBuilder>()
|
||||
for (next in expression.arguments) {
|
||||
val last = folded.lastOrNull()
|
||||
when {
|
||||
!next.wrapInStringConcat().canBeInterpreted() -> {
|
||||
folded += next
|
||||
buildersList.add(StringBuilder())
|
||||
}
|
||||
last == null || !last.wrapInStringConcat().canBeInterpreted() -> {
|
||||
val result = next.wrapInToStringConcatAndInterpret()
|
||||
folded += result
|
||||
buildersList.add(StringBuilder((result as? IrConst<*>)?.value?.toString() ?: ""))
|
||||
}
|
||||
else -> {
|
||||
val nextAsConst = next.wrapInToStringConcatAndInterpret()
|
||||
if (nextAsConst !is IrConst<*>) {
|
||||
folded += next
|
||||
buildersList.add(StringBuilder())
|
||||
} else {
|
||||
folded[folded.size - 1] = IrConstImpl.string(
|
||||
// Inlined strings may have `last.startOffset > next.endOffset`
|
||||
min(last.startOffset, next.startOffset), max(last.endOffset, next.endOffset), expression.type, ""
|
||||
)
|
||||
buildersList.last().append(nextAsConst.value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val foldedConst = folded.singleOrNull() as? IrConst<*>
|
||||
if (foldedConst != null) {
|
||||
return IrConstImpl.string(expression.startOffset, expression.endOffset, expression.type, buildersList.single().toString())
|
||||
}
|
||||
|
||||
folded.zip(buildersList).forEach {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(it.first as? IrConst<String>)?.value = it.second.toString()
|
||||
}
|
||||
return IrStringConcatenationImpl(expression.startOffset, expression.endOffset, expression.type, folded)
|
||||
}
|
||||
}
|
||||
+34
-142
@@ -8,29 +8,45 @@ package org.jetbrains.kotlin.ir.interpreter.checker
|
||||
import org.jetbrains.kotlin.constant.ErrorValue
|
||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.name
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrErrorExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrStringConcatenationImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.toConstantValue
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class IrConstTransformer(
|
||||
private val interpreter: IrInterpreter,
|
||||
fun IrFile.transformConst(
|
||||
interpreter: IrInterpreter,
|
||||
mode: EvaluationMode,
|
||||
evaluatedConstTracker: EvaluatedConstTracker?,
|
||||
onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
suppressExceptions: Boolean = false,
|
||||
) {
|
||||
val irConstExpressionTransformer = IrConstExpressionTransformer(
|
||||
interpreter, this, mode, evaluatedConstTracker, onWarning, onError, suppressExceptions
|
||||
)
|
||||
val irConstAnnotationTransformer = IrConstAnnotationTransformer(
|
||||
interpreter, this, mode, evaluatedConstTracker, onWarning, onError, suppressExceptions
|
||||
)
|
||||
this.transform(irConstExpressionTransformer, null)
|
||||
this.transform(irConstAnnotationTransformer, null)
|
||||
}
|
||||
|
||||
internal abstract class IrConstTransformer(
|
||||
protected val interpreter: IrInterpreter,
|
||||
private val irFile: IrFile,
|
||||
private val mode: EvaluationMode,
|
||||
private val evaluatedConstTracker: EvaluatedConstTracker? = null,
|
||||
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
private val suppressExceptions: Boolean = false,
|
||||
private val onWarning: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
private val onError: (IrFile, IrElement, IrErrorExpression) -> Unit,
|
||||
private val suppressExceptions: Boolean,
|
||||
) : IrElementTransformerVoid() {
|
||||
private fun IrExpression.warningIfError(original: IrExpression): IrExpression {
|
||||
if (this is IrErrorExpression) {
|
||||
@@ -52,7 +68,7 @@ class IrConstTransformer(
|
||||
return this
|
||||
}
|
||||
|
||||
private fun IrExpression.canBeInterpreted(
|
||||
protected fun IrExpression.canBeInterpreted(
|
||||
containingDeclaration: IrElement? = null,
|
||||
configuration: IrInterpreterConfiguration = interpreter.environment.configuration
|
||||
): Boolean {
|
||||
@@ -66,7 +82,7 @@ class IrConstTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.interpret(failAsError: Boolean): IrExpression {
|
||||
protected fun IrExpression.interpret(failAsError: Boolean): IrExpression {
|
||||
val result = try {
|
||||
interpreter.interpret(this, irFile)
|
||||
} catch (e: Throwable) {
|
||||
@@ -83,128 +99,4 @@ class IrConstTransformer(
|
||||
)
|
||||
return if (failAsError) result.reportIfError(this) else result.warningIfError(this)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
if (expression.canBeInterpreted()) {
|
||||
return expression.interpret(failAsError = false)
|
||||
}
|
||||
return super.visitCall(expression)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField): IrStatement {
|
||||
transformAnnotations(declaration)
|
||||
|
||||
val initializer = declaration.initializer
|
||||
val expression = initializer?.expression ?: return declaration
|
||||
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
|
||||
if (!isConst) return super.visitField(declaration)
|
||||
|
||||
if (expression.canBeInterpreted(declaration, interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||
initializer.expression = expression.interpret(failAsError = true)
|
||||
}
|
||||
|
||||
return super.visitField(declaration)
|
||||
}
|
||||
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation): IrExpression {
|
||||
fun IrExpression.wrapInStringConcat(): IrExpression = IrStringConcatenationImpl(
|
||||
this.startOffset, this.endOffset, expression.type, listOf(this@wrapInStringConcat)
|
||||
)
|
||||
|
||||
fun IrExpression.wrapInToStringConcatAndInterpret(): IrExpression = wrapInStringConcat().interpret(failAsError = false)
|
||||
|
||||
// here `StringBuilder`'s list is used to optimize memory, everything works without it
|
||||
val folded = mutableListOf<IrExpression>()
|
||||
val buildersList = mutableListOf<StringBuilder>()
|
||||
for (next in expression.arguments) {
|
||||
val last = folded.lastOrNull()
|
||||
when {
|
||||
!next.wrapInStringConcat().canBeInterpreted() -> {
|
||||
folded += next
|
||||
buildersList.add(StringBuilder())
|
||||
}
|
||||
last == null || !last.wrapInStringConcat().canBeInterpreted() -> {
|
||||
val result = next.wrapInToStringConcatAndInterpret()
|
||||
folded += result
|
||||
buildersList.add(StringBuilder((result as? IrConst<*>)?.value?.toString() ?: ""))
|
||||
}
|
||||
else -> {
|
||||
val nextAsConst = next.wrapInToStringConcatAndInterpret()
|
||||
if (nextAsConst !is IrConst<*>) {
|
||||
folded += next
|
||||
buildersList.add(StringBuilder())
|
||||
} else {
|
||||
folded[folded.size - 1] = IrConstImpl.string(
|
||||
// Inlined strings may have `last.startOffset > next.endOffset`
|
||||
min(last.startOffset, next.startOffset), max(last.endOffset, next.endOffset), expression.type, ""
|
||||
)
|
||||
buildersList.last().append(nextAsConst.value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val foldedConst = folded.singleOrNull() as? IrConst<*>
|
||||
if (foldedConst != null) {
|
||||
return IrConstImpl.string(expression.startOffset, expression.endOffset, expression.type, buildersList.single().toString())
|
||||
}
|
||||
|
||||
folded.zip(buildersList).forEach {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(it.first as? IrConst<String>)?.value = it.second.toString()
|
||||
}
|
||||
return IrStringConcatenationImpl(expression.startOffset, expression.endOffset, expression.type, folded)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement {
|
||||
transformAnnotations(declaration)
|
||||
return super.visitDeclaration(declaration)
|
||||
}
|
||||
|
||||
private fun transformAnnotations(annotationContainer: IrAnnotationContainer) {
|
||||
annotationContainer.annotations.forEach { annotation ->
|
||||
transformAnnotation(annotation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformAnnotation(annotation: IrConstructorCall) {
|
||||
for (i in 0 until annotation.valueArgumentsCount) {
|
||||
val arg = annotation.getValueArgument(i) ?: continue
|
||||
when (arg) {
|
||||
is IrVararg -> annotation.putValueArgument(i, arg.transformVarArg())
|
||||
else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrVararg.transformVarArg(): IrVararg {
|
||||
if (elements.isEmpty()) return this
|
||||
val newIrVararg = IrVarargImpl(this.startOffset, this.endOffset, this.type, this.varargElementType)
|
||||
for (element in this.elements) {
|
||||
when (val arg = (element as? IrSpreadElement)?.expression ?: element) {
|
||||
is IrVararg -> arg.transformVarArg().elements.forEach { newIrVararg.addElement(it) }
|
||||
is IrExpression -> newIrVararg.addElement(arg.transformSingleArg(this.varargElementType))
|
||||
else -> newIrVararg.addElement(arg)
|
||||
}
|
||||
}
|
||||
return newIrVararg
|
||||
}
|
||||
|
||||
private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression {
|
||||
if (this.canBeInterpreted(configuration = interpreter.environment.configuration.copy(treatFloatInSpecialWay = false))) {
|
||||
return this.interpret(failAsError = true).convertToConstIfPossible(expectedType)
|
||||
} else if (this is IrConstructorCall) {
|
||||
transformAnnotation(this)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun IrExpression.convertToConstIfPossible(type: IrType): IrExpression {
|
||||
return when {
|
||||
this !is IrConst<*> || type is IrErrorType -> this
|
||||
type.isArray() -> this.convertToConstIfPossible((type as IrSimpleType).arguments.single().typeOrNull!!)
|
||||
type.isPrimitiveArray() -> this.convertToConstIfPossible(this.type)
|
||||
else -> this.value.toIrConst(type, this.startOffset, this.endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user