Deserialization code clean up

This commit is contained in:
Roman Artemev
2019-02-27 19:32:15 +03:00
committed by romanart
parent d085e66aa3
commit 3770d310f1
13 changed files with 48 additions and 426 deletions
@@ -133,8 +133,8 @@ fun compile(
?: JsKlibMetadataVersion.INSTANCE
val lookupTracker = LookupTracker.DO_NOTHING
val languageSettings = configuration.languageVersionSettings
val storageManeger = LockBasedStorageManager("JsDepencencies")
val dfsHandler: MetadataDFSHandler = DependencyMetadataLoader(lookupTracker, metadataVersion, languageSettings, storageManeger)
val storageManager = LockBasedStorageManager("JsDependencies")
val dfsHandler: MetadataDFSHandler = DependencyMetadataLoader(lookupTracker, metadataVersion, languageSettings, storageManager)
val sortedDeps = DFS.dfs(dependencies, CompiledModule::dependencies, dfsHandler)
val builtInModule = sortedDeps.firstOrNull()?.moduleDescriptor // null in case compiling builtInModule itself
@@ -219,6 +219,7 @@ fun compile(
).generateUnboundSymbolsAsDependencies(it)
}
// TODO: check the order
val irFiles = deserializedModuleFragments.flatMap { it.files } + moduleFragment.files
moduleFragment.files.clear()
@@ -5,33 +5,16 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.util.explicitParameters
import org.jetbrains.kotlin.ir.util.isFunction
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isSuspendFunction
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
val IrConstructor.constructedClass get() = this.parent as IrClass
val <T : IrDeclaration> T.original get() = this
val IrDeclaration.containingDeclaration get() = this.parent
val IrDeclarationParent.fqNameSafe: FqName
get() = when (this) {
@@ -67,79 +50,12 @@ val IrDeclaration.name: Name
private val SPECIAL_INIT_NAME = Name.special("<init>")
val IrField.fqNameSafe: FqName get() = this.parent.fqNameSafe.child(this.name)
/**
* @return naturally-ordered list of all parameters available inside the function body.
*/
val IrFunction.allParameters: List<IrValueParameter>
get() = if (this is IrConstructor) {
listOf(this.constructedClass.thisReceiver
?: error(this.descriptor)
) + explicitParameters
} else {
explicitParameters
}
val IrValueParameter.isVararg get() = this.varargElementType != null
val IrFunction.isSuspend get() = this is IrSimpleFunction && this.isSuspend
fun IrClass.isUnit() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.unit.toSafe()
fun IrClass.isKotlinArray() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.array.toSafe()
val IrClass.superClasses get() = this.superTypes.map { it.classifierOrFail as IrClassSymbol }
fun IrClass.getSuperClassNotAny() = this.superClasses.map { it.owner }.atMostOne { !it.isInterface && !it.isAny() }
fun IrClass.isAny() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.any.toSafe()
fun IrClass.isNothing() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.nothing.toSafe()
fun IrClass.getSuperInterfaces() = this.superClasses.map { it.owner }.filter { it.isInterface }
val IrProperty.konanBackingField: IrField?
get() {
assert(this.isReal)
this.backingField?.let { return it }
// (this.descriptor as? DeserializedPropertyDescriptor)?.konanBackingField?.let { backingFieldDescriptor ->
// val result = IrFieldImpl(
// this.startOffset,
// this.endOffset,
// IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
// backingFieldDescriptor,
// this.getter!!.returnType
// ).also {
// it.parent = this.parent
// }
// this.backingField = result
// return result
// }
return null
}
val IrField.containingClass get() = this.parent as? IrClass
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
// Note: psi2ir doesn't set `origin = FAKE_OVERRIDE` for fields and properties yet.
val IrProperty.isReal: Boolean get() = this.descriptor.kind.isReal
val IrField.isReal: Boolean get() = this.descriptor.kind.isReal
val IrSimpleFunction.isOverridable: Boolean
get() = visibility != Visibilities.PRIVATE
&& modality != Modality.FINAL
&& (parent as? IrClass)?.isFinalClass != true
val IrFunction.isOverridable get() = this is IrSimpleFunction && this.isOverridable
val IrFunction.isOverridableOrOverrides
get() = this is IrSimpleFunction && (this.isOverridable || this.overriddenSymbols.isNotEmpty())
val IrClass.isFinalClass: Boolean
get() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
if (this == other) return true
@@ -152,10 +68,6 @@ fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
return false
}
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
internal val IrValueParameter.isValueParameter get() = this.index >= 0
private val IrCall.annotationClass
get() = (this.symbol.owner as IrConstructor).constructedClass
@@ -169,31 +81,6 @@ fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
it.annotationClass.fqNameSafe == fqName
}
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
val annotation = this.annotations.findAnnotation(fqName)
if (annotation == null) {
// As a last resort try searching the descriptor.
// This is needed for a period while we don't have IR for platform libraries.
return this.descriptor.annotations
.findAnnotation(fqName)
?.getArgumentValueOrNull<T>(argumentName)
}
for (index in 0 until annotation.valueArgumentsCount) {
val parameter = annotation.symbol.owner.valueParameters[index]
if (parameter.name == Name.identifier(argumentName)) {
val actual = annotation.getValueArgument(index) as? IrConst<T>
return actual?.value
}
}
return null
}
fun IrValueParameter.isInlineParameter(): Boolean =
!this.isNoinline && (this.type.isFunction() || this.type.isSuspendFunction()) && !this.type.isMarkedNullable()
val IrDeclaration.parentDeclarationsWithSelf: Sequence<IrDeclaration>
get() = generateSequence(this, { it.parent as? IrDeclaration })
fun IrClass.companionObject() = this.declarations.singleOrNull {it is IrClass && it.isCompanion }
val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.getter
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.FqName
@@ -30,10 +29,6 @@ internal val IrDeclaration.isLocal get() = DescriptorUtils.isLocal(this.descript
internal val IrDeclaration.module get() = this.descriptor.module
@Deprecated("Do not call this method in the compiler front-end.")
internal val IrField.isDelegate
get() = @Suppress("DEPRECATION") this.descriptor.isDelegated
internal const val SYNTHETIC_OFFSET = -2
val File.lineStartOffsets: IntArray
@@ -211,31 +211,6 @@ private fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility
"$this\$$moduleName"
}
internal val IrFunction.symbolName: String
get() {
if (!this.isExported()) {
throw AssertionError(this.descriptor.toString())
}
if (isExternal) {
this.descriptor.externalSymbolOrThrow()?.let {
return it
}
}
// this.descriptor.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
// val name = getAnnotationValue(it) ?: this.name.asString()
// return name // no wrapping currently required
// }
val parent = this.parent
val containingDeclarationPart = parent.fqNameSafe.let {
if (it.isRoot) "" else "$it."
}
return "kfun:$containingDeclarationPart$functionName"
}
internal val IrField.symbolName: String
get() {
val containingDeclarationPart = parent.fqNameSafe.let {
@@ -5,19 +5,11 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.descriptors.getFunction
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
import java.util.regex.Pattern
class DescriptorTable {
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
@@ -5,27 +5,9 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.typeUtil.isUnit
/**
* List of all implemented interfaces (including those which implemented by a super class)
*/
internal val IrClass.implementedInterfaces: List<IrClass>
get() {
val superClassImplementedInterfaces = this.getSuperClassNotAny()?.implementedInterfaces ?: emptyList()
val superInterfaces = this.getSuperInterfaces()
val superInterfacesImplementedInterfaces = superInterfaces.flatMap { it.implementedInterfaces }
return (superClassImplementedInterfaces +
superInterfacesImplementedInterfaces +
superInterfaces).distinct()
}
/**
@@ -71,62 +53,9 @@ internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false
return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT }
}
// TODO: don't forget to remove descriptor access here.
//internal val FunctionDescriptor.isTypedIntrinsic: Boolean
// get() = this.descriptor.isTypedIntrinsic
//
//internal val DeclarationDescriptor.isFrozen: Boolean
// get() = this.descriptor.isFrozen
internal val arrayTypes = setOf(
"kotlin.Array",
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray",
"kotlin.native.ImmutableBlob",
"kotlin.native.internal.NativePtrArray"
)
internal val IrClass.isArray: Boolean
get() = this.fqNameSafe.asString() in arrayTypes
internal val IrClass.isInterface: Boolean
get() = (this.kind == ClassKind.INTERFACE)
fun IrClass.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT
|| this.kind == ClassKind.ENUM_CLASS
//internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
// when (index) {
// 0 -> return !isSuspend && returnType.let { (it.isInlined() || it.isUnit()) }
// 1 -> return dispatchReceiverParameter.let { it != null && it.type.isInlined() }
// 2 -> return extensionReceiverParameter.let { it != null && it.type.isInlined() }
// else -> return this.valueParameters[index - 3].type.isInlined()
// }
//}
//
//internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean {
// when (index) {
// 0 -> return isSuspend || returnType.let { !it.isInlined() && !it.isUnit() }
// 1 -> return dispatchReceiverParameter.let { it != null && !it.type.isInlined() }
// 2 -> return extensionReceiverParameter.let { it != null && !it.type.isInlined() }
// else -> return !this.valueParameters[index - 3].type.isInlined()
// }
//}
//private fun FunctionDescriptor.needBridgeToAt(target: FunctionDescriptor, index: Int)
// = hasValueTypeAt(index) xor target.hasValueTypeAt(index)
//internal fun FunctionDescriptor.needBridgeTo(target: FunctionDescriptor)
// = (0..this.valueParameters.size + 2).any { needBridgeToAt(target, it) }
internal val IrSimpleFunction.target: IrSimpleFunction
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
@@ -136,55 +65,6 @@ internal val IrFunction.target: IrFunction get() = when (this) {
else -> error(this)
}
//private fun FunctionDescriptor.bridgeDirectionToAt(target: FunctionDescriptor, index: Int)
// = when {
// hasValueTypeAt(index) && target.hasReferenceAt(index) -> BridgeDirection.FROM_VALUE_TYPE
// hasReferenceAt(index) && target.hasValueTypeAt(index) -> BridgeDirection.TO_VALUE_TYPE
// else -> BridgeDirection.NOT_NEEDED
//}
val IrSimpleFunction.allOverriddenDescriptors: Set<IrSimpleFunction>
get() {
val result = mutableSetOf<IrSimpleFunction>()
fun traverse(function: IrSimpleFunction) {
if (function in result) return
result += function
function.overriddenSymbols.forEach { traverse(it.owner) }
}
traverse(this)
return result
}
//internal fun IrSimpleFunction.bridgeDirectionsTo(
// overriddenDescriptor: IrSimpleFunction
//): BridgeDirections {
// val ourDirections = BridgeDirections(this.valueParameters.size)
// for (index in ourDirections.array.indices)
// ourDirections.array[index] = this.bridgeDirectionToAt(overriddenDescriptor, index)
//
// val target = this.target
// if (!this.isReal && modality != Modality.ABSTRACT
// && target.overrides(overriddenDescriptor)
// && ourDirections == target.bridgeDirectionsTo(overriddenDescriptor)) {
// // Bridge is inherited from superclass.
// return BridgeDirections(this.valueParameters.size)
// }
//
// return ourDirections
//}
tailrec internal fun IrDeclaration.findPackage(): IrPackageFragment {
val parent = this.parent
return parent as? IrPackageFragment
?: (parent as IrDeclaration).findPackage()
}
fun IrFunction.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
this in map.values
val IrDeclaration.isPropertyAccessor get() =
this is IrSimpleFunction && this.correspondingProperty != null
@@ -13,13 +13,16 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>,
val checkerDesc: (DeclarationDescriptor) -> Long?,
val checkerID: (Long) -> Boolean,
val descriptorResolver: (FqName) -> DeclarationDescriptor
abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor,
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
) {
protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor
protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean
protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long?
private val cache = mutableMapOf<String, Collection<DeclarationDescriptor>>()
private fun getContributedDescriptors(packageFqNameString: String): Collection<DeclarationDescriptor> =
@@ -40,7 +43,7 @@ class DescriptorReferenceDeserializer(
private val membersCache = mutableMapOf<ClassName, ClassMembers>()
private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId()?.index ?: checkerDesc(descriptor)
private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId()?.index ?: getDescriptorIdOrNull(descriptor)
private fun getMembers(packageFqNameString: String, classFqNameString: String,
members: Collection<DeclarationDescriptor>): ClassMembers =
@@ -119,8 +122,8 @@ class DescriptorReferenceDeserializer(
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
}
if (protoIndex?.let { checkerID(it) } == true) {
return descriptorResolver(packageFqName.child(Name.identifier(name)))
if (protoIndex?.let { checkIfSpecialDescriptorId(it) } == true) {
return resolveSpecialDescriptor(packageFqName.child(Name.identifier(name)))
}
val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members)
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
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.utils.Namer
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -31,36 +30,43 @@ class IrKlibProtoBufModuleDeserializer(
logger: LoggingContext,
builtIns: IrBuiltIns,
symbolTable: SymbolTable,
val forwardModuleDescriptor: ModuleDescriptor?)
private val forwardModuleDescriptor: ModuleDescriptor?)
: IrModuleDeserializer(logger, builtIns, symbolTable) {
val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>()
private val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>()
val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>()
val reachableTopLevels = mutableSetOf<UniqIdKey>()
val deserializedTopLevels = mutableSetOf<UniqIdKey>()
val forwardDeclarations = mutableSetOf<IrSymbol>()
private val reachableTopLevels = mutableSetOf<UniqIdKey>()
private val deserializedTopLevels = mutableSetOf<UniqIdKey>()
private val forwardDeclarations = mutableSetOf<IrSymbol>()
var deserializedModuleDescriptor: ModuleDescriptor? = null
var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>()
var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
private var deserializedModuleDescriptor: ModuleDescriptor? = null
private var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
private var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>()
private var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
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 descriptorToDirectoryMap = mutableMapOf<ModuleDescriptor, File>()
private val descriptorReferenceDeserializer = object : DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations) {
override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
override fun checkIfSpecialDescriptorId(id: Long) =
(FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= id && id < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP)
override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) =
knownBuiltInsDescriptors[descriptor]?.index ?: if (isBuiltInFunction(descriptor))
FUNCTION_INDEX_START + builtInFunctionId(descriptor)
else null
}
private val descriptorToDirectoryMap = mutableMapOf<ModuleDescriptor, File>()
// val moduleRoot = libraryDir
private fun irDirectory(m: ModuleDescriptor): File = descriptorToDirectoryMap[m]!!
private val FUNCTION_INDEX_START: Long
init {
// TODO: think about order
var currentIndex = 0x1_0000_0000L
builtIns.knownBuiltins.forEach {
require(it is IrFunction)
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ClassKind.*
@@ -15,11 +14,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
@@ -27,8 +22,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrNullaryPrimitiveImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.js.resolve.JsPlatform.builtIns
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.Variance
internal class IrModuleSerializer(
@@ -1,53 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.StringTableImpl
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import java.io.OutputStream
class KonanStringTable : StringTableImpl() {
fun getClassOrPackageFqNameIndex(descriptor: ClassOrPackageFragmentDescriptor): Int {
when (descriptor) {
is PackageFragmentDescriptor ->
return getPackageFqNameIndex(descriptor.fqName)
is ClassDescriptor ->
return getFqNameIndex(descriptor as ClassifierDescriptorWithTypeParameters)
else -> error("Can not get fqNameIndex for $descriptor")
}
}
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
val superClassifiers = descriptor.getAllSuperClassifiers()
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
.filter { it != descriptor }
.toList()
if (superClassifiers.size == 1) {
superClassifiers[0].classId
} else {
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
superClass?.classId ?: ClassId.topLevel(descriptor.module.builtIns.any.fqNameSafe)
}
} else {
super.getLocalClassIdReplacement(descriptor)
}
}
fun serializeTo(output: OutputStream) {
val (strings, qualifiedNames) = buildProto()
strings.writeDelimitedTo(output)
qualifiedNames.writeDelimitedTo(output)
}
}
@@ -5,14 +5,12 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.common.descriptors.propertyIfAccessor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
internal val DeclarationDescriptor.isExpectMember: Boolean
get() = this is MemberDescriptor && this.isExpect
@@ -20,30 +18,6 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
fun <T> AnnotationDescriptor.getArgumentValueOrNull(name: String): T? {
val constantValue = this.allValueArguments.entries.atMostOne {
it.key.asString() == name
}?.value
return constantValue?.value as T?
}
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
fun getAnnotationValue(annotation: AnnotationDescriptor): String? {
return annotation.allValueArguments.values.ifNotEmpty {
val stringValue = single() as? StringValue
stringValue?.value
}
}
fun CallableMemberDescriptor.externalSymbolOrThrow(): String? {
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
return getAnnotationValue(it)!!
}
throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation")
}
tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
return if (this is PackageFragmentDescriptor) this
else this.containingDeclaration!!.findPackage()
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf.QualifiedNameTable.QualifiedName
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.deserialization.getClassId
// TODO Come up with a better file name.
internal fun NameResolverImpl.getDescriptorByFqNameIndex(
module: ModuleDescriptor,
nameTable: ProtoBuf.QualifiedNameTable,
fqNameIndex: Int): DeclarationDescriptor {
if (fqNameIndex == -1) return module.getPackage(FqName.ROOT)
val packageName = this.getPackageFqName(fqNameIndex)
// TODO: Here we are using internals of NameresolverImpl.
// Consider extending NameResolver.
val proto = nameTable.getQualifiedName(fqNameIndex)
when (proto.kind!!) {
QualifiedName.Kind.CLASS,
QualifiedName.Kind.LOCAL ->
return module.findClassAcrossModuleDependencies(this.getClassId(fqNameIndex))!!
QualifiedName.Kind.PACKAGE ->
return module.getPackage(FqName(packageName))
}
}
@@ -22,11 +22,15 @@ data class UniqId (
// isLocal=true in UniqId is good while we dealing with a single current module.
// To disambiguate module local declarations of different modules we use UniqIdKey.
// It has moduleDescriptor specified for isLocal=true uniqIds.
// TODO: make sure UniqId is really uniq for any global declaration
data class UniqIdKey private constructor(val uniqId: UniqId, val moduleDescriptor: ModuleDescriptor?) {
constructor(moduleDescriptor: ModuleDescriptor?, uniqId: UniqId)
: this(uniqId, if (uniqId.isLocal) moduleDescriptor!! else null)
}
// TODO: think about this
internal val IrDeclaration.uniqIdIndex: Long
get() = this.uniqSymbolName().hashCode().toLong()