[IR] User-friendly message about unexpected unlinked symbols
^KT-53649
This commit is contained in:
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||
@@ -21,9 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
@@ -95,7 +94,7 @@ fun compileIr(
|
||||
moduleToName: Map<IrModuleFragment, String>,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable,
|
||||
deserializer: JsIrLinker,
|
||||
irLinker: JsIrLinker,
|
||||
phaseConfig: PhaseConfig,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
dceRuntimeDiagnostic: RuntimeDiagnostic?,
|
||||
@@ -114,8 +113,6 @@ fun compileIr(
|
||||
is MainModule.Klib -> dependencyModules
|
||||
}
|
||||
|
||||
val allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
|
||||
|
||||
val context = JsIrBackendContext(
|
||||
moduleDescriptor,
|
||||
irBuiltIns,
|
||||
@@ -133,13 +130,11 @@ fun compileIr(
|
||||
)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
val irProviders = listOf(deserializer)
|
||||
val irProviders = listOf(irLinker)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
deserializer.postProcess()
|
||||
if (!allowUnboundSymbols) {
|
||||
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
|
||||
}
|
||||
irLinker.postProcess()
|
||||
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
|
||||
allModules.forEach { module ->
|
||||
collectNativeImplementations(context, module)
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaserState
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations
|
||||
@@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
fun compileWithIC(
|
||||
mainModule: IrModuleFragment,
|
||||
configuration: CompilerConfiguration,
|
||||
deserializer: JsIrLinker,
|
||||
irLinker: JsIrLinker,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
filesToLower: Collection<IrFile>,
|
||||
mainArguments: List<String>? = null,
|
||||
@@ -63,11 +63,11 @@ fun compileWithIC(
|
||||
)
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
val irProviders = listOf(deserializer)
|
||||
val irProviders = listOf(irLinker)
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
deserializer.postProcess()
|
||||
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
|
||||
irLinker.postProcess()
|
||||
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
|
||||
allModules.forEach {
|
||||
collectNativeImplementations(context, it)
|
||||
|
||||
@@ -26,7 +26,7 @@ fun interface CacheExecutor {
|
||||
fun execute(
|
||||
mainModule: IrModuleFragment,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
deserializer: JsIrLinker,
|
||||
irLinker: JsIrLinker,
|
||||
configuration: CompilerConfiguration,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
@@ -87,7 +87,7 @@ class CacheUpdater(
|
||||
val allResolvedDependencies = jsResolveLibraries(
|
||||
allModules,
|
||||
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||
compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||
compilerConfiguration.resolverLogger
|
||||
)
|
||||
|
||||
return allResolvedDependencies.getFullList().associateBy { KotlinLibraryFile(it) }
|
||||
@@ -568,7 +568,7 @@ class CacheUpdater(
|
||||
val rebuiltFragments = executor.execute(
|
||||
mainModule = loadedIr.loadedFragments[mainLibraryFile] ?: notFoundIcError("main lib loaded fragment", mainLibraryFile),
|
||||
allModules = loadedIr.loadedFragments.values,
|
||||
deserializer = loadedIr.linker,
|
||||
irLinker = loadedIr.linker,
|
||||
configuration = compilerConfiguration,
|
||||
dirtyFiles = loadedIr.loadedFragments.flatMap { (libFile, libFragment) ->
|
||||
dirtyFileExports[libFile]?.let { libDirtyFiles ->
|
||||
@@ -617,7 +617,7 @@ fun rebuildCacheForDirtyFiles(
|
||||
return currentIrModule to buildCacheForModuleFiles(
|
||||
mainModule = currentIrModule,
|
||||
allModules = irModules.values,
|
||||
deserializer = jsIrLinker,
|
||||
irLinker = jsIrLinker,
|
||||
configuration = configuration,
|
||||
dirtyFiles = dirtyIrFiles,
|
||||
exportedDeclarations = exportedDeclarations,
|
||||
@@ -628,7 +628,7 @@ fun rebuildCacheForDirtyFiles(
|
||||
fun buildCacheForModuleFiles(
|
||||
mainModule: IrModuleFragment,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
deserializer: JsIrLinker,
|
||||
irLinker: JsIrLinker,
|
||||
configuration: CompilerConfiguration,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
@@ -639,7 +639,7 @@ fun buildCacheForModuleFiles(
|
||||
allModules = allModules,
|
||||
filesToLower = dirtyFiles,
|
||||
configuration = configuration,
|
||||
deserializer = deserializer,
|
||||
irLinker = irLinker,
|
||||
mainArguments = mainArguments,
|
||||
exportedDeclarations = exportedDeclarations,
|
||||
)
|
||||
|
||||
+2
-3
@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.irMessageLogger
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
@@ -36,13 +36,12 @@ internal class JsIrLinkerLoader(
|
||||
) {
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private fun createLinker(loadedModules: Map<ModuleDescriptor, KotlinLibrary>): JsIrLinker {
|
||||
val logger = compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
||||
val signaturer = IdSignatureDescriptor(JsManglerDesc)
|
||||
val symbolTable = SymbolTable(signaturer, irFactory)
|
||||
val moduleDescriptor = loadedModules.keys.last()
|
||||
val typeTranslator = TypeTranslatorImpl(symbolTable, compilerConfiguration.languageVersionSettings, moduleDescriptor)
|
||||
val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable)
|
||||
return JsIrLinker(null, logger, irBuiltIns, symbolTable, null)
|
||||
return JsIrLinker(null, compilerConfiguration.irMessageLogger, irBuiltIns, symbolTable, null)
|
||||
}
|
||||
|
||||
private fun loadModules(): Map<ModuleDescriptor, KotlinLibrary> {
|
||||
|
||||
+5
-3
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getIoFile
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -113,15 +114,16 @@ open class JvmIrCodegenFactory(
|
||||
val symbolTable = SymbolTable(signaturer, IrFactoryImpl)
|
||||
mangler to symbolTable
|
||||
}
|
||||
val messageLogger = input.configuration.irMessageLogger
|
||||
val psi2ir = Psi2IrTranslator(
|
||||
input.languageVersionSettings,
|
||||
Psi2IrConfiguration(
|
||||
input.ignoreErrors,
|
||||
allowUnboundSymbols = false,
|
||||
input.skipBodies,
|
||||
)
|
||||
input.skipBodies
|
||||
),
|
||||
messageLogger::checkNoUnboundSymbols
|
||||
)
|
||||
val messageLogger = input.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
||||
val psi2irContext = psi2ir.createGeneratorContext(
|
||||
input.module,
|
||||
input.bindingContext,
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.JvmSerializeIrMode
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.irMessageLogger
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class JvmIrSerializerImpl(private val configuration: CompilerConfiguration) : JvmIrSerializer {
|
||||
@@ -34,7 +34,7 @@ class JvmIrSerializerImpl(private val configuration: CompilerConfiguration) : Jv
|
||||
|
||||
private fun makeSerializerSession(fileClassFqName: FqName) =
|
||||
JvmIrSerializerSession(
|
||||
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
|
||||
configuration.irMessageLogger,
|
||||
declarationTable,
|
||||
mutableMapOf(),
|
||||
configuration.get(JVMConfigurationKeys.SERIALIZE_IR) ?: JvmSerializeIrMode.NONE,
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.wasm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.wasm.ir2wasm.WasmCompiledModuleFragment
|
||||
import org.jetbrains.kotlin.backend.wasm.ir2wasm.WasmModuleFragmentGenerator
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.markExportedDeclarations
|
||||
@@ -16,7 +17,6 @@ import org.jetbrains.kotlin.ir.backend.js.loadIr
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.wasm.ir.convertors.WasmIrToBinary
|
||||
@@ -35,7 +35,7 @@ fun compileToLoweredIr(
|
||||
): Pair<List<IrModuleFragment>, WasmBackendContext> {
|
||||
val mainModule = depsDescriptors.mainModule
|
||||
val configuration = depsDescriptors.compilerConfiguration
|
||||
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = loadIr(
|
||||
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, irLinker) = loadIr(
|
||||
depsDescriptors,
|
||||
irFactory,
|
||||
verifySignatures = false,
|
||||
@@ -52,15 +52,15 @@ fun compileToLoweredIr(
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
allModules.forEach {
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(deserializer)).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
|
||||
}
|
||||
|
||||
// Create stubs
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(deserializer)).generateUnboundSymbolsAsDependencies()
|
||||
ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
|
||||
allModules.forEach { it.patchDeclarationParents() }
|
||||
|
||||
deserializer.postProcess()
|
||||
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
|
||||
irLinker.postProcess()
|
||||
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
|
||||
for (module in allModules)
|
||||
for (file in module.files)
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.linkage.IrProvider
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||
@@ -44,6 +43,7 @@ fun interface Psi2IrPostprocessingStep {
|
||||
class Psi2IrTranslator(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val configuration: Psi2IrConfiguration,
|
||||
private val checkNoUnboundSymbols: (SymbolTable, String) -> Unit
|
||||
) {
|
||||
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
|
||||
|
||||
@@ -80,6 +80,7 @@ class Psi2IrTranslator(
|
||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
|
||||
fragmentInfo: EvaluatorFragmentInfo? = null
|
||||
): IrModuleFragment {
|
||||
|
||||
val moduleGenerator = fragmentInfo?.let {
|
||||
FragmentModuleGenerator(context, it)
|
||||
} ?: ModuleGenerator(context, expectDescriptorToSymbol)
|
||||
@@ -92,9 +93,7 @@ class Psi2IrTranslator(
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||
|
||||
deserializers.forEach { it.postProcess() }
|
||||
if (!context.configuration.allowUnboundSymbols) {
|
||||
context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n")
|
||||
}
|
||||
context.checkNoUnboundSymbols { "after generation of IR module ${irModule.name.asString()}" }
|
||||
|
||||
postprocessingSteps.forEach { it.invoke(irModule) }
|
||||
// assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference
|
||||
@@ -102,7 +101,13 @@ class Psi2IrTranslator(
|
||||
// TODO: remove it once plugin API improved
|
||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||
deserializers.forEach { it.postProcess() }
|
||||
context.checkNoUnboundSymbols { "after applying all post-processing steps for the generated IR module ${irModule.name.asString()}" }
|
||||
|
||||
return irModule
|
||||
}
|
||||
|
||||
private fun GeneratorContext.checkNoUnboundSymbols(whenDetected: () -> String) {
|
||||
if (!configuration.allowUnboundSymbols)
|
||||
checkNoUnboundSymbols(symbolTable, whenDetected())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
interface IrMessageLogger {
|
||||
@@ -25,4 +26,7 @@ interface IrMessageLogger {
|
||||
@JvmStatic
|
||||
val IR_MESSAGE_LOGGER = CompilerConfigurationKey<IrMessageLogger>("ir message logger")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val CompilerConfiguration.irMessageLogger: IrMessageLogger
|
||||
get() = this[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
||||
|
||||
@@ -1177,10 +1177,3 @@ val SymbolTable.allUnbound: Set<IrSymbol>
|
||||
addUnbound(unboundTypeAliases)
|
||||
addUnbound(unboundTypeParameters)
|
||||
}
|
||||
|
||||
fun SymbolTable.noUnboundLeft(message: String) {
|
||||
val unbound = this.allUnbound
|
||||
assert(unbound.isEmpty()) {
|
||||
message + "\n" + unbound.joinToString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -51,7 +51,7 @@ abstract class KotlinIrLinker(
|
||||
|
||||
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
|
||||
|
||||
protected open val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport get() = UnlinkedDeclarationsSupport.DISABLED
|
||||
open val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport get() = UnlinkedDeclarationsSupport.DISABLED
|
||||
protected open val userVisibleIrModulesSupport: UserVisibleIrModulesSupport get() = UserVisibleIrModulesSupport.DEFAULT
|
||||
|
||||
fun deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled(
|
||||
@@ -75,7 +75,7 @@ abstract class KotlinIrLinker(
|
||||
if (unlinkedDeclarationsSupport.allowUnboundSymbols)
|
||||
referenceDeserializedSymbol(symbolTable, null, symbolKind, idSignature)
|
||||
else
|
||||
throw SignatureIdNotFoundInModuleWithDependencies(
|
||||
SignatureIdNotFoundInModuleWithDependencies(
|
||||
idSignature = idSignature,
|
||||
problemModuleDeserializer = moduleDeserializer,
|
||||
allModuleDeserializers = deserializersForModules.values,
|
||||
@@ -86,7 +86,7 @@ abstract class KotlinIrLinker(
|
||||
|
||||
fun resolveModuleDeserializer(module: ModuleDescriptor, idSignature: IdSignature?): IrModuleDeserializer {
|
||||
return deserializersForModules[module.name.asString()]
|
||||
?: throw NoDeserializerForModule(module.name, idSignature).raiseIssue(messageLogger)
|
||||
?: NoDeserializerForModule(module.name, idSignature).raiseIssue(messageLogger)
|
||||
}
|
||||
|
||||
protected abstract fun createModuleDeserializer(
|
||||
@@ -165,7 +165,7 @@ abstract class KotlinIrLinker(
|
||||
?: return null
|
||||
} catch (e: IrSymbolTypeMismatchException) {
|
||||
if (!unlinkedDeclarationsSupport.allowUnboundSymbols) {
|
||||
throw SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger)
|
||||
SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-19
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.backend.common.serialization.linkerissues
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
sealed class IrDeserializationException(message: String) : Exception(message) {
|
||||
override val message: String get() = super.message!!
|
||||
@@ -22,20 +20,3 @@ class IrSymbolTypeMismatchException(
|
||||
class IrDisallowedErrorNode(
|
||||
clazz: Class<out IrAnnotationContainer>
|
||||
) : IrDeserializationException("${clazz::class.java.simpleName} found but error nodes are not allowed.")
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
internal inline fun <reified T : IrSymbol> checkSymbolType(symbol: IrSymbol): T {
|
||||
contract {
|
||||
returns() implies (symbol is T)
|
||||
}
|
||||
|
||||
if (symbol !is T) throw IrSymbolTypeMismatchException(T::class.java, symbol) else return symbol
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
internal inline fun <reified T : IrAnnotationContainer> checkErrorNodesAllowed(errorNodesAllowed: Boolean) {
|
||||
contract {
|
||||
returns() implies errorNodesAllowed
|
||||
}
|
||||
if (!errorNodesAllowed) throw IrDisallowedErrorNode(T::class.java)
|
||||
}
|
||||
|
||||
+46
-6
@@ -5,11 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization.linkerissues
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.CompilationErrorException
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictKind.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictKind.Companion.mostSignificantConflictKind
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictReason.Companion.mostSignificantConflictReasons
|
||||
import org.jetbrains.kotlin.ir.linkage.KotlinIrLinkerInternalException
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -18,12 +20,50 @@ import org.jetbrains.kotlin.utils.ResolvedDependencyId
|
||||
import org.jetbrains.kotlin.utils.ResolvedDependencyVersion
|
||||
import kotlin.Comparator
|
||||
|
||||
abstract class KotlinIrLinkerIssue {
|
||||
/**
|
||||
* TODO: Currently, [KotlinIrLinkerInternalException] is only needed to show the stacktrace to the user.
|
||||
* If stacktrace is not needed it's enough to throw [CompilationErrorException] to interrupt the compilation process.
|
||||
* But, probably, we don't even need to show the stacktrace, so we could probably get rid of [KotlinIrLinkerInternalException] at all.
|
||||
*/
|
||||
abstract class KotlinIrLinkerIssue(private val needStacktrace: Boolean) {
|
||||
protected abstract val errorMessage: String
|
||||
|
||||
fun raiseIssue(messageLogger: IrMessageLogger): KotlinIrLinkerInternalException {
|
||||
fun raiseIssue(messageLogger: IrMessageLogger): Nothing {
|
||||
messageLogger.report(IrMessageLogger.Severity.ERROR, errorMessage, null)
|
||||
throw KotlinIrLinkerInternalException()
|
||||
throw if (needStacktrace) KotlinIrLinkerInternalException() else CompilationErrorException()
|
||||
}
|
||||
}
|
||||
|
||||
class UnexpectedUnboundIrSymbols(unboundSymbols: Set<IrSymbol>, whenDetected: String) : KotlinIrLinkerIssue(needStacktrace = false) {
|
||||
override val errorMessage = buildString {
|
||||
// cause:
|
||||
append("There ").append(
|
||||
when (val count = unboundSymbols.size) {
|
||||
1 -> "is still an unbound symbol"
|
||||
else -> "are still $count unbound symbols"
|
||||
}
|
||||
).append(" ").append(whenDetected).append(":\n")
|
||||
unboundSymbols.joinTo(this, separator = "\n")
|
||||
|
||||
// explanation:
|
||||
append("\n\nThis could happen if there are two libraries, where one library was compiled against the different version")
|
||||
append(" of the other library than the one currently used in the project.")
|
||||
|
||||
// action items:
|
||||
append(" Please check that the project configuration is correct and has consistent versions of dependencies.")
|
||||
if (unboundSymbols.any { looksLikeEnumEntries(it.signature) }) {
|
||||
append("\n\nAnother possible reason is that some parts of the project are compiled with EnumEntries language feature enabled,")
|
||||
append(" but other parts or used libraries are compiled with EnumEntries language feature disabled.")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun looksLikeEnumEntries(signature: IdSignature?) : Boolean = when (signature) {
|
||||
is IdSignature.AccessorSignature -> looksLikeEnumEntries(signature.propertySignature)
|
||||
is IdSignature.CompositeSignature -> looksLikeEnumEntries(signature.inner)
|
||||
is IdSignature.CommonSignature -> signature.shortName == "entries"
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +72,7 @@ class SignatureIdNotFoundInModuleWithDependencies(
|
||||
private val problemModuleDeserializer: IrModuleDeserializer,
|
||||
private val allModuleDeserializers: Collection<IrModuleDeserializer>,
|
||||
private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
|
||||
) : KotlinIrLinkerIssue() {
|
||||
) : KotlinIrLinkerIssue(needStacktrace = false) {
|
||||
override val errorMessage = try {
|
||||
computeErrorMessage()
|
||||
} catch (e: Throwable) {
|
||||
@@ -89,7 +129,7 @@ class SignatureIdNotFoundInModuleWithDependencies(
|
||||
}
|
||||
}
|
||||
|
||||
class NoDeserializerForModule(moduleName: Name, idSignature: IdSignature?) : KotlinIrLinkerIssue() {
|
||||
class NoDeserializerForModule(moduleName: Name, idSignature: IdSignature?) : KotlinIrLinkerIssue(needStacktrace = false) {
|
||||
override val errorMessage = buildString {
|
||||
append("Could not load module ${moduleName.asString()}")
|
||||
if (idSignature != null) append(" in an attempt to find deserializer for symbol ${idSignature.render()}.")
|
||||
@@ -100,7 +140,7 @@ class SymbolTypeMismatch(
|
||||
private val cause: IrSymbolTypeMismatchException,
|
||||
private val allModuleDeserializers: Collection<IrModuleDeserializer>,
|
||||
private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
|
||||
) : KotlinIrLinkerIssue() {
|
||||
) : KotlinIrLinkerIssue(needStacktrace = true) {
|
||||
override val errorMessage = try {
|
||||
computeErrorMessage()
|
||||
} catch (e: Throwable) {
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.serialization.linkerissues
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.allUnbound
|
||||
import org.jetbrains.kotlin.ir.util.irMessageLogger
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
internal inline fun <reified T : IrSymbol> checkSymbolType(symbol: IrSymbol): T {
|
||||
contract {
|
||||
returns() implies (symbol is T)
|
||||
}
|
||||
|
||||
if (symbol !is T) throw IrSymbolTypeMismatchException(T::class.java, symbol) else return symbol
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
internal inline fun <reified T : IrAnnotationContainer> checkErrorNodesAllowed(errorNodesAllowed: Boolean) {
|
||||
contract {
|
||||
returns() implies errorNodesAllowed
|
||||
}
|
||||
if (!errorNodesAllowed) throw IrDisallowedErrorNode(T::class.java)
|
||||
}
|
||||
|
||||
// N.B. Checks for absence of unbound symbols only when unbound symbols are not allowed.
|
||||
fun KotlinIrLinker.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: String) {
|
||||
if (!unlinkedDeclarationsSupport.allowUnboundSymbols)
|
||||
messageLogger.checkNoUnboundSymbols(symbolTable, whenDetected)
|
||||
}
|
||||
|
||||
// N.B. Always checks for absence of unbound symbols. The condition whether this check should be applied is controlled outside.
|
||||
fun IrMessageLogger.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: String) {
|
||||
val unboundSymbols = symbolTable.allUnbound
|
||||
if (unboundSymbols.isNotEmpty())
|
||||
UnexpectedUnboundIrSymbols(unboundSymbols, whenDetected).raiseIssue(this)
|
||||
}
|
||||
|
||||
// N.B. Always checks for absence of unbound symbols. The condition whether this check should be applied is controlled outside.
|
||||
fun CompilerConfiguration.checkNoUnboundSymbols(symbolTable: SymbolTable, whenDetected: String) {
|
||||
val unboundSymbols = symbolTable.allUnbound
|
||||
if (unboundSymbols.isNotEmpty())
|
||||
UnexpectedUnboundIrSymbols(unboundSymbols, whenDetected).raiseIssue(irMessageLogger)
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
+2
-6
@@ -34,11 +34,7 @@ import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsFactories
|
||||
import org.jetbrains.kotlin.ir.backend.js.TopDownAnalyzerFacadeForJSIR
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||
@@ -258,7 +254,7 @@ class ClassicFrontendFacade(
|
||||
val resolvedLibraries = jsResolveLibraries(
|
||||
names,
|
||||
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||
configuration.resolverLogger
|
||||
).getFullResolvedList()
|
||||
|
||||
var builtInsModule: KotlinBuiltIns? = null
|
||||
|
||||
+2
-3
@@ -26,8 +26,7 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.backend.js.resolverLogger
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
|
||||
@@ -262,7 +261,7 @@ fun resolveJsLibraries(
|
||||
): List<KotlinResolvedLibrary> {
|
||||
val paths = getAllJsDependenciesPaths(module, testServices)
|
||||
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
|
||||
val logger = configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||
val logger = configuration.resolverLogger
|
||||
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList()
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||
@@ -96,7 +97,11 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
|
||||
protected open fun generateIrModule(ignoreErrors: Boolean = false): IrModuleFragment {
|
||||
assert(myFiles != null) { "myFiles not initialized" }
|
||||
assert(myEnvironment != null) { "myEnvironment not initialized" }
|
||||
val psi2Ir = Psi2IrTranslator(myEnvironment.configuration.languageVersionSettings, Psi2IrConfiguration(ignoreErrors))
|
||||
val psi2Ir = Psi2IrTranslator(
|
||||
myEnvironment.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(ignoreErrors),
|
||||
myEnvironment.configuration::checkNoUnboundSymbols
|
||||
)
|
||||
return doGenerateIrModule(psi2Ir)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataIncrementalSerializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
@@ -257,12 +258,21 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
|
||||
return md
|
||||
}
|
||||
|
||||
private fun generateIrModule(stdlib: KotlinLibrary, ignoreErrors: Boolean, expectActualSymbols: MutableMap<DeclarationDescriptor, IrSymbol>): Pair<IrModuleFragment, BindingContext> {
|
||||
private fun generateIrModule(
|
||||
stdlib: KotlinLibrary,
|
||||
ignoreErrors: Boolean,
|
||||
expectActualSymbols: MutableMap<DeclarationDescriptor, IrSymbol>
|
||||
): Pair<IrModuleFragment, BindingContext> {
|
||||
val stdlibDescriptor = getModuleDescriptor(stdlib)
|
||||
|
||||
val ktFiles = myFiles.psiFiles
|
||||
|
||||
val psi2Ir = Psi2IrTranslator(myEnvironment.configuration.languageVersionSettings, Psi2IrConfiguration(ignoreErrors))
|
||||
val messageLogger = IrMessageLogger.None
|
||||
val psi2Ir = Psi2IrTranslator(
|
||||
myEnvironment.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(ignoreErrors),
|
||||
myEnvironment.configuration::checkNoUnboundSymbols
|
||||
)
|
||||
val analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(
|
||||
ktFiles, myEnvironment.project, myEnvironment.configuration,
|
||||
moduleDescriptors = listOf(stdlibDescriptor),
|
||||
@@ -280,7 +290,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
|
||||
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl, NameProvider.DEFAULT)
|
||||
val context = psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
|
||||
val irBuiltIns = context.irBuiltIns
|
||||
val irLinker = JsIrLinker(moduleDescriptor, IrMessageLogger.None, irBuiltIns, symbolTable, null)
|
||||
val irLinker = JsIrLinker(moduleDescriptor, messageLogger, irBuiltIns, symbolTable, null)
|
||||
irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib)
|
||||
|
||||
return psi2Ir.generateModuleFragment(context, ktFiles, listOf(irLinker), emptyList(), expectActualSymbols) to bindingContext
|
||||
|
||||
+2
-2
@@ -692,12 +692,12 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
||||
|
||||
fun testUnreachableExtensionVarPropertyDeclaration() {
|
||||
val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null)
|
||||
assertEquals("Output:\n$output", ExitCode.INTERNAL_ERROR, exitCode)
|
||||
assertEquals("Output:\n$output", ExitCode.COMPILATION_ERROR, exitCode)
|
||||
}
|
||||
|
||||
fun testUnreachableExtensionValPropertyDeclaration() {
|
||||
val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null)
|
||||
assertEquals("Output:\n$output", ExitCode.INTERNAL_ERROR, exitCode)
|
||||
assertEquals("Output:\n$output", ExitCode.COMPILATION_ERROR, exitCode)
|
||||
}
|
||||
|
||||
fun testAnonymousObjectTypeMetadata() {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.build.report.DoNothingBuildReporter
|
||||
@@ -462,13 +463,14 @@ class GenerateIrRuntime {
|
||||
}
|
||||
|
||||
private fun doPsi2Ir(files: List<KtFile>, analysisResult: AnalysisResult): IrModuleFragment {
|
||||
val psi2Ir = Psi2IrTranslator(languageVersionSettings, Psi2IrConfiguration())
|
||||
val messageLogger = IrMessageLogger.None
|
||||
val psi2Ir = Psi2IrTranslator(languageVersionSettings, Psi2IrConfiguration(), messageLogger::checkNoUnboundSymbols)
|
||||
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl)
|
||||
val psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
||||
|
||||
val irLinker = JsIrLinker(
|
||||
psi2IrContext.moduleDescriptor,
|
||||
IrMessageLogger.None,
|
||||
messageLogger,
|
||||
psi2IrContext.irBuiltIns,
|
||||
psi2IrContext.symbolTable,
|
||||
null
|
||||
@@ -476,7 +478,7 @@ class GenerateIrRuntime {
|
||||
|
||||
val irProviders = listOf(irLinker)
|
||||
|
||||
val psi2IrTranslator = Psi2IrTranslator(languageVersionSettings, psi2IrContext.configuration)
|
||||
val psi2IrTranslator = Psi2IrTranslator(languageVersionSettings, psi2IrContext.configuration, messageLogger::checkNoUnboundSymbols)
|
||||
return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, emptyList(), null)
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
fun executorWithBoxExport(
|
||||
currentModule: IrModuleFragment,
|
||||
allModules: Collection<IrModuleFragment>,
|
||||
deserializer: JsIrLinker,
|
||||
irLinker: JsIrLinker,
|
||||
configuration: CompilerConfiguration,
|
||||
dirtyFiles: Collection<IrFile>,
|
||||
exportedDeclarations: Set<FqName>,
|
||||
@@ -222,7 +222,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
|
||||
return buildCacheForModuleFiles(
|
||||
mainModule = currentModule,
|
||||
allModules = allModules,
|
||||
deserializer = deserializer,
|
||||
irLinker = irLinker,
|
||||
configuration = configuration,
|
||||
dirtyFiles = dirtyFiles,
|
||||
exportedDeclarations = exportedDeclarations + FqName(BOX_FUNCTION_NAME),
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.js.test.converters
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -24,8 +25,8 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransf
|
||||
import org.jetbrains.kotlin.ir.backend.js.SourceMapsInfo
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.irMessageLogger
|
||||
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.test.handlers.JsBoxRunner.Companion.TEST_FUNCTION
|
||||
@@ -212,7 +213,7 @@ class JsIrBackendFacade(
|
||||
private fun loadIrFromKlib(module: TestModule, configuration: CompilerConfiguration): IrModuleInfo {
|
||||
val filesToLoad = module.files.takeIf { !firstTimeCompilation }?.map { "/${it.relativePath}" }?.toSet()
|
||||
|
||||
val messageLogger = configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None
|
||||
val messageLogger = configuration.irMessageLogger
|
||||
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImplForJsIC(WholeWorldStageController()),)
|
||||
|
||||
val moduleDescriptor = testServices.moduleDescriptorProvider.getModuleDescriptor(module)
|
||||
@@ -239,13 +240,14 @@ class JsIrBackendFacade(
|
||||
inputArtifact: ClassicFrontendOutputArtifact
|
||||
): IrModuleInfo {
|
||||
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 symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImplForJsIC(WholeWorldStageController()),)
|
||||
val verifySignatures = JsEnvironmentConfigurationDirectives.SKIP_MANGLE_VERIFICATION !in module.directives
|
||||
|
||||
val psi2Ir = Psi2IrTranslator(
|
||||
configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(errorPolicy.allowErrors)
|
||||
Psi2IrConfiguration(errorPolicy.allowErrors),
|
||||
messageLogger::checkNoUnboundSymbols
|
||||
)
|
||||
val psi2IrContext = psi2Ir.createGeneratorContext(
|
||||
inputArtifact.analysisResult.moduleDescriptor,
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.irMessageLogger
|
||||
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.test.utils.JsIrIncrementalDataProvider
|
||||
@@ -56,7 +56,7 @@ class JsKlibBackendFacade(
|
||||
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
||||
project,
|
||||
configuration,
|
||||
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
|
||||
configuration.irMessageLogger,
|
||||
inputArtifact.bindingContext,
|
||||
inputArtifact.sourceFiles,
|
||||
klibPath = outputFile,
|
||||
@@ -76,7 +76,7 @@ class JsKlibBackendFacade(
|
||||
val lib = jsResolveLibraries(
|
||||
dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile),
|
||||
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
|
||||
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger()
|
||||
configuration.resolverLogger
|
||||
).getFullResolvedList().last().library
|
||||
|
||||
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
|
||||
|
||||
+7
-2
@@ -4,6 +4,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.DescriptorByIdSignatureFinderImpl
|
||||
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.konan.descriptors.isForwardDeclarationModule
|
||||
@@ -52,7 +53,11 @@ internal fun Context.psiToIr(
|
||||
|
||||
val allowUnboundSymbols = config.configuration[KonanConfigKeys.PARTIAL_LINKAGE] ?: false
|
||||
|
||||
val translator = Psi2IrTranslator(config.configuration.languageVersionSettings, Psi2IrConfiguration(ignoreErrors = false, allowUnboundSymbols = allowUnboundSymbols))
|
||||
val translator = Psi2IrTranslator(
|
||||
config.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(ignoreErrors = false, allowUnboundSymbols = allowUnboundSymbols),
|
||||
messageLogger::checkNoUnboundSymbols
|
||||
)
|
||||
val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
|
||||
|
||||
val pluginExtensions = IrGenerationExtension.getInstances(config.project)
|
||||
@@ -211,7 +216,7 @@ internal fun Context.psiToIr(
|
||||
// Enable lazy IR genration for newly-created symbols inside BE
|
||||
stubGenerator.unboundSymbolGeneration = true
|
||||
|
||||
symbolTable.noUnboundLeft("Unbound symbols left after linker")
|
||||
messageLogger.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
|
||||
mainModule.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
|
||||
|
||||
|
||||
+6
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.scripting.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
|
||||
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.checkNoUnboundSymbols
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
@@ -67,7 +68,11 @@ class JsCoreScriptingCompiler(
|
||||
|
||||
val files = listOf(snippetKtFile)
|
||||
val (bindingContext, module) = analysisResult
|
||||
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, Psi2IrConfiguration())
|
||||
val psi2ir = Psi2IrTranslator(
|
||||
environment.configuration.languageVersionSettings,
|
||||
Psi2IrConfiguration(),
|
||||
environment.configuration::checkNoUnboundSymbols
|
||||
)
|
||||
|
||||
val generatorExtensions =
|
||||
if (replCompilerState == null) GeneratorExtensions()
|
||||
|
||||
+2
-5
@@ -17,10 +17,7 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateJsCode
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.NameTables
|
||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
@@ -38,7 +35,7 @@ class JsScriptDependencyCompiler(
|
||||
fun compile(dependencies: List<ModuleDescriptor>): String {
|
||||
val builtIns: KotlinBuiltIns = dependencies.single { it.allDependencyModules.isEmpty() }.builtIns
|
||||
val languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT
|
||||
val messageLogger = configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
|
||||
val messageLogger = configuration.irMessageLogger
|
||||
val moduleName = Name.special("<script-dependencies>")
|
||||
val storageManager = LockBasedStorageManager.NO_LOCKS
|
||||
val moduleDescriptor = ModuleDescriptorImpl(moduleName, storageManager, builtIns, null).also {
|
||||
|
||||
Reference in New Issue
Block a user