[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.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
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.symbols.*
|
||||||
|
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.ir.util.ReferenceSymbolTable
|
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
@@ -51,4 +53,7 @@ interface IrPluginContext : IrGeneratorContext {
|
|||||||
fun referenceConstructors(classFqn: FqName): Collection<IrConstructorSymbol>
|
fun referenceConstructors(classFqn: FqName): Collection<IrConstructorSymbol>
|
||||||
fun referenceFunctions(fqName: FqName): Collection<IrSimpleFunctionSymbol>
|
fun referenceFunctions(fqName: FqName): Collection<IrSimpleFunctionSymbol>
|
||||||
fun referenceProperties(fqName: FqName): Collection<IrPropertySymbol>
|
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.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
import org.jetbrains.kotlin.ir.linkage.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
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.IrMessageLogger
|
||||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||||
@@ -134,4 +135,14 @@ open class IrPluginContextImpl constructor(
|
|||||||
descriptors.map { st.referenceProperty(it) }
|
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.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
interface IrDeserializer : IrProvider {
|
interface IrDeserializer : IrProvider {
|
||||||
|
|
||||||
@@ -16,6 +18,14 @@ interface IrDeserializer : IrProvider {
|
|||||||
fun resolveSymbol(symbol: IrSymbol, context: TranslationPluginContext): IrDeclaration? = null
|
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 init(moduleFragment: IrModuleFragment?, extensions: Collection<IrLinkerExtension>) {}
|
||||||
|
fun resolveBySignatureInModule(signature: IdSignature, kind: TopLevelSymbolKind, moduleName: Name): IrSymbol
|
||||||
fun postProcess() {}
|
fun postProcess() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.library.IrLibrary
|
import org.jetbrains.kotlin.library.IrLibrary
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.protobuf.CodedInputStream
|
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
|
||||||
@@ -64,6 +65,7 @@ abstract class KotlinIrLinker(
|
|||||||
|
|
||||||
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
private val modulesWithReachableTopLevels = mutableSetOf<IrModuleDeserializer>()
|
||||||
|
|
||||||
|
// TODO: replace with Map<Name, IrModuleDeserializer>
|
||||||
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
||||||
|
|
||||||
abstract val fakeOverrideBuilder: FakeOverrideBuilder
|
abstract val fakeOverrideBuilder: FakeOverrideBuilder
|
||||||
@@ -665,6 +667,23 @@ abstract class KotlinIrLinker(
|
|||||||
// symbolTable.noUnboundLeft("unbound after fake overrides:")
|
// 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
|
// 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.
|
// 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.
|
// So we force deserialization of actuals for all deserialized expect symbols here.
|
||||||
|
|||||||
Reference in New Issue
Block a user