[Plugin API] Add API to load top level declaration by its signature
- request from JP Compose, #KT-44100
This commit is contained in:
+5
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
@@ -51,4 +53,7 @@ interface IrPluginContext : IrGeneratorContext {
|
||||
fun referenceConstructors(classFqn: FqName): Collection<IrConstructorSymbol>
|
||||
fun referenceFunctions(fqName: FqName): Collection<IrSimpleFunctionSymbol>
|
||||
fun referenceProperties(fqName: FqName): Collection<IrPropertySymbol>
|
||||
|
||||
// temporary solution to load synthetic top-level declaration
|
||||
fun referenceTopLevel(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleDescriptor: ModuleDescriptor): IrSymbol?
|
||||
}
|
||||
|
||||
+11
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.ir.util.IrMessageLogger
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
@@ -134,4 +135,14 @@ open class IrPluginContextImpl constructor(
|
||||
descriptors.map { st.referenceProperty(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun referenceTopLevel(
|
||||
signature: IdSignature,
|
||||
kind: IrDeserializer.TopLevelSymbolKind,
|
||||
moduleDescriptor: ModuleDescriptor
|
||||
): IrSymbol? {
|
||||
val symbol = linker.resolveBySignatureInModule(signature, kind, moduleDescriptor.name)
|
||||
linker.postProcess()
|
||||
return symbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
interface IrDeserializer : IrProvider {
|
||||
|
||||
@@ -16,6 +18,14 @@ interface IrDeserializer : IrProvider {
|
||||
fun resolveSymbol(symbol: IrSymbol, context: TranslationPluginContext): IrDeclaration? = null
|
||||
}
|
||||
|
||||
enum class TopLevelSymbolKind {
|
||||
FUNCTION_SYMBOL,
|
||||
CLASS_SYMBOL,
|
||||
PROPERTY_SYMBOL,
|
||||
TYPEALIAS_SYMBOL;
|
||||
}
|
||||
|
||||
fun init(moduleFragment: IrModuleFragment?, extensions: Collection<IrLinkerExtension>) {}
|
||||
fun resolveBySignatureInModule(signature: IdSignature, kind: TopLevelSymbolKind, moduleName: Name): IrSymbol
|
||||
fun postProcess() {}
|
||||
}
|
||||
|
||||
+19
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.library.IrLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.protobuf.CodedInputStream
|
||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
@@ -64,6 +65,7 @@ abstract class KotlinIrLinker(
|
||||
|
||||
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
||||
|
||||
// TODO: replace with Map<Name, IrModuleDeserializer>
|
||||
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
||||
|
||||
abstract val fakeOverrideBuilder: FakeOverrideBuilder
|
||||
@@ -665,6 +667,23 @@ abstract class KotlinIrLinker(
|
||||
// symbolTable.noUnboundLeft("unbound after fake overrides:")
|
||||
}
|
||||
|
||||
private fun topLevelKindToSymbolKind(kind: IrDeserializer.TopLevelSymbolKind): BinarySymbolData.SymbolKind {
|
||||
return when (kind) {
|
||||
IrDeserializer.TopLevelSymbolKind.CLASS_SYMBOL -> BinarySymbolData.SymbolKind.CLASS_SYMBOL
|
||||
IrDeserializer.TopLevelSymbolKind.PROPERTY_SYMBOL -> BinarySymbolData.SymbolKind.PROPERTY_SYMBOL
|
||||
IrDeserializer.TopLevelSymbolKind.FUNCTION_SYMBOL -> BinarySymbolData.SymbolKind.FUNCTION_SYMBOL
|
||||
IrDeserializer.TopLevelSymbolKind.TYPEALIAS_SYMBOL -> BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol {
|
||||
val moduleDeserializer =
|
||||
deserializersForModules.entries.find { it.key.name == moduleName }?.value ?: error("No module for name '$moduleName' found")
|
||||
assert(signature == signature.topLevelSignature()) { "Signature '$signature' has to be top level" }
|
||||
if (signature !in moduleDeserializer) error("No signature $signature in module $moduleName")
|
||||
return moduleDeserializer.deserializeIrSymbol(signature, topLevelKindToSymbolKind(kind))
|
||||
}
|
||||
|
||||
// The issue here is that an expect can not trigger its actual deserialization by reachability
|
||||
// because the expect can not see the actual higher in the module dependency dag.
|
||||
// So we force deserialization of actuals for all deserialized expect symbols here.
|
||||
|
||||
Reference in New Issue
Block a user