[PLUGIN API] Implement custom linkage for plugin extensions
This commit is contained in:
@@ -84,7 +84,7 @@ object JvmBackendFacade {
|
|||||||
|
|
||||||
stubGenerator.setIrProviders(irProviders)
|
stubGenerator.setIrProviders(irProviders)
|
||||||
|
|
||||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders, expectDescriptorToSymbol = null)
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders, pluginExtensions, expectDescriptorToSymbol = null)
|
||||||
irLinker.postProcess()
|
irLinker.postProcess()
|
||||||
|
|
||||||
stubGenerator.unboundSymbolGeneration = true
|
stubGenerator.unboundSymbolGeneration = true
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class Psi2IrTranslator(
|
|||||||
val irProviders = generateTypicalIrProviderList(
|
val irProviders = generateTypicalIrProviderList(
|
||||||
moduleDescriptor, context.irBuiltIns, context.symbolTable, extensions = generatorExtensions
|
moduleDescriptor, context.irBuiltIns, context.symbolTable, extensions = generatorExtensions
|
||||||
)
|
)
|
||||||
return generateModuleFragment(context, ktFiles, irProviders)
|
return generateModuleFragment(context, ktFiles, irProviders, emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createGeneratorContext(
|
fun createGeneratorContext(
|
||||||
@@ -76,6 +76,7 @@ class Psi2IrTranslator(
|
|||||||
context: GeneratorContext,
|
context: GeneratorContext,
|
||||||
ktFiles: Collection<KtFile>,
|
ktFiles: Collection<KtFile>,
|
||||||
irProviders: List<IrProvider>,
|
irProviders: List<IrProvider>,
|
||||||
|
linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>,
|
||||||
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>? = null
|
||||||
): IrModuleFragment {
|
): IrModuleFragment {
|
||||||
val moduleGenerator = ModuleGenerator(context)
|
val moduleGenerator = ModuleGenerator(context)
|
||||||
@@ -86,7 +87,7 @@ class Psi2IrTranslator(
|
|||||||
postprocess(context, irModule)
|
postprocess(context, irModule)
|
||||||
|
|
||||||
val deserializers = irProviders.filterIsInstance<IrDeserializer>()
|
val deserializers = irProviders.filterIsInstance<IrDeserializer>()
|
||||||
deserializers.forEach { it.init(irModule) }
|
deserializers.forEach { it.init(irModule, linkerExtensions) }
|
||||||
|
|
||||||
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ interface IrDeserializer : IrProvider {
|
|||||||
fun resolveSymbol(symbol: IrSymbol): IrDeclaration? = null
|
fun resolveSymbol(symbol: IrSymbol): IrDeclaration? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun init(moduleFragment: IrModuleFragment?) {}
|
fun init(moduleFragment: IrModuleFragment?, extensions: Collection<IrLinkerExtension>) {}
|
||||||
fun postProcess() {}
|
fun postProcess() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-2
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.protobuf.CodedInputStream
|
|||||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
|
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual
|
import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructorCall as ProtoConstructorCall
|
import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructorCall as ProtoConstructorCall
|
||||||
@@ -67,6 +68,8 @@ abstract class KotlinIrLinker(
|
|||||||
|
|
||||||
private val haveSeen = mutableSetOf<IrSymbol>()
|
private val haveSeen = mutableSetOf<IrSymbol>()
|
||||||
|
|
||||||
|
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
|
||||||
|
|
||||||
abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy) :
|
abstract inner class BasicIrModuleDeserializer(moduleDescriptor: ModuleDescriptor, override val klib: IrLibrary, override val strategy: DeserializationStrategy) :
|
||||||
IrModuleDeserializer(moduleDescriptor) {
|
IrModuleDeserializer(moduleDescriptor) {
|
||||||
|
|
||||||
@@ -518,6 +521,22 @@ abstract class KotlinIrLinker(
|
|||||||
|
|
||||||
protected open fun platformSpecificSymbol(symbol: IrSymbol): Boolean = false
|
protected open fun platformSpecificSymbol(symbol: IrSymbol): Boolean = false
|
||||||
|
|
||||||
|
private fun tryResolveCustomDeclaration(symbol: IrSymbol): IrDeclaration? {
|
||||||
|
val descriptor = symbol.descriptor
|
||||||
|
|
||||||
|
if (descriptor is WrappedDeclarationDescriptor<*>) return null
|
||||||
|
if (descriptor is CallableMemberDescriptor) {
|
||||||
|
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
|
// skip fake overrides
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return linkerExtensions.firstNotNullResult { it.resolveSymbol(symbol) }?.also {
|
||||||
|
require(symbol.owner == it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
|
||||||
|
|
||||||
if (!symbol.isPublicApi) {
|
if (!symbol.isPublicApi) {
|
||||||
@@ -529,7 +548,7 @@ abstract class KotlinIrLinker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!symbol.isBound) {
|
if (!symbol.isBound) {
|
||||||
findDeserializedDeclarationForSymbol(symbol) ?: return null
|
findDeserializedDeclarationForSymbol(symbol) ?: tryResolveCustomDeclaration(symbol) ?: return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we do have serializations for those, but let's just create a stub for now.
|
// TODO: we do have serializations for those, but let's just create a stub for now.
|
||||||
@@ -548,7 +567,8 @@ abstract class KotlinIrLinker(
|
|||||||
protected open fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer =
|
protected open fun createCurrentModuleDeserializer(moduleFragment: IrModuleFragment, dependencies: Collection<IrModuleDeserializer>): IrModuleDeserializer =
|
||||||
CurrentModuleDeserializer(moduleFragment, dependencies)
|
CurrentModuleDeserializer(moduleFragment, dependencies)
|
||||||
|
|
||||||
override fun init(moduleFragment: IrModuleFragment?) {
|
override fun init(moduleFragment: IrModuleFragment?, extensions: Collection<IrDeserializer.IrLinkerExtension>) {
|
||||||
|
linkerExtensions = extensions
|
||||||
if (moduleFragment != null) {
|
if (moduleFragment != null) {
|
||||||
val currentModuleDependencies = moduleFragment.descriptor.allDependencyModules.map {
|
val currentModuleDependencies = moduleFragment.descriptor.allDependencyModules.map {
|
||||||
deserializersForModules[it] ?: error("No deserializer found for $it")
|
deserializersForModules[it] ?: error("No deserializer found for $it")
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ fun loadIr(
|
|||||||
|
|
||||||
val moduleFragment = deserializedModuleFragments.last()
|
val moduleFragment = deserializedModuleFragments.last()
|
||||||
|
|
||||||
irLinker.init(null)
|
irLinker.init(null, emptyList())
|
||||||
ExternalDependenciesGenerator(symbolTable, listOf(irLinker), configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
ExternalDependenciesGenerator(symbolTable, listOf(irLinker), configuration.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
||||||
irLinker.postProcess()
|
irLinker.postProcess()
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ fun GeneratorContext.generateModuleFragmentWithPlugins(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return psi2Ir.generateModuleFragment(this, files, listOf(irLinker), expectDescriptorToSymbol)
|
return psi2Ir.generateModuleFragment(this, files, listOf(irLinker), extensions, expectDescriptorToSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
private fun createBuiltIns(storageManager: StorageManager) = object : KotlinBuiltIns(storageManager) {}
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ class GenerateIrRuntime {
|
|||||||
val irProviders = listOf(irLinker)
|
val irProviders = listOf(irLinker)
|
||||||
|
|
||||||
val psi2IrTranslator = Psi2IrTranslator(languageVersionSettings, psi2IrContext.configuration, signaturer)
|
val psi2IrTranslator = Psi2IrTranslator(languageVersionSettings, psi2IrContext.configuration, signaturer)
|
||||||
return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, null)
|
return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, emptyList(), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doSerializeModule(moduleFragment: IrModuleFragment, bindingContext: BindingContext, files: List<KtFile>, perFile: Boolean = false): String {
|
private fun doSerializeModule(moduleFragment: IrModuleFragment, bindingContext: BindingContext, files: List<KtFile>, perFile: Boolean = false): String {
|
||||||
@@ -531,7 +531,7 @@ class GenerateIrRuntime {
|
|||||||
val jsLinker = JsIrLinker(moduleDescriptor, logger, irBuiltIns, symbolTable, functionFactory, null)
|
val jsLinker = JsIrLinker(moduleDescriptor, logger, irBuiltIns, symbolTable, functionFactory, null)
|
||||||
|
|
||||||
val moduleFragment = jsLinker.deserializeFullModule(moduleDescriptor, moduleDescriptor.kotlinLibrary)
|
val moduleFragment = jsLinker.deserializeFullModule(moduleDescriptor, moduleDescriptor.kotlinLibrary)
|
||||||
jsLinker.init(null)
|
jsLinker.init(null, emptyList())
|
||||||
// Create stubs
|
// Create stubs
|
||||||
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker), languageVersionSettings)
|
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker), languageVersionSettings)
|
||||||
.generateUnboundSymbolsAsDependencies()
|
.generateUnboundSymbolsAsDependencies()
|
||||||
@@ -562,7 +562,7 @@ class GenerateIrRuntime {
|
|||||||
|
|
||||||
val moduleFragment = jsLinker.deserializeFullModule(moduleDescriptor, moduleDescriptor.kotlinLibrary)
|
val moduleFragment = jsLinker.deserializeFullModule(moduleDescriptor, moduleDescriptor.kotlinLibrary)
|
||||||
// Create stubs
|
// Create stubs
|
||||||
jsLinker.init(null)
|
jsLinker.init(null, emptyList())
|
||||||
// Create stubs
|
// Create stubs
|
||||||
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker), languageVersionSettings)
|
ExternalDependenciesGenerator(symbolTable, listOf(jsLinker), languageVersionSettings)
|
||||||
.generateUnboundSymbolsAsDependencies()
|
.generateUnboundSymbolsAsDependencies()
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ class JsCoreScriptingCompiler(
|
|||||||
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, signaturer = signaturer)
|
val psi2ir = Psi2IrTranslator(environment.configuration.languageVersionSettings, signaturer = signaturer)
|
||||||
val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable = symbolTable)
|
val psi2irContext = psi2ir.createGeneratorContext(module, bindingContext, symbolTable = symbolTable)
|
||||||
val providers = generateTypicalIrProviderList(module, psi2irContext.irBuiltIns, psi2irContext.symbolTable)
|
val providers = generateTypicalIrProviderList(module, psi2irContext.irBuiltIns, psi2irContext.symbolTable)
|
||||||
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, providers, null) // TODO: deserializer
|
val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, providers, emptyList(), null) // TODO: deserializer
|
||||||
|
|
||||||
val context = JsIrBackendContext(
|
val context = JsIrBackendContext(
|
||||||
irModuleFragment.descriptor,
|
irModuleFragment.descriptor,
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ class JsScriptDependencyCompiler(
|
|||||||
val moduleFragment = irDependencies.last()
|
val moduleFragment = irDependencies.last()
|
||||||
val irProviders = listOf(jsLinker)
|
val irProviders = listOf(jsLinker)
|
||||||
|
|
||||||
jsLinker.init(null)
|
jsLinker.init(null, emptyList())
|
||||||
|
|
||||||
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
ExternalDependenciesGenerator(symbolTable, irProviders, configuration.languageVersionSettings)
|
||||||
.generateUnboundSymbolsAsDependencies()
|
.generateUnboundSymbolsAsDependencies()
|
||||||
|
|||||||
Reference in New Issue
Block a user