From c00c7ffbe0002eb4026d41c80a05b1a1c759d889 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Tue, 11 Apr 2023 12:56:59 +0200 Subject: [PATCH] [K2] Use file name as one of parameters to extract evaluated const It is not enough to store evaluated constants only by pair. We need to consider case there constant can be located in different files with the same offset but with different values. #KT-57928 Fixed #KT-57929 Fixed --- .../fir/serialization/FirElementSerializer.kt | 6 +- .../serialization/FirSerializerExtension.kt | 11 ++++ .../FirSerializerExtensionBase.kt | 1 - .../constant/ConstValueProvider.kt | 11 ++++ .../constant/FirToConstantValueTransformer.kt | 59 +++++++++++------- .../fir/serialization/firKlibSerialization.kt | 2 +- .../fir/backend/ConstValueProviderImpl.kt | 10 ++- .../interpreter/checker/IrConstTransformer.kt | 3 +- .../objectConstValInAnnotationArgument.kt | 3 +- .../serialization/annotationSerialization.kt | 32 +++++++--- .../serialization/annotationWithDefaults.kt | 2 +- .../handlers/IrInterpreterDumpHandler.kt | 62 +++++-------------- .../kotlin/constant/EvaluatedConstTracker.kt | 21 ++++--- 13 files changed, 123 insertions(+), 100 deletions(-) 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] } }