[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
@@ -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.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel 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.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity 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.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.SymbolTable 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.backend.ast.JsProgram
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import java.io.File import java.io.File
@@ -95,7 +94,7 @@ fun compileIr(
moduleToName: Map<IrModuleFragment, String>, moduleToName: Map<IrModuleFragment, String>,
irBuiltIns: IrBuiltIns, irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable, symbolTable: SymbolTable,
deserializer: JsIrLinker, irLinker: JsIrLinker,
phaseConfig: PhaseConfig, phaseConfig: PhaseConfig,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
dceRuntimeDiagnostic: RuntimeDiagnostic?, dceRuntimeDiagnostic: RuntimeDiagnostic?,
@@ -114,8 +113,6 @@ fun compileIr(
is MainModule.Klib -> dependencyModules is MainModule.Klib -> dependencyModules
} }
val allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val context = JsIrBackendContext( val context = JsIrBackendContext(
moduleDescriptor, moduleDescriptor,
irBuiltIns, irBuiltIns,
@@ -133,13 +130,11 @@ fun compileIr(
) )
// Load declarations referenced during `context` initialization // Load declarations referenced during `context` initialization
val irProviders = listOf(deserializer) val irProviders = listOf(irLinker)
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
deserializer.postProcess() irLinker.postProcess()
if (!allowUnboundSymbols) { irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
symbolTable.noUnboundLeft("Unbound symbols at the end of linker")
}
allModules.forEach { module -> allModules.forEach { module ->
collectNativeImplementations(context, 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.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.PhaserState 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.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.backend.js.lower.collectNativeImplementations 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.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator 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.js.config.RuntimeDiagnostic
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
fun compileWithIC( fun compileWithIC(
mainModule: IrModuleFragment, mainModule: IrModuleFragment,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
deserializer: JsIrLinker, irLinker: JsIrLinker,
allModules: Collection<IrModuleFragment>, allModules: Collection<IrModuleFragment>,
filesToLower: Collection<IrFile>, filesToLower: Collection<IrFile>,
mainArguments: List<String>? = null, mainArguments: List<String>? = null,
@@ -63,11 +63,11 @@ fun compileWithIC(
) )
// Load declarations referenced during `context` initialization // Load declarations referenced during `context` initialization
val irProviders = listOf(deserializer) val irProviders = listOf(irLinker)
ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
deserializer.postProcess() irLinker.postProcess()
symbolTable.noUnboundLeft("Unbound symbols at the end of linker") irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
allModules.forEach { allModules.forEach {
collectNativeImplementations(context, it) collectNativeImplementations(context, it)
@@ -26,7 +26,7 @@ fun interface CacheExecutor {
fun execute( fun execute(
mainModule: IrModuleFragment, mainModule: IrModuleFragment,
allModules: Collection<IrModuleFragment>, allModules: Collection<IrModuleFragment>,
deserializer: JsIrLinker, irLinker: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<IrFile>, dirtyFiles: Collection<IrFile>,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
@@ -87,7 +87,7 @@ class CacheUpdater(
val allResolvedDependencies = jsResolveLibraries( val allResolvedDependencies = jsResolveLibraries(
allModules, allModules,
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(), compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger() compilerConfiguration.resolverLogger
) )
return allResolvedDependencies.getFullList().associateBy { KotlinLibraryFile(it) } return allResolvedDependencies.getFullList().associateBy { KotlinLibraryFile(it) }
@@ -568,7 +568,7 @@ class CacheUpdater(
val rebuiltFragments = executor.execute( val rebuiltFragments = executor.execute(
mainModule = loadedIr.loadedFragments[mainLibraryFile] ?: notFoundIcError("main lib loaded fragment", mainLibraryFile), mainModule = loadedIr.loadedFragments[mainLibraryFile] ?: notFoundIcError("main lib loaded fragment", mainLibraryFile),
allModules = loadedIr.loadedFragments.values, allModules = loadedIr.loadedFragments.values,
deserializer = loadedIr.linker, irLinker = loadedIr.linker,
configuration = compilerConfiguration, configuration = compilerConfiguration,
dirtyFiles = loadedIr.loadedFragments.flatMap { (libFile, libFragment) -> dirtyFiles = loadedIr.loadedFragments.flatMap { (libFile, libFragment) ->
dirtyFileExports[libFile]?.let { libDirtyFiles -> dirtyFileExports[libFile]?.let { libDirtyFiles ->
@@ -617,7 +617,7 @@ fun rebuildCacheForDirtyFiles(
return currentIrModule to buildCacheForModuleFiles( return currentIrModule to buildCacheForModuleFiles(
mainModule = currentIrModule, mainModule = currentIrModule,
allModules = irModules.values, allModules = irModules.values,
deserializer = jsIrLinker, irLinker = jsIrLinker,
configuration = configuration, configuration = configuration,
dirtyFiles = dirtyIrFiles, dirtyFiles = dirtyIrFiles,
exportedDeclarations = exportedDeclarations, exportedDeclarations = exportedDeclarations,
@@ -628,7 +628,7 @@ fun rebuildCacheForDirtyFiles(
fun buildCacheForModuleFiles( fun buildCacheForModuleFiles(
mainModule: IrModuleFragment, mainModule: IrModuleFragment,
allModules: Collection<IrModuleFragment>, allModules: Collection<IrModuleFragment>,
deserializer: JsIrLinker, irLinker: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<IrFile>, dirtyFiles: Collection<IrFile>,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
@@ -639,7 +639,7 @@ fun buildCacheForModuleFiles(
allModules = allModules, allModules = allModules,
filesToLower = dirtyFiles, filesToLower = dirtyFiles,
configuration = configuration, configuration = configuration,
deserializer = deserializer, irLinker = irLinker,
mainArguments = mainArguments, mainArguments = mainArguments,
exportedDeclarations = exportedDeclarations, exportedDeclarations = exportedDeclarations,
) )
@@ -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.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator 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.SymbolTable
import org.jetbrains.kotlin.ir.util.irMessageLogger
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -36,13 +36,12 @@ internal class JsIrLinkerLoader(
) { ) {
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
private fun createLinker(loadedModules: Map<ModuleDescriptor, KotlinLibrary>): JsIrLinker { private fun createLinker(loadedModules: Map<ModuleDescriptor, KotlinLibrary>): JsIrLinker {
val logger = compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
val signaturer = IdSignatureDescriptor(JsManglerDesc) val signaturer = IdSignatureDescriptor(JsManglerDesc)
val symbolTable = SymbolTable(signaturer, irFactory) val symbolTable = SymbolTable(signaturer, irFactory)
val moduleDescriptor = loadedModules.keys.last() val moduleDescriptor = loadedModules.keys.last()
val typeTranslator = TypeTranslatorImpl(symbolTable, compilerConfiguration.languageVersionSettings, moduleDescriptor) val typeTranslator = TypeTranslatorImpl(symbolTable, compilerConfiguration.languageVersionSettings, moduleDescriptor)
val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable) 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> { private fun loadModules(): Map<ModuleDescriptor, KotlinLibrary> {
@@ -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.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl 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.intrinsics.IrIntrinsicMethods
import org.jetbrains.kotlin.backend.jvm.ir.getIoFile import org.jetbrains.kotlin.backend.jvm.ir.getIoFile
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
@@ -113,15 +114,16 @@ open class JvmIrCodegenFactory(
val symbolTable = SymbolTable(signaturer, IrFactoryImpl) val symbolTable = SymbolTable(signaturer, IrFactoryImpl)
mangler to symbolTable mangler to symbolTable
} }
val messageLogger = input.configuration.irMessageLogger
val psi2ir = Psi2IrTranslator( val psi2ir = Psi2IrTranslator(
input.languageVersionSettings, input.languageVersionSettings,
Psi2IrConfiguration( Psi2IrConfiguration(
input.ignoreErrors, input.ignoreErrors,
allowUnboundSymbols = false, allowUnboundSymbols = false,
input.skipBodies, input.skipBodies
) ),
messageLogger::checkNoUnboundSymbols
) )
val messageLogger = input.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
val psi2irContext = psi2ir.createGeneratorContext( val psi2irContext = psi2ir.createGeneratorContext(
input.module, input.module,
input.bindingContext, input.bindingContext,
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmSerializeIrMode import org.jetbrains.kotlin.config.JvmSerializeIrMode
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile 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 import org.jetbrains.kotlin.name.FqName
class JvmIrSerializerImpl(private val configuration: CompilerConfiguration) : JvmIrSerializer { class JvmIrSerializerImpl(private val configuration: CompilerConfiguration) : JvmIrSerializer {
@@ -34,7 +34,7 @@ class JvmIrSerializerImpl(private val configuration: CompilerConfiguration) : Jv
private fun makeSerializerSession(fileClassFqName: FqName) = private fun makeSerializerSession(fileClassFqName: FqName) =
JvmIrSerializerSession( JvmIrSerializerSession(
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None, configuration.irMessageLogger,
declarationTable, declarationTable,
mutableMapOf(), mutableMapOf(),
configuration.get(JVMConfigurationKeys.SERIALIZE_IR) ?: JvmSerializeIrMode.NONE, 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.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel 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.WasmCompiledModuleFragment
import org.jetbrains.kotlin.backend.wasm.ir2wasm.WasmModuleFragmentGenerator import org.jetbrains.kotlin.backend.wasm.ir2wasm.WasmModuleFragmentGenerator
import org.jetbrains.kotlin.backend.wasm.lower.markExportedDeclarations 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.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator 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.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.wasm.ir.convertors.WasmIrToBinary import org.jetbrains.kotlin.wasm.ir.convertors.WasmIrToBinary
@@ -35,7 +35,7 @@ fun compileToLoweredIr(
): Pair<List<IrModuleFragment>, WasmBackendContext> { ): Pair<List<IrModuleFragment>, WasmBackendContext> {
val mainModule = depsDescriptors.mainModule val mainModule = depsDescriptors.mainModule
val configuration = depsDescriptors.compilerConfiguration val configuration = depsDescriptors.compilerConfiguration
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = loadIr( val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, irLinker) = loadIr(
depsDescriptors, depsDescriptors,
irFactory, irFactory,
verifySignatures = false, verifySignatures = false,
@@ -52,15 +52,15 @@ fun compileToLoweredIr(
// Load declarations referenced during `context` initialization // Load declarations referenced during `context` initialization
allModules.forEach { allModules.forEach {
ExternalDependenciesGenerator(symbolTable, listOf(deserializer)).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
} }
// Create stubs // Create stubs
ExternalDependenciesGenerator(symbolTable, listOf(deserializer)).generateUnboundSymbolsAsDependencies() ExternalDependenciesGenerator(symbolTable, listOf(irLinker)).generateUnboundSymbolsAsDependencies()
allModules.forEach { it.patchDeclarationParents() } allModules.forEach { it.patchDeclarationParents() }
deserializer.postProcess() irLinker.postProcess()
symbolTable.noUnboundLeft("Unbound symbols at the end of linker") irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
for (module in allModules) for (module in allModules)
for (file in module.files) 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.linkage.IrProvider
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.noUnboundLeft
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
@@ -44,6 +43,7 @@ fun interface Psi2IrPostprocessingStep {
class Psi2IrTranslator( class Psi2IrTranslator(
val languageVersionSettings: LanguageVersionSettings, val languageVersionSettings: LanguageVersionSettings,
val configuration: Psi2IrConfiguration, val configuration: Psi2IrConfiguration,
private val checkNoUnboundSymbols: (SymbolTable, String) -> Unit
) { ) {
private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>() private val postprocessingSteps = SmartList<Psi2IrPostprocessingStep>()
@@ -80,6 +80,7 @@ class Psi2IrTranslator(
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null, expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
fragmentInfo: EvaluatorFragmentInfo? = null fragmentInfo: EvaluatorFragmentInfo? = null
): IrModuleFragment { ): IrModuleFragment {
val moduleGenerator = fragmentInfo?.let { val moduleGenerator = fragmentInfo?.let {
FragmentModuleGenerator(context, it) FragmentModuleGenerator(context, it)
} ?: ModuleGenerator(context, expectDescriptorToSymbol) } ?: ModuleGenerator(context, expectDescriptorToSymbol)
@@ -92,9 +93,7 @@ class Psi2IrTranslator(
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders) moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
deserializers.forEach { it.postProcess() } deserializers.forEach { it.postProcess() }
if (!context.configuration.allowUnboundSymbols) { context.checkNoUnboundSymbols { "after generation of IR module ${irModule.name.asString()}" }
context.symbolTable.noUnboundLeft("Unbound symbols not allowed\n")
}
postprocessingSteps.forEach { it.invoke(irModule) } postprocessingSteps.forEach { it.invoke(irModule) }
// assert(context.symbolTable.allUnbound.isEmpty()) // TODO: fix IrPluginContext to make it not produce additional external reference // 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 // TODO: remove it once plugin API improved
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders) moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
deserializers.forEach { it.postProcess() } deserializers.forEach { it.postProcess() }
context.checkNoUnboundSymbols { "after applying all post-processing steps for the generated IR module ${irModule.name.asString()}" }
return irModule return irModule
} }
private fun GeneratorContext.checkNoUnboundSymbols(whenDetected: () -> String) {
if (!configuration.allowUnboundSymbols)
checkNoUnboundSymbols(symbolTable, whenDetected())
}
} }
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.util package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.config.CompilerConfigurationKey
interface IrMessageLogger { interface IrMessageLogger {
@@ -25,4 +26,7 @@ interface IrMessageLogger {
@JvmStatic @JvmStatic
val IR_MESSAGE_LOGGER = CompilerConfigurationKey<IrMessageLogger>("ir message logger") 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(unboundTypeAliases)
addUnbound(unboundTypeParameters) addUnbound(unboundTypeParameters)
} }
fun SymbolTable.noUnboundLeft(message: String) {
val unbound = this.allUnbound
assert(unbound.isEmpty()) {
message + "\n" + unbound.joinToString("\n")
}
}
@@ -51,7 +51,7 @@ abstract class KotlinIrLinker(
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension> 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 protected open val userVisibleIrModulesSupport: UserVisibleIrModulesSupport get() = UserVisibleIrModulesSupport.DEFAULT
fun deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled( fun deserializeOrReturnUnboundIrSymbolIfPartialLinkageEnabled(
@@ -75,7 +75,7 @@ abstract class KotlinIrLinker(
if (unlinkedDeclarationsSupport.allowUnboundSymbols) if (unlinkedDeclarationsSupport.allowUnboundSymbols)
referenceDeserializedSymbol(symbolTable, null, symbolKind, idSignature) referenceDeserializedSymbol(symbolTable, null, symbolKind, idSignature)
else else
throw SignatureIdNotFoundInModuleWithDependencies( SignatureIdNotFoundInModuleWithDependencies(
idSignature = idSignature, idSignature = idSignature,
problemModuleDeserializer = moduleDeserializer, problemModuleDeserializer = moduleDeserializer,
allModuleDeserializers = deserializersForModules.values, allModuleDeserializers = deserializersForModules.values,
@@ -86,7 +86,7 @@ abstract class KotlinIrLinker(
fun resolveModuleDeserializer(module: ModuleDescriptor, idSignature: IdSignature?): IrModuleDeserializer { fun resolveModuleDeserializer(module: ModuleDescriptor, idSignature: IdSignature?): IrModuleDeserializer {
return deserializersForModules[module.name.asString()] return deserializersForModules[module.name.asString()]
?: throw NoDeserializerForModule(module.name, idSignature).raiseIssue(messageLogger) ?: NoDeserializerForModule(module.name, idSignature).raiseIssue(messageLogger)
} }
protected abstract fun createModuleDeserializer( protected abstract fun createModuleDeserializer(
@@ -165,7 +165,7 @@ abstract class KotlinIrLinker(
?: return null ?: return null
} catch (e: IrSymbolTypeMismatchException) { } catch (e: IrSymbolTypeMismatchException) {
if (!unlinkedDeclarationsSupport.allowUnboundSymbols) { if (!unlinkedDeclarationsSupport.allowUnboundSymbols) {
throw SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger) SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger)
} }
} }
} }
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.backend.common.serialization.linkerissues
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
sealed class IrDeserializationException(message: String) : Exception(message) { sealed class IrDeserializationException(message: String) : Exception(message) {
override val message: String get() = super.message!! override val message: String get() = super.message!!
@@ -22,20 +20,3 @@ class IrSymbolTypeMismatchException(
class IrDisallowedErrorNode( class IrDisallowedErrorNode(
clazz: Class<out IrAnnotationContainer> clazz: Class<out IrAnnotationContainer>
) : IrDeserializationException("${clazz::class.java.simpleName} found but error nodes are not allowed.") ) : 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)
}
@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.backend.common.serialization.linkerissues 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.IrModuleDeserializer
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictKind.* 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.PotentialConflictKind.Companion.mostSignificantConflictKind
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictReason.Companion.mostSignificantConflictReasons import org.jetbrains.kotlin.backend.common.serialization.linkerissues.PotentialConflictReason.Companion.mostSignificantConflictReasons
import org.jetbrains.kotlin.ir.linkage.KotlinIrLinkerInternalException 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.IdSignature
import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -18,12 +20,50 @@ import org.jetbrains.kotlin.utils.ResolvedDependencyId
import org.jetbrains.kotlin.utils.ResolvedDependencyVersion import org.jetbrains.kotlin.utils.ResolvedDependencyVersion
import kotlin.Comparator 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 protected abstract val errorMessage: String
fun raiseIssue(messageLogger: IrMessageLogger): KotlinIrLinkerInternalException { fun raiseIssue(messageLogger: IrMessageLogger): Nothing {
messageLogger.report(IrMessageLogger.Severity.ERROR, errorMessage, null) 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 problemModuleDeserializer: IrModuleDeserializer,
private val allModuleDeserializers: Collection<IrModuleDeserializer>, private val allModuleDeserializers: Collection<IrModuleDeserializer>,
private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
) : KotlinIrLinkerIssue() { ) : KotlinIrLinkerIssue(needStacktrace = false) {
override val errorMessage = try { override val errorMessage = try {
computeErrorMessage() computeErrorMessage()
} catch (e: Throwable) { } 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 { override val errorMessage = buildString {
append("Could not load module ${moduleName.asString()}") append("Could not load module ${moduleName.asString()}")
if (idSignature != null) append(" in an attempt to find deserializer for symbol ${idSignature.render()}.") 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 cause: IrSymbolTypeMismatchException,
private val allModuleDeserializers: Collection<IrModuleDeserializer>, private val allModuleDeserializers: Collection<IrModuleDeserializer>,
private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport private val userVisibleIrModulesSupport: UserVisibleIrModulesSupport
) : KotlinIrLinkerIssue() { ) : KotlinIrLinkerIssue(needStacktrace = true) {
override val errorMessage = try { override val errorMessage = try {
computeErrorMessage() computeErrorMessage()
} catch (e: Throwable) { } catch (e: Throwable) {
@@ -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.lower.ExpectDeclarationRemover
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.* 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.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
@@ -84,30 +85,22 @@ private val CompilerConfiguration.metadataVersion
private val CompilerConfiguration.expectActualLinker: Boolean private val CompilerConfiguration.expectActualLinker: Boolean
get() = get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) ?: false 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 { override fun fatal(message: String): Nothing {
if (this == null) return DummyLogger messageLogger.report(IrMessageLogger.Severity.ERROR, message, null)
kotlin.error("FATAL ERROR: $message")
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")
} }
} }
}
class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile)
fun generateIrForKlibSerialization( fun generateIrForKlibSerialization(
project: Project, project: Project,
@@ -123,7 +116,7 @@ fun generateIrForKlibSerialization(
): IrModuleFragment { ): IrModuleFragment {
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER) val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT 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 allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val serializedIrFiles = mutableListOf<SerializedIrFile>() val serializedIrFiles = mutableListOf<SerializedIrFile>()
@@ -153,7 +146,11 @@ fun generateIrForKlibSerialization(
} }
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory) 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 psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
val irBuiltIns = psi2IrContext.irBuiltIns val irBuiltIns = psi2IrContext.irBuiltIns
@@ -215,7 +212,7 @@ fun generateKLib(
val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files
val configuration = depsDescriptors.compilerConfiguration val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library } 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 icData = mutableListOf<KotlinFileSerializedData>()
val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>() val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
@@ -311,7 +308,7 @@ fun loadIr(
val configuration = depsDescriptors.compilerConfiguration val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library } val allDependencies = depsDescriptors.allDependencies.map { it.library }
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT 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 allowUnboundSymbol = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val signaturer = IdSignatureDescriptor(JsManglerDesc) val signaturer = IdSignatureDescriptor(JsManglerDesc)
@@ -459,9 +456,6 @@ fun getIrModuleInfoForSourceFiles(
) )
val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, irLinker, messageLogger) 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. // TODO: not sure whether this check should be enabled by default. Add configuration key for it.
val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc)) val mangleChecker = ManglerChecker(JsManglerIr, Ir2DescriptorManglerAdapter(JsManglerDesc))
@@ -513,7 +507,8 @@ private fun preparePsi2Ir(
val analysisResult = depsDescriptors.jsFrontEndResult val analysisResult = depsDescriptors.jsFrontEndResult
val psi2Ir = Psi2IrTranslator( val psi2Ir = Psi2IrTranslator(
depsDescriptors.compilerConfiguration.languageVersionSettings, depsDescriptors.compilerConfiguration.languageVersionSettings,
Psi2IrConfiguration(errorIgnorancePolicy.allowErrors, allowUnboundSymbols) Psi2IrConfiguration(errorIgnorancePolicy.allowErrors, allowUnboundSymbols),
depsDescriptors.compilerConfiguration::checkNoUnboundSymbols
) )
return psi2Ir.createGeneratorContext( return psi2Ir.createGeneratorContext(
analysisResult.moduleDescriptor, analysisResult.moduleDescriptor,
@@ -530,8 +525,7 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null, expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null,
stubGenerator: DeclarationStubGenerator? = null stubGenerator: DeclarationStubGenerator? = null
): IrModuleFragment { ): IrModuleFragment {
val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration) val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, messageLogger::checkNoUnboundSymbols)
val extensions = IrGenerationExtension.getInstances(project) val extensions = IrGenerationExtension.getInstances(project)
if (extensions.isNotEmpty()) { if (extensions.isNotEmpty()) {
@@ -606,7 +600,7 @@ class ModulesStructure(
val allResolvedDependencies = jsResolveLibraries( val allResolvedDependencies = jsResolveLibraries(
dependencies, dependencies,
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(), compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
compilerConfiguration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger() compilerConfiguration.resolverLogger
) )
val allDependencies = allResolvedDependencies.getFullResolvedList() val allDependencies = allResolvedDependencies.getFullResolvedList()
@@ -34,11 +34,7 @@ import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.backend.js.JsFactories import org.jetbrains.kotlin.ir.backend.js.*
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.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
@@ -258,7 +254,7 @@ class ClassicFrontendFacade(
val resolvedLibraries = jsResolveLibraries( val resolvedLibraries = jsResolveLibraries(
names, names,
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(), configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger() configuration.resolverLogger
).getFullResolvedList() ).getFullResolvedList()
var builtInsModule: KotlinBuiltIns? = null var builtInsModule: KotlinBuiltIns? = null
@@ -26,8 +26,7 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
import org.jetbrains.kotlin.fir.session.FirSessionFactory import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
import org.jetbrains.kotlin.ir.backend.js.toResolverLogger import org.jetbrains.kotlin.ir.backend.js.resolverLogger
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary
@@ -262,7 +261,7 @@ fun resolveJsLibraries(
): List<KotlinResolvedLibrary> { ): List<KotlinResolvedLibrary> {
val paths = getAllJsDependenciesPaths(module, testServices) val paths = getAllJsDependenciesPaths(module, testServices)
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList() val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
val logger = configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger() val logger = configuration.resolverLogger
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList() 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.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl 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.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
@@ -96,7 +97,11 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() {
protected open fun generateIrModule(ignoreErrors: Boolean = false): IrModuleFragment { protected open fun generateIrModule(ignoreErrors: Boolean = false): IrModuleFragment {
assert(myFiles != null) { "myFiles not initialized" } assert(myFiles != null) { "myFiles not initialized" }
assert(myEnvironment != null) { "myEnvironment 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) 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.CompatibilityMode
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion 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.KlibMetadataIncrementalSerializer
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
@@ -257,12 +258,21 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
return md 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 stdlibDescriptor = getModuleDescriptor(stdlib)
val ktFiles = myFiles.psiFiles 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( val analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(
ktFiles, myEnvironment.project, myEnvironment.configuration, ktFiles, myEnvironment.project, myEnvironment.configuration,
moduleDescriptors = listOf(stdlibDescriptor), moduleDescriptors = listOf(stdlibDescriptor),
@@ -280,7 +290,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl, NameProvider.DEFAULT) val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl, NameProvider.DEFAULT)
val context = psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable) val context = psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
val irBuiltIns = context.irBuiltIns 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) irLinker.deserializeIrModuleHeader(stdlibDescriptor, stdlib)
return psi2Ir.generateModuleFragment(context, ktFiles, listOf(irLinker), emptyList(), expectActualSymbols) to bindingContext return psi2Ir.generateModuleFragment(context, ktFiles, listOf(irLinker), emptyList(), expectActualSymbols) to bindingContext
@@ -692,12 +692,12 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
fun testUnreachableExtensionVarPropertyDeclaration() { fun testUnreachableExtensionVarPropertyDeclaration() {
val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null) 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() { fun testUnreachableExtensionValPropertyDeclaration() {
val (output, exitCode) = compileKotlin("source.kt", tmpdir, expectedFileName = null) 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() { 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.phaser.invokeToplevel
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
import org.jetbrains.kotlin.backend.common.serialization.KlibIrVersion 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.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.build.report.DoNothingBuildReporter import org.jetbrains.kotlin.build.report.DoNothingBuildReporter
@@ -462,13 +463,14 @@ class GenerateIrRuntime {
} }
private fun doPsi2Ir(files: List<KtFile>, analysisResult: AnalysisResult): IrModuleFragment { 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 symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImpl)
val psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable) val psi2IrContext = psi2Ir.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
val irLinker = JsIrLinker( val irLinker = JsIrLinker(
psi2IrContext.moduleDescriptor, psi2IrContext.moduleDescriptor,
IrMessageLogger.None, messageLogger,
psi2IrContext.irBuiltIns, psi2IrContext.irBuiltIns,
psi2IrContext.symbolTable, psi2IrContext.symbolTable,
null null
@@ -476,7 +478,7 @@ class GenerateIrRuntime {
val irProviders = listOf(irLinker) 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) return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, emptyList(), null)
} }
@@ -213,7 +213,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
fun executorWithBoxExport( fun executorWithBoxExport(
currentModule: IrModuleFragment, currentModule: IrModuleFragment,
allModules: Collection<IrModuleFragment>, allModules: Collection<IrModuleFragment>,
deserializer: JsIrLinker, irLinker: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<IrFile>, dirtyFiles: Collection<IrFile>,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
@@ -222,7 +222,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
return buildCacheForModuleFiles( return buildCacheForModuleFiles(
mainModule = currentModule, mainModule = currentModule,
allModules = allModules, allModules = allModules,
deserializer = deserializer, irLinker = irLinker,
configuration = configuration, configuration = configuration,
dirtyFiles = dirtyFiles, dirtyFiles = dirtyFiles,
exportedDeclarations = exportedDeclarations + FqName(BOX_FUNCTION_NAME), 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.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.toPhaseMap 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.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration 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.SourceMapsInfo
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.TranslationMode
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImplForJsIC 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.SymbolTable
import org.jetbrains.kotlin.ir.util.irMessageLogger
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.test.handlers.JsBoxRunner.Companion.TEST_FUNCTION 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 { private fun loadIrFromKlib(module: TestModule, configuration: CompilerConfiguration): IrModuleInfo {
val filesToLoad = module.files.takeIf { !firstTimeCompilation }?.map { "/${it.relativePath}" }?.toSet() 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 symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImplForJsIC(WholeWorldStageController()),)
val moduleDescriptor = testServices.moduleDescriptorProvider.getModuleDescriptor(module) val moduleDescriptor = testServices.moduleDescriptorProvider.getModuleDescriptor(module)
@@ -239,13 +240,14 @@ class JsIrBackendFacade(
inputArtifact: ClassicFrontendOutputArtifact inputArtifact: ClassicFrontendOutputArtifact
): IrModuleInfo { ): IrModuleInfo {
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT 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 symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), IrFactoryImplForJsIC(WholeWorldStageController()),)
val verifySignatures = JsEnvironmentConfigurationDirectives.SKIP_MANGLE_VERIFICATION !in module.directives val verifySignatures = JsEnvironmentConfigurationDirectives.SKIP_MANGLE_VERIFICATION !in module.directives
val psi2Ir = Psi2IrTranslator( val psi2Ir = Psi2IrTranslator(
configuration.languageVersionSettings, configuration.languageVersionSettings,
Psi2IrConfiguration(errorPolicy.allowErrors) Psi2IrConfiguration(errorPolicy.allowErrors),
messageLogger::checkNoUnboundSymbols
) )
val psi2IrContext = psi2Ir.createGeneratorContext( val psi2IrContext = psi2Ir.createGeneratorContext(
inputArtifact.analysisResult.moduleDescriptor, inputArtifact.analysisResult.moduleDescriptor,
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.backend.js.* 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.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.test.utils.JsIrIncrementalDataProvider import org.jetbrains.kotlin.js.test.utils.JsIrIncrementalDataProvider
@@ -56,7 +56,7 @@ class JsKlibBackendFacade(
configuration[CommonConfigurationKeys.MODULE_NAME]!!, configuration[CommonConfigurationKeys.MODULE_NAME]!!,
project, project,
configuration, configuration,
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None, configuration.irMessageLogger,
inputArtifact.bindingContext, inputArtifact.bindingContext,
inputArtifact.sourceFiles, inputArtifact.sourceFiles,
klibPath = outputFile, klibPath = outputFile,
@@ -76,7 +76,7 @@ class JsKlibBackendFacade(
val lib = jsResolveLibraries( val lib = jsResolveLibraries(
dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile), dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile),
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(), configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
configuration[IrMessageLogger.IR_MESSAGE_LOGGER].toResolverLogger() configuration.resolverLogger
).getFullResolvedList().last().library ).getFullResolvedList().last().library
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns( val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
@@ -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.extensions.IrPluginContextImpl
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl 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.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule 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 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 generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
val pluginExtensions = IrGenerationExtension.getInstances(config.project) val pluginExtensions = IrGenerationExtension.getInstances(config.project)
@@ -211,7 +216,7 @@ internal fun Context.psiToIr(
// Enable lazy IR genration for newly-created symbols inside BE // Enable lazy IR genration for newly-created symbols inside BE
stubGenerator.unboundSymbolGeneration = true 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))) mainModule.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.scripting.js package org.jetbrains.kotlin.scripting.js
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl 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.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -67,7 +68,11 @@ class JsCoreScriptingCompiler(
val files = listOf(snippetKtFile) val files = listOf(snippetKtFile)
val (bindingContext, module) = analysisResult val (bindingContext, module) = analysisResult
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, Psi2IrConfiguration()) val psi2ir = Psi2IrTranslator(
environment.configuration.languageVersionSettings,
Psi2IrConfiguration(),
environment.configuration::checkNoUnboundSymbols
)
val generatorExtensions = val generatorExtensions =
if (replCompilerState == null) GeneratorExtensions() if (replCompilerState == null) GeneratorExtensions()
@@ -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.generateJsCode
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker 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.backend.js.utils.NameTables
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator import org.jetbrains.kotlin.ir.util.*
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.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
@@ -38,7 +35,7 @@ class JsScriptDependencyCompiler(
fun compile(dependencies: List<ModuleDescriptor>): String { fun compile(dependencies: List<ModuleDescriptor>): String {
val builtIns: KotlinBuiltIns = dependencies.single { it.allDependencyModules.isEmpty() }.builtIns val builtIns: KotlinBuiltIns = dependencies.single { it.allDependencyModules.isEmpty() }.builtIns
val languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT val languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT
val messageLogger = configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None val messageLogger = configuration.irMessageLogger
val moduleName = Name.special("<script-dependencies>") val moduleName = Name.special("<script-dependencies>")
val storageManager = LockBasedStorageManager.NO_LOCKS val storageManager = LockBasedStorageManager.NO_LOCKS
val moduleDescriptor = ModuleDescriptorImpl(moduleName, storageManager, builtIns, null).also { val moduleDescriptor = ModuleDescriptorImpl(moduleName, storageManager, builtIns, null).also {