JVM_IR: deserialize lazy declarations

This commit is contained in:
Georgy Bronnikov
2021-04-13 15:11:50 +03:00
committed by TeamCityServer
parent ad8892f71f
commit 6b80c00cc6
15 changed files with 468 additions and 75 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
@@ -74,13 +75,19 @@ open class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = tru
else
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB
override fun generateFacadeClass(irFactory: IrFactory, source: DeserializedContainerSource): IrClass? {
if (!generateFacades || source !is JvmPackagePartSource) return null
val facadeName = source.facadeClassName ?: source.className
return irFactory.buildClass {
origin = if (source.facadeClassName != null) IrDeclarationOrigin.JVM_MULTIFILE_CLASS else IrDeclarationOrigin.FILE_CLASS
name = facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName()
}.also {
override fun generateFacadeClass(
irFactory: IrFactory,
deserializedSource: DeserializedContainerSource,
stubGenerator: DeclarationStubGenerator
): IrClass? {
if (!generateFacades || deserializedSource !is JvmPackagePartSource) return null
val facadeName = deserializedSource.facadeClassName ?: deserializedSource.className
return JvmFileFacadeClass(
if (deserializedSource.facadeClassName != null) IrDeclarationOrigin.JVM_MULTIFILE_CLASS else IrDeclarationOrigin.FILE_CLASS,
facadeName.fqNameForTopLevelClassMaybeWithDollars.shortName(),
deserializedSource,
stubGenerator
).also {
it.createParameterDeclarations()
classNameOverride[it] = facadeName
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrLinker
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.MetadataSource
@@ -78,7 +79,7 @@ open class JvmIrCodegenFactory(
psi2irContext.irBuiltIns.functionFactory = functionFactory
val stubGenerator =
DeclarationStubGeneratorImpl(psi2irContext.moduleDescriptor, symbolTable, state.languageVersionSettings, jvmGeneratorExtensions)
DeclarationStubGeneratorImpl(psi2irContext.moduleDescriptor, symbolTable, psi2irContext.irBuiltIns, jvmGeneratorExtensions)
val frontEndContext = object : TranslationPluginContext {
override val moduleDescriptor: ModuleDescriptor
get() = psi2irContext.moduleDescriptor
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2021 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.jvm
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.name.Name
class JvmFileFacadeClass(
origin: IrDeclarationOrigin,
name: Name,
source: SourceElement,
private val stubGenerator: DeclarationStubGenerator
) : IrClassImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin,
IrClassSymbolImpl(), name, ClassKind.CLASS, DescriptorVisibilities.PUBLIC, Modality.FINAL,
source = source
), DeserializableClass {
private var irLoaded: Boolean? = null
override fun loadIr(): Boolean {
irLoaded?.let { return it }
irLoaded = stubGenerator.extensions.deserializeFacadeClass(
this,
stubGenerator.moduleDescriptor,
stubGenerator.irBuiltIns,
stubGenerator.symbolTable,
parent,
allowErrorNodes = false
)
return irLoaded as Boolean
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.lazy.LazyScopedTypeParametersResolver
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -19,13 +18,13 @@ import org.jetbrains.kotlin.ir.util.TypeTranslator
class DeclarationStubGeneratorImpl(
moduleDescriptor: ModuleDescriptor,
symbolTable: SymbolTable,
languageVersionSettings: LanguageVersionSettings,
irBuiltins: IrBuiltIns,
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY,
) : DeclarationStubGenerator(moduleDescriptor, symbolTable, extensions) {
) : DeclarationStubGenerator(moduleDescriptor, symbolTable, irBuiltins, extensions) {
override val typeTranslator: TypeTranslator =
TypeTranslatorImpl(
lazyTable,
languageVersionSettings,
irBuiltins.languageVersionSettings,
moduleDescriptor,
{ LazyScopedTypeParametersResolver(lazyTable) },
true,
@@ -42,7 +41,7 @@ fun generateTypicalIrProviderList(
extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY
): List<IrProvider> {
val stubGenerator = DeclarationStubGeneratorImpl(
moduleDescriptor, symbolTable, irBuiltins.languageVersionSettings, extensions
moduleDescriptor, symbolTable, irBuiltins, extensions
)
return listOfNotNull(deserializer, stubGenerator)
}
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
class IrClassImpl(
open class IrClassImpl(
override val startOffset: Int,
override val endOffset: Int,
override var origin: IrDeclarationOrigin,
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -40,7 +41,7 @@ class IrLazyClass(
override val isFun: Boolean,
override val stubGenerator: DeclarationStubGenerator,
override val typeTranslator: TypeTranslator
) : IrClass(), IrLazyDeclarationBase {
) : IrClass(), IrLazyDeclarationBase, DeserializableClass {
init {
symbol.bind(this)
}
@@ -110,4 +111,14 @@ class IrLazyClass(
override var metadata: MetadataSource?
get() = null
set(_) = error("We should never need to store metadata of external declarations.")
private var irLoaded: Boolean? = null
override fun loadIr(): Boolean {
assert(parent is IrPackageFragment)
irLoaded?.let { return it }
return stubGenerator.extensions.deserializeLazyClass(
this, stubGenerator, parent, allowErrorNodes = false
).also { irLoaded = it }
}
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.withScope
import org.jetbrains.kotlin.name.Name
@@ -48,7 +49,13 @@ class IrLazyFunction(
override var annotations: List<IrConstructorCall> by createLazyAnnotations()
override var body: IrBody? = null
override var body: IrBody? by lazyVar {
if (!isInline) return@lazyVar null
val toplevel = getToplevel()
val loaded = (toplevel as? DeserializableClass)?.loadIR() ?: false
// Underlying field has been set by IR loading
if (loaded) body else null
}
override var returnType: IrType by createReturnType()
@@ -99,4 +106,12 @@ class IrLazyFunction(
init {
symbol.bind(this)
}
private fun getToplevel(): IrDeclaration {
var current: IrDeclarationParent = parent
while (current is IrDeclaration && current.parent !is IrPackageFragment) {
current = current.parent
}
return current as IrDeclaration
}
}
@@ -0,0 +1,158 @@
/*
* Copyright 2010-2021 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.ir.declarations.lazy
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
// An IrFactory that does not recreate declarations for already bound symbols.
class LazyIrFactory(
private val delegate: IrFactory,
) : IrFactory by delegate {
override fun createClass(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrClassSymbol,
name: Name,
kind: ClassKind,
visibility: DescriptorVisibility,
modality: Modality,
isCompanion: Boolean,
isInner: Boolean,
isData: Boolean,
isExternal: Boolean,
isInline: Boolean,
isExpect: Boolean,
isFun: Boolean,
source: SourceElement
): IrClass = if (symbol.isBound)
symbol.owner
else
delegate.createClass(
startOffset, endOffset, origin, symbol, name, kind, visibility, modality,
isCompanion, isInner, isData, isExternal, isInline, isExpect, isFun, source
)
override fun createConstructor(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrConstructorSymbol,
name: Name,
visibility: DescriptorVisibility,
returnType: IrType,
isInline: Boolean,
isExternal: Boolean,
isPrimary: Boolean,
isExpect: Boolean,
containerSource: DeserializedContainerSource?
): IrConstructor = if (symbol.isBound)
symbol.owner
else
delegate.createConstructor(
startOffset, endOffset, origin, symbol, name, visibility, returnType,
isInline, isExternal, isPrimary, isExpect, containerSource
)
override fun createEnumEntry(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrEnumEntrySymbol,
name: Name
): IrEnumEntry = if (symbol.isBound)
symbol.owner
else
delegate.createEnumEntry(startOffset, endOffset, origin, symbol, name)
override fun createField(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrFieldSymbol,
name: Name,
type: IrType,
visibility: DescriptorVisibility,
isFinal: Boolean,
isExternal: Boolean,
isStatic: Boolean
): IrField = if (symbol.isBound)
symbol.owner
else
delegate.createField(startOffset, endOffset, origin, symbol, name, type, visibility, isFinal, isExternal, isStatic)
override fun createFunction(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrSimpleFunctionSymbol,
name: Name,
visibility: DescriptorVisibility,
modality: Modality,
returnType: IrType,
isInline: Boolean,
isExternal: Boolean,
isTailrec: Boolean,
isSuspend: Boolean,
isOperator: Boolean,
isInfix: Boolean,
isExpect: Boolean,
isFakeOverride: Boolean,
containerSource: DeserializedContainerSource?
): IrSimpleFunction = if (symbol.isBound)
symbol.owner
else
delegate.createFunction(
startOffset, endOffset, origin, symbol, name, visibility, modality, returnType,
isInline, isExternal, isTailrec, isSuspend, isOperator, isInfix, isExpect, isFakeOverride, containerSource
)
override fun createProperty(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
symbol: IrPropertySymbol,
name: Name,
visibility: DescriptorVisibility,
modality: Modality,
isVar: Boolean,
isConst: Boolean,
isLateinit: Boolean,
isDelegated: Boolean,
isExternal: Boolean,
isExpect: Boolean,
isFakeOverride: Boolean,
containerSource: DeserializedContainerSource?
): IrProperty = if (symbol.isBound)
symbol.owner
else
delegate.createProperty(
startOffset, endOffset, origin, symbol, name, visibility, modality,
isVar, isConst, isLateinit, isDelegated, isExternal, isExpect, isFakeOverride, containerSource
)
override fun createTypeAlias(
startOffset: Int,
endOffset: Int,
symbol: IrTypeAliasSymbol,
name: Name,
visibility: DescriptorVisibility,
expandedType: IrType,
isActual: Boolean,
origin: IrDeclarationOrigin
): IrTypeAlias = if (symbol.isBound)
symbol.owner
else
delegate.createTypeAlias(startOffset, endOffset, symbol, name, visibility, expandedType, isActual, origin)
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.linkage.IrProvider
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
abstract class DeclarationStubGenerator(
val moduleDescriptor: ModuleDescriptor,
val symbolTable: SymbolTable,
val irBuiltIns: IrBuiltIns,
val extensions: StubGeneratorExtensions = StubGeneratorExtensions.EMPTY,
) : IrProvider {
protected val lazyTable = symbolTable.lazyWrapper
@@ -89,7 +91,7 @@ abstract class DeclarationStubGenerator(
val packageFragment = directMember.containingDeclaration as? PackageFragmentDescriptor ?: return null
val containerSource = directMember.safeAs<DescriptorWithContainerSource>()?.containerSource ?: return null
return facadeClassMap.getOrPut(containerSource) {
extensions.generateFacadeClass(symbolTable.irFactory, containerSource)?.also { facade ->
extensions.generateFacadeClass(symbolTable.irFactory, containerSource, this)?.also { facade ->
val packageStub = generateOrGetEmptyExternalPackageFragmentStub(packageFragment)
facade.parent = packageStub
packageStub.declarations.add(facade)
@@ -7,23 +7,49 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.types.KotlinType
interface DeserializableClass {
fun loadIr(): Boolean
}
open class StubGeneratorExtensions {
open fun computeExternalDeclarationOrigin(descriptor: DeclarationDescriptor): IrDeclarationOrigin? = null
open fun generateFacadeClass(irFactory: IrFactory, source: DeserializedContainerSource): IrClass? = null
open fun generateFacadeClass(
irFactory: IrFactory,
deserializedSource: DeserializedContainerSource,
stubGenerator: DeclarationStubGenerator,
): IrClass? = null
open fun isPropertyWithPlatformField(descriptor: PropertyDescriptor): Boolean = false
open fun isStaticFunction(descriptor: FunctionDescriptor): Boolean = false
open fun deserializeLazyClass(
irClass: IrLazyClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
parent: IrDeclarationParent,
allowErrorNodes: Boolean,
): Boolean = false
open fun deserializeFacadeClass(
irClass: IrClass,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
parent: IrDeclarationParent,
allowErrorNodes: Boolean,
): Boolean = false
open val enhancedNullability: EnhancedNullability
get() = EnhancedNullability
@@ -66,7 +66,7 @@ class IrDeclarationDeserializer(
private val symbolTable: SymbolTable,
val irFactory: IrFactory,
private val fileReader: IrLibraryFile,
private val file: IrFile,
private val parent: IrDeclarationParent,
val allowErrorNodes: Boolean,
private val deserializeInlineFunctions: Boolean,
private var deserializeBodies: Boolean,
@@ -166,7 +166,7 @@ class IrDeclarationDeserializer(
}
}
private var currentParent: IrDeclarationParent = file
private var currentParent: IrDeclarationParent = parent
private inline fun <T : IrDeclarationParent> T.usingParent(block: T.() -> Unit): T =
this.apply {
@@ -298,7 +298,7 @@ class IrDeclarationDeserializer(
}
}
private fun deserializeIrClass(proto: ProtoClass): IrClass =
fun deserializeIrClass(proto: ProtoClass): IrClass =
withDeserializedIrDeclarationBase(proto.base) { symbol, signature, startOffset, endOffset, origin, fcode ->
val flags = ClassFlags.decode(fcode)
@@ -7,27 +7,6 @@ option optimize_for = LITE_RUNTIME;
/* Stored in JVM .class annotations */
//message UniqIdInfo {
// required fixed64 id = 1;
// repeated int32 toplevel_fq_name = 2;
//}
//message SignatureTable {
// repeated common.serialization.proto.IrSignature signature = 1;
//}
//
//message TypeTable {
// repeated common.serialization.proto.IrType type = 1;
//}
//message UniqIdTable {
// repeated UniqIdInfo infos = 1;
//}
//message StringTable {
// repeated string string = 1;
//}
message XStatementOrExpression {
oneof kind {
common.serialization.proto.IrStatement statement = 1;
@@ -35,38 +14,11 @@ message XStatementOrExpression {
}
}
//message StatementsAndExpressionsTable {
// repeated XStatementOrExpression statement_or_expression = 1;
//}
//message ExternalReference {
// required fixed64 id = 1;
// required int32 index = 2; /* index into the table of packages in ExternalRefs */
//}
//
//message JvmExternalPackage {
// repeated int32 fq_name = 1;
// required common.serialization.proto.IrDeclarationContainer declaration_container = 2;
//}
//message ExternalRefs {
// repeated JvmExternalPackage package = 1;
// repeated ExternalReference reference = 2;
//}
message AuxTables {
repeated bytes type = 1;
repeated bytes signature = 2;
repeated bytes string = 3;
repeated bytes body = 4;
// required TypeTable type_table = 2;
// required SignatureTable signature_table = 1;
// required StringTable string_table = 3;
// required StatementsAndExpressionsTable statements_and_expressions_table = 4;
// required ExternalRefs external_refs = 5;
// required UniqIdTable uniq_id_table = 6;
}
message JvmIrFile {
@@ -0,0 +1,180 @@
/*
* Copyright 2010-2021 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.jvm.serialization
import org.jetbrains.kotlin.backend.common.overrides.DefaultFakeOverrideClassFilter
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.overrides.FileLocalAwareLinker
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinder
import org.jetbrains.kotlin.backend.common.serialization.IrDeclarationDeserializer
import org.jetbrains.kotlin.backend.common.serialization.IrLibraryFile
import org.jetbrains.kotlin.backend.common.serialization.IrSymbolDeserializer
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
import org.jetbrains.kotlin.backend.jvm.serialization.proto.JvmIr
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.LazyIrFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.protobuf.ByteString
fun deserializeClassFromByteArray(
byteArray: ByteArray,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
parent: IrDeclarationParent,
allowErrorNodes: Boolean,
) {
val irProto = JvmIr.JvmIrClass.parseFrom(byteArray)
val irLibraryFile = IrLibraryFileFromAnnotation(
irProto.auxTables.typeList,
irProto.auxTables.signatureList,
irProto.auxTables.stringList,
irProto.auxTables.bodyList
)
val descriptorFinder =
DescriptorByIdSignatureFinder(moduleDescriptor, JvmDescriptorMangler(null), DescriptorByIdSignatureFinder.LookupMode.MODULE_WITH_DEPENDENCIES)
val symbolDeserializer = IrSymbolDeserializer(
symbolTable,
irLibraryFile,
/* TODO */ actuals = emptyList(),
enqueueLocalTopLevelDeclaration = {}, // just link to it in symbolTable
handleExpectActualMapping = { _, _ -> TODO() },
deserializePublicSymbol = { idSignature, symbolKind ->
referencePublicSymbol(symbolTable, descriptorFinder, idSignature, symbolKind)
}
)
val lazyIrFactory = LazyIrFactory(irBuiltIns.irFactory)
val deserializer = IrDeclarationDeserializer(
irBuiltIns, symbolTable, lazyIrFactory, irLibraryFile, parent,
allowErrorNodes = allowErrorNodes,
deserializeInlineFunctions = true,
deserializeBodies = true,
symbolDeserializer,
DefaultFakeOverrideClassFilter,
makeEmptyFakeOverrideBuilder(symbolTable, irBuiltIns)
)
deserializer.deserializeIrClass(irProto.irClass)
}
fun deserializeIrFileFromByteArray(
byteArray: ByteArray,
moduleDescriptor: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable,
facadeClass: IrClass,
allowErrorNodes: Boolean,
) {
val irProto = JvmIr.JvmIrFile.parseFrom(byteArray)
val irLibraryFile = IrLibraryFileFromAnnotation(
irProto.auxTables.typeList,
irProto.auxTables.signatureList,
irProto.auxTables.stringList,
irProto.auxTables.bodyList
)
val descriptorFinder =
DescriptorByIdSignatureFinder(moduleDescriptor, JvmDescriptorMangler(null), DescriptorByIdSignatureFinder.LookupMode.MODULE_WITH_DEPENDENCIES)
val symbolDeserializer = IrSymbolDeserializer(
symbolTable,
irLibraryFile,
/* TODO */ actuals = emptyList(),
enqueueLocalTopLevelDeclaration = {}, // just link to it in symbolTable
handleExpectActualMapping = { _, _ -> TODO() },
deserializePublicSymbol = { idSignature, symbolKind ->
referencePublicSymbol(symbolTable, descriptorFinder, idSignature, symbolKind)
}
)
val lazyIrFactory = LazyIrFactory(irBuiltIns.irFactory)
val deserializer = IrDeclarationDeserializer(
irBuiltIns, symbolTable, lazyIrFactory, irLibraryFile, facadeClass,
allowErrorNodes = allowErrorNodes,
deserializeInlineFunctions = true,
deserializeBodies = true,
symbolDeserializer,
DefaultFakeOverrideClassFilter,
makeEmptyFakeOverrideBuilder(symbolTable, irBuiltIns)
)
for (declarationProto in irProto.declarationList) {
deserializer.deserializeDeclaration(declarationProto)
}
}
private class IrLibraryFileFromAnnotation(
val types: List<ByteString>,
val signatures: List<ByteString>,
val strings: List<ByteString>,
val bodies: List<ByteString>,
) : IrLibraryFile() {
override fun irDeclaration(index: Int): ByteArray {
error("This method is never supposed to be called")
}
override fun type(index: Int): ByteArray = types[index].toByteArray()
override fun signature(index: Int): ByteArray = signatures[index].toByteArray()
override fun string(index: Int): ByteArray = strings[index].toByteArray()
override fun body(index: Int): ByteArray = bodies[index].toByteArray()
}
private fun referencePublicSymbol(
symbolTable: SymbolTable,
descriptorFinder: DescriptorByIdSignatureFinder,
idSig: IdSignature,
symbolKind: BinarySymbolData.SymbolKind
): IrSymbol {
with(symbolTable) {
val descriptor = descriptorFinder.findDescriptorBySignature(idSig)
return if (descriptor != null) {
when (symbolKind) {
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> referenceClass(descriptor as ClassDescriptor)
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> referenceConstructor(descriptor as ClassConstructorDescriptor)
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> referenceEnumEntry(descriptor as ClassDescriptor)
BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL -> referenceField(descriptor as PropertyDescriptor)
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> referenceSimpleFunction(descriptor as FunctionDescriptor)
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> referenceTypeAlias(descriptor as TypeAliasDescriptor)
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> referenceProperty(descriptor as PropertyDescriptor)
else -> error("Unexpected classifier symbol kind: $symbolKind for signature $idSig")
}
} else {
when (symbolKind) {
BinarySymbolData.SymbolKind.CLASS_SYMBOL -> referenceClassFromLinker(idSig)
BinarySymbolData.SymbolKind.CONSTRUCTOR_SYMBOL -> referenceConstructorFromLinker(idSig)
BinarySymbolData.SymbolKind.ENUM_ENTRY_SYMBOL -> referenceEnumEntryFromLinker(idSig)
BinarySymbolData.SymbolKind.STANDALONE_FIELD_SYMBOL -> referenceFieldFromLinker(idSig)
BinarySymbolData.SymbolKind.FUNCTION_SYMBOL -> referenceSimpleFunctionFromLinker(idSig)
BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL -> referenceTypeAliasFromLinker(idSig)
BinarySymbolData.SymbolKind.PROPERTY_SYMBOL -> referencePropertyFromLinker(idSig)
else -> error("Unexpected classifier symbol kind: $symbolKind for signature $idSig")
}
}
}
}
// TODO: implement properly
private fun makeEmptyFakeOverrideBuilder(symbolTable: SymbolTable, irBuiltIns: IrBuiltIns): FakeOverrideBuilder {
return FakeOverrideBuilder(
object : FileLocalAwareLinker {
override fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol? = null
override fun tryReferencingSimpleFunctionByLocalSignature(
parent: IrDeclaration, idSignature: IdSignature
): IrSimpleFunctionSymbol? = null
},
symbolTable,
IdSignatureSerializer(JvmIrMangler),
irBuiltIns
)
}
@@ -85,7 +85,7 @@ class IrTextDumpHandler(testServices: TestServices) : AbstractIrHandler(testServ
val stubGenerator = DeclarationStubGeneratorImpl(
irModule.descriptor,
SymbolTable(signaturer, IrFactoryImpl), // TODO
module.languageVersionSettings
irModule.irBuiltins
)
val baseFile = testServices.moduleStructure.originalTestDataFiles.first()
@@ -58,7 +58,7 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
val stubGenerator = DeclarationStubGeneratorImpl(
irModule.descriptor,
SymbolTable(signaturer, IrFactoryImpl), // TODO
myEnvironment.configuration.languageVersionSettings
irModule.irBuiltins
)
val path = wholeFile.path