[JS IR BE] Merge native fixes into Ir Serializer
This commit is contained in:
+2
-3
@@ -210,9 +210,8 @@ fun IrConstructor.callsSuper(irBuiltIns: IrBuiltIns): Boolean {
|
|||||||
assert(++numberOfCalls == 1) { "More than one delegating constructor call: ${symbol.owner}" }
|
assert(++numberOfCalls == 1) { "More than one delegating constructor call: ${symbol.owner}" }
|
||||||
val delegatingClass = expression.symbol.owner.parent as IrClass
|
val delegatingClass = expression.symbol.owner.parent as IrClass
|
||||||
// TODO: figure out why Lazy IR multiplies Declarations for descriptors and fix it
|
// TODO: figure out why Lazy IR multiplies Declarations for descriptors and fix it
|
||||||
if (delegatingClass.descriptor == superClass.classifierOrFail.descriptor || (
|
// It happens because of IrBuiltIns whose IrDeclarations are different for runtime and test
|
||||||
delegatingClass.defaultType.isAny() && superClass.isAny()
|
if (delegatingClass.descriptor == superClass.classifierOrFail.descriptor)
|
||||||
))
|
|
||||||
callsSuper = true
|
callsSuper = true
|
||||||
else if (delegatingClass.descriptor != constructedClass.descriptor)
|
else if (delegatingClass.descriptor != constructedClass.descriptor)
|
||||||
throw AssertionError(
|
throw AssertionError(
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class JsIrBackendContext(
|
|||||||
val coroutineSuspendOrReturn =
|
val coroutineSuspendOrReturn =
|
||||||
symbolTable.referenceSimpleFunction(getInternalFunctions(COROUTINE_SUSPEND_OR_RETURN_JS_NAME).single())
|
symbolTable.referenceSimpleFunction(getInternalFunctions(COROUTINE_SUSPEND_OR_RETURN_JS_NAME).single())
|
||||||
|
|
||||||
val intrinsics = JsIntrinsics(irBuiltIns, this)
|
val intrinsics by lazy { JsIntrinsics(irBuiltIns, this) }
|
||||||
|
|
||||||
private val operatorMap = referenceOperators()
|
private val operatorMap = referenceOperators()
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.backend.common.CompilerPhaseManager
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||||
@@ -85,7 +84,7 @@ fun compile(
|
|||||||
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext)
|
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext)
|
||||||
|
|
||||||
val symbolTable = SymbolTable()
|
val symbolTable = SymbolTable()
|
||||||
// irDependencyModules.forEach { symbolTable.loadModule(it) }
|
if (!isKlibCompilation) irDependencyModules.forEach { symbolTable.loadModule(it) }
|
||||||
|
|
||||||
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
val psi2IrTranslator = Psi2IrTranslator(configuration.languageVersionSettings)
|
||||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
val psi2IrContext = psi2IrTranslator.createGeneratorContext(analysisResult.moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
||||||
@@ -105,6 +104,10 @@ fun compile(
|
|||||||
|
|
||||||
if (isKlibCompilation) {
|
if (isKlibCompilation) {
|
||||||
val logggg = object : LoggingContext {
|
val logggg = object : LoggingContext {
|
||||||
|
override var inVerbosePhase: Boolean
|
||||||
|
get() = TODO("not implemented")
|
||||||
|
set(_) {}
|
||||||
|
|
||||||
override fun log(message: () -> String) {}
|
override fun log(message: () -> String) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +176,7 @@ fun compile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
md.initialize(CompositePackageFragmentProvider(packageProviders))
|
md.initialize(CompositePackageFragmentProvider(packageProviders))
|
||||||
md.setDependencies(listOf(md/*, builtIns.builtInsModule*/))
|
md.setDependencies(listOf(md))
|
||||||
|
|
||||||
|
|
||||||
val st = SymbolTable()
|
val st = SymbolTable()
|
||||||
|
|
||||||
@@ -198,7 +200,7 @@ fun compile(
|
|||||||
|
|
||||||
deserializedModuleFragment.replaceUnboundSymbols(context)
|
deserializedModuleFragment.replaceUnboundSymbols(context)
|
||||||
|
|
||||||
jsPhases.invokeToplevel(context.phaseConfig, context, moduleFragment)
|
jsPhases.invokeToplevel(context.phaseConfig, context, deserializedModuleFragment)
|
||||||
|
|
||||||
return Result(md, context.jsProgram.toString(), null)
|
return Result(md, context.jsProgram.toString(), null)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+3
-858
@@ -55,9 +55,9 @@ fun ReferenceSymbolTable.translateErased(type: KotlinType): IrSimpleType {
|
|||||||
|
|
||||||
internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
||||||
val typeArguments: Map<IrTypeParameterSymbol, IrType?>?,
|
val typeArguments: Map<IrTypeParameterSymbol, IrType?>?,
|
||||||
val parent: IrDeclarationParent?) : IrCopierForInliner {
|
val parent: IrDeclarationParent?) {
|
||||||
|
|
||||||
override fun copy(irElement: IrElement): IrElement {
|
fun copy(irElement: IrElement): IrElement {
|
||||||
// Create new symbols.
|
// Create new symbols.
|
||||||
irElement.acceptVoid(symbolRemapper)
|
irElement.acceptVoid(symbolRemapper)
|
||||||
|
|
||||||
@@ -205,8 +205,6 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addCurrentSubstituteMap(globalSubstituteMap: MutableMap<DeclarationDescriptor, SubstitutedDescriptor>) { }
|
|
||||||
|
|
||||||
private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper)
|
private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper)
|
||||||
: DeepCopySymbolRemapper(descriptorsRemapper) {
|
: DeepCopySymbolRemapper(descriptorsRemapper) {
|
||||||
|
|
||||||
@@ -232,857 +230,4 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context,
|
|||||||
InlinerTypeRemapper(symbolRemapper, typeArguments),
|
InlinerTypeRemapper(symbolRemapper, typeArguments),
|
||||||
InlinerSymbolRenamer()
|
InlinerSymbolRenamer()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface IrCopierForInliner {
|
|
||||||
fun copy(irElement: IrElement): IrElement
|
|
||||||
fun addCurrentSubstituteMap(globalSubstituteMap: MutableMap<DeclarationDescriptor, SubstitutedDescriptor>)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescriptor,
|
|
||||||
val parentDescriptor: DeclarationDescriptor,
|
|
||||||
val context: JsIrBackendContext,
|
|
||||||
val typeSubstitutor: TypeSubstitutor?) : IrCopierForInliner {
|
|
||||||
|
|
||||||
private val descriptorSubstituteMap: MutableMap<DeclarationDescriptor, DeclarationDescriptor> = mutableMapOf()
|
|
||||||
private var nameIndex = 0
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun copy(irElement: IrElement): IrElement {
|
|
||||||
// Create all class descriptors and all necessary descriptors in order to create KotlinTypes.
|
|
||||||
irElement.acceptVoid(DescriptorCollectorCreatePhase())
|
|
||||||
// Initialize all created descriptors possibly using previously created types.
|
|
||||||
irElement.acceptVoid(DescriptorCollectorInitPhase())
|
|
||||||
return irElement.accept(InlineCopyIr(), null)
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class DescriptorCollectorCreatePhase : IrElementVisitorVoidWithContext() {
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildren(this, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitClassNew(declaration: IrClass) {
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
val newDescriptor = copyClassDescriptor(oldDescriptor)
|
|
||||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
|
||||||
descriptorSubstituteMap[oldDescriptor.thisAsReceiverParameter] = newDescriptor.thisAsReceiverParameter
|
|
||||||
|
|
||||||
super.visitClassNew(declaration)
|
|
||||||
|
|
||||||
val constructors = oldDescriptor.constructors.map { oldConstructorDescriptor ->
|
|
||||||
descriptorSubstituteMap[oldConstructorDescriptor] as ClassConstructorDescriptor
|
|
||||||
}.toSet()
|
|
||||||
|
|
||||||
val oldPrimaryConstructor = oldDescriptor.unsubstitutedPrimaryConstructor
|
|
||||||
val primaryConstructor = oldPrimaryConstructor?.let { descriptorSubstituteMap[it] as ClassConstructorDescriptor }
|
|
||||||
|
|
||||||
val contributedDescriptors = oldDescriptor.unsubstitutedMemberScope
|
|
||||||
.getContributedDescriptors()
|
|
||||||
.map { descriptorSubstituteMap[it]!! }
|
|
||||||
newDescriptor.initialize(
|
|
||||||
SimpleMemberScope(contributedDescriptors),
|
|
||||||
constructors,
|
|
||||||
primaryConstructor
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitPropertyNew(declaration: IrProperty) {
|
|
||||||
copyPropertyOrField(declaration.descriptor)
|
|
||||||
super.visitPropertyNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitFieldNew(declaration: IrField) {
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
if (descriptorSubstituteMap[oldDescriptor] == null) {
|
|
||||||
copyPropertyOrField(oldDescriptor) // A field without a property or a field of a delegated property.
|
|
||||||
}
|
|
||||||
super.visitFieldNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitFunctionNew(declaration: IrFunction) {
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property.
|
|
||||||
val oldContainingDeclaration =
|
|
||||||
if (oldDescriptor.visibility == Visibilities.LOCAL)
|
|
||||||
parentDescriptor
|
|
||||||
else
|
|
||||||
oldDescriptor.containingDeclaration
|
|
||||||
descriptorSubstituteMap[oldDescriptor] = copyFunctionDescriptor(oldDescriptor, oldContainingDeclaration)
|
|
||||||
}
|
|
||||||
super.visitFunctionNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//--- Copy descriptors ------------------------------------------------//
|
|
||||||
|
|
||||||
private fun generateCopyName(name: Name): Name {
|
|
||||||
val declarationName = name.toString() // Name of declaration
|
|
||||||
val indexStr = (nameIndex++).toString() // Unique for inline target index
|
|
||||||
return Name.identifier(declarationName + "_" + indexStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyFunctionDescriptor(oldDescriptor: CallableDescriptor, oldContainingDeclaration: DeclarationDescriptor) =
|
|
||||||
when (oldDescriptor) {
|
|
||||||
is ConstructorDescriptor -> copyConstructorDescriptor(oldDescriptor)
|
|
||||||
is SimpleFunctionDescriptor -> copySimpleFunctionDescriptor(oldDescriptor, oldContainingDeclaration)
|
|
||||||
else -> TODO("Unsupported FunctionDescriptor subtype: $oldDescriptor")
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copySimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor, oldContainingDeclaration: DeclarationDescriptor) : FunctionDescriptor {
|
|
||||||
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
|
|
||||||
return SimpleFunctionDescriptorImpl.create(
|
|
||||||
/* containingDeclaration = */ newContainingDeclaration,
|
|
||||||
/* annotations = */ oldDescriptor.annotations,
|
|
||||||
/* name = */ generateCopyName(oldDescriptor.name),
|
|
||||||
/* kind = */ oldDescriptor.kind,
|
|
||||||
/* source = */ oldDescriptor.source
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyConstructorDescriptor(oldDescriptor: ConstructorDescriptor) : FunctionDescriptor {
|
|
||||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
|
||||||
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
|
|
||||||
return ClassConstructorDescriptorImpl.create(
|
|
||||||
/* containingDeclaration = */ newContainingDeclaration as ClassDescriptor,
|
|
||||||
/* annotations = */ oldDescriptor.annotations,
|
|
||||||
/* isPrimary = */ oldDescriptor.isPrimary,
|
|
||||||
/* source = */ oldDescriptor.source
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyPropertyOrField(oldDescriptor: PropertyDescriptor) {
|
|
||||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
|
||||||
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration) as ClassDescriptor
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
val newDescriptor = PropertyDescriptorImpl.create(
|
|
||||||
/* containingDeclaration = */ newContainingDeclaration,
|
|
||||||
/* annotations = */ oldDescriptor.annotations,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* visibility = */ oldDescriptor.visibility,
|
|
||||||
/* isVar = */ oldDescriptor.isVar,
|
|
||||||
/* name = */ oldDescriptor.name,
|
|
||||||
/* kind = */ oldDescriptor.kind,
|
|
||||||
/* source = */ oldDescriptor.source,
|
|
||||||
/* lateInit = */ oldDescriptor.isLateInit,
|
|
||||||
/* isConst = */ oldDescriptor.isConst,
|
|
||||||
/* isExpect = */ oldDescriptor.isExpect,
|
|
||||||
/* isActual = */ oldDescriptor.isActual,
|
|
||||||
/* isExternal = */ oldDescriptor.isExternal,
|
|
||||||
/* isDelegated = */ oldDescriptor.isDelegated
|
|
||||||
)
|
|
||||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyClassDescriptor(oldDescriptor: ClassDescriptor): ClassDescriptorImpl {
|
|
||||||
val oldSuperClass = oldDescriptor.getSuperClassOrAny()
|
|
||||||
val newSuperClass = descriptorSubstituteMap.getOrDefault(oldSuperClass, oldSuperClass) as ClassDescriptor
|
|
||||||
val oldInterfaces = oldDescriptor.getSuperInterfaces()
|
|
||||||
val newInterfaces = oldInterfaces.map { descriptorSubstituteMap.getOrDefault(it, it) as ClassDescriptor }
|
|
||||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
|
||||||
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
|
|
||||||
val newName = if (DescriptorUtils.isAnonymousObject(oldDescriptor)) // Anonymous objects are identified by their name.
|
|
||||||
oldDescriptor.name // We need to preserve it for LocalDeclarationsLowering.
|
|
||||||
else
|
|
||||||
generateCopyName(oldDescriptor.name)
|
|
||||||
|
|
||||||
val visibility = oldDescriptor.visibility
|
|
||||||
|
|
||||||
return object : ClassDescriptorImpl(
|
|
||||||
/* containingDeclaration = */ newContainingDeclaration,
|
|
||||||
/* name = */ newName,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* kind = */ oldDescriptor.kind,
|
|
||||||
/* supertypes = */ listOf(newSuperClass.defaultType) + newInterfaces.map { it.defaultType },
|
|
||||||
/* source = */ oldDescriptor.source,
|
|
||||||
/* isExternal = */ oldDescriptor.isExternal,
|
|
||||||
/* storageManager = */ LockBasedStorageManager.NO_LOCKS
|
|
||||||
) {
|
|
||||||
override fun getVisibility() = visibility
|
|
||||||
|
|
||||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> {
|
|
||||||
return oldDescriptor.declaredTypeParameters
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
inner class DescriptorCollectorInitPhase : IrElementVisitorVoidWithContext() {
|
|
||||||
|
|
||||||
private val initializedProperties = mutableSetOf<PropertyDescriptor>()
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildren(this, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitPropertyNew(declaration: IrProperty) {
|
|
||||||
initPropertyOrField(declaration.descriptor)
|
|
||||||
super.visitPropertyNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitFieldNew(declaration: IrField) {
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
if (!initializedProperties.contains(oldDescriptor)) {
|
|
||||||
initPropertyOrField(oldDescriptor) // A field without a property or a field of a delegated property.
|
|
||||||
}
|
|
||||||
super.visitFieldNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitFunctionNew(declaration: IrFunction) {
|
|
||||||
val oldDescriptor = declaration.descriptor
|
|
||||||
if (oldDescriptor !is PropertyAccessorDescriptor) { // Property accessors are copied along with their property.
|
|
||||||
val newDescriptor = initFunctionDescriptor(oldDescriptor)
|
|
||||||
oldDescriptor.extensionReceiverParameter?.let {
|
|
||||||
descriptorSubstituteMap[it] = newDescriptor.extensionReceiverParameter!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.visitFunctionNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
|
||||||
declaration.descriptor.let { descriptorSubstituteMap[it] = copyVariableDescriptor(it) }
|
|
||||||
|
|
||||||
super.visitVariable(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitCatch(aCatch: IrCatch) {
|
|
||||||
aCatch.parameter.let { descriptorSubstituteMap[it] = copyVariableDescriptor(it) }
|
|
||||||
|
|
||||||
super.visitCatch(aCatch)
|
|
||||||
}
|
|
||||||
|
|
||||||
//--- Copy descriptors ------------------------------------------------//
|
|
||||||
|
|
||||||
private fun generateCopyName(name: Name): Name {
|
|
||||||
val declarationName = name.toString() // Name of declaration
|
|
||||||
val indexStr = (nameIndex++).toString() // Unique for inline target index
|
|
||||||
return Name.identifier(declarationName + "_" + indexStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyVariableDescriptor(oldDescriptor: VariableDescriptor): VariableDescriptor {
|
|
||||||
val oldContainingDeclaration = oldDescriptor.containingDeclaration
|
|
||||||
val newContainingDeclaration = descriptorSubstituteMap.getOrDefault(oldContainingDeclaration, oldContainingDeclaration)
|
|
||||||
return IrTemporaryVariableDescriptorImpl(
|
|
||||||
containingDeclaration = newContainingDeclaration,
|
|
||||||
name = generateCopyName(oldDescriptor.name),
|
|
||||||
outType = substituteType(oldDescriptor.type)!!,
|
|
||||||
isMutable = oldDescriptor.isVar
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun initFunctionDescriptor(oldDescriptor: CallableDescriptor): CallableDescriptor =
|
|
||||||
when (oldDescriptor) {
|
|
||||||
is ConstructorDescriptor -> initConstructorDescriptor(oldDescriptor)
|
|
||||||
is SimpleFunctionDescriptor -> initSimpleFunctionDescriptor(oldDescriptor)
|
|
||||||
else -> TODO("Unsupported FunctionDescriptor subtype: $oldDescriptor")
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun initSimpleFunctionDescriptor(oldDescriptor: SimpleFunctionDescriptor): FunctionDescriptor =
|
|
||||||
(descriptorSubstituteMap[oldDescriptor] as SimpleFunctionDescriptorImpl).apply {
|
|
||||||
val oldDispatchReceiverParameter = oldDescriptor.dispatchReceiverParameter
|
|
||||||
val newDispatchReceiverParameter = oldDispatchReceiverParameter?.let { descriptorSubstituteMap.getOrDefault(it, it) as ReceiverParameterDescriptor }
|
|
||||||
val newTypeParameters = oldDescriptor.typeParameters // TODO substitute types
|
|
||||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this)
|
|
||||||
val newReceiverParameterType = substituteType(oldDescriptor.extensionReceiverParameter?.type)
|
|
||||||
val newReturnType = substituteType(oldDescriptor.returnType)
|
|
||||||
|
|
||||||
initialize(
|
|
||||||
/* receiverParameterType = */ newReceiverParameterType.createExtensionReceiver(this),
|
|
||||||
/* dispatchReceiverParameter = */ newDispatchReceiverParameter,
|
|
||||||
/* typeParameters = */ newTypeParameters,
|
|
||||||
/* unsubstitutedValueParameters = */ newValueParameters,
|
|
||||||
/* unsubstitutedReturnType = */ newReturnType,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* visibility = */ oldDescriptor.visibility
|
|
||||||
)
|
|
||||||
isTailrec = oldDescriptor.isTailrec
|
|
||||||
isSuspend = oldDescriptor.isSuspend
|
|
||||||
overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun initConstructorDescriptor(oldDescriptor: ConstructorDescriptor): FunctionDescriptor =
|
|
||||||
(descriptorSubstituteMap[oldDescriptor] as ClassConstructorDescriptorImpl).apply {
|
|
||||||
val newTypeParameters = oldDescriptor.typeParameters
|
|
||||||
val newValueParameters = copyValueParameters(oldDescriptor.valueParameters, this)
|
|
||||||
val receiverParameterType = substituteType(oldDescriptor.dispatchReceiverParameter?.type)
|
|
||||||
val returnType = substituteType(oldDescriptor.returnType)
|
|
||||||
|
|
||||||
initialize(
|
|
||||||
/* receiverParameterType = */ receiverParameterType.createExtensionReceiver(this),
|
|
||||||
/* dispatchReceiverParameter = */ null, // For constructor there is no explicit dispatch receiver.
|
|
||||||
/* typeParameters = */ newTypeParameters,
|
|
||||||
/* unsubstitutedValueParameters = */ newValueParameters,
|
|
||||||
/* unsubstitutedReturnType = */ returnType,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* visibility = */ oldDescriptor.visibility
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun initPropertyOrField(oldDescriptor: PropertyDescriptor) {
|
|
||||||
val newDescriptor = (descriptorSubstituteMap[oldDescriptor] as PropertyDescriptorImpl).apply {
|
|
||||||
setType(
|
|
||||||
/* outType = */ substituteType(oldDescriptor.type)!!,
|
|
||||||
/* typeParameters = */ oldDescriptor.typeParameters,
|
|
||||||
/* dispatchReceiverParameter = */ (containingDeclaration as ClassDescriptor).thisAsReceiverParameter,
|
|
||||||
/* extensionReceiverParamter = */ substituteType(oldDescriptor.extensionReceiverParameter?.type).createExtensionReceiver(this))
|
|
||||||
|
|
||||||
initialize(
|
|
||||||
/* getter = */ oldDescriptor.getter?.let { copyPropertyGetterDescriptor(it, this) },
|
|
||||||
/* setter = */ oldDescriptor.setter?.let { copyPropertySetterDescriptor(it, this) })
|
|
||||||
|
|
||||||
overriddenDescriptors += oldDescriptor.overriddenDescriptors
|
|
||||||
}
|
|
||||||
oldDescriptor.getter?.let { descriptorSubstituteMap[it] = newDescriptor.getter!! }
|
|
||||||
oldDescriptor.setter?.let { descriptorSubstituteMap[it] = newDescriptor.setter!! }
|
|
||||||
oldDescriptor.extensionReceiverParameter?.let {
|
|
||||||
descriptorSubstituteMap[it] = newDescriptor.extensionReceiverParameter!!
|
|
||||||
}
|
|
||||||
initializedProperties.add(oldDescriptor)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyPropertyGetterDescriptor(oldDescriptor: PropertyGetterDescriptor, newPropertyDescriptor: PropertyDescriptor) =
|
|
||||||
PropertyGetterDescriptorImpl(
|
|
||||||
/* correspondingProperty = */ newPropertyDescriptor,
|
|
||||||
/* annotations = */ oldDescriptor.annotations,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* visibility = */ oldDescriptor.visibility,
|
|
||||||
/* isDefault = */ oldDescriptor.isDefault,
|
|
||||||
/* isExternal = */ oldDescriptor.isExternal,
|
|
||||||
/* isInline = */ oldDescriptor.isInline,
|
|
||||||
/* kind = */ oldDescriptor.kind,
|
|
||||||
/* original = */ null,
|
|
||||||
/* source = */ oldDescriptor.source).apply {
|
|
||||||
initialize(substituteType(oldDescriptor.returnType))
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyPropertySetterDescriptor(oldDescriptor: PropertySetterDescriptor, newPropertyDescriptor: PropertyDescriptor) =
|
|
||||||
PropertySetterDescriptorImpl(
|
|
||||||
/* correspondingProperty = */ newPropertyDescriptor,
|
|
||||||
/* annotations = */ oldDescriptor.annotations,
|
|
||||||
/* modality = */ oldDescriptor.modality,
|
|
||||||
/* visibility = */ oldDescriptor.visibility,
|
|
||||||
/* isDefault = */ oldDescriptor.isDefault,
|
|
||||||
/* isExternal = */ oldDescriptor.isExternal,
|
|
||||||
/* isInline = */ oldDescriptor.isInline,
|
|
||||||
/* kind = */ oldDescriptor.kind,
|
|
||||||
/* original = */ null,
|
|
||||||
/* source = */ oldDescriptor.source).apply {
|
|
||||||
initialize(copyValueParameters(oldDescriptor.valueParameters, this).single())
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyValueParameters(oldValueParameters: List <ValueParameterDescriptor>, containingDeclaration: CallableDescriptor) =
|
|
||||||
oldValueParameters.map { oldDescriptor ->
|
|
||||||
val newDescriptor = ValueParameterDescriptorImpl(
|
|
||||||
containingDeclaration = containingDeclaration,
|
|
||||||
original = oldDescriptor.original,
|
|
||||||
index = oldDescriptor.index,
|
|
||||||
annotations = oldDescriptor.annotations,
|
|
||||||
name = oldDescriptor.name,
|
|
||||||
outType = substituteType(oldDescriptor.type)!!,
|
|
||||||
declaresDefaultValue = oldDescriptor.declaresDefaultValue(),
|
|
||||||
isCrossinline = oldDescriptor.isCrossinline,
|
|
||||||
isNoinline = oldDescriptor.isNoinline,
|
|
||||||
varargElementType = substituteType(oldDescriptor.varargElementType),
|
|
||||||
source = oldDescriptor.source
|
|
||||||
)
|
|
||||||
descriptorSubstituteMap[oldDescriptor] = newDescriptor
|
|
||||||
newDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
inner class InlineCopyIr : DeepCopyIrTree() {
|
|
||||||
|
|
||||||
override fun mapClassDeclaration (descriptor: ClassDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassDescriptor
|
|
||||||
override fun mapTypeAliasDeclaration (descriptor: TypeAliasDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as TypeAliasDescriptor
|
|
||||||
override fun mapFunctionDeclaration (descriptor: FunctionDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as FunctionDescriptor
|
|
||||||
override fun mapConstructorDeclaration (descriptor: ClassConstructorDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassConstructorDescriptor
|
|
||||||
override fun mapPropertyDeclaration (descriptor: PropertyDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as PropertyDescriptor
|
|
||||||
override fun mapLocalPropertyDeclaration (descriptor: VariableDescriptorWithAccessors) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as VariableDescriptorWithAccessors
|
|
||||||
override fun mapEnumEntryDeclaration (descriptor: ClassDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassDescriptor
|
|
||||||
override fun mapVariableDeclaration (descriptor: VariableDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as VariableDescriptor
|
|
||||||
override fun mapErrorDeclaration (descriptor: DeclarationDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor)
|
|
||||||
|
|
||||||
override fun mapClassReference (descriptor: ClassDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassDescriptor
|
|
||||||
override fun mapValueReference (descriptor: ValueDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ValueDescriptor
|
|
||||||
override fun mapVariableReference (descriptor: VariableDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as VariableDescriptor
|
|
||||||
override fun mapPropertyReference (descriptor: PropertyDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as PropertyDescriptor
|
|
||||||
override fun mapCallee (descriptor: FunctionDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as FunctionDescriptor
|
|
||||||
override fun mapDelegatedConstructorCallee (descriptor: ClassConstructorDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassConstructorDescriptor
|
|
||||||
override fun mapEnumConstructorCallee (descriptor: ClassConstructorDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassConstructorDescriptor
|
|
||||||
override fun mapLocalPropertyReference (descriptor: VariableDescriptorWithAccessors) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as VariableDescriptorWithAccessors
|
|
||||||
override fun mapClassifierReference (descriptor: ClassifierDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as ClassifierDescriptor
|
|
||||||
override fun mapReturnTarget (descriptor: FunctionDescriptor) = descriptorSubstituteMap.getOrDefault(descriptor, descriptor) as FunctionDescriptor
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun mapSuperQualifier(qualifier: ClassDescriptor?): ClassDescriptor? {
|
|
||||||
if (qualifier == null) return null
|
|
||||||
return descriptorSubstituteMap.getOrDefault(qualifier, qualifier) as ClassDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
//--- Visits ----------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrCall {
|
|
||||||
if (expression !is IrCallImpl) return super.visitCall(expression)
|
|
||||||
val newDescriptor = mapCallee(expression.descriptor)
|
|
||||||
return IrCallImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = context.symbolTable.translateErased(newDescriptor.returnType!!),
|
|
||||||
descriptor = newDescriptor,
|
|
||||||
typeArgumentsCount = expression.typeArgumentsCount,
|
|
||||||
origin = expression.origin,
|
|
||||||
superQualifierDescriptor = mapSuperQualifier(expression.superQualifier)
|
|
||||||
).apply {
|
|
||||||
transformValueArguments(expression)
|
|
||||||
substituteTypeArguments(expression)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitField(declaration: IrField): IrField {
|
|
||||||
val descriptor = mapPropertyDeclaration(declaration.descriptor)
|
|
||||||
return IrFieldImpl(
|
|
||||||
declaration.startOffset, declaration.endOffset,
|
|
||||||
mapDeclarationOrigin(declaration.origin),
|
|
||||||
descriptor,
|
|
||||||
context.symbolTable.translateErased(descriptor.type),
|
|
||||||
declaration.initializer?.transform(this@InlineCopyIr, null)
|
|
||||||
).apply {
|
|
||||||
transformAnnotations(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitFunction(declaration: IrFunction) =
|
|
||||||
context.symbolTable.withScope(mapFunctionDeclaration(declaration.descriptor)) { descriptor ->
|
|
||||||
IrFunctionImpl(
|
|
||||||
startOffset = declaration.startOffset,
|
|
||||||
endOffset = declaration.endOffset,
|
|
||||||
origin = mapDeclarationOrigin(declaration.origin),
|
|
||||||
descriptor = descriptor,
|
|
||||||
returnType = declaration.returnType,
|
|
||||||
body = declaration.body?.transform(this@InlineCopyIr, null)
|
|
||||||
).also {
|
|
||||||
it.returnType = context.symbolTable.translateErased(descriptor.returnType!!)
|
|
||||||
it.setOverrides(context.symbolTable)
|
|
||||||
it.transformParameters(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// override fun visitSimpleFunction(declaration: IrSimpleFunction): IrFunction {
|
|
||||||
// val descriptor = mapFunctionDeclaration(declaration.descriptor)
|
|
||||||
// return IrFunctionImpl(
|
|
||||||
// startOffset = declaration.startOffset,
|
|
||||||
// endOffset = declaration.endOffset,
|
|
||||||
// origin = mapDeclarationOrigin(declaration.origin),
|
|
||||||
// descriptor = descriptor
|
|
||||||
// ).also {
|
|
||||||
// it.returnType = context.symbolTable.translateErased(descriptor.returnType!!)
|
|
||||||
// it.body = declaration.body?.transform(this, null)
|
|
||||||
//
|
|
||||||
// it.setOverrides(context.symbolTable)
|
|
||||||
// }.transformParameters1(declaration)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// override fun visitConstructor(declaration: IrConstructor): IrConstructor {
|
|
||||||
// val descriptor = mapConstructorDeclaration(declaration.descriptor)
|
|
||||||
// return IrConstructorImpl(
|
|
||||||
// startOffset = declaration.startOffset,
|
|
||||||
// endOffset = declaration.endOffset,
|
|
||||||
// origin = mapDeclarationOrigin(declaration.origin),
|
|
||||||
// descriptor = descriptor
|
|
||||||
// ).also {
|
|
||||||
// it.returnType = context.symbolTable.translateErased(descriptor.returnType)
|
|
||||||
// it.body = declaration.body?.transform(this, null)
|
|
||||||
// }.transformParameters1(declaration)
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun FunctionDescriptor.getTypeParametersToTransform() =
|
|
||||||
when {
|
|
||||||
this is PropertyAccessorDescriptor -> correspondingProperty.typeParameters
|
|
||||||
else -> typeParameters
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun <T : IrFunction> T.transformParameters1(original: T): T =
|
|
||||||
apply {
|
|
||||||
transformTypeParameters(original, descriptor.getTypeParametersToTransform())
|
|
||||||
transformValueParameters1(original)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun <T : IrFunction> T.transformValueParameters1(original: T) =
|
|
||||||
apply {
|
|
||||||
dispatchReceiverParameter =
|
|
||||||
original.dispatchReceiverParameter?.replaceDescriptor1(
|
|
||||||
descriptor.dispatchReceiverParameter ?: throw AssertionError("No dispatch receiver in $descriptor")
|
|
||||||
)
|
|
||||||
|
|
||||||
extensionReceiverParameter =
|
|
||||||
original.extensionReceiverParameter?.replaceDescriptor1(
|
|
||||||
descriptor.extensionReceiverParameter ?: throw AssertionError("No extension receiver in $descriptor")
|
|
||||||
)
|
|
||||||
|
|
||||||
original.valueParameters.mapIndexedTo(valueParameters) { i, originalValueParameter ->
|
|
||||||
originalValueParameter.replaceDescriptor1(descriptor.valueParameters[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun IrValueParameter.replaceDescriptor1(newDescriptor: ParameterDescriptor) =
|
|
||||||
IrValueParameterImpl(
|
|
||||||
startOffset, endOffset,
|
|
||||||
mapDeclarationOrigin(origin),
|
|
||||||
newDescriptor,
|
|
||||||
context.symbolTable.translateErased(newDescriptor.type),
|
|
||||||
(newDescriptor as? ValueParameterDescriptor)?.varargElementType?.let { context.symbolTable.translateErased(it) },
|
|
||||||
defaultValue?.transform(this@InlineCopyIr, null)
|
|
||||||
).apply {
|
|
||||||
transformAnnotations(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrGetValue {
|
|
||||||
val descriptor = mapValueReference(expression.descriptor)
|
|
||||||
return IrGetValueImpl(
|
|
||||||
expression.startOffset, expression.endOffset,
|
|
||||||
context.symbolTable.translateErased(descriptor.type),
|
|
||||||
descriptor,
|
|
||||||
mapStatementOrigin(expression.origin)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable): IrVariable {
|
|
||||||
val descriptor = mapVariableDeclaration(declaration.descriptor)
|
|
||||||
return IrVariableImpl(
|
|
||||||
declaration.startOffset, declaration.endOffset,
|
|
||||||
mapDeclarationOrigin(declaration.origin),
|
|
||||||
descriptor,
|
|
||||||
context.symbolTable.translateErased(descriptor.type),
|
|
||||||
declaration.initializer?.transform(this, null)
|
|
||||||
).apply {
|
|
||||||
transformAnnotations(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T : IrFunction> T.transformDefaults(original: T): T {
|
|
||||||
for (originalValueParameter in original.descriptor.valueParameters) {
|
|
||||||
val valueParameter = descriptor.valueParameters[originalValueParameter.index]
|
|
||||||
original.getDefault(originalValueParameter)?.let { irDefaultParameterValue ->
|
|
||||||
putDefault(valueParameter, irDefaultParameterValue.transform(this@InlineCopyIr, null))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
fun getTypeOperatorReturnType(operator: IrTypeOperator, type: IrType) : IrType {
|
|
||||||
return when (operator) {
|
|
||||||
IrTypeOperator.CAST,
|
|
||||||
IrTypeOperator.IMPLICIT_CAST,
|
|
||||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
|
||||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION,
|
|
||||||
IrTypeOperator.SAM_CONVERSION -> type
|
|
||||||
IrTypeOperator.SAFE_CAST -> type.makeNullable()
|
|
||||||
IrTypeOperator.INSTANCEOF,
|
|
||||||
IrTypeOperator.NOT_INSTANCEOF -> context.irBuiltIns.booleanType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrTypeOperatorCall {
|
|
||||||
val erasedTypeOperand = substituteAndEraseType(expression.typeOperand)!!
|
|
||||||
val typeOperand = substituteAndBreakType(expression.typeOperand)
|
|
||||||
val returnType = getTypeOperatorReturnType(expression.operator, erasedTypeOperand)
|
|
||||||
return IrTypeOperatorCallImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = returnType,
|
|
||||||
operator = expression.operator,
|
|
||||||
typeOperand = typeOperand,
|
|
||||||
argument = expression.argument.transform(this, null),
|
|
||||||
typeOperandClassifier = (typeOperand as IrSimpleType).classifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn): IrReturn =
|
|
||||||
IrReturnImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = substituteAndEraseType(expression.type)!!,
|
|
||||||
returnTargetDescriptor = mapReturnTarget(expression.returnTarget),
|
|
||||||
value = expression.value.transform(this, null)
|
|
||||||
)
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitBlock(expression: IrBlock): IrBlock {
|
|
||||||
return if (expression is IrReturnableBlock) {
|
|
||||||
IrReturnableBlockImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = expression.type,
|
|
||||||
descriptor = expression.descriptor,
|
|
||||||
origin = mapStatementOrigin(expression.origin),
|
|
||||||
statements = expression.statements.map { it.transform(this, null) },
|
|
||||||
sourceFileSymbol = expression.sourceFileSymbol
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
IrBlockImpl(
|
|
||||||
expression.startOffset, expression.endOffset,
|
|
||||||
substituteAndEraseType(expression.type)!!,
|
|
||||||
mapStatementOrigin(expression.origin),
|
|
||||||
expression.statements.map { it.transform(this, null) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitClassReference(expression: IrClassReference): IrClassReference {
|
|
||||||
val newExpressionType = substituteAndEraseType(expression.type)!! // Substituted expression type.
|
|
||||||
val newDescriptorType = substituteType(expression.descriptor.defaultType)!! // Substituted type of referenced class.
|
|
||||||
val classDescriptor = newDescriptorType.constructor.declarationDescriptor!! // Get ClassifierDescriptor of the referenced class.
|
|
||||||
return IrClassReferenceImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = newExpressionType,
|
|
||||||
descriptor = classDescriptor,
|
|
||||||
classType = expression.classType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun visitGetClass(expression: IrGetClass): IrGetClass {
|
|
||||||
val type = substituteAndEraseType(expression.type)!!
|
|
||||||
return IrGetClassImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = type,
|
|
||||||
argument = expression.argument.transform(this, null)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
|
||||||
return irLoop
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrClass {
|
|
||||||
val descriptor = this.mapClassDeclaration(declaration.descriptor)
|
|
||||||
|
|
||||||
return context.symbolTable.declareClass(
|
|
||||||
declaration.startOffset, declaration.endOffset, mapDeclarationOrigin(declaration.origin),
|
|
||||||
descriptor
|
|
||||||
).apply {
|
|
||||||
declaration.declarations.mapTo(this.declarations) {
|
|
||||||
it.transform(this@InlineCopyIr, null) as IrDeclaration
|
|
||||||
}
|
|
||||||
this.transformAnnotations(declaration)
|
|
||||||
this.thisReceiver = declaration.thisReceiver?.replaceDescriptor1(this.descriptor.thisAsReceiverParameter)
|
|
||||||
|
|
||||||
this.transformTypeParameters(declaration, this.descriptor.declaredTypeParameters)
|
|
||||||
|
|
||||||
descriptor.defaultType.constructor.supertypes.mapTo(this.superTypes) {
|
|
||||||
context.symbolTable.translateErased(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun substituteType(type: KotlinType?): KotlinType? {
|
|
||||||
val substitutedType = (type?.let { typeSubstitutor?.substitute(it, Variance.INVARIANT) } ?: type)
|
|
||||||
?: return null
|
|
||||||
val oldClassDescriptor = TypeUtils.getClassDescriptor(substitutedType) ?: return substitutedType
|
|
||||||
return descriptorSubstituteMap[oldClassDescriptor]?.let { (it as ClassDescriptor).defaultType } ?: substitutedType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun substituteAndEraseType(oldType: IrType?): IrType? {
|
|
||||||
oldType ?: return null
|
|
||||||
|
|
||||||
val substitutedKotlinType = substituteType(oldType.toKotlinType())
|
|
||||||
?: return oldType
|
|
||||||
return context.symbolTable.translateErased(substitutedKotlinType)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun translateBroken(type: KotlinType): IrType {
|
|
||||||
val declarationDescriptor = type.constructor.declarationDescriptor
|
|
||||||
return when (declarationDescriptor) {
|
|
||||||
is ClassDescriptor -> {
|
|
||||||
val classifier = context.symbolTable.referenceClassifier(declarationDescriptor)
|
|
||||||
val typeArguments = type.arguments.map {
|
|
||||||
if (it.isStarProjection) {
|
|
||||||
IrStarProjectionImpl
|
|
||||||
} else {
|
|
||||||
makeTypeProjection(translateBroken(it.type), it.projectionKind)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IrSimpleTypeImpl(
|
|
||||||
classifier,
|
|
||||||
type.isMarkedNullable,
|
|
||||||
typeArguments,
|
|
||||||
emptyList()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is TypeParameterDescriptor -> IrSimpleTypeImpl(
|
|
||||||
context.symbolTable.referenceTypeParameter(declarationDescriptor),
|
|
||||||
type.isMarkedNullable,
|
|
||||||
emptyList(),
|
|
||||||
emptyList()
|
|
||||||
)
|
|
||||||
else -> error(declarationDescriptor ?: "null")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun substituteAndBreakType(oldType: IrType): IrType {
|
|
||||||
return translateBroken(substituteType(oldType.toKotlinType())!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun IrMemberAccessExpression.substituteTypeArguments(original: IrMemberAccessExpression) {
|
|
||||||
for (index in 0 until original.typeArgumentsCount) {
|
|
||||||
val originalTypeArgument = original.getTypeArgument(index)
|
|
||||||
val newTypeArgument = substituteAndBreakType(originalTypeArgument!!)
|
|
||||||
this.putTypeArgument(index, newTypeArgument)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun addCurrentSubstituteMap(globalSubstituteMap: MutableMap<DeclarationDescriptor, SubstitutedDescriptor>) {
|
|
||||||
descriptorSubstituteMap.forEach { t, u ->
|
|
||||||
globalSubstituteMap[t] = SubstitutedDescriptor(targetDescriptor, u)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SubstitutedDescriptor(val inlinedFunction: FunctionDescriptor, val descriptor: DeclarationDescriptor)
|
|
||||||
|
|
||||||
internal class DescriptorSubstitutorForExternalScope(
|
|
||||||
val globalSubstituteMap: Map<DeclarationDescriptor, SubstitutedDescriptor>,
|
|
||||||
val context: Context
|
|
||||||
)
|
|
||||||
: IrElementTransformerVoidWithContext() {
|
|
||||||
|
|
||||||
fun run(element: IrElement) {
|
|
||||||
element.transformChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
|
||||||
val oldExpression = super.visitCall(expression) as IrCall
|
|
||||||
|
|
||||||
val substitutedDescriptor = globalSubstituteMap[expression.descriptor.original]
|
|
||||||
?: return oldExpression
|
|
||||||
if (allScopes.any { it.scope.scopeOwner == substitutedDescriptor.inlinedFunction })
|
|
||||||
return oldExpression
|
|
||||||
return when (oldExpression) {
|
|
||||||
is IrCallImpl -> copyIrCallImpl(oldExpression, substitutedDescriptor)
|
|
||||||
is IrCallWithShallowCopy -> copyIrCallWithShallowCopy(oldExpression, substitutedDescriptor)
|
|
||||||
else -> oldExpression
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyIrCallImpl(oldExpression: IrCallImpl, substitutedDescriptor: SubstitutedDescriptor): IrCallImpl {
|
|
||||||
|
|
||||||
val oldDescriptor = oldExpression.descriptor
|
|
||||||
val newDescriptor = substitutedDescriptor.descriptor as FunctionDescriptor
|
|
||||||
|
|
||||||
if (newDescriptor == oldDescriptor)
|
|
||||||
return oldExpression
|
|
||||||
|
|
||||||
return IrCallImpl(
|
|
||||||
startOffset = oldExpression.startOffset,
|
|
||||||
endOffset = oldExpression.endOffset,
|
|
||||||
type = context.symbolTable.translateErased(newDescriptor.returnType!!),
|
|
||||||
symbol = createFunctionSymbol(newDescriptor),
|
|
||||||
descriptor = newDescriptor,
|
|
||||||
typeArgumentsCount = oldExpression.typeArgumentsCount,
|
|
||||||
origin = oldExpression.origin,
|
|
||||||
superQualifierSymbol = createClassSymbolOrNull(oldExpression.superQualifier)
|
|
||||||
).apply {
|
|
||||||
copyTypeArgumentsFrom(oldExpression)
|
|
||||||
|
|
||||||
oldExpression.descriptor.valueParameters.forEach {
|
|
||||||
val valueArgument = oldExpression.getValueArgument(it)
|
|
||||||
putValueArgument(it.index, valueArgument)
|
|
||||||
}
|
|
||||||
extensionReceiver = oldExpression.extensionReceiver
|
|
||||||
dispatchReceiver = oldExpression.dispatchReceiver
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun copyIrCallWithShallowCopy(oldExpression: IrCallWithShallowCopy, substitutedDescriptor: SubstitutedDescriptor): IrCall {
|
|
||||||
|
|
||||||
val oldDescriptor = oldExpression.descriptor
|
|
||||||
val newDescriptor = substitutedDescriptor.descriptor as FunctionDescriptor
|
|
||||||
|
|
||||||
if (newDescriptor == oldDescriptor)
|
|
||||||
return oldExpression
|
|
||||||
|
|
||||||
return oldExpression.shallowCopy(oldExpression.origin, createFunctionSymbol(newDescriptor), oldExpression.superQualifierSymbol)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+326
-413
@@ -7,433 +7,338 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
package org.jetbrains.kotlin.ir.backend.js.lower.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.backend.common.reportWarning
|
||||||
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.fileEntry
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.irTypeKotlinBuiltIns
|
import org.jetbrains.kotlin.ir.types.irTypeKotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
import org.jetbrains.kotlin.ir.util.file
|
import org.jetbrains.kotlin.ir.util.file
|
||||||
import org.jetbrains.kotlin.ir.util.getArguments
|
import org.jetbrains.kotlin.ir.util.getArguments
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
|
||||||
|
|
||||||
abstract class IrElementTransformerWithContext<D> : IrElementTransformer<D> {
|
|
||||||
|
|
||||||
private val scopeStack = mutableListOf<ScopeWithIr>()
|
|
||||||
|
|
||||||
final override fun visitFile(declaration: IrFile, data: D): IrFile {
|
|
||||||
scopeStack.push(ScopeWithIr(Scope(declaration.symbol), declaration))
|
|
||||||
val result = visitFileNew(declaration, data)
|
|
||||||
scopeStack.pop()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitClass(declaration: IrClass, data: D): IrStatement {
|
|
||||||
scopeStack.push(ScopeWithIr(Scope(declaration.symbol), declaration))
|
|
||||||
val result = visitClassNew(declaration, data)
|
|
||||||
scopeStack.pop()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitProperty(declaration: IrProperty, data: D): IrStatement {
|
|
||||||
scopeStack.push(ScopeWithIr(Scope(declaration.descriptor), declaration))
|
|
||||||
val result = visitPropertyNew(declaration, data)
|
|
||||||
scopeStack.pop()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitField(declaration: IrField, data: D): IrStatement {
|
|
||||||
scopeStack.push(ScopeWithIr(Scope(declaration.symbol), declaration))
|
|
||||||
val result = visitFieldNew(declaration, data)
|
|
||||||
scopeStack.pop()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitFunction(declaration: IrFunction, data: D): IrStatement {
|
|
||||||
scopeStack.push(ScopeWithIr(Scope(declaration.symbol), declaration))
|
|
||||||
val result = visitFunctionNew(declaration, data)
|
|
||||||
scopeStack.pop()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
protected val currentFile get() = scopeStack.lastOrNull { it.irElement is IrFile }!!.irElement as IrFile
|
|
||||||
protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwner is ClassDescriptor }
|
|
||||||
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor }
|
|
||||||
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwner is PropertyDescriptor }
|
|
||||||
protected val currentScope get() = scopeStack.peek()
|
|
||||||
protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2]
|
|
||||||
protected val allScopes get() = scopeStack
|
|
||||||
|
|
||||||
fun printScopeStack() {
|
|
||||||
scopeStack.forEach { println(it.scope.scopeOwner) }
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFileNew(declaration: IrFile, data: D): IrFile {
|
|
||||||
return super.visitFile(declaration, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitClassNew(declaration: IrClass, data: D): IrStatement {
|
|
||||||
return super.visitClass(declaration, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFunctionNew(declaration: IrFunction, data: D): IrStatement {
|
|
||||||
return super.visitFunction(declaration, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitPropertyNew(declaration: IrProperty, data: D): IrStatement {
|
|
||||||
return super.visitProperty(declaration, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFieldNew(declaration: IrField, data: D): IrStatement {
|
|
||||||
return super.visitField(declaration, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
typealias Context = JsIrBackendContext
|
typealias Context = JsIrBackendContext
|
||||||
|
|
||||||
internal class Ref<T>(var value: T)
|
|
||||||
|
|
||||||
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt
|
// backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt
|
||||||
internal class FunctionInlining(val context: Context): IrElementTransformerWithContext<Ref<Boolean>>() {
|
internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() {
|
||||||
|
|
||||||
// TODO private val deserializer = DeserializerDriver(context)
|
|
||||||
private val globalSubstituteMap = mutableMapOf<DeclarationDescriptor, SubstitutedDescriptor>()
|
|
||||||
private val inlineFunctions = mutableMapOf<FunctionDescriptor, Boolean>()
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
fun inline(irModule: IrModuleFragment): IrElement {
|
fun inline(irModule: IrModuleFragment): IrElement {
|
||||||
irTypeKotlinBuiltIns = irModule.irBuiltins.builtIns
|
irTypeKotlinBuiltIns = irModule.irBuiltins.builtIns
|
||||||
val transformedModule = irModule.accept(this, Ref(false))
|
return irModule.accept(this, data = null)
|
||||||
DescriptorSubstitutorForExternalScope(globalSubstituteMap, context).run(transformedModule) // Transform calls to object that might be returned from inline function call.
|
|
||||||
return transformedModule
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionNew(declaration: IrFunction, data: Ref<Boolean>): IrStatement {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
val descriptor = declaration.descriptor
|
val callSite = super.visitCall(expression) as IrCall
|
||||||
|
|
||||||
val localData = Ref(inlineFunctions[descriptor] ?: false)
|
|
||||||
val result = super.visitFunctionNew(declaration, localData)
|
|
||||||
data.value = data.value or localData.value
|
|
||||||
|
|
||||||
if (descriptor.needsInlining)
|
|
||||||
inlineFunctions[descriptor] = localData.value
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall, data: Ref<Boolean>): IrExpression {
|
|
||||||
|
|
||||||
val argsAreBad = Ref(false)
|
|
||||||
val callSite = super.visitCall(expression, argsAreBad) as IrCall
|
|
||||||
data.value = data.value or argsAreBad.value
|
|
||||||
val functionDescriptor = callSite.descriptor
|
val functionDescriptor = callSite.descriptor
|
||||||
if (!functionDescriptor.needsInlining) return callSite // This call does not need inlining.
|
if (!functionDescriptor.needsInlining)
|
||||||
|
return callSite // This call does not need inlining.
|
||||||
|
|
||||||
val callee = getFunctionDeclaration(callSite) // Get declaration of the function to be inlined.
|
val callee = getFunctionDeclaration(callSite.symbol) // Get declaration of the function to be inlined.
|
||||||
if (callee == null) { // We failed to get the declaration.
|
callee.transformChildrenVoid(this) // Process recursive inline.
|
||||||
val message = "Inliner failed to obtain function declaration: " +
|
|
||||||
functionDescriptor.fqNameSafe.toString()
|
|
||||||
context.reportWarning(message, currentFile, callSite) // Report warning.
|
|
||||||
return callSite
|
|
||||||
}
|
|
||||||
data.value = data.value or callee.second
|
|
||||||
|
|
||||||
val childIsBad = Ref(inlineFunctions[functionDescriptor] ?: false)
|
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
||||||
callee.first.transformChildren(this, childIsBad) // Process recursive inline.
|
val inliner = Inliner(callSite, callee, currentScope!!, parent, context)
|
||||||
inlineFunctions[functionDescriptor] = childIsBad.value
|
|
||||||
data.value = data.value or childIsBad.value
|
|
||||||
|
|
||||||
val currentCalleeIsBad = argsAreBad.value or childIsBad.value or callee.second
|
|
||||||
val inliner = Inliner(globalSubstituteMap, callSite, callee.first, !currentCalleeIsBad, currentScope!!,
|
|
||||||
allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull(), context, this)
|
|
||||||
// Create inliner for this scope.
|
// Create inliner for this scope.
|
||||||
return inliner.inline() // Return newly created IrInlineBody instead of IrCall.
|
return inliner.inline() // Return newly created IrInlineBody instead of IrCall.
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun getFunctionDeclaration(irCall: IrCall): Pair<IrFunction, Boolean>? {
|
private fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
||||||
|
|
||||||
val functionDescriptor = irCall.descriptor
|
val descriptor = symbol.descriptor.original
|
||||||
val originalDescriptor = functionDescriptor.resolveFakeOverride().original
|
// val originalDescriptor = functionDescriptor.resolveFakeOverride().original
|
||||||
|
|
||||||
val functionDeclaration =
|
val languageVersionSettings = context.configuration.languageVersionSettings
|
||||||
context.originalModuleIndex.functions[originalDescriptor] ?: context.symbolTable.referenceDeclaredFunction(originalDescriptor).owner
|
|
||||||
// ?: // If function is declared in the current module.
|
// TODO: Remove these hacks when coroutine intrinsics are fixed.
|
||||||
// TODO deserializer.deserializeInlineBody(originalDescriptor) // Function is declared in another module.
|
return when {
|
||||||
return (functionDeclaration as IrFunction?)?.let { it to false }
|
// descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||||
|
// error("Continuation.intercepted is not available with release coroutines")
|
||||||
|
//
|
||||||
|
// descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
|
||||||
|
// context.ir.symbols.konanSuspendCoroutineUninterceptedOrReturn.owner
|
||||||
|
//
|
||||||
|
// descriptor == context.ir.symbols.coroutineContextGetter ->
|
||||||
|
// context.ir.symbols.konanCoroutineContextGetter.owner
|
||||||
|
|
||||||
|
else -> (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: should we keep this at all?
|
|
||||||
private val inlineConstructor = FqName("kotlin.native.internal.InlineConstructor")
|
// TODO: should we keep this at all?
|
||||||
private val FunctionDescriptor.isInlineConstructor get() = annotations.hasAnnotation(inlineConstructor)
|
private val inlineConstructor = FqName("kotlin.native.internal.InlineConstructor")
|
||||||
|
private val FunctionDescriptor.isInlineConstructor get() = annotations.hasAnnotation(inlineConstructor)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor, SubstitutedDescriptor>,
|
private inner class Inliner(
|
||||||
val callSite: IrCall,
|
val callSite: IrCall,
|
||||||
val callee: IrFunction,
|
val callee: IrFunction,
|
||||||
val local: Boolean,
|
val currentScope: ScopeWithIr,
|
||||||
val currentScope: ScopeWithIr,
|
val parent: IrDeclarationParent?,
|
||||||
val parent: IrDeclarationParent?,
|
val context: Context
|
||||||
val context: Context,
|
) {
|
||||||
val owner: FunctionInlining /*TODO: make inner*/) {
|
|
||||||
|
|
||||||
val copyIrElement =
|
val copyIrElement = run {
|
||||||
if (!local)
|
val typeParameters =
|
||||||
DeepCopyIrTreeWithDescriptors(callee.descriptor, currentScope.scope.scopeOwner,
|
if (callee is IrConstructor)
|
||||||
context, createTypeSubstitutor(callSite))
|
callee.parentAsClass.typeParameters
|
||||||
else {
|
else callee.typeParameters
|
||||||
val typeParameters =
|
val typeArguments =
|
||||||
if (callee is IrConstructor)
|
(0 until callSite.typeArgumentsCount).map {
|
||||||
callee.parentAsClass.typeParameters
|
typeParameters[it].symbol to callSite.getTypeArgument(it)
|
||||||
else callee.typeParameters
|
}.associate { it }
|
||||||
val typeArguments =
|
DeepCopyIrTreeWithSymbolsForInliner(context, typeArguments, parent)
|
||||||
(0 until callSite.typeArgumentsCount).map {
|
}
|
||||||
typeParameters[it].symbol to callSite.getTypeArgument(it)
|
|
||||||
}.associate { it }
|
val substituteMap = mutableMapOf<ValueDescriptor, IrExpression>()
|
||||||
DeepCopyIrTreeWithSymbolsForInliner(context, typeArguments, parent)
|
|
||||||
|
fun inline() = inlineFunction(callSite, callee)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: JVM inliner crashed on attempt inline this function from transform.kt with:
|
||||||
|
* j.l.IllegalStateException: Couldn't obtain compiled function body for
|
||||||
|
* public inline fun <reified T : org.jetbrains.kotlin.ir.IrElement> kotlin.collections.MutableList<T>.transform...
|
||||||
|
*/
|
||||||
|
private inline fun <reified T : IrElement> MutableList<T>.transform(transformation: (T) -> IrElement) {
|
||||||
|
forEachIndexed { i, item ->
|
||||||
|
set(i, transformation(item) as T)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val substituteMap = mutableMapOf<ValueDescriptor, IrExpression>()
|
private fun inlineFunction(callSite: IrCall, callee: IrFunction): IrReturnableBlockImpl {
|
||||||
|
val copiedCallee = copyIrElement.copy(callee) as IrFunction
|
||||||
|
|
||||||
fun inline() = inlineFunction(callSite, callee)
|
val evaluationStatements = evaluateArguments(callSite, copiedCallee)
|
||||||
|
val statements = (copiedCallee.body as IrBlockBody).statements
|
||||||
|
|
||||||
/**
|
val irReturnableBlockSymbol = IrReturnableBlockSymbolImpl(copiedCallee.descriptor.original)
|
||||||
* TODO: JVM inliner crashed on attempt inline this function from transform.kt with:
|
val descriptor = callee.descriptor.original
|
||||||
* j.l.IllegalStateException: Couldn't obtain compiled function body for
|
val startOffset = callee.startOffset
|
||||||
* public inline fun <reified T : org.jetbrains.kotlin.ir.IrElement> kotlin.collections.MutableList<T>.transform...
|
val endOffset = callee.endOffset
|
||||||
*/
|
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
||||||
private inline fun <reified T : IrElement> MutableList<T>.transform(transformation: (T) -> IrElement) {
|
|
||||||
forEachIndexed { i, item ->
|
|
||||||
set(i, transformation(item) as T)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun inlineFunction(callSite: IrCall, callee: IrFunction): IrReturnableBlockImpl {
|
if (descriptor.isInlineConstructor) {
|
||||||
val copiedCallee = copyIrElement.copy(callee) as IrFunction
|
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
||||||
|
irBuilder.run {
|
||||||
val evaluationStatements = evaluateArguments(callSite, copiedCallee)
|
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
||||||
val statements = (copiedCallee.body as IrBlockBody).statements
|
val constructorCall = irCall(delegatingConstructorCall.symbol, callSite.type,
|
||||||
|
constructorDescriptor.typeParameters.map { delegatingConstructorCall.getTypeArgument(it)!! }).apply {
|
||||||
val irReturnableBlockSymbol = IrReturnableBlockSymbolImpl(copiedCallee.descriptor.original)
|
constructorDescriptor.valueParameters.forEach {
|
||||||
val descriptor = callee.descriptor.original
|
putValueArgument(
|
||||||
val startOffset = callee.startOffset
|
it,
|
||||||
val endOffset = callee.endOffset
|
delegatingConstructorCall.getValueArgument(it)
|
||||||
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, startOffset, endOffset)
|
)
|
||||||
|
}
|
||||||
if (descriptor.isInlineConstructor) {
|
}
|
||||||
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
|
val oldThis = delegatingConstructorCall.descriptor.constructedClass.thisAsReceiverParameter
|
||||||
irBuilder.run {
|
val newThis = currentScope.scope.createTemporaryVariable(
|
||||||
val constructorDescriptor = delegatingConstructorCall.descriptor.original
|
|
||||||
val constructorCall = irCall(delegatingConstructorCall.symbol, callSite.type,
|
|
||||||
constructorDescriptor.typeParameters.map { delegatingConstructorCall.getTypeArgument(it)!! }).apply {
|
|
||||||
constructorDescriptor.valueParameters.forEach { putValueArgument(it, delegatingConstructorCall.getValueArgument(it)) }
|
|
||||||
}
|
|
||||||
val oldThis = delegatingConstructorCall.descriptor.constructedClass.thisAsReceiverParameter
|
|
||||||
val newThis = currentScope.scope.createTemporaryVariable(
|
|
||||||
irExpression = constructorCall,
|
irExpression = constructorCall,
|
||||||
nameHint = delegatingConstructorCall.descriptor.fqNameSafe.toString() + ".this"
|
nameHint = delegatingConstructorCall.descriptor.fqNameSafe.toString() + ".this"
|
||||||
)
|
)
|
||||||
statements[0] = newThis
|
statements[0] = newThis
|
||||||
substituteMap[oldThis] = irGet(newThis)
|
substituteMap[oldThis] = irGet(newThis)
|
||||||
statements.add(irReturn(irGet(newThis)))
|
statements.add(irReturn(irGet(newThis)))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyIrElement.addCurrentSubstituteMap(globalSubstituteMap)
|
|
||||||
|
|
||||||
val transformer = ParameterSubstitutor()
|
|
||||||
statements.transform { it.transform(transformer, data = null) }
|
|
||||||
statements.addAll(0, evaluationStatements)
|
|
||||||
|
|
||||||
return IrReturnableBlockImpl(
|
|
||||||
startOffset = startOffset,
|
|
||||||
endOffset = endOffset,
|
|
||||||
type = copiedCallee.returnType,
|
|
||||||
symbol = irReturnableBlockSymbol,
|
|
||||||
origin = null,
|
|
||||||
statements = statements,
|
|
||||||
sourceFileSymbol = callee.file.symbol
|
|
||||||
).apply {
|
|
||||||
transformChildrenVoid(object: IrElementTransformerVoid() {
|
|
||||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
if (expression.returnTargetSymbol == copiedCallee.symbol)
|
|
||||||
return irBuilder.irReturn(expression.value)
|
|
||||||
return expression
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private inner class ParameterSubstitutor: IrElementTransformerVoid() {
|
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
|
||||||
val newExpression = super.visitGetValue(expression) as IrGetValue
|
|
||||||
val descriptor = newExpression.descriptor
|
|
||||||
val argument = substituteMap[descriptor]
|
|
||||||
|
|
||||||
if (argument == null) return newExpression
|
|
||||||
|
|
||||||
argument.transformChildrenVoid(this) // Default argument can contain subjects for substitution.
|
|
||||||
return copyIrElement.copy(argument) as IrExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------//
|
|
||||||
|
|
||||||
private val IrFunctionReference.isLambda: Boolean
|
|
||||||
get() {
|
|
||||||
return symbol.owner.visibility == Visibilities.LOCAL && origin == IrStatementOrigin.LAMBDA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
val transformer = ParameterSubstitutor()
|
||||||
if (!isLambdaCall(expression))
|
statements.transform { it.transform(transformer, data = null) }
|
||||||
return super.visitCall(expression)
|
statements.addAll(0, evaluationStatements)
|
||||||
|
|
||||||
val dispatchReceiver = expression.dispatchReceiver as IrGetValue
|
return IrReturnableBlockImpl(
|
||||||
val functionArgument = substituteMap[dispatchReceiver.descriptor]
|
startOffset = startOffset,
|
||||||
if (functionArgument == null)
|
endOffset = endOffset,
|
||||||
return super.visitCall(expression)
|
type = copiedCallee.returnType,
|
||||||
val dispatchDescriptor = dispatchReceiver.descriptor
|
symbol = irReturnableBlockSymbol,
|
||||||
if (dispatchDescriptor is ValueParameterDescriptor &&
|
origin = null,
|
||||||
dispatchDescriptor.isNoinline) return super.visitCall(expression)
|
statements = statements,
|
||||||
|
sourceFileSymbol = callee.file.symbol
|
||||||
|
).apply {
|
||||||
|
transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||||
|
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
if (functionArgument is IrFunctionReference) {
|
if (expression.returnTargetSymbol == copiedCallee.symbol)
|
||||||
if (!functionArgument.isLambda) return super.visitCall(expression)
|
return irBuilder.irReturn(expression.value)
|
||||||
|
return expression
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val functionDescriptor = functionArgument.descriptor
|
//---------------------------------------------------------------------//
|
||||||
val functionParameters = functionDescriptor.explicitParameters
|
|
||||||
val boundFunctionParameters = functionArgument.getArguments()
|
|
||||||
val unboundFunctionParameters = functionParameters - boundFunctionParameters.map { it.first }
|
|
||||||
val boundFunctionParametersMap = boundFunctionParameters.associate { it.first to it.second }
|
|
||||||
|
|
||||||
var unboundIndex = 0
|
private inner class ParameterSubstitutor : IrElementTransformerVoid() {
|
||||||
val unboundArgsSet = unboundFunctionParameters.toSet()
|
|
||||||
val valueParameters = expression.getArguments().drop(1) // Skip dispatch receiver.
|
|
||||||
|
|
||||||
val immediateCall = IrCallImpl(
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
|
val newExpression = super.visitGetValue(expression) as IrGetValue
|
||||||
|
val descriptor = newExpression.descriptor
|
||||||
|
val argument = substituteMap[descriptor] ?: return newExpression
|
||||||
|
|
||||||
|
argument.transformChildrenVoid(this) // Default argument can contain subjects for substitution.
|
||||||
|
return copyIrElement.copy(argument) as IrExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------//
|
||||||
|
|
||||||
|
private val IrFunctionReference.isLambda: Boolean
|
||||||
|
get() {
|
||||||
|
return symbol.owner.visibility == Visibilities.LOCAL && origin == IrStatementOrigin.LAMBDA
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
if (!isLambdaCall(expression))
|
||||||
|
return super.visitCall(expression)
|
||||||
|
|
||||||
|
val dispatchReceiver = expression.dispatchReceiver as IrGetValue
|
||||||
|
val functionArgument = substituteMap[dispatchReceiver.descriptor]
|
||||||
|
if (functionArgument == null)
|
||||||
|
return super.visitCall(expression)
|
||||||
|
val dispatchDescriptor = dispatchReceiver.descriptor
|
||||||
|
if (dispatchDescriptor is ValueParameterDescriptor &&
|
||||||
|
dispatchDescriptor.isNoinline
|
||||||
|
) return super.visitCall(expression)
|
||||||
|
|
||||||
|
if (functionArgument is IrFunctionReference) {
|
||||||
|
if (!functionArgument.isLambda) return super.visitCall(expression)
|
||||||
|
|
||||||
|
val functionDescriptor = functionArgument.descriptor
|
||||||
|
val functionParameters = functionDescriptor.explicitParameters
|
||||||
|
val boundFunctionParameters = functionArgument.getArguments()
|
||||||
|
val unboundFunctionParameters = functionParameters - boundFunctionParameters.map { it.first }
|
||||||
|
val boundFunctionParametersMap = boundFunctionParameters.associate { it.first to it.second }
|
||||||
|
|
||||||
|
var unboundIndex = 0
|
||||||
|
val unboundArgsSet = unboundFunctionParameters.toSet()
|
||||||
|
val valueParameters = expression.getArguments().drop(1) // Skip dispatch receiver.
|
||||||
|
|
||||||
|
val immediateCall = IrCallImpl(
|
||||||
startOffset = expression.startOffset,
|
startOffset = expression.startOffset,
|
||||||
endOffset = expression.endOffset,
|
endOffset = expression.endOffset,
|
||||||
type = expression.type,
|
type = expression.type,
|
||||||
symbol = functionArgument.symbol,
|
symbol = functionArgument.symbol,
|
||||||
descriptor = functionArgument.descriptor).apply {
|
descriptor = functionArgument.descriptor
|
||||||
functionParameters.forEach {
|
).apply {
|
||||||
val argument =
|
functionParameters.forEach {
|
||||||
|
val argument =
|
||||||
if (!unboundArgsSet.contains(it))
|
if (!unboundArgsSet.contains(it))
|
||||||
boundFunctionParametersMap[it]!!
|
boundFunctionParametersMap[it]!!
|
||||||
else
|
else
|
||||||
valueParameters[unboundIndex++].second
|
valueParameters[unboundIndex++].second
|
||||||
when (it) {
|
when (it) {
|
||||||
functionDescriptor.dispatchReceiverParameter -> this.dispatchReceiver = argument
|
functionDescriptor.dispatchReceiverParameter -> this.dispatchReceiver = argument
|
||||||
functionDescriptor.extensionReceiverParameter -> this.extensionReceiver = argument
|
functionDescriptor.extensionReceiverParameter -> this.extensionReceiver = argument
|
||||||
else -> putValueArgument((it as ValueParameterDescriptor).index, argument)
|
else -> putValueArgument((it as ValueParameterDescriptor).index, argument)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
assert(unboundIndex == valueParameters.size) { "Not all arguments of <invoke> are used" }
|
||||||
}
|
}
|
||||||
assert(unboundIndex == valueParameters.size) { "Not all arguments of <invoke> are used" }
|
return this@FunctionInlining.visitCall(super.visitCall(immediateCall) as IrCall)
|
||||||
}
|
}
|
||||||
return owner.visitCall(super.visitCall(immediateCall) as IrCall, Ref(false))
|
if (functionArgument !is IrBlock)
|
||||||
}
|
return super.visitCall(expression)
|
||||||
if (functionArgument !is IrBlock)
|
|
||||||
return super.visitCall(expression)
|
|
||||||
|
|
||||||
val functionDeclaration = functionArgument.statements[0] as IrFunction
|
val functionDeclaration = functionArgument.statements[0] as IrFunction
|
||||||
val newExpression = inlineFunction(expression, functionDeclaration) // Inline the lambda. Lambda parameters will be substituted with lambda arguments.
|
val newExpression = inlineFunction(
|
||||||
return newExpression.transform(this, null) // Substitute lambda arguments with target function arguments.
|
expression,
|
||||||
|
functionDeclaration
|
||||||
|
) // Inline the lambda. Lambda parameters will be substituted with lambda arguments.
|
||||||
|
return newExpression.transform(
|
||||||
|
this,
|
||||||
|
null
|
||||||
|
) // Substitute lambda arguments with target function arguments.
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitElement(element: IrElement) = element.accept(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------//
|
private fun isLambdaCall(irCall: IrCall) = irCall.symbol.owner.isFunctionInvoke && irCall.dispatchReceiver is IrGetValue
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) = element.accept(this, null)
|
//-------------------------------------------------------------------------//
|
||||||
}
|
|
||||||
|
|
||||||
private fun isLambdaCall(irCall: IrCall) = irCall.symbol.owner.isFunctionInvoke && irCall.dispatchReceiver is IrGetValue
|
private inner class ParameterToArgument(
|
||||||
|
val parameter: IrValueParameter,
|
||||||
|
val argumentExpression: IrExpression
|
||||||
|
) {
|
||||||
|
|
||||||
private fun createTypeSubstitutor(irCall: IrCall): TypeSubstitutor? {
|
val isInlinableLambdaArgument: Boolean
|
||||||
if (irCall.typeArgumentsCount == 0) return null
|
get() {
|
||||||
val descriptor = irCall.descriptor.resolveFakeOverride().original
|
if (!InlineUtil.isInlineParameter(parameter.descriptor)) return false
|
||||||
val typeParameters = descriptor.propertyIfAccessor.typeParameters
|
if (argumentExpression is IrFunctionReference
|
||||||
val substitutionContext = mutableMapOf<TypeConstructor, TypeProjection>()
|
&& !argumentExpression.descriptor.isSuspend
|
||||||
for (index in 0 until irCall.typeArgumentsCount) {
|
) return true // Skip suspend functions for now since it's not supported by FE anyway.
|
||||||
val typeArgument = irCall.getTypeArgument(index) ?: continue
|
|
||||||
substitutionContext[typeParameters[index].typeConstructor] = TypeProjectionImpl(typeArgument.toKotlinType())
|
// Do pattern-matching on IR.
|
||||||
|
if (argumentExpression !is IrBlock) return false
|
||||||
|
if (argumentExpression.origin != IrStatementOrigin.LAMBDA &&
|
||||||
|
argumentExpression.origin != IrStatementOrigin.ANONYMOUS_FUNCTION
|
||||||
|
) return false
|
||||||
|
val statements = argumentExpression.statements
|
||||||
|
val irFunction = statements[0]
|
||||||
|
val irCallableReference = statements[1]
|
||||||
|
if (irFunction !is IrFunction) return false
|
||||||
|
if (irCallableReference !is IrCallableReference) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val isImmutableVariableLoad: Boolean
|
||||||
|
get() = argumentExpression.let {
|
||||||
|
it is IrGetValue && !it.symbol.owner.let { v -> v is IrVariable && v.isVar }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return TypeSubstitutor.create(substitutionContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private class ParameterToArgument(val parameter: IrValueParameter,
|
private fun buildParameterToArgument(callSite: IrCall, callee: IrFunction): List<ParameterToArgument> {
|
||||||
val argumentExpression : IrExpression) {
|
|
||||||
|
|
||||||
val isInlinableLambdaArgument : Boolean
|
val parameterToArgument = mutableListOf<ParameterToArgument>()
|
||||||
get() {
|
|
||||||
if (!InlineUtil.isInlineParameter(parameter.descriptor)) return false
|
|
||||||
if (argumentExpression is IrFunctionReference
|
|
||||||
&& !argumentExpression.descriptor.isSuspend) return true // Skip suspend functions for now since it's not supported by FE anyway.
|
|
||||||
|
|
||||||
// Do pattern-matching on IR.
|
if (callSite.dispatchReceiver != null && // Only if there are non null dispatch receivers both
|
||||||
if (argumentExpression !is IrBlock) return false
|
callee.dispatchReceiverParameter != null
|
||||||
if (argumentExpression.origin != IrStatementOrigin.LAMBDA &&
|
) // on call site and in function declaration.
|
||||||
argumentExpression.origin != IrStatementOrigin.ANONYMOUS_FUNCTION) return false
|
parameterToArgument += ParameterToArgument(
|
||||||
val statements = argumentExpression.statements
|
parameter = callee.dispatchReceiverParameter!!,
|
||||||
val irFunction = statements[0]
|
argumentExpression = callSite.dispatchReceiver!!
|
||||||
val irCallableReference = statements[1]
|
)
|
||||||
if (irFunction !is IrFunction) return false
|
|
||||||
if (irCallableReference !is IrCallableReference) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
val isImmutableVariableLoad: Boolean
|
val valueArguments =
|
||||||
get() = argumentExpression.let {
|
|
||||||
it is IrGetValue && !it.descriptor.let { it is VariableDescriptor && it.isVar }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun buildParameterToArgument(callSite: IrCall, callee: IrFunction): List<ParameterToArgument> {
|
|
||||||
|
|
||||||
val parameterToArgument = mutableListOf<ParameterToArgument>()
|
|
||||||
|
|
||||||
if (callSite.dispatchReceiver != null && // Only if there are non null dispatch receivers both
|
|
||||||
callee.dispatchReceiverParameter != null) // on call site and in function declaration.
|
|
||||||
parameterToArgument += ParameterToArgument(
|
|
||||||
parameter = callee.dispatchReceiverParameter!!,
|
|
||||||
argumentExpression = callSite.dispatchReceiver!!
|
|
||||||
)
|
|
||||||
|
|
||||||
val valueArguments =
|
|
||||||
callSite.descriptor.valueParameters.map { callSite.getValueArgument(it) }.toMutableList()
|
callSite.descriptor.valueParameters.map { callSite.getValueArgument(it) }.toMutableList()
|
||||||
|
|
||||||
if (callee.extensionReceiverParameter != null) {
|
if (callee.extensionReceiverParameter != null) {
|
||||||
parameterToArgument += ParameterToArgument(
|
parameterToArgument += ParameterToArgument(
|
||||||
parameter = callee.extensionReceiverParameter!!,
|
parameter = callee.extensionReceiverParameter!!,
|
||||||
argumentExpression = if (callSite.extensionReceiver != null) {
|
argumentExpression = if (callSite.extensionReceiver != null) {
|
||||||
callSite.extensionReceiver!!
|
callSite.extensionReceiver!!
|
||||||
@@ -441,95 +346,103 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
|||||||
// Special case: lambda with receiver is called as usual lambda:
|
// Special case: lambda with receiver is called as usual lambda:
|
||||||
valueArguments.removeAt(0)!!
|
valueArguments.removeAt(0)!!
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else if (callSite.extensionReceiver != null) {
|
} else if (callSite.extensionReceiver != null) {
|
||||||
// Special case: usual lambda is called as lambda with receiver:
|
// Special case: usual lambda is called as lambda with receiver:
|
||||||
valueArguments.add(0, callSite.extensionReceiver!!)
|
valueArguments.add(0, callSite.extensionReceiver!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
|
val parametersWithDefaultToArgument = mutableListOf<ParameterToArgument>()
|
||||||
for (parameter in callee.valueParameters) {
|
for (parameter in callee.valueParameters) {
|
||||||
val argument = valueArguments[parameter.index]
|
val argument = valueArguments[parameter.index]
|
||||||
when {
|
when {
|
||||||
argument != null -> {
|
argument != null -> {
|
||||||
parameterToArgument += ParameterToArgument(
|
parameterToArgument += ParameterToArgument(
|
||||||
parameter = parameter,
|
parameter = parameter,
|
||||||
argumentExpression = argument
|
argumentExpression = argument
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// After ExpectDeclarationsRemoving pass default values from expect declarations
|
// After ExpectDeclarationsRemoving pass default values from expect declarations
|
||||||
// are represented correctly in IR.
|
// are represented correctly in IR.
|
||||||
parameter.defaultValue != null -> { // There is no argument - try default value.
|
parameter.defaultValue != null -> { // There is no argument - try default value.
|
||||||
parametersWithDefaultToArgument += ParameterToArgument(
|
parametersWithDefaultToArgument += ParameterToArgument(
|
||||||
parameter = parameter,
|
parameter = parameter,
|
||||||
argumentExpression = parameter.defaultValue!!.expression
|
argumentExpression = parameter.defaultValue!!.expression
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
parameter.varargElementType != null -> {
|
parameter.varargElementType != null -> {
|
||||||
val emptyArray = IrVarargImpl(
|
val emptyArray = IrVarargImpl(
|
||||||
startOffset = callSite.startOffset,
|
startOffset = callSite.startOffset,
|
||||||
endOffset = callSite.endOffset,
|
endOffset = callSite.endOffset,
|
||||||
type = parameter.type,
|
type = parameter.type,
|
||||||
varargElementType = parameter.varargElementType!!
|
varargElementType = parameter.varargElementType!!
|
||||||
)
|
)
|
||||||
parameterToArgument += ParameterToArgument(
|
parameterToArgument += ParameterToArgument(
|
||||||
parameter = parameter,
|
parameter = parameter,
|
||||||
argumentExpression = emptyArray
|
argumentExpression = emptyArray
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
val message = "Incomplete expression: call to ${callee.descriptor} " +
|
val message = "Incomplete expression: call to ${callee.descriptor} " +
|
||||||
"has no argument at index ${parameter.index}"
|
"has no argument at index ${parameter.index}"
|
||||||
throw Error(message)
|
throw Error(message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return parameterToArgument + parametersWithDefaultToArgument // All arguments except default are evaluated at callsite,
|
||||||
|
// but default arguments are evaluated inside callee.
|
||||||
}
|
}
|
||||||
return parameterToArgument + parametersWithDefaultToArgument // All arguments except default are evaluated at callsite,
|
|
||||||
// but default arguments are evaluated inside callee.
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun evaluateArguments(callSite: IrCall, callee: IrFunction): List<IrStatement> {
|
private fun evaluateArguments(callSite: IrCall, callee: IrFunction): List<IrStatement> {
|
||||||
|
|
||||||
val parameterToArgumentOld = buildParameterToArgument(callSite, callee)
|
val parameterToArgumentOld = buildParameterToArgument(callSite, callee)
|
||||||
val evaluationStatements = mutableListOf<IrStatement>()
|
val evaluationStatements = mutableListOf<IrStatement>()
|
||||||
val substitutor = ParameterSubstitutor()
|
val substitutor = ParameterSubstitutor()
|
||||||
parameterToArgumentOld.forEach {
|
parameterToArgumentOld.forEach {
|
||||||
val parameterDescriptor = it.parameter.descriptor
|
val parameterDescriptor = it.parameter.descriptor
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to create temporary variable for each argument except inlinable lambda arguments.
|
* We need to create temporary variable for each argument except inlinable lambda arguments.
|
||||||
* For simplicity and to produce simpler IR we don't create temporaries for every immutable variable,
|
* For simplicity and to produce simpler IR we don't create temporaries for every immutable variable,
|
||||||
* not only for those referring to inlinable lambdas.
|
* not only for those referring to inlinable lambdas.
|
||||||
*/
|
*/
|
||||||
if (it.isInlinableLambdaArgument) {
|
if (it.isInlinableLambdaArgument) {
|
||||||
substituteMap[parameterDescriptor] = it.argumentExpression
|
substituteMap[parameterDescriptor] = it.argumentExpression
|
||||||
return@forEach
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it.isImmutableVariableLoad) {
|
||||||
|
substituteMap[parameterDescriptor] = it.argumentExpression.transform(
|
||||||
|
substitutor,
|
||||||
|
data = null
|
||||||
|
) // Arguments may reference the previous ones - substitute them.
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
val newVariable = currentScope.scope.createTemporaryVariable(
|
||||||
|
irExpression = it.argumentExpression.transform(
|
||||||
|
substitutor,
|
||||||
|
data = null
|
||||||
|
), // Arguments may reference the previous ones - substitute them.
|
||||||
|
nameHint = callee.descriptor.name.toString(),
|
||||||
|
isMutable = false
|
||||||
|
)
|
||||||
|
|
||||||
|
evaluationStatements.add(newVariable)
|
||||||
|
val getVal = IrGetValueImpl(
|
||||||
|
startOffset = currentScope.irElement.startOffset,
|
||||||
|
endOffset = currentScope.irElement.endOffset,
|
||||||
|
type = newVariable.type,
|
||||||
|
symbol = newVariable.symbol
|
||||||
|
)
|
||||||
|
substituteMap[parameterDescriptor] = getVal
|
||||||
}
|
}
|
||||||
|
return evaluationStatements
|
||||||
if (it.isImmutableVariableLoad) {
|
|
||||||
substituteMap[parameterDescriptor] = it.argumentExpression.transform(substitutor, data = null) // Arguments may reference the previous ones - substitute them.
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
|
|
||||||
val newVariable = currentScope.scope.createTemporaryVariable(
|
|
||||||
irExpression = it.argumentExpression.transform(substitutor, data = null), // Arguments may reference the previous ones - substitute them.
|
|
||||||
nameHint = callee.descriptor.name.toString(),
|
|
||||||
isMutable = false)
|
|
||||||
|
|
||||||
evaluationStatements.add(newVariable)
|
|
||||||
val getVal = IrGetValueImpl(
|
|
||||||
startOffset = currentScope.irElement.startOffset,
|
|
||||||
endOffset = currentScope.irElement.endOffset,
|
|
||||||
type = newVariable.type,
|
|
||||||
symbol = newVariable.symbol
|
|
||||||
)
|
|
||||||
substituteMap[parameterDescriptor] = getVal
|
|
||||||
}
|
}
|
||||||
return evaluationStatements
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
|
import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
|
||||||
import org.jetbrains.kotlin.ir.util.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.ir.util.isFunctionTypeOrSubtype
|
||||||
|
import org.jetbrains.kotlin.ir.util.isKFunction
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -54,7 +55,7 @@ internal val FunctionDescriptor.isFunctionInvoke: Boolean
|
|||||||
internal val IrFunction.isFunctionInvoke: Boolean
|
internal val IrFunction.isFunctionInvoke: Boolean
|
||||||
get() {
|
get() {
|
||||||
val dispatchReceiver = dispatchReceiverParameter ?: return false
|
val dispatchReceiver = dispatchReceiverParameter ?: return false
|
||||||
assert(!dispatchReceiver.type.isFunctionTypeOrSubtype())
|
assert(!dispatchReceiver.type.isKFunction())
|
||||||
|
|
||||||
return dispatchReceiver.type.isFunctionTypeOrSubtype() &&
|
return dispatchReceiver.type.isFunctionTypeOrSubtype() &&
|
||||||
/*this.isOperator &&*/ this.name == OperatorNameConventions.INVOKE
|
/*this.isOperator &&*/ this.name == OperatorNameConventions.INVOKE
|
||||||
|
|||||||
+12
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
@@ -199,4 +200,14 @@ val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.corr
|
|||||||
|
|
||||||
val IrDeclaration.isSetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.setter
|
val IrDeclaration.isSetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.setter
|
||||||
|
|
||||||
val IrDeclaration.isAccessor get() = this.isGetter || this.isSetter
|
val IrDeclaration.isAccessor get() = this.isGetter || this.isSetter
|
||||||
|
|
||||||
|
val IrDeclaration.fileEntry: SourceManager.FileEntry
|
||||||
|
get() = parent.let {
|
||||||
|
when (it) {
|
||||||
|
is IrFile -> it.fileEntry
|
||||||
|
is IrPackageFragment -> TODO("Unknown file")
|
||||||
|
is IrDeclaration -> it.fileEntry
|
||||||
|
else -> TODO("Unexpected declaration parent")
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-24
@@ -36,34 +36,31 @@ internal val IrField.isDelegate
|
|||||||
|
|
||||||
internal const val SYNTHETIC_OFFSET = -2
|
internal const val SYNTHETIC_OFFSET = -2
|
||||||
|
|
||||||
class NaiveSourceBasedFileEntryImpl(override val name: String) : SourceManager.FileEntry {
|
val File.lineStartOffsets: IntArray
|
||||||
|
get() {
|
||||||
private val lineStartOffsets: IntArray
|
// TODO: could be incorrect, if file is not in system's line terminator format.
|
||||||
|
// Maybe use (0..document.lineCount - 1)
|
||||||
//-------------------------------------------------------------------------//
|
// .map { document.getLineStartOffset(it) }
|
||||||
|
// .toIntArray()
|
||||||
init {
|
// as in PSI.
|
||||||
val file = File(name)
|
val separatorLength = System.lineSeparator().length
|
||||||
if (file.isFile) {
|
val buffer = mutableListOf<Int>()
|
||||||
// TODO: could be incorrect, if file is not in system's line terminator format.
|
var currentOffset = 0
|
||||||
// Maybe use (0..document.lineCount - 1)
|
this.forEachLine { line ->
|
||||||
// .map { document.getLineStartOffset(it) }
|
|
||||||
// .toIntArray()
|
|
||||||
// as in PSI.
|
|
||||||
val separatorLength = System.lineSeparator().length
|
|
||||||
val buffer = mutableListOf<Int>()
|
|
||||||
var currentOffset = 0
|
|
||||||
file.forEachLine { line ->
|
|
||||||
buffer.add(currentOffset)
|
|
||||||
currentOffset += line.length + separatorLength
|
|
||||||
}
|
|
||||||
buffer.add(currentOffset)
|
buffer.add(currentOffset)
|
||||||
lineStartOffsets = buffer.toIntArray()
|
currentOffset += line.length + separatorLength
|
||||||
} else {
|
|
||||||
lineStartOffsets = IntArray(0)
|
|
||||||
}
|
}
|
||||||
|
buffer.add(currentOffset)
|
||||||
|
return buffer.toIntArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val SourceManager.FileEntry.lineStartOffsets
|
||||||
|
get() = File(name).let {
|
||||||
|
if (it.exists() && it.isFile) it.lineStartOffsets else IntArray(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
class NaiveSourceBasedFileEntryImpl(override val name: String, val lineStartOffsets: IntArray = IntArray(0)) : SourceManager.FileEntry {
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun getLineNumber(offset: Int): Int {
|
override fun getLineNumber(offset: Int): Int {
|
||||||
|
|||||||
+19
-34
@@ -19,17 +19,10 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
fun <K, V> MutableMap<K, V>.putOnce(k:K, v: V): Unit {
|
|
||||||
assert(!this.containsKey(k) || this[k] == v) {
|
|
||||||
"adding $v for $k, but it is already ${this[k]} for $k"
|
|
||||||
}
|
|
||||||
this.put(k, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DescriptorTable {
|
class DescriptorTable {
|
||||||
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
|
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
|
||||||
fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) {
|
fun put(descriptor: DeclarationDescriptor, uniqId: UniqId) {
|
||||||
descriptors.putOnce(descriptor, uniqId.index)
|
descriptors.getOrPut(descriptor) { uniqId.index }
|
||||||
}
|
}
|
||||||
fun get(descriptor: DeclarationDescriptor) = descriptors[descriptor]
|
fun get(descriptor: DeclarationDescriptor) = descriptors[descriptor]
|
||||||
}
|
}
|
||||||
@@ -54,35 +47,27 @@ class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: Descriptor
|
|||||||
currentIndex += BUILT_IN_UNIQ_ID_GAP
|
currentIndex += BUILT_IN_UNIQ_ID_GAP
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uniqIdByDeclaration(value: IrDeclaration): UniqId {
|
fun uniqIdByDeclaration(value: IrDeclaration) = table.getOrPut(value) {
|
||||||
val index = table.getOrPut(value) {
|
val index = if (isBuiltInFunction(value)) {
|
||||||
|
UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false)
|
||||||
if (isBuiltInFunction(value)) {
|
} else if (value.origin == IrDeclarationOrigin.FAKE_OVERRIDE ||
|
||||||
UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false)
|
!value.isExported()
|
||||||
} else if (value.origin == IrDeclarationOrigin.FAKE_OVERRIDE ||
|
|| value is IrVariable
|
||||||
!value.isExported()
|
|| value is IrTypeParameter
|
||||||
|| value is IrVariable
|
|| value is IrValueParameter
|
||||||
|| value is IrTypeParameter
|
|| value is IrAnonymousInitializerImpl
|
||||||
|| value is IrValueParameter
|
) {
|
||||||
|| value is IrAnonymousInitializerImpl
|
UniqId(currentIndex++, true)
|
||||||
) {
|
} else {
|
||||||
|
UniqId(value.uniqIdIndex, false)
|
||||||
val desc = value.descriptor
|
|
||||||
if (desc is CallableDescriptor) {
|
|
||||||
if (desc.visibility == Visibilities.PUBLIC || value.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
|
|
||||||
fun foo(){}
|
|
||||||
foo()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UniqId(currentIndex++, true)
|
|
||||||
} else {
|
|
||||||
UniqId(value.uniqIdIndex, false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debugIndex.put(index, "${if (index.isLocal) "" else value.uniqSymbolName()} descriptor = ${value.descriptor}")
|
// It can grow as large as 1/3 of ir/* size.
|
||||||
|
// debugIndex.put(index) {
|
||||||
|
// "${if (index.isLocal) "" else value.uniqSymbolName()} descriptor = ${value.descriptor}"
|
||||||
|
//}.also {it == null}
|
||||||
|
|
||||||
return index
|
index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-22
@@ -13,29 +13,42 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
|
|
||||||
class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>) {
|
class DescriptorReferenceDeserializer(
|
||||||
|
val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>,
|
||||||
|
val checkerDesc: (DeclarationDescriptor) -> Long?,
|
||||||
|
val checkerID: (Long) -> Boolean,
|
||||||
|
val descriptorResolver: (FqName) -> DeclarationDescriptor
|
||||||
|
) {
|
||||||
|
|
||||||
fun deserializeDescriptorReference(
|
fun deserializeDescriptorReference(
|
||||||
proto: IrKlibProtoBuf.DescriptorReference,
|
packageFqNameString: String,
|
||||||
checkerDesc: (DeclarationDescriptor) -> Long?,
|
classFqNameString: String,
|
||||||
checkerID: (Long) -> Boolean,
|
name: String,
|
||||||
descriptorResolver: (FqName) -> DeclarationDescriptor
|
index: Long?,
|
||||||
|
isEnumEntry: Boolean = false,
|
||||||
|
isEnumSpecial: Boolean = false,
|
||||||
|
isDefaultConstructor: Boolean = false,
|
||||||
|
isFakeOverride: Boolean = false,
|
||||||
|
isGetter: Boolean = false,
|
||||||
|
isSetter: Boolean = false
|
||||||
): DeclarationDescriptor {
|
): DeclarationDescriptor {
|
||||||
val packageFqName =
|
val packageFqName = packageFqNameString.let {
|
||||||
if (proto.packageFqName == "<root>") FqName.ROOT else FqName(proto.packageFqName) // TODO: whould we store an empty string in the protobuf?
|
if (it == "<root>") FqName.ROOT else FqName(it)
|
||||||
val classFqName = FqName(proto.classFqName)
|
}// TODO: whould we store an empty string in the protobuf?
|
||||||
val protoIndex = if (proto.hasUniqId()) proto.uniqId.index else null
|
|
||||||
|
|
||||||
val (clazz, members) = if (proto.classFqName == "") {
|
val classFqName = FqName(classFqNameString)
|
||||||
|
val protoIndex = index
|
||||||
|
|
||||||
|
val (clazz, members) = if (classFqNameString == "") {
|
||||||
Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors())
|
Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors())
|
||||||
} else {
|
} else {
|
||||||
val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!!
|
val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!!
|
||||||
Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors())
|
Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto.packageFqName.startsWith("cnames.") || proto.packageFqName.startsWith("objcnames.")) {
|
if (packageFqNameString.startsWith("cnames.") || packageFqNameString.startsWith("objcnames.")) {
|
||||||
val descriptor =
|
val descriptor =
|
||||||
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(proto.name), false))!!
|
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(name), false))!!
|
||||||
if (!descriptor.fqNameUnsafe.asString().startsWith("cnames") && !descriptor.fqNameUnsafe.asString().startsWith(
|
if (!descriptor.fqNameUnsafe.asString().startsWith("cnames") && !descriptor.fqNameUnsafe.asString().startsWith(
|
||||||
"objcnames"
|
"objcnames"
|
||||||
)
|
)
|
||||||
@@ -53,27 +66,25 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
|
|||||||
return descriptor
|
return descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto.isEnumEntry) {
|
if (isEnumEntry) {
|
||||||
val name = proto.name
|
|
||||||
val memberScope = (clazz as DeserializedClassDescriptor).getUnsubstitutedMemberScope()
|
val memberScope = (clazz as DeserializedClassDescriptor).getUnsubstitutedMemberScope()
|
||||||
return memberScope.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND)!!
|
return memberScope.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto.isEnumSpecial) {
|
if (isEnumSpecial) {
|
||||||
val name = proto.name
|
|
||||||
return clazz!!.getStaticScope()
|
return clazz!!.getStaticScope()
|
||||||
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protoIndex?.let { checkerID(it) } == true) {
|
if (protoIndex?.let { checkerID(it) } == true) {
|
||||||
return descriptorResolver(packageFqName.child(Name.identifier(proto.name)))
|
return descriptorResolver(packageFqName.child(Name.identifier(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
members.forEach { member ->
|
members.forEach { member ->
|
||||||
if (proto.isDefaultConstructor && member is ClassConstructorDescriptor) return member
|
if (isDefaultConstructor && member is ClassConstructorDescriptor) return member
|
||||||
|
|
||||||
val realMembers =
|
val realMembers =
|
||||||
if (proto.isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
if (isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
||||||
member.resolveFakeOverrideMaybeAbstract().map { it.original }
|
member.resolveFakeOverrideMaybeAbstract().map { it.original }
|
||||||
else
|
else
|
||||||
setOf(member)
|
setOf(member)
|
||||||
@@ -82,13 +93,13 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
|
|||||||
|
|
||||||
if (memberIndices.contains(protoIndex)) {
|
if (memberIndices.contains(protoIndex)) {
|
||||||
return when {
|
return when {
|
||||||
member is PropertyDescriptor && proto.isSetter -> member.setter!!
|
member is PropertyDescriptor && isSetter -> member.setter!!
|
||||||
member is PropertyDescriptor && proto.isGetter -> member.getter!!
|
member is PropertyDescriptor && isGetter -> member.getter!!
|
||||||
else -> member
|
else -> member
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error("Could not find serialized descriptor for index: ${proto.uniqId.index} ${proto.packageFqName},${proto.classFqName},${proto.name}")
|
error("Could not find serialized descriptor for index: $index $packageFqName,$classFqName,$name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4579
-3232
File diff suppressed because it is too large
Load Diff
+35
-16
@@ -9,9 +9,9 @@ import org.jetbrains.kotlin.backend.common.LoggingContext
|
|||||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializerProtocol
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializerProtocol
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.*
|
import org.jetbrains.kotlin.ir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.types.IrType
|
|||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
@@ -44,10 +43,15 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
|
|
||||||
var deserializedModuleDescriptor: ModuleDescriptor? = null
|
var deserializedModuleDescriptor: ModuleDescriptor? = null
|
||||||
var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
|
var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
|
||||||
|
var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>()
|
||||||
var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
|
var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
|
||||||
|
|
||||||
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
|
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
|
||||||
val descriptorReferenceDeserializer = DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations)
|
val descriptorReferenceDeserializer = DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations, {
|
||||||
|
knownBuiltInsDescriptors[it]?.index ?: if (isBuiltInFunction(it)) FUNCTION_INDEX_START + builtInFunctionId(it) else null
|
||||||
|
}, { (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= it && it < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP) }, {
|
||||||
|
builtIns.builtIns.getBuiltInClassByFqName(it)
|
||||||
|
})
|
||||||
|
|
||||||
val moduleRoot = libraryDir
|
val moduleRoot = libraryDir
|
||||||
val irDirectory = File(libraryDir, "ir/")
|
val irDirectory = File(libraryDir, "ir/")
|
||||||
@@ -94,7 +98,7 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
?: WrappedEnumEntryDescriptor()
|
?: WrappedEnumEntryDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.STANDALONE_FIELD_SYMBOL ->
|
IrKlibProtoBuf.IrSymbolKind.STANDALONE_FIELD_SYMBOL ->
|
||||||
IrFieldSymbolImpl(WrappedFieldDescriptor())
|
symbolTable.referenceField(WrappedFieldDescriptor())
|
||||||
|
|
||||||
IrKlibProtoBuf.IrSymbolKind.FIELD_SYMBOL ->
|
IrKlibProtoBuf.IrSymbolKind.FIELD_SYMBOL ->
|
||||||
symbolTable.referenceField(
|
symbolTable.referenceField(
|
||||||
@@ -135,6 +139,9 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
return deserializeIrTypeData(typeData)
|
return deserializeIrTypeData(typeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun deserializeString(proto: IrKlibProtoBuf.String) =
|
||||||
|
deserializedModuleProtoStringTables[deserializedModuleDescriptor]!!.getStrings(proto.index)
|
||||||
|
|
||||||
fun deserializeIrSymbolData(proto: IrKlibProtoBuf.IrSymbolData): IrSymbol {
|
fun deserializeIrSymbolData(proto: IrKlibProtoBuf.IrSymbolData): IrSymbol {
|
||||||
val key = proto.uniqId.uniqIdKey(deserializedModuleDescriptor!!)
|
val key = proto.uniqId.uniqIdKey(deserializedModuleDescriptor!!)
|
||||||
val topLevelKey = proto.topLevelUniqId.uniqIdKey(deserializedModuleDescriptor!!)
|
val topLevelKey = proto.topLevelUniqId.uniqIdKey(deserializedModuleDescriptor!!)
|
||||||
@@ -166,11 +173,18 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference) =
|
override fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference) =
|
||||||
descriptorReferenceDeserializer.deserializeDescriptorReference(proto, {
|
descriptorReferenceDeserializer.deserializeDescriptorReference(
|
||||||
knownBuiltInsDescriptors[it]?.index ?: if (isBuiltInFunction(it)) FUNCTION_INDEX_START + builtInFunctionId(it) else null
|
deserializeString(proto.packageFqName),
|
||||||
}, { (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= it && it < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP) }, {
|
deserializeString(proto.classFqName),
|
||||||
builtIns.builtIns.getBuiltInClassByFqName(it)
|
deserializeString(proto.name),
|
||||||
})
|
if (proto.hasUniqId()) proto.uniqId.index else null,
|
||||||
|
isEnumEntry = proto.isEnumEntry,
|
||||||
|
isEnumSpecial = proto.isEnumSpecial,
|
||||||
|
isDefaultConstructor = proto.isDefaultConstructor,
|
||||||
|
isFakeOverride = proto.isFakeOverride,
|
||||||
|
isGetter = proto.isGetter,
|
||||||
|
isSetter = proto.isSetter
|
||||||
|
)
|
||||||
|
|
||||||
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
|
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
|
||||||
get() {
|
get() {
|
||||||
@@ -282,6 +296,9 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
classDescriptor,
|
classDescriptor,
|
||||||
classDescriptor.modality
|
classDescriptor.modality
|
||||||
) { symbol: IrClassSymbol -> IrClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, symbol) }
|
) { symbol: IrClassSymbol -> IrClassImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin, symbol) }
|
||||||
|
.also {
|
||||||
|
it.parent = file
|
||||||
|
}
|
||||||
declaration
|
declaration
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -290,10 +307,13 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrFile(fileProto: IrKlibProtoBuf.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile {
|
fun deserializeIrFile(fileProto: IrKlibProtoBuf.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile {
|
||||||
val fileEntry = NaiveSourceBasedFileEntryImpl(fileProto.fileEntry.name)
|
val fileEntry = NaiveSourceBasedFileEntryImpl(
|
||||||
|
deserializeString(fileProto.fileEntry.name),
|
||||||
|
fileProto.fileEntry.lineStartOffsetsList.toIntArray()
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: we need to store "" in protobuf, I suppose. Or better yet, reuse fqname storage from metadata.
|
// TODO: we need to store "" in protobuf, I suppose. Or better yet, reuse fqname storage from metadata.
|
||||||
val fqName = if (fileProto.fqName == "<root>") FqName.ROOT else FqName(fileProto.fqName)
|
val fqName = deserializeString(fileProto.fqName).let { if (it == "<root>") FqName.ROOT else FqName(it) }
|
||||||
|
|
||||||
val packageFragmentDescriptor = EmptyPackageFragmentDescriptor(moduleDescriptor, fqName)
|
val packageFragmentDescriptor = EmptyPackageFragmentDescriptor(moduleDescriptor, fqName)
|
||||||
|
|
||||||
@@ -316,18 +336,17 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
|
|
||||||
deserializedModuleDescriptor = moduleDescriptor
|
deserializedModuleDescriptor = moduleDescriptor
|
||||||
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
||||||
|
deserializedModuleProtoStringTables.put(moduleDescriptor, proto.stringTable)
|
||||||
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
||||||
|
|
||||||
var i = 0
|
|
||||||
val files = proto.fileList.map {
|
val files = proto.fileList.map {
|
||||||
i++
|
|
||||||
// if (i >= 41)
|
|
||||||
// descriptorReferenceDeserializer.doCrash = true
|
|
||||||
deserializeIrFile(it, moduleDescriptor, deserializeAllDeclarations)
|
deserializeIrFile(it, moduleDescriptor, deserializeAllDeclarations)
|
||||||
}
|
}
|
||||||
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
||||||
module.patchDeclarationParents(null)
|
module.patchDeclarationParents(null)
|
||||||
return module
|
return module.also {
|
||||||
|
it.files.removeAll { f -> f.name == Namer.DYNAMIC_FILE_NAME }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModule(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, deserializeAllDeclarations: Boolean = false): IrModuleFragment {
|
fun deserializeIrModule(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, deserializeAllDeclarations: Boolean = false): IrModuleFragment {
|
||||||
|
|||||||
+69
-50
@@ -49,6 +49,7 @@ abstract class IrModuleDeserializer(
|
|||||||
abstract fun deserializeIrSymbol(proto: IrKlibProtoBuf.IrSymbol): IrSymbol
|
abstract fun deserializeIrSymbol(proto: IrKlibProtoBuf.IrSymbol): IrSymbol
|
||||||
abstract fun deserializeIrType(proto: IrKlibProtoBuf.IrTypeIndex): IrType
|
abstract fun deserializeIrType(proto: IrKlibProtoBuf.IrTypeIndex): IrType
|
||||||
abstract fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference): DeclarationDescriptor
|
abstract fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference): DeclarationDescriptor
|
||||||
|
abstract fun deserializeString(proto: IrKlibProtoBuf.String): String
|
||||||
|
|
||||||
private fun deserializeTypeArguments(proto: IrKlibProtoBuf.TypeArguments): List<IrType> {
|
private fun deserializeTypeArguments(proto: IrKlibProtoBuf.TypeArguments): List<IrType> {
|
||||||
logger.log { "### deserializeTypeArguments" }
|
logger.log { "### deserializeTypeArguments" }
|
||||||
@@ -378,6 +379,8 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrInstanceInitializerCallImpl(start, end, symbol, builtIns.unitType)
|
return IrInstanceInitializerCallImpl(start, end, symbol, builtIns.unitType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val getterToPropertyDescriptorMap = mutableMapOf<IrSimpleFunctionSymbol, WrappedPropertyDescriptor>()
|
||||||
|
|
||||||
private fun deserializePropertyReference(
|
private fun deserializePropertyReference(
|
||||||
proto: IrKlibProtoBuf.IrPropertyReference,
|
proto: IrKlibProtoBuf.IrPropertyReference,
|
||||||
start: Int, end: Int, type: IrType
|
start: Int, end: Int, type: IrType
|
||||||
@@ -386,7 +389,12 @@ abstract class IrModuleDeserializer(
|
|||||||
val field = if (proto.hasField()) deserializeIrSymbol(proto.field) as IrFieldSymbol else null
|
val field = if (proto.hasField()) deserializeIrSymbol(proto.field) as IrFieldSymbol else null
|
||||||
val getter = if (proto.hasGetter()) deserializeIrSymbol(proto.getter) as IrSimpleFunctionSymbol else null
|
val getter = if (proto.hasGetter()) deserializeIrSymbol(proto.getter) as IrSimpleFunctionSymbol else null
|
||||||
val setter = if (proto.hasSetter()) deserializeIrSymbol(proto.setter) as IrSimpleFunctionSymbol else null
|
val setter = if (proto.hasSetter()) deserializeIrSymbol(proto.setter) as IrSimpleFunctionSymbol else null
|
||||||
val descriptor = WrappedPropertyDescriptor()
|
val descriptor =
|
||||||
|
if (proto.hasDescriptor())
|
||||||
|
deserializeDescriptorReference(proto.descriptor) as PropertyDescriptor
|
||||||
|
else
|
||||||
|
field?.descriptor as? WrappedPropertyDescriptor // If field's descriptor coincides with property's.
|
||||||
|
?: getterToPropertyDescriptorMap.getOrPut(getter!!) { WrappedPropertyDescriptor() }
|
||||||
|
|
||||||
val callable = IrPropertyReferenceImpl(
|
val callable = IrPropertyReferenceImpl(
|
||||||
start, end, type,
|
start, end, type,
|
||||||
@@ -531,7 +539,7 @@ abstract class IrModuleDeserializer(
|
|||||||
val loopId = proto.loopId
|
val loopId = proto.loopId
|
||||||
loopIndex.getOrPut(loopId) { loop }
|
loopIndex.getOrPut(loopId) { loop }
|
||||||
|
|
||||||
val label = if (proto.hasLabel()) proto.label else null
|
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
|
||||||
val body = if (proto.hasBody()) deserializeExpression(proto.body) else null
|
val body = if (proto.hasBody()) deserializeExpression(proto.body) else null
|
||||||
val condition = deserializeExpression(proto.condition)
|
val condition = deserializeExpression(proto.condition)
|
||||||
|
|
||||||
@@ -559,7 +567,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeBreak(proto: IrKlibProtoBuf.IrBreak, start: Int, end: Int, type: IrType): IrBreak {
|
private fun deserializeBreak(proto: IrKlibProtoBuf.IrBreak, start: Int, end: Int, type: IrType): IrBreak {
|
||||||
val label = if (proto.hasLabel()) proto.label else null
|
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
|
||||||
val loopId = proto.loopId
|
val loopId = proto.loopId
|
||||||
val loop = loopIndex[loopId]!!
|
val loop = loopIndex[loopId]!!
|
||||||
val irBreak = IrBreakImpl(start, end, type, loop)
|
val irBreak = IrBreakImpl(start, end, type, loop)
|
||||||
@@ -569,7 +577,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeContinue(proto: IrKlibProtoBuf.IrContinue, start: Int, end: Int, type: IrType): IrContinue {
|
private fun deserializeContinue(proto: IrKlibProtoBuf.IrContinue, start: Int, end: Int, type: IrType): IrContinue {
|
||||||
val label = if (proto.hasLabel()) proto.label else null
|
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
|
||||||
val loopId = proto.loopId
|
val loopId = proto.loopId
|
||||||
val loop = loopIndex[loopId]!!
|
val loop = loopIndex[loopId]!!
|
||||||
val irContinue = IrContinueImpl(start, end, type, loop)
|
val irContinue = IrContinueImpl(start, end, type, loop)
|
||||||
@@ -595,7 +603,7 @@ abstract class IrModuleDeserializer(
|
|||||||
LONG
|
LONG
|
||||||
-> IrConstImpl.long(start, end, type, proto.long)
|
-> IrConstImpl.long(start, end, type, proto.long)
|
||||||
STRING
|
STRING
|
||||||
-> IrConstImpl.string(start, end, type, proto.string)
|
-> IrConstImpl.string(start, end, type, deserializeString(proto.string))
|
||||||
FLOAT
|
FLOAT
|
||||||
-> IrConstImpl.float(start, end, type, proto.float)
|
-> IrConstImpl.float(start, end, type, proto.float)
|
||||||
DOUBLE
|
DOUBLE
|
||||||
@@ -684,7 +692,7 @@ abstract class IrModuleDeserializer(
|
|||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
): IrTypeParameter {
|
): IrTypeParameter {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
|
||||||
val name = Name.identifier(proto.name)
|
val name = Name.identifier(deserializeString(proto.name))
|
||||||
val variance = deserializeIrTypeVariance(proto.variance)
|
val variance = deserializeIrTypeVariance(proto.variance)
|
||||||
|
|
||||||
val parameter = symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
val parameter = symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||||
@@ -733,7 +741,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IrValueParameterImpl(
|
IrValueParameterImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
paramSymbol,
|
paramSymbol,
|
||||||
proto.name.let { if (paramSymbol.descriptor is ReceiverParameterDescriptor) Name.special(it) else Name.identifier(it) },
|
deserializeString(proto.name).let { if (paramSymbol.descriptor is ReceiverParameterDescriptor) Name.special(it) else Name.identifier(it) },
|
||||||
proto.index,
|
proto.index,
|
||||||
deserializeIrType(proto.type),
|
deserializeIrType(proto.type),
|
||||||
varargElementType,
|
varargElementType,
|
||||||
@@ -755,11 +763,11 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
val modality = deserializeModality(proto.modality)
|
val modality = deserializeModality(proto.modality)
|
||||||
val clazz = symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
val clazz = symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||||
symbol.descriptor, modality) { symbol ->
|
symbol.descriptor, modality) {
|
||||||
IrClassImpl(
|
IrClassImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
symbol,
|
it,
|
||||||
proto.name.let { if (it.startsWith('<')) Name.special(it) else Name.identifier(it) },
|
deserializeString(proto.name).let { if (it.startsWith('<')) Name.special(it) else Name.identifier(it) },
|
||||||
deserializeClassKind(proto.kind),
|
deserializeClassKind(proto.kind),
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
modality,
|
modality,
|
||||||
@@ -814,7 +822,7 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
private fun deserializeIrFunction(
|
private fun deserializeIrFunction(
|
||||||
proto: IrKlibProtoBuf.IrFunction,
|
proto: IrKlibProtoBuf.IrFunction,
|
||||||
start: Int, end: Int, origin: IrDeclarationOrigin, correspondingProperty: IrProperty? = null
|
start: Int, end: Int, origin: IrDeclarationOrigin, isAccessor: Boolean
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
|
|
||||||
logger.log { "### deserializing IrFunction ${proto.base.name}" }
|
logger.log { "### deserializing IrFunction ${proto.base.name}" }
|
||||||
@@ -824,7 +832,7 @@ abstract class IrModuleDeserializer(
|
|||||||
symbol.descriptor, {
|
symbol.descriptor, {
|
||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
start, end, origin, it,
|
start, end, origin, it,
|
||||||
proto.base.name.let { if (correspondingProperty != null) Name.special(it) else Name.identifier(it) },
|
deserializeString(proto.base.name).let { if (isAccessor) Name.special(it) else Name.identifier(it) },
|
||||||
deserializeVisibility(proto.base.visibility),
|
deserializeVisibility(proto.base.visibility),
|
||||||
deserializeModality(proto.modality),
|
deserializeModality(proto.modality),
|
||||||
deserializeIrType(proto.base.returnType),
|
deserializeIrType(proto.base.returnType),
|
||||||
@@ -839,7 +847,7 @@ abstract class IrModuleDeserializer(
|
|||||||
val overridden = proto.overriddenList.map { deserializeIrSymbol(it) as IrSimpleFunctionSymbol }
|
val overridden = proto.overriddenList.map { deserializeIrSymbol(it) as IrSimpleFunctionSymbol }
|
||||||
function.overriddenSymbols.addAll(overridden)
|
function.overriddenSymbols.addAll(overridden)
|
||||||
|
|
||||||
function.correspondingProperty = correspondingProperty
|
// function.correspondingProperty = correspondingProperty
|
||||||
|
|
||||||
return function
|
return function
|
||||||
}
|
}
|
||||||
@@ -861,7 +869,7 @@ abstract class IrModuleDeserializer(
|
|||||||
end,
|
end,
|
||||||
origin,
|
origin,
|
||||||
symbol,
|
symbol,
|
||||||
Name.identifier(proto.name),
|
Name.identifier(deserializeString(proto.name)),
|
||||||
type,
|
type,
|
||||||
proto.isVar,
|
proto.isVar,
|
||||||
proto.isConst,
|
proto.isConst,
|
||||||
@@ -883,7 +891,7 @@ abstract class IrModuleDeserializer(
|
|||||||
irrelevantOrigin,
|
irrelevantOrigin,
|
||||||
symbol.descriptor
|
symbol.descriptor
|
||||||
) {
|
) {
|
||||||
IrEnumEntryImpl(start, end, origin, it, Name.identifier(proto.name))
|
IrEnumEntryImpl(start, end, origin, it, Name.identifier(deserializeString(proto.name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto.hasCorrespondingClass()) {
|
if (proto.hasCorrespondingClass()) {
|
||||||
@@ -908,8 +916,8 @@ abstract class IrModuleDeserializer(
|
|||||||
return initializer
|
return initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeVisibility(value: String): Visibility { // TODO: switch to enum
|
private fun deserializeVisibility(value: IrKlibProtoBuf.Visibility): Visibility { // TODO: switch to enum
|
||||||
return when (value) {
|
return when (deserializeString(value.name)) {
|
||||||
"public" -> Visibilities.PUBLIC
|
"public" -> Visibilities.PUBLIC
|
||||||
"private" -> Visibilities.PRIVATE
|
"private" -> Visibilities.PRIVATE
|
||||||
"private_to_this" -> Visibilities.PRIVATE_TO_THIS
|
"private_to_this" -> Visibilities.PRIVATE_TO_THIS
|
||||||
@@ -934,7 +942,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IrConstructorImpl(
|
IrConstructorImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
it,
|
it,
|
||||||
Name.special(proto.base.name),
|
Name.special(deserializeString(proto.base.name)),
|
||||||
deserializeVisibility(proto.base.visibility),
|
deserializeVisibility(proto.base.visibility),
|
||||||
deserializeIrType(proto.base.returnType),
|
deserializeIrType(proto.base.returnType),
|
||||||
proto.base.isInline,
|
proto.base.isInline,
|
||||||
@@ -960,7 +968,7 @@ abstract class IrModuleDeserializer(
|
|||||||
{ IrFieldImpl(
|
{ IrFieldImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
it,
|
it,
|
||||||
Name.identifier(proto.name),
|
Name.identifier(deserializeString(proto.name)),
|
||||||
type,
|
type,
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
proto.isFinal,
|
proto.isFinal,
|
||||||
@@ -990,18 +998,25 @@ abstract class IrModuleDeserializer(
|
|||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
): IrProperty {
|
): IrProperty {
|
||||||
|
|
||||||
val backingField = if (proto.hasBackingField()) {
|
val backingField = if (proto.hasBackingField()) deserializeIrField(proto.backingField, start, end, origin) else null
|
||||||
deserializeIrField(proto.backingField, start, end, origin)
|
val getter = if (proto.hasGetter()) deserializeIrFunction(proto.getter, start, end, origin, true) else null
|
||||||
} else null
|
val setter = if (proto.hasSetter()) deserializeIrFunction(proto.setter, start, end, origin, true) else null
|
||||||
|
|
||||||
|
backingField?.let { (it.descriptor as? WrappedFieldDescriptor)?.bind(it) }
|
||||||
|
getter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
||||||
|
setter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
||||||
|
|
||||||
val descriptor =
|
val descriptor =
|
||||||
if (proto.hasDescriptor()) deserializeDescriptorReference(proto.descriptor) as PropertyDescriptor else null
|
if (proto.hasDescriptor())
|
||||||
?: WrappedPropertyDescriptor()
|
deserializeDescriptorReference(proto.descriptor) as PropertyDescriptor
|
||||||
|
else
|
||||||
|
backingField?.descriptor as? WrappedPropertyDescriptor // If field's descriptor coincides with property's.
|
||||||
|
?: getterToPropertyDescriptorMap.getOrPut(getter!!.symbol) { WrappedPropertyDescriptor() }
|
||||||
|
|
||||||
val property = IrPropertyImpl(
|
val property = IrPropertyImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
descriptor,
|
descriptor,
|
||||||
Name.identifier(proto.name),
|
Name.identifier(deserializeString(proto.name)),
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
deserializeModality(proto.modality),
|
deserializeModality(proto.modality),
|
||||||
proto.isVar,
|
proto.isVar,
|
||||||
@@ -1023,29 +1038,34 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
property.backingField = backingField
|
property.backingField = backingField
|
||||||
|
property.getter = getter
|
||||||
|
property.setter = setter
|
||||||
|
|
||||||
backingField?.let { it.correspondingProperty = property }
|
backingField?.let { it.correspondingProperty = property }
|
||||||
|
getter?.let { it.correspondingProperty = property }
|
||||||
|
setter?.let { it.correspondingProperty = property }
|
||||||
|
|
||||||
property.getter =
|
// property.getter =
|
||||||
if (proto.hasGetter()) deserializeIrFunction(proto.getter, start, end, origin, property) else null
|
// if (proto.hasGetter()) deserializeIrFunction(proto.getter, start, end, origin, property) else null
|
||||||
property.setter =
|
// property.setter =
|
||||||
if (proto.hasSetter()) deserializeIrFunction(proto.setter, start, end, origin, property) else null
|
// if (proto.hasSetter()) deserializeIrFunction(proto.setter, start, end, origin, property) else null
|
||||||
|
//
|
||||||
// property.getter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
//// property.getter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
||||||
// property.setter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
//// property.setter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
||||||
|
//
|
||||||
property.getter?.let {
|
// property.getter?.let {
|
||||||
val descriptor = it.descriptor
|
// val descriptor = it.descriptor
|
||||||
if (descriptor is WrappedSimpleFunctionDescriptor) descriptor.bind(it)
|
// if (descriptor is WrappedSimpleFunctionDescriptor) descriptor.bind(it)
|
||||||
symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
// symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||||
descriptor, { symbol -> it })
|
// descriptor, { symbol -> it })
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
property.setter?.let {
|
// property.setter?.let {
|
||||||
val descriptor = it.descriptor
|
// val descriptor = it.descriptor
|
||||||
if (descriptor is WrappedSimpleFunctionDescriptor) descriptor.bind(it)
|
// if (descriptor is WrappedSimpleFunctionDescriptor) descriptor.bind(it)
|
||||||
symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
// symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||||
descriptor, { symbol -> it })
|
// descriptor, { symbol -> it })
|
||||||
}
|
// }
|
||||||
|
|
||||||
return property
|
return property
|
||||||
}
|
}
|
||||||
@@ -1063,12 +1083,13 @@ abstract class IrModuleDeserializer(
|
|||||||
IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class
|
IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class
|
||||||
val originIndex = allKnownOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name }
|
val originIndex = allKnownOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name }
|
||||||
val irrelevantOrigin = object : IrDeclarationOriginImpl("irrelevant") {}
|
val irrelevantOrigin = object : IrDeclarationOriginImpl("irrelevant") {}
|
||||||
|
fun deserializeIrDeclarationOrigin(proto: IrKlibProtoBuf.IrDeclarationOrigin) = originIndex[deserializeString(proto.custom)]!!
|
||||||
|
|
||||||
protected fun deserializeDeclaration(proto: IrKlibProtoBuf.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration {
|
protected fun deserializeDeclaration(proto: IrKlibProtoBuf.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration {
|
||||||
|
|
||||||
val start = proto.coordinates.startOffset
|
val start = proto.coordinates.startOffset
|
||||||
val end = proto.coordinates.endOffset
|
val end = proto.coordinates.endOffset
|
||||||
val origin = originIndex[proto.origin.name]!!
|
val origin = deserializeIrDeclarationOrigin(proto.origin)
|
||||||
|
|
||||||
val declarator = proto.declarator
|
val declarator = proto.declarator
|
||||||
|
|
||||||
@@ -1082,7 +1103,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IR_CLASS
|
IR_CLASS
|
||||||
-> deserializeIrClass(declarator.irClass, start, end, origin)
|
-> deserializeIrClass(declarator.irClass, start, end, origin)
|
||||||
IR_FUNCTION
|
IR_FUNCTION
|
||||||
-> deserializeIrFunction(declarator.irFunction, start, end, origin)
|
-> deserializeIrFunction(declarator.irFunction, start, end, origin, false)
|
||||||
IR_PROPERTY
|
IR_PROPERTY
|
||||||
-> deserializeIrProperty(declarator.irProperty, start, end, origin)
|
-> deserializeIrProperty(declarator.irProperty, start, end, origin)
|
||||||
IR_TYPE_ALIAS
|
IR_TYPE_ALIAS
|
||||||
@@ -1104,8 +1125,6 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
parent?.let { declaration.parent = it }
|
parent?.let { declaration.parent = it }
|
||||||
|
|
||||||
val sourceFileName = proto.fileName
|
|
||||||
|
|
||||||
val descriptor = declaration.descriptor
|
val descriptor = declaration.descriptor
|
||||||
|
|
||||||
if (descriptor is WrappedDeclarationDescriptor<*>) {
|
if (descriptor is WrappedDeclarationDescriptor<*>) {
|
||||||
|
|||||||
+37
-65
@@ -389,9 +389,20 @@ internal class IrModuleSerializer(
|
|||||||
private fun serializeCall(call: IrCall): IrKlibProtoBuf.IrCall {
|
private fun serializeCall(call: IrCall): IrKlibProtoBuf.IrCall {
|
||||||
val proto = IrKlibProtoBuf.IrCall.newBuilder()
|
val proto = IrKlibProtoBuf.IrCall.newBuilder()
|
||||||
|
|
||||||
|
if (call.dispatchReceiver?.type is IrDynamicType) {
|
||||||
|
val declaration = call.symbol.owner
|
||||||
|
dynamicFile.run {
|
||||||
|
if (!declarations.contains(declaration)) {
|
||||||
|
declaration.parent = dynamicFile
|
||||||
|
declarations += declaration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proto.kind = irCallToPrimitiveKind(call)
|
proto.kind = irCallToPrimitiveKind(call)
|
||||||
proto.symbol = serializeIrSymbol(call.symbol)
|
proto.symbol = serializeIrSymbol(call.symbol)
|
||||||
|
|
||||||
|
|
||||||
call.superQualifierSymbol?.let {
|
call.superQualifierSymbol?.let {
|
||||||
proto.`super` = serializeIrSymbol(it)
|
proto.`super` = serializeIrSymbol(it)
|
||||||
}
|
}
|
||||||
@@ -657,68 +668,6 @@ internal class IrModuleSerializer(
|
|||||||
return proto.build()
|
return proto.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun serializeDynamicMemberExpression(expression: IrDynamicMemberExpression): IrKlibProtoBuf.IrDynamicMemberExpression {
|
|
||||||
val proto = IrKlibProtoBuf.IrDynamicMemberExpression.newBuilder()
|
|
||||||
.setMemberName(serializeString(expression.memberName))
|
|
||||||
.setReceiver(serializeExpression(expression.receiver))
|
|
||||||
|
|
||||||
return proto.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun serializeDynamicOperatorExpression(expression: IrDynamicOperatorExpression): IrKlibProtoBuf.IrDynamicOperatorExpression {
|
|
||||||
val proto = IrKlibProtoBuf.IrDynamicOperatorExpression.newBuilder()
|
|
||||||
.setOperator(serializeDynamicOperator(expression.operator))
|
|
||||||
.setReceiver(serializeExpression(expression.receiver))
|
|
||||||
|
|
||||||
expression.arguments.forEach { proto.addArgument(serializeExpression(it)) }
|
|
||||||
|
|
||||||
return proto.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun serializeDynamicOperator(operator: IrDynamicOperator) = when (operator) {
|
|
||||||
IrDynamicOperator.UNARY_PLUS -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_PLUS
|
|
||||||
IrDynamicOperator.UNARY_MINUS -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_MINUS
|
|
||||||
|
|
||||||
IrDynamicOperator.EXCL -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCL
|
|
||||||
|
|
||||||
IrDynamicOperator.PREFIX_INCREMENT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_INCREMENT
|
|
||||||
IrDynamicOperator.PREFIX_DECREMENT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_DECREMENT
|
|
||||||
|
|
||||||
IrDynamicOperator.POSTFIX_INCREMENT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_INCREMENT
|
|
||||||
IrDynamicOperator.POSTFIX_DECREMENT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_DECREMENT
|
|
||||||
|
|
||||||
IrDynamicOperator.BINARY_PLUS -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_PLUS
|
|
||||||
IrDynamicOperator.BINARY_MINUS -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_MINUS
|
|
||||||
IrDynamicOperator.MUL -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MUL
|
|
||||||
IrDynamicOperator.DIV -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.DIV
|
|
||||||
IrDynamicOperator.MOD -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MOD
|
|
||||||
|
|
||||||
IrDynamicOperator.GT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.GT
|
|
||||||
IrDynamicOperator.LT -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.LT
|
|
||||||
IrDynamicOperator.GE -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.GE
|
|
||||||
IrDynamicOperator.LE -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.LE
|
|
||||||
|
|
||||||
IrDynamicOperator.EQEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQEQ
|
|
||||||
IrDynamicOperator.EXCLEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQ
|
|
||||||
|
|
||||||
IrDynamicOperator.EQEQEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQEQEQ
|
|
||||||
IrDynamicOperator.EXCLEQEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQEQ
|
|
||||||
|
|
||||||
IrDynamicOperator.ANDAND -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.ANDAND
|
|
||||||
IrDynamicOperator.OROR -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.OROR
|
|
||||||
|
|
||||||
IrDynamicOperator.EQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQ
|
|
||||||
IrDynamicOperator.PLUSEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PLUSEQ
|
|
||||||
IrDynamicOperator.MINUSEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MINUSEQ
|
|
||||||
IrDynamicOperator.MULEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MULEQ
|
|
||||||
IrDynamicOperator.DIVEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.DIVEQ
|
|
||||||
IrDynamicOperator.MODEQ -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MODEQ
|
|
||||||
|
|
||||||
IrDynamicOperator.ARRAY_ACCESS -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.ARRAY_ACCESS
|
|
||||||
|
|
||||||
IrDynamicOperator.INVOKE -> IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.INVOKE
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun serializeBreak(expression: IrBreak): IrKlibProtoBuf.IrBreak {
|
private fun serializeBreak(expression: IrBreak): IrKlibProtoBuf.IrBreak {
|
||||||
val proto = IrKlibProtoBuf.IrBreak.newBuilder()
|
val proto = IrKlibProtoBuf.IrBreak.newBuilder()
|
||||||
val label = expression.label?.let { serializeString(it) }
|
val label = expression.label?.let { serializeString(it) }
|
||||||
@@ -794,8 +743,6 @@ internal class IrModuleSerializer(
|
|||||||
is IrVararg -> operationProto.vararg = serializeVararg(expression)
|
is IrVararg -> operationProto.vararg = serializeVararg(expression)
|
||||||
is IrWhen -> operationProto.`when` = serializeWhen(expression)
|
is IrWhen -> operationProto.`when` = serializeWhen(expression)
|
||||||
is IrWhileLoop -> operationProto.`while` = serializeWhile(expression)
|
is IrWhileLoop -> operationProto.`while` = serializeWhile(expression)
|
||||||
is IrDynamicMemberExpression -> operationProto.dynamicMember = serializeDynamicMemberExpression(expression)
|
|
||||||
is IrDynamicOperatorExpression -> operationProto.dynamicOperator = serializeDynamicOperatorExpression(expression)
|
|
||||||
else -> {
|
else -> {
|
||||||
TODO("Expression serialization not implemented yet: ${ir2string(expression)}.")
|
TODO("Expression serialization not implemented yet: ${ir2string(expression)}.")
|
||||||
}
|
}
|
||||||
@@ -1127,7 +1074,7 @@ internal class IrModuleSerializer(
|
|||||||
fun serializeModule(module: IrModuleFragment): IrKlibProtoBuf.IrModule {
|
fun serializeModule(module: IrModuleFragment): IrKlibProtoBuf.IrModule {
|
||||||
val proto = IrKlibProtoBuf.IrModule.newBuilder()
|
val proto = IrKlibProtoBuf.IrModule.newBuilder()
|
||||||
.setName(serializeString(module.name.toString()))
|
.setName(serializeString(module.name.toString()))
|
||||||
|
module.addSyntheticDynamicFile()
|
||||||
module.files.forEach {
|
module.files.forEach {
|
||||||
proto.addFile(serializeIrFile(it))
|
proto.addFile(serializeIrFile(it))
|
||||||
}
|
}
|
||||||
@@ -1146,6 +1093,31 @@ internal class IrModuleSerializer(
|
|||||||
return proto.build()
|
return proto.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val dynamicPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.dynamic"))
|
||||||
|
private lateinit var dynamicFile: IrFile
|
||||||
|
|
||||||
|
private fun IrModuleFragment.addSyntheticDynamicFile() {
|
||||||
|
dynamicFile = IrFileImpl(object : SourceManager.FileEntry {
|
||||||
|
override val name = Namer.DYNAMIC_FILE_NAME
|
||||||
|
override val maxOffset = UNDEFINED_OFFSET
|
||||||
|
|
||||||
|
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int) =
|
||||||
|
SourceRangeInfo(
|
||||||
|
"",
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getLineNumber(offset: Int) = UNDEFINED_OFFSET
|
||||||
|
override fun getColumnNumber(offset: Int) = UNDEFINED_OFFSET
|
||||||
|
}, dynamicPackage)
|
||||||
|
files += dynamicFile
|
||||||
|
}
|
||||||
|
|
||||||
fun serializedIrModule(module: IrModuleFragment): SerializedIr {
|
fun serializedIrModule(module: IrModuleFragment): SerializedIr {
|
||||||
val moduleHeader = serializeModule(module).toByteArray()
|
val moduleHeader = serializeModule(module).toByteArray()
|
||||||
return SerializedIr(moduleHeader, topLevelDeclarations, declarationTable.debugIndex)
|
return SerializedIr(moduleHeader, topLevelDeclarations, declarationTable.debugIndex)
|
||||||
|
|||||||
+4
-4
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
|
|
||||||
|
|
||||||
class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) {
|
class DescriptorReferenceSerializer(val declarationTable: DeclarationTable, val serializeString: (String) -> IrKlibProtoBuf.String) {
|
||||||
|
|
||||||
// Not all exported descriptors are deserialized, some a synthesized anew during metadata deserialization.
|
// Not all exported descriptors are deserialized, some a synthesized anew during metadata deserialization.
|
||||||
// Those created descriptors can't carry the uniqIdIndex, since it is available only for deserialized descriptors.
|
// Those created descriptors can't carry the uniqIdIndex, since it is available only for deserialized descriptors.
|
||||||
@@ -72,9 +72,9 @@ class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) {
|
|||||||
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
|
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
|
||||||
|
|
||||||
val proto = IrKlibProtoBuf.DescriptorReference.newBuilder()
|
val proto = IrKlibProtoBuf.DescriptorReference.newBuilder()
|
||||||
.setPackageFqName(packageFqName)
|
.setPackageFqName(serializeString(packageFqName))
|
||||||
.setClassFqName(classFqName)
|
.setClassFqName(serializeString(classFqName))
|
||||||
.setName(descriptor.name.toString())
|
.setName(serializeString(descriptor.name.toString()))
|
||||||
|
|
||||||
if (uniqId != null) proto.setUniqId(protoUniqId(uniqId))
|
if (uniqId != null) proto.setUniqId(protoUniqId(uniqId))
|
||||||
|
|
||||||
|
|||||||
+85
-33
@@ -5,9 +5,9 @@ option java_outer_classname = "IrKlibProtoBuf";
|
|||||||
option optimize_for = LITE_RUNTIME;
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
message DescriptorReference {
|
message DescriptorReference {
|
||||||
required string package_fq_name = 1;
|
required String package_fq_name = 1;
|
||||||
required string class_fq_name = 2;
|
required String class_fq_name = 2;
|
||||||
required string name = 3;
|
required String name = 3;
|
||||||
optional UniqId uniq_id = 4;
|
optional UniqId uniq_id = 4;
|
||||||
optional bool is_getter = 5 [default = false];
|
optional bool is_getter = 5 [default = false];
|
||||||
optional bool is_setter = 6 [default = false];
|
optional bool is_setter = 6 [default = false];
|
||||||
@@ -28,28 +28,85 @@ message Coordinates {
|
|||||||
required int32 end_offset = 2;
|
required int32 end_offset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Visibility {
|
||||||
|
required String name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IrStatementOrigin {
|
||||||
|
required String name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KnownOrigin {
|
||||||
|
CUSTOM = 1;
|
||||||
|
DEFINED = 2;
|
||||||
|
FAKE_OVERRIDE = 3;
|
||||||
|
FOR_LOOP_ITERATOR = 4;
|
||||||
|
FOR_LOOP_VARIABLE = 5;
|
||||||
|
FOR_LOOP_IMPLICIT_VARIABLE = 6;
|
||||||
|
PROPERTY_BACKING_FIELD = 7;
|
||||||
|
DEFAULT_PROPERTY_ACCESSOR = 8;
|
||||||
|
DELEGATE = 9;
|
||||||
|
DELEGATED_PROPERTY_ACCESSOR = 10;
|
||||||
|
DELEGATED_MEMBER = 11;
|
||||||
|
ENUM_CLASS_SPECIAL_MEMBER = 12;
|
||||||
|
FUNCTION_FOR_DEFAULT_PARAMETER = 13;
|
||||||
|
FILE_CLASS = 14;
|
||||||
|
GENERATED_DATA_CLASS_MEMBER = 15;
|
||||||
|
GENERATED_INLINE_CLASS_MEMBER = 16;
|
||||||
|
LOCAL_FUNCTION_FOR_LAMBDA = 17;
|
||||||
|
CATCH_PARAMETER = 19;
|
||||||
|
INSTANCE_RECEIVER = 20;
|
||||||
|
PRIMARY_CONSTRUCTOR_PARAMETER = 21;
|
||||||
|
IR_TEMPORARY_VARIABLE = 22;
|
||||||
|
IR_EXTERNAL_DECLARATION_STUB = 23;
|
||||||
|
IR_EXTERNAL_JAVA_DECLARATION_STUB = 24;
|
||||||
|
IR_BUILTINS_STUB = 25;
|
||||||
|
BRIDGE = 26;
|
||||||
|
FIELD_FOR_ENUM_ENTRY = 27;
|
||||||
|
FIELD_FOR_ENUM_VALUES = 28;
|
||||||
|
FIELD_FOR_OBJECT_INSTANCE = 29;
|
||||||
|
}
|
||||||
|
|
||||||
|
message IrDeclarationOrigin {
|
||||||
|
oneof either {
|
||||||
|
KnownOrigin origin = 1;
|
||||||
|
String custom = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ------ Top Level---------------------------------------------- */
|
/* ------ Top Level---------------------------------------------- */
|
||||||
|
|
||||||
message IrDeclarationContainer {
|
message IrDeclarationContainer {
|
||||||
repeated IrDeclaration declaration = 1;
|
repeated IrDeclaration declaration = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FileEntry { // TODO: extend me.
|
message FileEntry {
|
||||||
required string name = 1;
|
required String name = 1;
|
||||||
|
repeated int32 line_start_offsets = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrFile {
|
message IrFile {
|
||||||
repeated UniqId declaration_id = 1;
|
repeated UniqId declaration_id = 1;
|
||||||
required FileEntry file_entry = 2;
|
required FileEntry file_entry = 2;
|
||||||
// TODO: we need a better string management. See metadata serialization as an example.
|
required String fq_name = 3;
|
||||||
required string fq_name = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrModule {
|
message IrModule {
|
||||||
required string name = 1;
|
required String name = 1;
|
||||||
repeated IrFile file = 2;
|
repeated IrFile file = 2;
|
||||||
required IrSymbolTable symbol_table = 3;
|
required IrSymbolTable symbol_table = 3;
|
||||||
required IrTypeTable type_table = 4;
|
required IrTypeTable type_table = 4;
|
||||||
|
required StringTable string_table = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------ String Table ------------------------------------------ */
|
||||||
|
|
||||||
|
message String {
|
||||||
|
required int32 index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringTable {
|
||||||
|
repeated string strings = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------ IrSymbols --------------------------------------------- */
|
/* ------ IrSymbols --------------------------------------------- */
|
||||||
@@ -74,7 +131,7 @@ message IrSymbolData {
|
|||||||
required IrSymbolKind kind = 1;
|
required IrSymbolKind kind = 1;
|
||||||
required UniqId uniq_id = 2;
|
required UniqId uniq_id = 2;
|
||||||
required UniqId top_level_uniq_id = 3;
|
required UniqId top_level_uniq_id = 3;
|
||||||
optional string fqname = 4;
|
optional String fqname = 4;
|
||||||
optional DescriptorReference descriptor_reference = 5;
|
optional DescriptorReference descriptor_reference = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +210,7 @@ message IrTypeIndex {
|
|||||||
|
|
||||||
message IrBreak {
|
message IrBreak {
|
||||||
required int32 loop_id = 1;
|
required int32 loop_id = 1;
|
||||||
optional string label = 2;
|
optional String label = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrBlock {
|
message IrBlock {
|
||||||
@@ -183,7 +240,7 @@ message IrCall {
|
|||||||
|
|
||||||
message IrFunctionReference {
|
message IrFunctionReference {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
optional string origin = 2;
|
optional IrStatementOrigin origin = 2;
|
||||||
required MemberAccessCommon member_access = 3;
|
required MemberAccessCommon member_access = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,8 +249,9 @@ message IrPropertyReference {
|
|||||||
optional IrSymbol field = 1;
|
optional IrSymbol field = 1;
|
||||||
optional IrSymbol getter = 2;
|
optional IrSymbol getter = 2;
|
||||||
optional IrSymbol setter = 3;
|
optional IrSymbol setter = 3;
|
||||||
optional string origin = 4;
|
optional IrStatementOrigin origin = 4;
|
||||||
required MemberAccessCommon member_access = 5;
|
required MemberAccessCommon member_access = 5;
|
||||||
|
optional DescriptorReference descriptor = 6; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrComposite {
|
message IrComposite {
|
||||||
@@ -216,13 +274,13 @@ message IrConst {
|
|||||||
int64 long = 7;
|
int64 long = 7;
|
||||||
float float = 8;
|
float float = 8;
|
||||||
double double = 9;
|
double double = 9;
|
||||||
string string = 10;
|
String string = 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrContinue {
|
message IrContinue {
|
||||||
required int32 loop_id = 1;
|
required int32 loop_id = 1;
|
||||||
optional string label = 2;
|
optional String label = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrDelegatingConstructorCall {
|
message IrDelegatingConstructorCall {
|
||||||
@@ -272,7 +330,7 @@ message IrInstanceInitializerCall {
|
|||||||
message Loop {
|
message Loop {
|
||||||
required int32 loop_id = 1;
|
required int32 loop_id = 1;
|
||||||
required IrExpression condition = 2;
|
required IrExpression condition = 2;
|
||||||
optional string label = 3;
|
optional String label = 3;
|
||||||
optional IrExpression body = 4;
|
optional IrExpression body = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,8 +469,8 @@ message IrFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message IrFunctionBase {
|
message IrFunctionBase {
|
||||||
required string name = 1;
|
required String name = 1;
|
||||||
required string visibility = 2;
|
required Visibility visibility = 2;
|
||||||
required bool is_inline = 3;
|
required bool is_inline = 3;
|
||||||
required bool is_external = 4;
|
required bool is_external = 4;
|
||||||
required IrTypeParameterContainer type_parameters = 5;
|
required IrTypeParameterContainer type_parameters = 5;
|
||||||
@@ -433,8 +491,8 @@ message IrConstructor {
|
|||||||
message IrField {
|
message IrField {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
optional IrExpression initializer = 2;
|
optional IrExpression initializer = 2;
|
||||||
required string name = 3;
|
required String name = 3;
|
||||||
required string visibility = 4;
|
required Visibility visibility = 4;
|
||||||
required bool is_final = 5;
|
required bool is_final = 5;
|
||||||
required bool is_external = 6;
|
required bool is_external = 6;
|
||||||
required bool is_static = 7;
|
required bool is_static = 7;
|
||||||
@@ -443,8 +501,8 @@ message IrField {
|
|||||||
|
|
||||||
message IrProperty {
|
message IrProperty {
|
||||||
optional DescriptorReference descriptor = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
|
optional DescriptorReference descriptor = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
|
||||||
required string name = 2;
|
required String name = 2;
|
||||||
required string visibility = 3;
|
required Visibility visibility = 3;
|
||||||
required ModalityKind modality = 4;
|
required ModalityKind modality = 4;
|
||||||
required bool is_var = 5;
|
required bool is_var = 5;
|
||||||
required bool is_const = 6;
|
required bool is_const = 6;
|
||||||
@@ -457,7 +515,7 @@ message IrProperty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message IrVariable {
|
message IrVariable {
|
||||||
required string name = 1;
|
required String name = 1;
|
||||||
required IrSymbol symbol = 2;
|
required IrSymbol symbol = 2;
|
||||||
required IrTypeIndex type = 3;
|
required IrTypeIndex type = 3;
|
||||||
required bool is_var = 4;
|
required bool is_var = 4;
|
||||||
@@ -484,7 +542,7 @@ enum ModalityKind { // It is ModalityKind to not clash with Modality in descript
|
|||||||
|
|
||||||
message IrValueParameter {
|
message IrValueParameter {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
required string name = 2;
|
required String name = 2;
|
||||||
required int32 index = 3;
|
required int32 index = 3;
|
||||||
required IrTypeIndex type = 4;
|
required IrTypeIndex type = 4;
|
||||||
optional IrTypeIndex vararg_element_type = 5;
|
optional IrTypeIndex vararg_element_type = 5;
|
||||||
@@ -495,7 +553,7 @@ message IrValueParameter {
|
|||||||
|
|
||||||
message IrTypeParameter {
|
message IrTypeParameter {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
required string name = 2;
|
required String name = 2;
|
||||||
required int32 index = 3;
|
required int32 index = 3;
|
||||||
required IrTypeVariance variance = 4;
|
required IrTypeVariance variance = 4;
|
||||||
repeated IrTypeIndex super_type = 5;
|
repeated IrTypeIndex super_type = 5;
|
||||||
@@ -508,9 +566,9 @@ message IrTypeParameterContainer {
|
|||||||
|
|
||||||
message IrClass {
|
message IrClass {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
required string name = 2;
|
required String name = 2;
|
||||||
required ClassKind kind = 3;
|
required ClassKind kind = 3;
|
||||||
required string visibility = 4;
|
required Visibility visibility = 4;
|
||||||
required ModalityKind modality = 5;
|
required ModalityKind modality = 5;
|
||||||
// TODO: consider using flags for the booleans.
|
// TODO: consider using flags for the booleans.
|
||||||
required bool is_companion = 6;
|
required bool is_companion = 6;
|
||||||
@@ -528,7 +586,7 @@ message IrEnumEntry {
|
|||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
optional IrExpression initializer = 2;
|
optional IrExpression initializer = 2;
|
||||||
optional IrDeclaration corresponding_class = 3;
|
optional IrDeclaration corresponding_class = 3;
|
||||||
required string name = 4;
|
required String name = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrAnonymousInit {
|
message IrAnonymousInit {
|
||||||
@@ -554,17 +612,11 @@ message IrDeclarator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrDeclarationOrigin {
|
|
||||||
required string name = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message IrDeclaration {
|
message IrDeclaration {
|
||||||
required IrDeclarationOrigin origin = 1;
|
required IrDeclarationOrigin origin = 1;
|
||||||
required Coordinates coordinates = 2;
|
required Coordinates coordinates = 2;
|
||||||
required Annotations annotations = 3;
|
required Annotations annotations = 3;
|
||||||
required IrDeclarator declarator = 4;
|
required IrDeclarator declarator = 4;
|
||||||
//repeated IrDeclaration nested = 5;
|
|
||||||
required string file_name = 5; // TODO: files should be communicated some other way, I suppose.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------- IrStatements --------------------------------------------- */
|
/* ------- IrStatements --------------------------------------------- */
|
||||||
|
|||||||
+1
@@ -58,6 +58,7 @@ abstract class IrLazyDeclarationBase(
|
|||||||
|
|
||||||
val containingDeclaration =
|
val containingDeclaration =
|
||||||
((currentDescriptor as? PropertyAccessorDescriptor)?.correspondingProperty ?: currentDescriptor).containingDeclaration
|
((currentDescriptor as? PropertyAccessorDescriptor)?.correspondingProperty ?: currentDescriptor).containingDeclaration
|
||||||
|
|
||||||
return when (containingDeclaration) {
|
return when (containingDeclaration) {
|
||||||
is PackageFragmentDescriptor -> stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(containingDeclaration).also {
|
is PackageFragmentDescriptor -> stubGenerator.generateOrGetEmptyExternalPackageFragmentStub(containingDeclaration).also {
|
||||||
it.declarations.add(this)
|
it.declarations.add(this)
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.toIrType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
@@ -98,8 +96,8 @@ class IrBuiltIns(
|
|||||||
builtIns.nothing to IrTypeMapper({ nothingType }, { nothingNType }),
|
builtIns.nothing to IrTypeMapper({ nothingType }, { nothingNType }),
|
||||||
builtIns.unit to IrTypeMapper({ unitType }, { buildNullableType(unitType) }),
|
builtIns.unit to IrTypeMapper({ unitType }, { buildNullableType(unitType) }),
|
||||||
builtIns.string to IrTypeMapper({ stringType }, { buildNullableType(stringType) }),
|
builtIns.string to IrTypeMapper({ stringType }, { buildNullableType(stringType) }),
|
||||||
builtIns.throwable to IrTypeMapper({ throwableType }, { buildNullableType(throwableType) })
|
builtIns.throwable to IrTypeMapper({ throwableType }, { buildNullableType(throwableType) }),
|
||||||
// builtIns.array to { arrayClass.owner.defaultType }
|
builtIns.array to IrTypeMapper({ arrayType }, { buildNullableType(arrayType) })
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) =
|
fun getPrimitiveTypeOrNullByDescriptor(descriptor: ClassifierDescriptor, isNullable: Boolean) =
|
||||||
@@ -165,6 +163,7 @@ class IrBuiltIns(
|
|||||||
|
|
||||||
val collectionClass by lazy { builtIns.collection.toIrSymbol() }
|
val collectionClass by lazy { builtIns.collection.toIrSymbol() }
|
||||||
|
|
||||||
|
val arrayType by lazy { builtIns.array.toIrType(symbolTable = symbolTable) }
|
||||||
val arrayClass by lazy { builtIns.array.toIrSymbol() }
|
val arrayClass by lazy { builtIns.array.toIrSymbol() }
|
||||||
|
|
||||||
val throwableType by lazy { builtIns.throwable.defaultType.toIrType() }
|
val throwableType by lazy { builtIns.throwable.defaultType.toIrType() }
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ fun IrType.makeNullable(addKotlinType:Boolean = true) =
|
|||||||
else
|
else
|
||||||
this
|
this
|
||||||
|
|
||||||
|
// TODO: get rid of this
|
||||||
var irTypeKotlinBuiltIns: KotlinBuiltIns? = null
|
var irTypeKotlinBuiltIns: KotlinBuiltIns? = null
|
||||||
|
|
||||||
fun IrType.toKotlinType(): KotlinType {
|
fun IrType.toKotlinType(): KotlinType {
|
||||||
|
|||||||
Reference in New Issue
Block a user