JVM_IR: deserialize lazy declarations
This commit is contained in:
committed by
TeamCityServer
parent
ad8892f71f
commit
6b80c00cc6
+14
-7
@@ -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
|
||||
}
|
||||
|
||||
+2
-1
@@ -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
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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
|
||||
|
||||
|
||||
+3
-3
@@ -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 {
|
||||
|
||||
+180
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user