From a4945878aa3bc7751c55ac504904a9f2f18cb8a8 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Tue, 29 Sep 2020 14:41:59 +0300 Subject: [PATCH] [KLIB] Pass `containsErrorCode` flag from library/IC cache into deserializer - Make deserializer track whether error node are allowed. --- .../IncrementalCompilationSupport.kt | 1 + .../serialization/IrFileDeserializer.kt | 11 +++++++- .../common/serialization/KotlinIrLinker.kt | 27 ++++++++++--------- .../jetbrains/kotlin/ir/backend/js/klib.kt | 3 ++- .../js/lower/serialization/ir/JsIrLinker.kt | 20 ++++++++------ .../jetbrains/kotlin/library/KotlinLibrary.kt | 3 +++ 6 files changed, 43 insertions(+), 22 deletions(-) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt index 1c6a51d98c9..e81e0c2893e 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IncrementalCompilationSupport.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.SerializedIrFile import org.jetbrains.kotlin.library.impl.* +class ICData(val icData: List, val containsErrorCode: Boolean) class ICKotlinLibrary(private val icData: List) : IrLibrary { override val dataFlowGraph: ByteArray? = null diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index 389bc40944b..68a4787b9bd 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -114,7 +114,8 @@ abstract class IrFileDeserializer( val symbolTable: SymbolTable, protected var deserializeBodies: Boolean, private val deserializeFakeOverrides: Boolean, - private val fakeOverrideQueue: MutableList + private val fakeOverrideQueue: MutableList, + private val allowErrorNodes: Boolean ) { protected val irFactory: IrFactory get() = symbolTable.irFactory @@ -202,6 +203,7 @@ abstract class IrFileDeserializer( } private fun deserializeErrorType(proto: ProtoErrorType): IrErrorType { + require(allowErrorNodes) { "IrErrorType found but error code is not allowed" } val annotations = deserializeAnnotations(proto.annotationList) return IrErrorTypeImpl(null, annotations, Variance.INVARIANT) } @@ -468,6 +470,9 @@ abstract class IrFileDeserializer( proto: ProtoErrorExpression, start: Int, end: Int, type: IrType ): IrErrorExpression { + require(allowErrorNodes) { + "IrErrorExpression($start, $end, \"${deserializeString(proto.description)}\") found but error code is not allowed" + } return IrErrorExpressionImpl(start, end, type, deserializeString(proto.description)) } @@ -475,6 +480,9 @@ abstract class IrFileDeserializer( proto: ProtoErrorCallExpression, start: Int, end: Int, type: IrType ): IrErrorCallExpression { + require(allowErrorNodes) { + "IrErrorCallExpressionImpl($start, $end, \"${deserializeString(proto.description)}\") found but error code is not allowed" + } return IrErrorCallExpressionImpl(start, end, type, deserializeString(proto.description)).apply { if (proto.hasReceiver()) { explicitReceiver = deserializeExpression(proto.receiver) @@ -1110,6 +1118,7 @@ abstract class IrFileDeserializer( } private fun deserializeErrorDeclaration(proto: ProtoErrorDeclaration): IrErrorDeclaration { + require(allowErrorNodes) { "IrErrorDeclaration found but error code is not allowed" } val coordinates = BinaryCoordinates.decode(proto.coordinates) val descriptor = WrappedErrorDescriptor() return irFactory.createErrorDeclaration(coordinates.startOffset, coordinates.endOffset, descriptor).also { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index eebf197b36f..5e7f339740a 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -77,7 +77,7 @@ abstract class KotlinIrLinker( private lateinit var linkerExtensions: Collection - abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy) : + abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy, private val containsErrorCode: Boolean = false) : IrModuleDeserializer(moduleDescriptor) { private val fileToDeserializerMap = mutableMapOf() @@ -122,7 +122,7 @@ abstract class KotlinIrLinker( for (i in 0 until fileCount) { val fileStream = klib.file(i).codedInputStream - files.add(deserializeIrFile(ProtoFile.parseFrom(fileStream, newInstance()), i, delegate)) + files.add(deserializeIrFile(ProtoFile.parseFrom(fileStream, newInstance()), i, delegate, containsErrorCode)) } moduleFragment.files.addAll(files) @@ -155,20 +155,22 @@ abstract class KotlinIrLinker( override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList()) - private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int, moduleDeserializer: IrModuleDeserializer): IrFile { + private fun deserializeIrFile(fileProto: ProtoFile, fileIndex: Int, moduleDeserializer: IrModuleDeserializer, allowErrorNodes: Boolean): IrFile { val fileName = fileProto.fileEntry.name val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray()) val fileDeserializer = - IrDeserializerForFile(fileProto.annotationList, - fileProto.actualsList, - fileIndex, - !strategy.needBodies, - strategy.inlineBodies, - deserializeFakeOverrides, - moduleDeserializer).apply { + IrDeserializerForFile( + fileProto.annotationList, + fileProto.actualsList, + fileIndex, + !strategy.needBodies, + strategy.inlineBodies, + deserializeFakeOverrides, + moduleDeserializer, allowErrorNodes + ).apply { // Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations. // Thus we schedule their deserialization in deserializer's constructor. @@ -230,8 +232,9 @@ abstract class KotlinIrLinker( onlyHeaders: Boolean, inlineBodies: Boolean, deserializeFakeOverrides: Boolean, - private val moduleDeserializer: IrModuleDeserializer - ) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue) { + private val moduleDeserializer: IrModuleDeserializer, + allowErrorNodes: Boolean + ) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue, allowErrorNodes) { private var fileLoops = mutableMapOf() diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index b93f3d7f69e..e31dbecb792 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy +import org.jetbrains.kotlin.backend.common.serialization.ICData import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion import org.jetbrains.kotlin.backend.common.serialization.knownBuiltins import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker @@ -160,7 +161,7 @@ fun generateKLib( psi2IrContext.symbolTable, functionFactory, feContext, - serializedIrFiles, + serializedIrFiles?.let { ICData(it, errorPolicy.allowErrors) }, deserializeFakeOverrides ) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 7f08e62a42b..b939637c93b 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -19,14 +19,15 @@ import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.library.IrLibrary -import org.jetbrains.kotlin.library.SerializedIrFile +import org.jetbrains.kotlin.library.KotlinLibrary +import org.jetbrains.kotlin.library.containsErrorCode import org.jetbrains.kotlin.resolve.BindingContext class JsIrLinker( private val currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, override val functionalInterfaceFactory: IrAbstractFunctionFactory, override val translationPluginContext: TranslationPluginContext?, - private val icData: List? = null, + private val icData: ICData? = null, deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides ) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { @@ -35,17 +36,20 @@ class JsIrLinker( override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor === moduleDescriptor.builtIns.builtInsModule - override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer = - JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy) + private val IrLibrary.libContainsErrorCode: Boolean + get() = this is KotlinLibrary && this.containsErrorCode - private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy) : - KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy) + override fun createModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary?, strategy: DeserializationStrategy): IrModuleDeserializer = + JsModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy, klib.libContainsErrorCode) + + private inner class JsModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy, allowErrorCode: Boolean) : + KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy, allowErrorCode) override fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection): IrModuleDeserializer { val currentModuleDeserializer = super.createCurrentModuleDeserializer(moduleFragment, dependencies) icData?.let { - return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it) { lib -> - JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy) + return CurrentModuleWithICDeserializer(currentModuleDeserializer, symbolTable, builtIns, it.icData) { lib -> + JsModuleDeserializer(currentModuleDeserializer.moduleDescriptor, lib, currentModuleDeserializer.strategy, it.containsErrorCode) } } return currentModuleDeserializer diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt index 155f9ad1cf5..522bccfe071 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt @@ -78,3 +78,6 @@ val KotlinLibrary.exportForwardDeclarations: List val BaseKotlinLibrary.nativeTargets: List get() = manifestProperties.propertyList(KLIB_PROPERTY_NATIVE_TARGETS) + +val KotlinLibrary.containsErrorCode: Boolean + get() = manifestProperties.getProperty(KLIB_PROPERTY_CONTAINS_ERROR_CODE) == "true" \ No newline at end of file