From 8be98da1d3840e2fc3a4470d323fe9b28ce5dd10 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 9 Aug 2023 14:59:26 +0200 Subject: [PATCH] [PL] Halt compilation when there are linkage issues logged with the ERROR severity ^KT-61097 --- .../ir/linkage/partial/PartialLinkageUtils.kt | 2 +- .../linkage/issues/KotlinIrLinkerIssues.kt | 4 ++++ .../PartialLinkageSupportForLinkerImpl.kt | 9 +++++++- .../PartialLinkageSupportForLoweringsImpl.kt | 22 ++++++++++++++----- .../partial/PartiallyLinkedIrTreePatcher.kt | 4 +++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageUtils.kt index 1fecb165fd9..9c24ad1d39a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/partial/PartialLinkageUtils.kt @@ -135,7 +135,7 @@ object PartialLinkageUtils { } // A workaround for KT-58837 until KT-58904 is fixed. TODO: Merge with IrMessageLogger. -class PartialLinkageLogger(private val irLogger: IrMessageLogger, logLevel: PartialLinkageLogLevel) { +class PartialLinkageLogger(val irLogger: IrMessageLogger, val logLevel: PartialLinkageLogLevel) { class Location(val moduleName: String, val filePath: String, val lineNumber: Int, val columnNumber: Int) { fun render(): StringBuilder = StringBuilder().apply { append(moduleName) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt index 78441897444..e54010db087 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/issues/KotlinIrLinkerIssues.kt @@ -29,6 +29,10 @@ abstract class KotlinIrLinkerIssue { } } +object PartialLinkageErrorsLogged : KotlinIrLinkerIssue() { + override val errorMessage = "There are linkage errors reported by the partial linkage engine" +} + class UnexpectedUnboundIrSymbols(unboundSymbols: Set, whenDetected: String) : KotlinIrLinkerIssue() { override val errorMessage = buildString { // cause: diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt index eb7098b947d..09344c6ebdf 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLinkerImpl.kt @@ -5,12 +5,14 @@ package org.jetbrains.kotlin.backend.common.linkage.partial +import org.jetbrains.kotlin.backend.common.linkage.issues.PartialLinkageErrorsLogged import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageConfig +import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageLogLevel import org.jetbrains.kotlin.ir.linkage.partial.PartialLinkageLogger import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.IrMessageLogger @@ -29,7 +31,7 @@ else internal class PartialLinkageSupportForLinkerImpl( builtIns: IrBuiltIns, allowErrorTypes: Boolean, - logger: PartialLinkageLogger + private val logger: PartialLinkageLogger ) : PartialLinkageSupportForLinker { private val stubGenerator = MissingDeclarationStubGenerator(builtIns) private val classifierExplorer = ClassifierExplorer(builtIns, stubGenerator, allowErrorTypes) @@ -81,5 +83,10 @@ internal class PartialLinkageSupportForLinkerImpl( // Patch the stubs which were not patched yet. patcher.patchDeclarations(stubGenerator.grabDeclarationsToPatch()) + + // Make sure that there are no linkage issues that have been reported with the 'error' severity. + // If there are, abort the current compilation. + if (logger.logLevel == PartialLinkageLogLevel.ERROR && patcher.linkageIssuesLogged > 0) + PartialLinkageErrorsLogged.raiseIssue(logger.irLogger) } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLoweringsImpl.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLoweringsImpl.kt index 70b78a97250..a21fd007b04 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLoweringsImpl.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartialLinkageSupportForLoweringsImpl.kt @@ -33,11 +33,22 @@ internal class PartialLinkageSupportForLoweringsImpl( ) : PartialLinkageSupportForLowerings { override val isEnabled get() = true - // N.B. errorMessagesRendered is always >= than throwExpressionsGenerated. - var throwExpressionsGenerated = 0 // Track each generate `throw` expression. + /** To track the amount of rendered linkage issues. */ + var linkageIssuesRendered = 0 private set - var errorMessagesRendered = 0 // Track each rendered error message. + /** + * To track the amount of logged linkage issues. + * Note that the following condition is always true: [linkageIssuesLogged] <= [linkageIssuesRendered]. + */ + var linkageIssuesLogged = 0 + private set + + /** + * To track the amount of generated `throw` expressions. + * Note that the following condition is always true: [throwExpressionsGenerated] <= [linkageIssuesRendered]. + */ + var throwExpressionsGenerated = 0 private set override fun throwLinkageError( @@ -51,7 +62,7 @@ internal class PartialLinkageSupportForLoweringsImpl( else renderAndLogLinkageError(partialLinkageCase, element, file) // Render + log with the appropriate severity. - throwExpressionsGenerated++ // Track each generate `throw` expression. + throwExpressionsGenerated++ // Track each generated `throw` expression. return IrCallImpl( startOffset = element.startOffset, @@ -70,13 +81,14 @@ internal class PartialLinkageSupportForLoweringsImpl( val errorMessage = renderLinkageError(partialLinkageCase) val locationInSourceCode = file.computeLocationForOffset(element.startOffsetOfFirstDenotableIrElement()) + linkageIssuesLogged++ // Track each logged linkage issue. logger.log(errorMessage, locationInSourceCode) return errorMessage } private fun renderLinkageError(partialLinkageCase: PartialLinkageCase): String { - errorMessagesRendered++ // Track each rendered error message. + linkageIssuesRendered++ // Track each rendered linkage issue. return partialLinkageCase.renderLinkageError() } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt index 18025b0489a..c4c7b5ad3f8 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt @@ -58,6 +58,8 @@ internal class PartiallyLinkedIrTreePatcher( // Used only to generate IR expressions that throw linkage errors. private val supportForLowerings by lazy { PartialLinkageSupportForLoweringsImpl(builtIns, logger) } + val linkageIssuesLogged get() = supportForLowerings.linkageIssuesLogged + fun shouldBeSkipped(declaration: IrDeclaration): Boolean = PLModule.determineModuleFor(declaration).shouldBeSkipped fun patchModuleFragments(roots: Sequence) { @@ -887,7 +889,7 @@ internal class PartiallyLinkedIrTreePatcher( } private inner class AnnotationChecker(currentFile: PLFile) : ExpressionTransformer(currentFile) { - private val currentErrorMessagesCount get() = supportForLowerings.errorMessagesRendered + private val currentErrorMessagesCount get() = supportForLowerings.linkageIssuesRendered private val initialErrorMessagesCount = currentErrorMessagesCount // Memoize the number of PL errors generated to this moment. var isUsableAnnotation = true