[IR] User-friendly message about unexpected unlinked symbols

^KT-53649
This commit is contained in:
Dmitriy Dolovov
2022-09-08 17:59:40 +02:00
committed by Space
parent 6c4dafc23c
commit e4556ecc0d
27 changed files with 231 additions and 143 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.lower.ExpectDeclarationRemover
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
@@ -84,30 +85,22 @@ private val CompilerConfiguration.metadataVersion
private val CompilerConfiguration.expectActualLinker: Boolean
get() = get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) ?: false
class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile)
val CompilerConfiguration.resolverLogger: Logger
get() = when (val messageLogger = this[IrMessageLogger.IR_MESSAGE_LOGGER]) {
null -> DummyLogger
else -> object : Logger {
override fun log(message: String) = messageLogger.report(IrMessageLogger.Severity.INFO, message, null)
override fun error(message: String) = messageLogger.report(IrMessageLogger.Severity.ERROR, message, null)
override fun warning(message: String) = messageLogger.report(IrMessageLogger.Severity.WARNING, message, null)
fun IrMessageLogger?.toResolverLogger(): Logger {
if (this == null) return DummyLogger
return object : Logger {
override fun log(message: String) {
report(IrMessageLogger.Severity.INFO, message, null)
}
override fun error(message: String) {
report(IrMessageLogger.Severity.ERROR, message, null)
}
override fun warning(message: String) {
report(IrMessageLogger.Severity.WARNING, message, null)
}
override fun fatal(message: String): Nothing {
report(IrMessageLogger.Severity.ERROR, message, null)
kotlin.error("FATAL ERROR: $message")
override fun fatal(message: String): Nothing {
messageLogger.report(IrMessageLogger.Severity.ERROR, message, null)
kotlin.error("FATAL ERROR: $message")
}
}
}
}
class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile)
fun generateIrForKlibSerialization(
project: Project,
@@ -123,7 +116,7 @@ fun generateIrForKlibSerialization(
): IrModuleFragment {
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
val messageLogger = configuration.irMessageLogger
val allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val serializedIrFiles = mutableListOf<SerializedIrFile>()
@@ -153,7 +146,11 @@ fun generateIrForKlibSerialization(
}
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory)
val psi2Ir = Psi2IrTranslator(configuration.languageVersionSettings, Psi2IrConfiguration(errorPolicy.allowErrors, allowUnboundSymbols))
val psi2Ir = Psi2IrTranslator(
configuration.languageVersionSettings,
Psi2IrConfiguration(errorPolicy.allowErrors, allowUnboundSymbols),
messageLogger::checkNoUnboundSymbols
)
val psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
val irBuiltIns = psi2IrContext.irBuiltIns
@@ -215,7 +212,7 @@ fun generateKLib(
val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files
val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library }
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
val messageLogger = configuration.irMessageLogger
val icData = mutableListOf<KotlinFileSerializedData>()
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
@@ -311,7 +308,7 @@ fun loadIr(
val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library }
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
val messageLogger = configuration.irMessageLogger
val allowUnboundSymbol = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val signaturer = IdSignatureDescriptor(JsManglerDesc)
@@ -459,9 +456,6 @@ fun getIrModuleInfoForSourceFiles(
)
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, messageLogger)
if (!allowUnboundSymbols) {
symbolTable.noUnboundLeft("Unbound symbols left after linker")
}
// TODO: not sure whether this check should be enabled by default. Add configuration key for it.
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
@@ -513,7 +507,8 @@ private fun preparePsi2Ir(
val analysisResult = depsDescriptors.jsFrontEndResult
val psi2Ir = Psi2IrTranslator(
depsDescriptors.compilerConfiguration.languageVersionSettings,
Psi2IrConfiguration(errorIgnorancePolicy.allowErrors, allowUnboundSymbols)
Psi2IrConfiguration(errorIgnorancePolicy.allowErrors, allowUnboundSymbols),
depsDescriptors.compilerConfiguration::checkNoUnboundSymbols
)
return psi2Ir.createGeneratorContext(
analysisResult.moduleDescriptor,
@@ -530,8 +525,7 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
stubGenerator: DeclarationStubGenerator? = null
): IrModuleFragment {
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration)
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, messageLogger::checkNoUnboundSymbols)
val extensions = IrGenerationExtension.getInstances(project)
if (extensions.isNotEmpty()) {
@@ -606,7 +600,7 @@ class ModulesStructure(
val allResolvedDependencies = jsResolveLibraries(
dependencies,
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
compilerConfiguration.resolverLogger
)
val allDependencies = allResolvedDependencies.getFullResolvedList()