diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index ec128cccbc8..7bd82b594d5 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -94,8 +94,10 @@ class FirElementSerializer private constructor( } for (file in files) { - for (declaration in file.declarations) { - addDeclaration(declaration) {} + extension.processFile(file) { + for (declaration in file.declarations) { + addDeclaration(declaration) {} + } } } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt index 29e2b4fa61b..5bedaa58cb8 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.serialization import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProviderInternals import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeFlexibleType @@ -27,6 +28,16 @@ abstract class FirSerializerExtension { protected abstract val constValueProvider: ConstValueProvider? + @OptIn(ConstValueProviderInternals::class) + internal inline fun processFile(firFile: FirFile, action: () -> T): T { + constValueProvider?.processingFirFile = firFile + return try { + action() + } finally { + constValueProvider?.processingFirFile = null + } + } + open fun shouldUseTypeTable(): Boolean = false open fun shouldUseNormalizedVisibility(): Boolean = false diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtensionBase.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtensionBase.kt index ab743039ce6..47d1e052f22 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtensionBase.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtensionBase.kt @@ -95,7 +95,6 @@ abstract class FirSerializerExtensionBase( } override fun serializeTypeAnnotations(annotations: List, proto: ProtoBuf.Type.Builder) { - // TODO support const extraction for type annotations annotations.serializeAnnotations(proto, protocol.typeAnnotation) } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstValueProvider.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstValueProvider.kt index 75104dd0bfa..00cd156db38 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstValueProvider.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstValueProvider.kt @@ -8,11 +8,22 @@ package org.jetbrains.kotlin.fir.serialization.constant import org.jetbrains.kotlin.constant.ConstantValue import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.expressions.FirExpression +@RequiresOptIn( + message = "Please note that this is internal API and it is supposed to be used with special conditions", + level = RequiresOptIn.Level.WARNING +) +annotation class ConstValueProviderInternals + abstract class ConstValueProvider { abstract val session: FirSession abstract val evaluatedConstTracker: EvaluatedConstTracker + var processingFirFile: FirFile? = null + @ConstValueProviderInternals + set + abstract fun findConstantValueFor(firExpression: FirExpression?): ConstantValue<*>? } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/FirToConstantValueTransformer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/FirToConstantValueTransformer.kt index 6210cc3476d..47224209182 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/FirToConstantValueTransformer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/FirToConstantValueTransformer.kt @@ -27,28 +27,28 @@ import org.jetbrains.kotlin.types.ConstantValueKind internal fun FirExpression.toConstantValue(session: FirSession, constValueProvider: ConstValueProvider? = null): ConstantValue<*>? { constValueProvider?.findConstantValueFor(this)?.let { return it } - return accept(FirToConstantValueTransformerUnsafe(constValueProvider), session) + return accept(FirToConstantValueTransformerUnsafe(), FirToConstantValueTransformerData(session, constValueProvider)) } internal fun FirExpression?.hasConstantValue(session: FirSession): Boolean { return this?.accept(FirToConstantValueChecker, session) == true } -private class FirToConstantValueTransformerSafe( - constValueProvider: ConstValueProvider? -) : FirToConstantValueTransformer(failOnNonConst = false, constValueProvider) +private class FirToConstantValueTransformerSafe : FirToConstantValueTransformer(failOnNonConst = false) -private class FirToConstantValueTransformerUnsafe( - constValueProvider: ConstValueProvider? -) : FirToConstantValueTransformer(failOnNonConst = true, constValueProvider) +private class FirToConstantValueTransformerUnsafe : FirToConstantValueTransformer(failOnNonConst = true) + +private data class FirToConstantValueTransformerData( + val session: FirSession, + val constValueProvider: ConstValueProvider?, +) private abstract class FirToConstantValueTransformer( private val failOnNonConst: Boolean, - private val constValueProvider: ConstValueProvider? -) : FirDefaultVisitor?, FirSession>() { +) : FirDefaultVisitor?, FirToConstantValueTransformerData>() { override fun visitElement( element: FirElement, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*>? { if (failOnNonConst) { error("Illegal element as annotation argument: ${element::class.qualifiedName} -> ${element.render()}") @@ -58,7 +58,7 @@ private abstract class FirToConstantValueTransformer( override fun visitConstExpression( constExpression: FirConstExpression, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*>? { val value = constExpression.value return when (constExpression.kind) { @@ -80,7 +80,10 @@ private abstract class FirToConstantValueTransformer( } } - override fun visitStringConcatenationCall(stringConcatenationCall: FirStringConcatenationCall, data: FirSession): ConstantValue<*>? { + override fun visitStringConcatenationCall( + stringConcatenationCall: FirStringConcatenationCall, + data: FirToConstantValueTransformerData + ): ConstantValue<*>? { val strings = stringConcatenationCall.argumentList.arguments.map { it.accept(this, data) } if (strings.any { it == null || it !is StringValue }) return null return StringValue(strings.joinToString(separator = "") { (it as StringValue).value }) @@ -88,33 +91,33 @@ private abstract class FirToConstantValueTransformer( override fun visitArrayOfCall( arrayOfCall: FirArrayOfCall, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*> { return ArrayValue(arrayOfCall.argumentList.arguments.mapNotNull { it.accept(this, data) }) } override fun visitAnnotation( annotation: FirAnnotation, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*> { - val mapping = annotation.argumentMapping.mapping.convertToConstantValues(data, constValueProvider) + val mapping = annotation.argumentMapping.mapping.convertToConstantValues(data.session, data.constValueProvider) return AnnotationValue.create(annotation.annotationTypeRef.coneType, mapping) } - override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: FirSession): ConstantValue<*> { + override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: FirToConstantValueTransformerData): ConstantValue<*> { return visitAnnotation(annotationCall, data) } override fun visitGetClassCall( getClassCall: FirGetClassCall, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*>? { return create(getClassCall.argument.typeRef.coneTypeUnsafe()) } override fun visitQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*>? { val symbol = qualifiedAccessExpression.toResolvedCallableSymbol() ?: return null val fir = symbol.fir @@ -139,10 +142,12 @@ private abstract class FirToConstantValueTransformer( symbol is FirConstructorSymbol -> { val constructorCall = qualifiedAccessExpression as FirFunctionCall - val constructedClassSymbol = symbol.containingClassLookupTag()?.toFirRegularClassSymbol(data) ?: return null + val constructedClassSymbol = symbol.containingClassLookupTag()?.toFirRegularClassSymbol(data.session) ?: return null if (constructedClassSymbol.classKind != ClassKind.ANNOTATION_CLASS) return null - val mapping = constructorCall.resolvedArgumentMapping?.convertToConstantValues(data, constValueProvider) ?: return null + val mapping = constructorCall.resolvedArgumentMapping + ?.convertToConstantValues(data.session, data.constValueProvider) + ?: return null return AnnotationValue.create(qualifiedAccessExpression.typeRef.coneType, mapping) } @@ -174,13 +179,16 @@ private abstract class FirToConstantValueTransformer( } } - override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: FirSession): ConstantValue<*>? { + override fun visitPropertyAccessExpression( + propertyAccessExpression: FirPropertyAccessExpression, + data: FirToConstantValueTransformerData + ): ConstantValue<*>? { return visitQualifiedAccessExpression(propertyAccessExpression, data) } override fun visitFunctionCall( functionCall: FirFunctionCall, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*>? { if (functionCall.isArrayOfCall) { return FirArrayOfCallTransformer().transformFunctionCall(functionCall, null).accept(this, data) @@ -190,12 +198,15 @@ private abstract class FirToConstantValueTransformer( override fun visitVarargArgumentsExpression( varargArgumentsExpression: FirVarargArgumentsExpression, - data: FirSession + data: FirToConstantValueTransformerData ): ConstantValue<*> { return ArrayValue(varargArgumentsExpression.arguments.mapNotNull { it.accept(this, data) }) } - override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: FirSession): ConstantValue<*>? { + override fun visitNamedArgumentExpression( + namedArgumentExpression: FirNamedArgumentExpression, + data: FirToConstantValueTransformerData + ): ConstantValue<*>? { return namedArgumentExpression.expression.accept(this, data) } } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt index f5ee3bdb2f0..02dd663868c 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt @@ -46,7 +46,7 @@ fun serializeSingleFirFile( } } - val classesProto = file.declarations.makeClassesProtoWithNested() + val classesProto = serializerExtension.processFile(file) { file.declarations.makeClassesProtoWithNested() } val hasTopLevelDeclarations = file.declarations.any { it is FirMemberDeclaration && it.shouldBeSerialized(actualizedExpectDeclarations) && diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt index 8fb5aa14c0c..7fd7adadc3c 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt @@ -10,7 +10,9 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider +import org.jetbrains.kotlin.name.Name class ConstValueProviderImpl( components: Fir2IrComponents, @@ -19,18 +21,20 @@ class ConstValueProviderImpl( override val evaluatedConstTracker: EvaluatedConstTracker = components.configuration.evaluatedConstTracker override fun findConstantValueFor(firExpression: FirExpression?): ConstantValue<*>? { - if (firExpression == null) return null + val firFile = processingFirFile + if (firExpression == null || firFile == null) return null + val fileName = firFile.packageFqName.child(Name.identifier(firFile.name)).asString() return if (firExpression is FirQualifiedAccessExpression) { // TODO check that this behavior is expected in ConversionUtils and if not fix it val calleeReference = firExpression.calleeReference val start = calleeReference.source?.startOffsetSkippingComments() ?: calleeReference.source?.startOffset ?: return null val end = firExpression.source?.endOffset ?: return null - evaluatedConstTracker.load(start, end) + evaluatedConstTracker.load(start, end, fileName) } else { val start = firExpression.source?.startOffset ?: return null val end = firExpression.source?.endOffset ?: return null - evaluatedConstTracker.load(start, end) + evaluatedConstTracker.load(start, end, fileName) } } } \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt index 68a35bb8f02..1ea6a8b7716 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray import org.jetbrains.kotlin.ir.types.* 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 @@ -76,7 +77,7 @@ class IrConstTransformer( } evaluatedConstTracker?.save( - result.startOffset, result.endOffset, + result.startOffset, result.endOffset, irFile.fqName.child(Name.identifier(irFile.name)).asString(), constant = if (result is IrErrorExpression) ErrorValue.create(result.description) else (result as IrConst<*>).toConstantValue() ) diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/objectConstValInAnnotationArgument.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/objectConstValInAnnotationArgument.kt index 9256a922136..0bd8db588f4 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/objectConstValInAnnotationArgument.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/objectConstValInAnnotationArgument.kt @@ -4,8 +4,7 @@ annotation class Key(val value: String) object Messanger { const val DEFAULT_TEXT = "OK" - // Note: second `EVALUATED` from `message$default` - fun message(@Key(value = DEFAULT_TEXT) text: String = DEFAULT_TEXT): String { + fun message(@Key(value = DEFAULT_TEXT) text: String = DEFAULT_TEXT): String { return text } } diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt index 7dfdabd135a..df4fc43b1a2 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt @@ -50,17 +50,16 @@ enum class SomeEnum { B; } -// TODO: can be uncommented after fix KT-57135 -//@field:BinaryAnnotation("Str" + "ing") -//var x: Int = 5 +@field:BinaryAnnotation("Str" + "ing") +var x: Int = 5 -//object Delegate { -// operator fun getValue(instance: Any?, property: Any) : String = "" -// operator fun setValue(instance: Any?, property: Any, value: String) {} -//} -// -//@delegate:BinaryAnnotation("Str" + "ing") -//val p: String by Delegate +object Delegate { + operator fun getValue(instance: Any?, property: Any) : String = "" + operator fun setValue(instance: Any?, property: Any, value: String) {} +} + +@delegate:BinaryAnnotation("Str" + "ing") +val p: String by Delegate // 7. VALUE_PARAMETER @@ -70,6 +69,19 @@ fun foo(@BinaryAnnotation("Str" + "ing") a: Int) { } val @receiver:BinaryAnnotation("Str" + "ing") String.a: Int get() = 0 +class WithConstructorArgumentAnnotation( + @BinaryAnnotation("Str" + "ing") + val a: Int +) + +@setparam:BinaryAnnotation("Str" + "ing") +var setParamProp: Int = 0 + get() = field + 1 + set(x: Int) { field = x * 2 } + +var mutablePropWithAnnotationOnSetterParam = 0 + set(@BinaryAnnotation("Str" + "ing") x: Int) { field = x * 2 } + // 9. FUNCTION @BinaryAnnotation("Str" + "ing") fun bar() {} diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt index 118d65ae8a3..f2997ba88b8 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt @@ -7,7 +7,7 @@ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) -annotation class AnnotationWithDefault(val str: String = "Str" + "ing") +annotation class AnnotationWithDefault(val str: String = "Str" + "ing") @AnnotationWithDefault() class A diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInterpreterDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInterpreterDumpHandler.kt index a853c03f8f8..06a24197787 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInterpreterDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/IrInterpreterDumpHandler.kt @@ -6,20 +6,12 @@ package org.jetbrains.kotlin.test.backend.handlers import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.codeMetaInfo.model.ParsedCodeMetaInfo import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.constant.ErrorValue import org.jetbrains.kotlin.constant.EvaluatedConstTracker -import org.jetbrains.kotlin.ir.IrElement -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.IrConst -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid -import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.ir.declarations.name import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.IGNORE_BACKEND_K2 import org.jetbrains.kotlin.test.model.* @@ -44,7 +36,7 @@ interface IrInterpreterDumpHandler { val evaluatedConstTracker = configuration.get(CommonConfigurationKeys.EVALUATED_CONST_TRACKER) ?: return val irModule = testServices.dependencyProvider.getArtifact(module, BackendKinds.IrBackend).irModuleFragment for ((irFile, testFile) in matchIrFileWithTestFile(irModule, module)) { - evaluatedConstTracker.processFile(testFile, irFile, testServices.defaultsProvider.defaultTargetBackend ?: module.targetBackend) + evaluatedConstTracker.processFile(testFile, irFile) } } @@ -54,44 +46,18 @@ interface IrInterpreterDumpHandler { return targetBackend in ignoredBackends || TargetBackend.ANY in ignoredBackends } - private fun EvaluatedConstTracker.processFile(testFile: TestFile, irFile: IrFile, targetBackend: TargetBackend?) { - irFile.accept(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitDeclaration(declaration: IrDeclarationBase) { - if (declaration.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS) return - visitAnnotations(declaration) - super.visitDeclaration(declaration) - } - - // TODO can be dropped if we are going to draw one info per line segment - override fun visitField(declaration: IrField) { - if (targetBackend == TargetBackend.JVM_IR) { - declaration.correspondingPropertySymbol?.owner?.let { visitAnnotations(it) } - } - super.visitField(declaration) - } - - private fun visitAnnotations(annotationContainer: IrAnnotationContainer) { - annotationContainer.annotations.forEach { annotation -> - annotation.acceptVoid(this) - } - } - - override fun visitConst(expression: IrConst<*>) { - val constantValue = this@processFile.load(expression.startOffset, expression.endOffset) ?: return - val message = constantValue.stringTemplateValue() - val metaInfo = ParsedCodeMetaInfo( - expression.startOffset, expression.endOffset, - attributes = mutableListOf(), - tag = if (constantValue is ErrorValue) "WAS_NOT_EVALUATED" else "EVALUATED", - description = StringUtil.escapeLineBreak(message) - ) - globalMetadataInfoHandler.addMetadataInfosForFile(testFile, listOf(metaInfo)) - } - }, null) + private fun EvaluatedConstTracker.processFile(testFile: TestFile, irFile: IrFile) { + this.load(irFile.name)?.forEach { (pair, constantValue) -> + val (start, end) = pair + val message = constantValue.stringTemplateValue() + val metaInfo = ParsedCodeMetaInfo( + start, end, + attributes = mutableListOf(), + tag = if (constantValue is ErrorValue) "WAS_NOT_EVALUATED" else "EVALUATED", + description = StringUtil.escapeLineBreak(message) + ) + globalMetadataInfoHandler.addMetadataInfosForFile(testFile, listOf(metaInfo)) + } } } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/constant/EvaluatedConstTracker.kt b/core/compiler.common/src/org/jetbrains/kotlin/constant/EvaluatedConstTracker.kt index b3ba217e7f2..f5448f89c02 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/constant/EvaluatedConstTracker.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/constant/EvaluatedConstTracker.kt @@ -8,8 +8,9 @@ package org.jetbrains.kotlin.constant import java.util.concurrent.ConcurrentHashMap abstract class EvaluatedConstTracker { - abstract fun save(start: Int, end: Int, constant: ConstantValue<*>) - abstract fun load(start: Int, end: Int): ConstantValue<*>? + abstract fun save(start: Int, end: Int, file: String, constant: ConstantValue<*>) + abstract fun load(start: Int, end: Int, file: String): ConstantValue<*>? + abstract fun load(file: String): Map, ConstantValue<*>>? companion object { /** @@ -24,14 +25,20 @@ abstract class EvaluatedConstTracker { } private class DefaultEvaluatedConstTracker : EvaluatedConstTracker() { - private val storage = ConcurrentHashMap, ConstantValue<*>>() + private val storage = ConcurrentHashMap, ConstantValue<*>>>() - override fun save(start: Int, end: Int, constant: ConstantValue<*>) { - storage[start to end] = constant + override fun save(start: Int, end: Int, file: String, constant: ConstantValue<*>) { + storage + .getOrPut(file) { ConcurrentHashMap() } + .let { it[start to end] = constant } } - override fun load(start: Int, end: Int): ConstantValue<*>? { - return storage[start to end] + override fun load(start: Int, end: Int, file: String): ConstantValue<*>? { + return storage[file]?.get(start to end) + } + + override fun load(file: String): Map, ConstantValue<*>>? { + return storage[file] } }