Commonized native and js IR serialization infrastructure
This commit is contained in:
committed by
alexander-gorshenev
parent
909a5fd32d
commit
cc93239397
+1
-1
@@ -732,4 +732,4 @@ allprojects {
|
|||||||
repositories.redirect()
|
repositories.redirect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-11
@@ -1,7 +1,7 @@
|
|||||||
syntax = "proto2";
|
syntax = "proto2";
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir;
|
package org.jetbrains.kotlin.backend.common.serialization;
|
||||||
|
|
||||||
option java_outer_classname = "IrKlibProtoBuf";
|
option java_outer_classname = "KotlinIr";
|
||||||
option optimize_for = LITE_RUNTIME;
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
message DescriptorReference {
|
message DescriptorReference {
|
||||||
@@ -74,6 +74,11 @@ message IrDeclarationOrigin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Name {
|
||||||
|
required String name = 1;
|
||||||
|
required bool is_special = 2;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------ Top Level---------------------------------------------- */
|
/* ------ Top Level---------------------------------------------- */
|
||||||
|
|
||||||
message IrDeclarationContainer {
|
message IrDeclarationContainer {
|
||||||
@@ -89,10 +94,12 @@ message IrFile {
|
|||||||
repeated UniqId declaration_id = 1;
|
repeated UniqId declaration_id = 1;
|
||||||
required FileEntry file_entry = 2;
|
required FileEntry file_entry = 2;
|
||||||
required String fq_name = 3;
|
required String fq_name = 3;
|
||||||
|
required Annotations annotations = 4;
|
||||||
|
repeated IrSymbol explicitly_exported_to_compiler = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrModule {
|
message IrModule {
|
||||||
required String name = 1;
|
required Name 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;
|
||||||
@@ -519,7 +526,7 @@ message IrFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message IrFunctionBase {
|
message IrFunctionBase {
|
||||||
required String name = 1;
|
required Name name = 1;
|
||||||
required Visibility 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;
|
||||||
@@ -541,7 +548,7 @@ 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 Name name = 3;
|
||||||
required Visibility 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;
|
||||||
@@ -551,7 +558,7 @@ message IrField {
|
|||||||
|
|
||||||
message IrProperty {
|
message IrProperty {
|
||||||
optional DescriptorReference descriptor_reference = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
|
optional DescriptorReference descriptor_reference = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
|
||||||
required String name = 2;
|
required Name name = 2;
|
||||||
required Visibility visibility = 3;
|
required Visibility visibility = 3;
|
||||||
required ModalityKind modality = 4;
|
required ModalityKind modality = 4;
|
||||||
required bool is_var = 5;
|
required bool is_var = 5;
|
||||||
@@ -565,7 +572,7 @@ message IrProperty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message IrVariable {
|
message IrVariable {
|
||||||
required String name = 1;
|
required Name 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;
|
||||||
@@ -592,7 +599,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 Name 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;
|
||||||
@@ -603,7 +610,7 @@ message IrValueParameter {
|
|||||||
|
|
||||||
message IrTypeParameter {
|
message IrTypeParameter {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
required String name = 2;
|
required Name 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;
|
||||||
@@ -616,7 +623,7 @@ message IrTypeParameterContainer {
|
|||||||
|
|
||||||
message IrClass {
|
message IrClass {
|
||||||
required IrSymbol symbol = 1;
|
required IrSymbol symbol = 1;
|
||||||
required String name = 2;
|
required Name name = 2;
|
||||||
required ClassKind kind = 3;
|
required ClassKind kind = 3;
|
||||||
required Visibility visibility = 4;
|
required Visibility visibility = 4;
|
||||||
required ModalityKind modality = 5;
|
required ModalityKind modality = 5;
|
||||||
@@ -636,7 +643,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 Name name = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message IrAnonymousInit {
|
message IrAnonymousInit {
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.common.library
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.io.RandomAccessFile
|
||||||
|
import java.nio.MappedByteBuffer
|
||||||
|
import java.nio.channels.FileChannel
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
data class DeclarationId(val id: Long, val isLocal: Boolean)
|
||||||
|
|
||||||
|
|
||||||
|
fun File.map(mode: FileChannel.MapMode = FileChannel.MapMode.READ_ONLY,
|
||||||
|
start: Long = 0, size: Long = -1): MappedByteBuffer {
|
||||||
|
val file = RandomAccessFile(path,
|
||||||
|
if (mode == FileChannel.MapMode.READ_ONLY) "r" else "rw")
|
||||||
|
val fileSize = if (mode == FileChannel.MapMode.READ_ONLY)
|
||||||
|
file.length() else size.also { assert(size != -1L) }
|
||||||
|
return file.channel.map(mode, start, fileSize) // Shall we .also { file.close() }?
|
||||||
|
}
|
||||||
|
|
||||||
|
class CombinedIrFileReader(file: File) {
|
||||||
|
private val buffer = file.map(FileChannel.MapMode.READ_ONLY)
|
||||||
|
private val declarationToOffsetSize = mutableMapOf<DeclarationId, Pair<Int, Int>>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
val declarationsCount = buffer.int
|
||||||
|
for (i in 0 until declarationsCount) {
|
||||||
|
val id = buffer.long
|
||||||
|
val isLocal = buffer.int != 0
|
||||||
|
val offset = buffer.int
|
||||||
|
val size = buffer.int
|
||||||
|
declarationToOffsetSize[DeclarationId(id, isLocal)] = offset to size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun declarationBytes(id: DeclarationId): ByteArray {
|
||||||
|
val offsetSize = declarationToOffsetSize[id] ?: throw Error("No declaration with $id here")
|
||||||
|
val result = ByteArray(offsetSize.second)
|
||||||
|
buffer.position(offsetSize.first)
|
||||||
|
buffer.get(result, 0, offsetSize.second)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val SINGLE_INDEX_RECORD_SIZE = 20 // sizeof(Long) + 3 * sizeof(Int).
|
||||||
|
private const val INDEX_HEADER_SIZE = 4 // sizeof(Int).
|
||||||
|
|
||||||
|
class CombinedIrFileWriter(val declarationCount: Int) {
|
||||||
|
private var currentDeclaration = 0
|
||||||
|
private var currentPosition = 0
|
||||||
|
private val file = Files.createTempFile("ir", "").toFile().also {
|
||||||
|
it.deleteOnExit()
|
||||||
|
}
|
||||||
|
private val randomAccessFile = RandomAccessFile(file.path, "rw")
|
||||||
|
|
||||||
|
init {
|
||||||
|
randomAccessFile.writeInt(declarationCount)
|
||||||
|
assert(randomAccessFile.filePointer.toInt() == INDEX_HEADER_SIZE)
|
||||||
|
for (i in 0 until declarationCount) {
|
||||||
|
randomAccessFile.writeLong(-1) // id
|
||||||
|
randomAccessFile.writeInt(-1) // isLocal
|
||||||
|
randomAccessFile.writeInt(-1) // offset
|
||||||
|
randomAccessFile.writeInt(-1) // size
|
||||||
|
}
|
||||||
|
currentPosition = randomAccessFile.filePointer.toInt()
|
||||||
|
assert(currentPosition == INDEX_HEADER_SIZE + SINGLE_INDEX_RECORD_SIZE * declarationCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun skipDeclaration() {
|
||||||
|
currentDeclaration++
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addDeclaration(id: DeclarationId, bytes: ByteArray) {
|
||||||
|
randomAccessFile.seek((currentDeclaration * SINGLE_INDEX_RECORD_SIZE + INDEX_HEADER_SIZE).toLong())
|
||||||
|
randomAccessFile.writeLong(id.id)
|
||||||
|
randomAccessFile.writeInt(if (id.isLocal) 1 else 0)
|
||||||
|
randomAccessFile.writeInt(currentPosition)
|
||||||
|
randomAccessFile.writeInt(bytes.size)
|
||||||
|
randomAccessFile.seek(currentPosition.toLong())
|
||||||
|
randomAccessFile.write(bytes)
|
||||||
|
assert(randomAccessFile.filePointer < Int.MAX_VALUE.toLong())
|
||||||
|
currentPosition = randomAccessFile.filePointer.toInt()
|
||||||
|
currentDeclaration++
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finishWriting(): File {
|
||||||
|
assert(currentDeclaration == declarationCount)
|
||||||
|
randomAccessFile.close()
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
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.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
val IrConstructor.constructedClass get() = this.parent as IrClass
|
||||||
|
|
||||||
|
val <T : IrDeclaration> T.original get() = this
|
||||||
|
|
||||||
|
val IrDeclarationParent.fqNameSafe: FqName
|
||||||
|
get() = when (this) {
|
||||||
|
is IrPackageFragment -> this.fqName
|
||||||
|
is IrDeclaration -> this.parent.fqNameSafe.child(this.name)
|
||||||
|
|
||||||
|
else -> error(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrClass.classId: ClassId?
|
||||||
|
get() {
|
||||||
|
val parent = this.parent
|
||||||
|
return when (parent) {
|
||||||
|
is IrClass -> parent.classId?.createNestedClassId(this.name)
|
||||||
|
is IrPackageFragment -> ClassId.topLevel(parent.fqName.child(this.name))
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrDeclaration.name: Name
|
||||||
|
get() = when (this) {
|
||||||
|
is IrSimpleFunction -> this.name
|
||||||
|
is IrClass -> this.name
|
||||||
|
is IrEnumEntry -> this.name
|
||||||
|
is IrProperty -> this.name
|
||||||
|
is IrLocalDelegatedProperty -> this.name
|
||||||
|
is IrField -> this.name
|
||||||
|
is IrVariable -> this.name
|
||||||
|
is IrConstructor -> SPECIAL_INIT_NAME
|
||||||
|
is IrValueParameter -> this.name
|
||||||
|
else -> error(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val SPECIAL_INIT_NAME = Name.special("<init>")
|
||||||
|
|
||||||
|
val IrValueParameter.isVararg get() = this.varargElementType != null
|
||||||
|
|
||||||
|
val IrFunction.isSuspend get() = this is IrSimpleFunction && this.isSuspend
|
||||||
|
|
||||||
|
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
|
||||||
|
|
||||||
|
fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
|
||||||
|
if (this == other) return true
|
||||||
|
|
||||||
|
this.overriddenSymbols.forEach {
|
||||||
|
if (it.owner.overrides(other)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrCall.annotationClass
|
||||||
|
get() = (this.symbol.owner as IrConstructor).constructedClass
|
||||||
|
|
||||||
|
fun List<IrCall>.hasAnnotation(fqName: FqName): Boolean =
|
||||||
|
this.any { it.annotationClass.fqNameSafe == fqName }
|
||||||
|
|
||||||
|
fun IrAnnotationContainer.hasAnnotation(fqName: FqName) =
|
||||||
|
this.annotations.hasAnnotation(fqName)
|
||||||
|
|
||||||
|
fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
|
||||||
|
it.annotationClass.fqNameSafe == fqName
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrClass.isInterface: Boolean
|
||||||
|
get() = (this.kind == ClassKind.INTERFACE)
|
||||||
|
|
||||||
|
|
||||||
|
fun IrClass.companionObject() = this.declarations.singleOrNull {it is IrClass && it.isCompanion }
|
||||||
|
|
||||||
|
val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.getter
|
||||||
|
|
||||||
|
val IrDeclaration.isSetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.setter
|
||||||
|
|
||||||
|
val IrDeclaration.isAccessor get() = this.isGetter || this.isSetter
|
||||||
|
|
||||||
|
val IrDeclaration.isPropertyAccessor get() =
|
||||||
|
this is IrSimpleFunction && this.correspondingProperty != null
|
||||||
|
|
||||||
|
val IrDeclaration.isPropertyField get() =
|
||||||
|
this is IrField && this.correspondingProperty != null
|
||||||
|
|
||||||
|
val IrDeclaration.isTopLevelDeclaration get() =
|
||||||
|
parent !is IrDeclaration && !this.isPropertyAccessor && !this.isPropertyField
|
||||||
|
|
||||||
|
fun IrDeclaration.findTopLevelDeclaration(): IrDeclaration = when {
|
||||||
|
this.isTopLevelDeclaration ->
|
||||||
|
this
|
||||||
|
this.isPropertyAccessor ->
|
||||||
|
(this as IrSimpleFunction).correspondingProperty!!.findTopLevelDeclaration()
|
||||||
|
this.isPropertyField ->
|
||||||
|
(this as IrField).correspondingProperty!!.findTopLevelDeclaration()
|
||||||
|
else ->
|
||||||
|
(this.parent as IrDeclaration).findTopLevelDeclaration()
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrDeclaration.isAnonymousObject get() = DescriptorUtils.isAnonymousObject(this.descriptor)
|
||||||
|
val IrDeclaration.isLocal get() = DescriptorUtils.isLocal(this.descriptor)
|
||||||
|
|
||||||
|
val IrDeclaration.module get() = this.descriptor.module
|
||||||
|
|
||||||
|
const val SYNTHETIC_OFFSET = -2
|
||||||
|
|
||||||
|
val File.lineStartOffsets: IntArray
|
||||||
|
get() {
|
||||||
|
// 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()
|
||||||
|
// as in PSI.
|
||||||
|
val separatorLength = System.lineSeparator().length
|
||||||
|
val buffer = mutableListOf<Int>()
|
||||||
|
var currentOffset = 0
|
||||||
|
this.forEachLine { line ->
|
||||||
|
buffer.add(currentOffset)
|
||||||
|
currentOffset += line.length + separatorLength
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
assert(offset != UNDEFINED_OFFSET)
|
||||||
|
if (offset == SYNTHETIC_OFFSET) return 0
|
||||||
|
val index = lineStartOffsets.binarySearch(offset)
|
||||||
|
return if (index >= 0) index else -index - 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun getColumnNumber(offset: Int): Int {
|
||||||
|
assert(offset != UNDEFINED_OFFSET)
|
||||||
|
if (offset == SYNTHETIC_OFFSET) return 0
|
||||||
|
var lineNumber = getLineNumber(offset)
|
||||||
|
return offset - lineStartOffsets[lineNumber]
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override val maxOffset: Int
|
||||||
|
//get() = TODO("not implemented")
|
||||||
|
get() = UNDEFINED_OFFSET
|
||||||
|
|
||||||
|
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo {
|
||||||
|
//TODO("not implemented")
|
||||||
|
return SourceRangeInfo(name, beginOffset, -1, -1, endOffset, -1, -1)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
-23
@@ -3,13 +3,12 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
|
||||||
|
|
||||||
class DescriptorTable {
|
class DescriptorTable {
|
||||||
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
|
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
|
||||||
@@ -20,29 +19,28 @@ class DescriptorTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We don't manage id clashes anyhow now.
|
// TODO: We don't manage id clashes anyhow now.
|
||||||
class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: DescriptorTable, val symbolTable: SymbolTable) {
|
abstract class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: DescriptorTable, mangler: KotlinMangler): KotlinMangler by mangler {
|
||||||
|
|
||||||
private val table = mutableMapOf<IrDeclaration, UniqId>()
|
private val table = mutableMapOf<IrDeclaration, UniqId>()
|
||||||
val debugIndex = mutableMapOf<UniqId, String>()
|
val debugIndex = mutableMapOf<UniqId, String>()
|
||||||
val descriptors = descriptorTable
|
val descriptors = descriptorTable
|
||||||
private var currentIndex = 0x1_0000_0000L
|
abstract protected var currentIndex: Long
|
||||||
|
protected var initialized: Boolean = false
|
||||||
|
|
||||||
private val FUNCTION_INDEX_START: Long
|
open fun loadKnownBuiltins() {
|
||||||
|
builtIns.knownBuiltins.forEach {
|
||||||
init {
|
|
||||||
val known = builtIns.knownBuiltins
|
|
||||||
known.forEach {
|
|
||||||
table.put(it, UniqId(currentIndex++, false))
|
table.put(it, UniqId(currentIndex++, false))
|
||||||
}
|
}
|
||||||
|
initialized = true
|
||||||
FUNCTION_INDEX_START = currentIndex
|
|
||||||
currentIndex += BUILT_IN_UNIQ_ID_GAP
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uniqIdByDeclaration(value: IrDeclaration) = table.getOrPut(value) {
|
fun uniqIdByDeclaration(value: IrDeclaration) = table.getOrPut(value) {
|
||||||
val index = if (isBuiltInFunction(value)) {
|
if (!initialized) error("DeclarationTable has not been initialized")
|
||||||
UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false)
|
computeUniqIdByDeclaration(value)
|
||||||
} else if (value.origin == IrDeclarationOrigin.FAKE_OVERRIDE ||
|
}
|
||||||
|
|
||||||
|
open protected fun computeUniqIdByDeclaration(value: IrDeclaration): UniqId {
|
||||||
|
val index = if (value.origin == IrDeclarationOrigin.FAKE_OVERRIDE ||
|
||||||
!value.isExported()
|
!value.isExported()
|
||||||
|| value is IrVariable
|
|| value is IrVariable
|
||||||
|| value is IrTypeParameter
|
|| value is IrTypeParameter
|
||||||
@@ -51,18 +49,13 @@ class DeclarationTable(val builtIns: IrBuiltIns, val descriptorTable: Descriptor
|
|||||||
) {
|
) {
|
||||||
UniqId(currentIndex++, true)
|
UniqId(currentIndex++, true)
|
||||||
} else {
|
} else {
|
||||||
UniqId(value.uniqIdIndex, false)
|
UniqId(value.hashedMangle, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// It can grow as large as 1/3 of ir/* size.
|
return index
|
||||||
// debugIndex.put(index) {
|
|
||||||
// "${if (index.isLocal) "" else value.uniqSymbolName()} descriptor = ${value.descriptor}"
|
|
||||||
//}.also {it == null}
|
|
||||||
|
|
||||||
index
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is what we pre-populate tables with
|
// This is what we pre-populate tables with
|
||||||
val IrBuiltIns.knownBuiltins
|
val IrBuiltIns.knownBuiltins
|
||||||
get() = irBuiltInsExternalPackageFragment.declarations
|
get() = irBuiltInsExternalPackageFragment.declarations
|
||||||
+38
-39
@@ -3,10 +3,12 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.UniqIdKey
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.resolveFakeOverrideMaybeAbstract
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -16,57 +18,53 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
|||||||
abstract class DescriptorReferenceDeserializer(
|
abstract class DescriptorReferenceDeserializer(
|
||||||
val currentModule: ModuleDescriptor,
|
val currentModule: ModuleDescriptor,
|
||||||
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
|
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
|
||||||
) {
|
) : DescriptorUniqIdAware {
|
||||||
|
|
||||||
|
|
||||||
protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor
|
protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor
|
||||||
protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean
|
protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean
|
||||||
protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long?
|
protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long?
|
||||||
|
|
||||||
private val cache = mutableMapOf<String, Collection<DeclarationDescriptor>>()
|
protected fun getContributedDescriptors(packageFqNameString: String, name: String): Collection<DeclarationDescriptor> {
|
||||||
|
val packageFqName = packageFqNameString.let {
|
||||||
|
if (it == "<root>") FqName.ROOT else FqName(it)
|
||||||
|
}// TODO: whould we store an empty string in the protobuf?
|
||||||
|
|
||||||
private fun getContributedDescriptors(packageFqNameString: String): Collection<DeclarationDescriptor> =
|
val contributedName = if (name.startsWith("<get-") || name.startsWith("<set-")) {
|
||||||
cache.getOrPut(packageFqNameString) {
|
name.substring(5, name.length - 1) // FIXME: rework serialization format.
|
||||||
val packageFqName = packageFqNameString.let {
|
} else {
|
||||||
if (it == "<root>") FqName.ROOT else FqName(it)
|
name
|
||||||
}// TODO: whould we store an empty string in the protobuf?
|
|
||||||
|
|
||||||
currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors()
|
|
||||||
}
|
}
|
||||||
|
return currentModule.getPackage(packageFqName).memberScope
|
||||||
|
.getContributedDescriptors(nameFilter = { it.asString() == contributedName })
|
||||||
|
}
|
||||||
|
|
||||||
private data class ClassName(val packageFqName: String, val classFqName: String)
|
protected class ClassMembers(val defaultConstructor: ClassConstructorDescriptor?,
|
||||||
|
|
||||||
private class ClassMembers(val defaultConstructor: ClassConstructorDescriptor?,
|
|
||||||
val members: Map<Long, DeclarationDescriptor>,
|
val members: Map<Long, DeclarationDescriptor>,
|
||||||
val realMembers: Map<Long, DeclarationDescriptor>)
|
val realMembers: Map<Long, DeclarationDescriptor>)
|
||||||
|
|
||||||
private val membersCache = mutableMapOf<ClassName, ClassMembers>()
|
private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId() ?: getDescriptorIdOrNull(descriptor)
|
||||||
|
|
||||||
|
protected fun getMembers(members: Collection<DeclarationDescriptor>): ClassMembers {
|
||||||
private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId()?.index ?: getDescriptorIdOrNull(descriptor)
|
val allMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
|
||||||
|
val realMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
|
||||||
private fun getMembers(packageFqNameString: String, classFqNameString: String,
|
var classConstructorDescriptor: ClassConstructorDescriptor? = null
|
||||||
members: Collection<DeclarationDescriptor>): ClassMembers =
|
members.forEach { member ->
|
||||||
membersCache.getOrPut(ClassName(packageFqNameString, classFqNameString)) {
|
if (member is ClassConstructorDescriptor)
|
||||||
val allMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
|
classConstructorDescriptor = member
|
||||||
val realMembersMap = mutableMapOf<Long, DeclarationDescriptor>()
|
val realMembers =
|
||||||
var classConstructorDescriptor: ClassConstructorDescriptor? = null
|
|
||||||
members.forEach { member ->
|
|
||||||
if (member is ClassConstructorDescriptor)
|
|
||||||
classConstructorDescriptor = member
|
|
||||||
val realMembers =
|
|
||||||
if (member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
if (member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
||||||
member.resolveFakeOverrideMaybeAbstract().map { it.original }
|
member.resolveFakeOverrideMaybeAbstract()
|
||||||
else
|
else
|
||||||
setOf(member)
|
setOf(member)
|
||||||
|
|
||||||
computeUniqIdIndex(member)?.let { allMembersMap[it] = member }
|
computeUniqIdIndex(member)?.let { allMembersMap[it] = member }
|
||||||
realMembers.map { computeUniqIdIndex(it) }.filterNotNull().forEach { realMembersMap[it] = member }
|
realMembers.mapNotNull { computeUniqIdIndex(it) }.forEach { realMembersMap[it] = member }
|
||||||
}
|
|
||||||
ClassMembers(classConstructorDescriptor, allMembersMap, realMembersMap)
|
|
||||||
}
|
}
|
||||||
|
return ClassMembers(classConstructorDescriptor, allMembersMap, realMembersMap)
|
||||||
|
}
|
||||||
|
|
||||||
fun deserializeDescriptorReference(
|
open fun deserializeDescriptorReference(
|
||||||
packageFqNameString: String,
|
packageFqNameString: String,
|
||||||
classFqNameString: String,
|
classFqNameString: String,
|
||||||
name: String,
|
name: String,
|
||||||
@@ -82,16 +80,17 @@ abstract class DescriptorReferenceDeserializer(
|
|||||||
if (it == "<root>") FqName.ROOT else FqName(it)
|
if (it == "<root>") FqName.ROOT else FqName(it)
|
||||||
}// TODO: whould we store an empty string in the protobuf?
|
}// TODO: whould we store an empty string in the protobuf?
|
||||||
|
|
||||||
val classFqName = FqName(classFqNameString)
|
val classFqName = if (classFqNameString == "<root>") FqName.ROOT else FqName(classFqNameString)
|
||||||
val protoIndex = index
|
val protoIndex = index
|
||||||
|
|
||||||
val (clazz, members) = if (classFqNameString == "") {
|
val (clazz, members) = if (classFqNameString == "" || classFqNameString == "<root>") {
|
||||||
Pair(null, getContributedDescriptors(packageFqNameString))
|
Pair(null, getContributedDescriptors(packageFqNameString, name))
|
||||||
} 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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This is still native specific. Eliminate.
|
||||||
if (packageFqNameString.startsWith("cnames.") || packageFqNameString.startsWith("objcnames.")) {
|
if (packageFqNameString.startsWith("cnames.") || packageFqNameString.startsWith("objcnames.")) {
|
||||||
val descriptor =
|
val descriptor =
|
||||||
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(name), false))!!
|
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(name), false))!!
|
||||||
@@ -100,7 +99,7 @@ abstract class DescriptorReferenceDeserializer(
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (descriptor is DeserializedClassDescriptor) {
|
if (descriptor is DeserializedClassDescriptor) {
|
||||||
val uniqId = UniqId(descriptor.getUniqId()!!.index, false)
|
val uniqId = UniqId(descriptor.getUniqId()!!, false)
|
||||||
val newKey = UniqIdKey(null, uniqId)
|
val newKey = UniqIdKey(null, uniqId)
|
||||||
val oldKey = UniqIdKey(null, UniqId(protoIndex!!, false))
|
val oldKey = UniqIdKey(null, UniqId(protoIndex!!, false))
|
||||||
|
|
||||||
@@ -126,7 +125,7 @@ abstract class DescriptorReferenceDeserializer(
|
|||||||
return resolveSpecialDescriptor(packageFqName.child(Name.identifier(name)))
|
return resolveSpecialDescriptor(packageFqName.child(Name.identifier(name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members)
|
val membersWithIndices = getMembers(members)
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
isDefaultConstructor -> membersWithIndices.defaultConstructor
|
isDefaultConstructor -> membersWithIndices.defaultConstructor
|
||||||
@@ -144,4 +143,4 @@ abstract class DescriptorReferenceDeserializer(
|
|||||||
} ?:
|
} ?:
|
||||||
error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}")
|
error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-27
@@ -3,11 +3,11 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
*
|
*
|
||||||
* TODO: this method is actually a part of resolve and probably duplicates another one
|
* TODO: this method is actually a part of resolve and probably duplicates another one
|
||||||
*/
|
*/
|
||||||
internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false): IrSimpleFunction {
|
fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false): IrSimpleFunction {
|
||||||
if (this.isReal) {
|
if (this.isReal) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -53,34 +53,22 @@ internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false
|
|||||||
return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT }
|
return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val IrClass.isInterface: Boolean
|
/**
|
||||||
get() = (this.kind == ClassKind.INTERFACE)
|
* Implementation of given method.
|
||||||
|
*
|
||||||
|
* TODO: this method is actually a part of resolve and probably duplicates another one
|
||||||
|
*/
|
||||||
|
internal fun IrSimpleFunction.resolveFakeOverrideMaybeAbstract() = this.resolveFakeOverride(allowAbstract = true)
|
||||||
|
|
||||||
internal val IrSimpleFunction.target: IrSimpleFunction
|
internal fun IrProperty.resolveFakeOverrideMaybeAbstract() = this.getter!!.resolveFakeOverrideMaybeAbstract().correspondingProperty!!
|
||||||
|
|
||||||
|
internal fun IrField.resolveFakeOverrideMaybeAbstract() = this.correspondingProperty!!.getter!!.resolveFakeOverrideMaybeAbstract().correspondingProperty!!.backingField
|
||||||
|
|
||||||
|
val IrSimpleFunction.target: IrSimpleFunction
|
||||||
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
|
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
|
||||||
|
|
||||||
internal val IrFunction.target: IrFunction get() = when (this) {
|
val IrFunction.target: IrFunction get() = when (this) {
|
||||||
is IrSimpleFunction -> this.target
|
is IrSimpleFunction -> this.target
|
||||||
is IrConstructor -> this
|
is IrConstructor -> this
|
||||||
else -> error(this)
|
else -> error(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
val IrDeclaration.isPropertyAccessor get() =
|
|
||||||
this is IrSimpleFunction && this.correspondingProperty != null
|
|
||||||
|
|
||||||
val IrDeclaration.isPropertyField get() =
|
|
||||||
this is IrField && this.correspondingProperty != null
|
|
||||||
|
|
||||||
val IrDeclaration.isTopLevelDeclaration get() =
|
|
||||||
parent !is IrDeclaration && !this.isPropertyAccessor && !this.isPropertyField
|
|
||||||
|
|
||||||
fun IrDeclaration.findTopLevelDeclaration(): IrDeclaration = when {
|
|
||||||
this.isTopLevelDeclaration ->
|
|
||||||
this
|
|
||||||
this.isPropertyAccessor ->
|
|
||||||
(this as IrSimpleFunction).correspondingProperty!!.findTopLevelDeclaration()
|
|
||||||
this.isPropertyField ->
|
|
||||||
(this as IrField).correspondingProperty!!.findTopLevelDeclaration()
|
|
||||||
else ->
|
|
||||||
(this.parent as IrDeclaration).findTopLevelDeclaration()
|
|
||||||
}
|
|
||||||
+172
-175
@@ -3,7 +3,7 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||||
@@ -24,11 +24,14 @@ import org.jetbrains.kotlin.ir.types.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
import org.jetbrains.kotlin.ir.util.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.IrKlibProtoBuf.IrStatement.*
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrStatement.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.IrKlibProtoBuf.IrOperation.OperationCase.*
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrOperation.OperationCase.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.IrKlibProtoBuf.IrConst.ValueCase.*
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrConst.ValueCase.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.IrKlibProtoBuf.IrDeclarator.DeclaratorCase.*
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrDeclarator.DeclaratorCase.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.IrKlibProtoBuf.IrType.KindCase.*
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrType.KindCase.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrVarargElement.VarargElementCase
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.KotlinIr.IrTypeArgument.KindCase.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -46,12 +49,18 @@ abstract class IrModuleDeserializer(
|
|||||||
val symbolTable: SymbolTable
|
val symbolTable: SymbolTable
|
||||||
) : IrDeserializer {
|
) : IrDeserializer {
|
||||||
|
|
||||||
abstract fun deserializeIrSymbol(proto: IrKlibProtoBuf.IrSymbol): IrSymbol
|
abstract fun deserializeIrSymbol(proto: KotlinIr.IrSymbol): IrSymbol
|
||||||
abstract fun deserializeIrType(proto: IrKlibProtoBuf.IrTypeIndex): IrType
|
abstract fun deserializeIrType(proto: KotlinIr.IrTypeIndex): IrType
|
||||||
abstract fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference): DeclarationDescriptor
|
abstract fun deserializeDescriptorReference(proto: KotlinIr.DescriptorReference): DeclarationDescriptor
|
||||||
abstract fun deserializeString(proto: IrKlibProtoBuf.String): String
|
abstract fun deserializeString(proto: KotlinIr.String): String
|
||||||
|
abstract fun deserializeLoopHeader(loopIndex: Int, loopBuilder: () -> IrLoopBase): IrLoopBase
|
||||||
|
|
||||||
private fun deserializeTypeArguments(proto: IrKlibProtoBuf.TypeArguments): List<IrType> {
|
private fun deserializeName(proto: KotlinIr.Name): Name {
|
||||||
|
val name = deserializeString(proto.name)
|
||||||
|
return if (proto.isSpecial) Name.special(name) else Name.identifier(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deserializeTypeArguments(proto: KotlinIr.TypeArguments): List<IrType> {
|
||||||
logger.log { "### deserializeTypeArguments" }
|
logger.log { "### deserializeTypeArguments" }
|
||||||
val result = mutableListOf<IrType>()
|
val result = mutableListOf<IrType>()
|
||||||
proto.typeArgumentList.forEach { typeProto ->
|
proto.typeArgumentList.forEach { typeProto ->
|
||||||
@@ -62,34 +71,35 @@ abstract class IrModuleDeserializer(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrTypeVariance(variance: IrKlibProtoBuf.IrTypeVariance) = when (variance) {
|
fun deserializeIrTypeVariance(variance: KotlinIr.IrTypeVariance) = when (variance) {
|
||||||
IrKlibProtoBuf.IrTypeVariance.IN -> Variance.IN_VARIANCE
|
KotlinIr.IrTypeVariance.IN -> Variance.IN_VARIANCE
|
||||||
IrKlibProtoBuf.IrTypeVariance.OUT -> Variance.OUT_VARIANCE
|
KotlinIr.IrTypeVariance.OUT -> Variance.OUT_VARIANCE
|
||||||
IrKlibProtoBuf.IrTypeVariance.INV -> Variance.INVARIANT
|
KotlinIr.IrTypeVariance.INV -> Variance.INVARIANT
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrTypeArgument(proto: IrKlibProtoBuf.IrTypeArgument) = when (proto.kindCase) {
|
fun deserializeIrTypeArgument(proto: KotlinIr.IrTypeArgument) = when (proto.kindCase) {
|
||||||
IrKlibProtoBuf.IrTypeArgument.KindCase.STAR -> IrStarProjectionImpl
|
STAR -> IrStarProjectionImpl
|
||||||
IrKlibProtoBuf.IrTypeArgument.KindCase.TYPE -> makeTypeProjection(
|
TYPE -> makeTypeProjection(
|
||||||
deserializeIrType(proto.type.type), deserializeIrTypeVariance(proto.type.variance)
|
deserializeIrType(proto.type.type), deserializeIrTypeVariance(proto.type.variance)
|
||||||
)
|
)
|
||||||
else -> TODO("Unexpected projection kind")
|
else -> TODO("Unexpected projection kind")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeAnnotations(annotations: IrKlibProtoBuf.Annotations): List<IrCall> {
|
fun deserializeAnnotations(annotations: KotlinIr.Annotations): List<IrCall> {
|
||||||
return annotations.annotationList.map {
|
return annotations.annotationList.map {
|
||||||
deserializeCall(it, 0, 0, builtIns.unitType) // TODO: need a proper deserialization here
|
deserializeCall(it, 0, 0, builtIns.unitType) // TODO: need a proper deserialization here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeSimpleType(proto: IrKlibProtoBuf.IrSimpleType): IrSimpleType {
|
open fun getPrimitiveTypeOrNull(symbol: IrClassifierSymbol, hasQuestionMark: Boolean): IrSimpleType? = null
|
||||||
|
|
||||||
|
fun deserializeSimpleType(proto: KotlinIr.IrSimpleType): IrSimpleType {
|
||||||
val symbol = deserializeIrSymbol(proto.classifier) as? IrClassifierSymbol
|
val symbol = deserializeIrSymbol(proto.classifier) as? IrClassifierSymbol
|
||||||
//?: error("could not convert sym to ClassifierSym ${proto.classifier.kind} ${proto.classifier.uniqId.index} ${proto.classifier.uniqId.isLocal}")
|
|
||||||
?: error("could not convert sym to ClassifierSymbol")
|
?: error("could not convert sym to ClassifierSymbol")
|
||||||
logger.log { "deserializeSimpleType: symbol=$symbol" }
|
logger.log { "deserializeSimpleType: symbol=$symbol" }
|
||||||
|
|
||||||
val result = builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, proto.hasQuestionMark) ?: run {
|
val result = getPrimitiveTypeOrNull(symbol, proto.hasQuestionMark) ?: run {
|
||||||
val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
|
val arguments = proto.argumentList.map { deserializeIrTypeArgument(it) }
|
||||||
val annotations = deserializeAnnotations(proto.annotations)
|
val annotations = deserializeAnnotations(proto.annotations)
|
||||||
IrSimpleTypeImpl(
|
IrSimpleTypeImpl(
|
||||||
@@ -105,17 +115,17 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeDynamicType(proto: IrKlibProtoBuf.IrDynamicType): IrDynamicType {
|
fun deserializeDynamicType(proto: KotlinIr.IrDynamicType): IrDynamicType {
|
||||||
val annotations = deserializeAnnotations(proto.annotations)
|
val annotations = deserializeAnnotations(proto.annotations)
|
||||||
return IrDynamicTypeImpl(null, annotations, Variance.INVARIANT)
|
return IrDynamicTypeImpl(null, annotations, Variance.INVARIANT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeErrorType(proto: IrKlibProtoBuf.IrErrorType): IrErrorType {
|
fun deserializeErrorType(proto: KotlinIr.IrErrorType): IrErrorType {
|
||||||
val annotations = deserializeAnnotations(proto.annotations)
|
val annotations = deserializeAnnotations(proto.annotations)
|
||||||
return IrErrorTypeImpl(null, annotations, Variance.INVARIANT)
|
return IrErrorTypeImpl(null, annotations, Variance.INVARIANT)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrTypeData(proto: IrKlibProtoBuf.IrType): IrType {
|
fun deserializeIrTypeData(proto: KotlinIr.IrType): IrType {
|
||||||
return when (proto.kindCase) {
|
return when (proto.kindCase) {
|
||||||
SIMPLE -> deserializeSimpleType(proto.simple)
|
SIMPLE -> deserializeSimpleType(proto.simple)
|
||||||
DYNAMIC -> deserializeDynamicType(proto.dynamic)
|
DYNAMIC -> deserializeDynamicType(proto.dynamic)
|
||||||
@@ -127,7 +137,7 @@ abstract class IrModuleDeserializer(
|
|||||||
/* -------------------------------------------------------------- */
|
/* -------------------------------------------------------------- */
|
||||||
|
|
||||||
private fun deserializeBlockBody(
|
private fun deserializeBlockBody(
|
||||||
proto: IrKlibProtoBuf.IrBlockBody,
|
proto: KotlinIr.IrBlockBody,
|
||||||
start: Int, end: Int
|
start: Int, end: Int
|
||||||
): IrBlockBody {
|
): IrBlockBody {
|
||||||
|
|
||||||
@@ -141,7 +151,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrBlockBodyImpl(start, end, statements)
|
return IrBlockBodyImpl(start, end, statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeBranch(proto: IrKlibProtoBuf.IrBranch, start: Int, end: Int): IrBranch {
|
private fun deserializeBranch(proto: KotlinIr.IrBranch, start: Int, end: Int): IrBranch {
|
||||||
|
|
||||||
val condition = deserializeExpression(proto.condition)
|
val condition = deserializeExpression(proto.condition)
|
||||||
val result = deserializeExpression(proto.result)
|
val result = deserializeExpression(proto.result)
|
||||||
@@ -149,7 +159,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrBranchImpl(start, end, condition, result)
|
return IrBranchImpl(start, end, condition, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeCatch(proto: IrKlibProtoBuf.IrCatch, start: Int, end: Int): IrCatch {
|
private fun deserializeCatch(proto: KotlinIr.IrCatch, start: Int, end: Int): IrCatch {
|
||||||
val catchParameter =
|
val catchParameter =
|
||||||
deserializeDeclaration(proto.catchParameter, null) as IrVariable // TODO: we need a proper parent here
|
deserializeDeclaration(proto.catchParameter, null) as IrVariable // TODO: we need a proper parent here
|
||||||
val result = deserializeExpression(proto.result)
|
val result = deserializeExpression(proto.result)
|
||||||
@@ -158,15 +168,15 @@ abstract class IrModuleDeserializer(
|
|||||||
return catch
|
return catch
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSyntheticBody(proto: IrKlibProtoBuf.IrSyntheticBody, start: Int, end: Int): IrSyntheticBody {
|
private fun deserializeSyntheticBody(proto: KotlinIr.IrSyntheticBody, start: Int, end: Int): IrSyntheticBody {
|
||||||
val kind = when (proto.kind) {
|
val kind = when (proto.kind) {
|
||||||
IrKlibProtoBuf.IrSyntheticBodyKind.ENUM_VALUES -> IrSyntheticBodyKind.ENUM_VALUES
|
KotlinIr.IrSyntheticBodyKind.ENUM_VALUES -> IrSyntheticBodyKind.ENUM_VALUES
|
||||||
IrKlibProtoBuf.IrSyntheticBodyKind.ENUM_VALUEOF -> IrSyntheticBodyKind.ENUM_VALUEOF
|
KotlinIr.IrSyntheticBodyKind.ENUM_VALUEOF -> IrSyntheticBodyKind.ENUM_VALUEOF
|
||||||
}
|
}
|
||||||
return IrSyntheticBodyImpl(start, end, kind)
|
return IrSyntheticBodyImpl(start, end, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeStatement(proto: IrKlibProtoBuf.IrStatement): IrElement {
|
private fun deserializeStatement(proto: KotlinIr.IrStatement): IrElement {
|
||||||
val start = proto.coordinates.startOffset
|
val start = proto.coordinates.startOffset
|
||||||
val end = proto.coordinates.endOffset
|
val end = proto.coordinates.endOffset
|
||||||
val element = when (proto.statementCase) {
|
val element = when (proto.statementCase) {
|
||||||
@@ -191,7 +201,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeBlock(proto: IrKlibProtoBuf.IrBlock, start: Int, end: Int, type: IrType): IrBlock {
|
private fun deserializeBlock(proto: KotlinIr.IrBlock, start: Int, end: Int, type: IrType): IrBlock {
|
||||||
val statements = mutableListOf<IrStatement>()
|
val statements = mutableListOf<IrStatement>()
|
||||||
val statementProtos = proto.statementList
|
val statementProtos = proto.statementList
|
||||||
statementProtos.forEach {
|
statementProtos.forEach {
|
||||||
@@ -203,7 +213,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrBlockImpl(start, end, type, isLambdaOrigin, statements)
|
return IrBlockImpl(start, end, type, isLambdaOrigin, statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeMemberAccessCommon(access: IrMemberAccessExpression, proto: IrKlibProtoBuf.MemberAccessCommon) {
|
private fun deserializeMemberAccessCommon(access: IrMemberAccessExpression, proto: KotlinIr.MemberAccessCommon) {
|
||||||
|
|
||||||
proto.valueArgumentList.mapIndexed { i, arg ->
|
proto.valueArgumentList.mapIndexed { i, arg ->
|
||||||
if (arg.hasExpression()) {
|
if (arg.hasExpression()) {
|
||||||
@@ -225,7 +235,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeClassReference(
|
private fun deserializeClassReference(
|
||||||
proto: IrKlibProtoBuf.IrClassReference,
|
proto: KotlinIr.IrClassReference,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
@@ -236,7 +246,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrClassReferenceImpl(start, end, type, symbol, classType)
|
return IrClassReferenceImpl(start, end, type, symbol, classType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeCall(proto: IrKlibProtoBuf.IrCall, start: Int, end: Int, type: IrType): IrCall {
|
private fun deserializeCall(proto: KotlinIr.IrCall, start: Int, end: Int, type: IrType): IrCall {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFunctionSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrFunctionSymbol
|
||||||
|
|
||||||
val superSymbol = if (proto.hasSuper()) {
|
val superSymbol = if (proto.hasSuper()) {
|
||||||
@@ -244,7 +254,7 @@ abstract class IrModuleDeserializer(
|
|||||||
} else null
|
} else null
|
||||||
|
|
||||||
val call: IrCall = when (proto.kind) {
|
val call: IrCall = when (proto.kind) {
|
||||||
IrKlibProtoBuf.IrCall.Primitive.NOT_PRIMITIVE ->
|
KotlinIr.IrCall.Primitive.NOT_PRIMITIVE ->
|
||||||
// TODO: implement the last three args here.
|
// TODO: implement the last three args here.
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
start, end, type,
|
start, end, type,
|
||||||
@@ -253,11 +263,11 @@ abstract class IrModuleDeserializer(
|
|||||||
proto.memberAccess.valueArgumentList.size,
|
proto.memberAccess.valueArgumentList.size,
|
||||||
null, superSymbol
|
null, superSymbol
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrCall.Primitive.NULLARY ->
|
KotlinIr.IrCall.Primitive.NULLARY ->
|
||||||
IrNullaryPrimitiveImpl(start, end, type, null, symbol)
|
IrNullaryPrimitiveImpl(start, end, type, null, symbol)
|
||||||
IrKlibProtoBuf.IrCall.Primitive.UNARY ->
|
KotlinIr.IrCall.Primitive.UNARY ->
|
||||||
IrUnaryPrimitiveImpl(start, end, type, null, symbol)
|
IrUnaryPrimitiveImpl(start, end, type, null, symbol)
|
||||||
IrKlibProtoBuf.IrCall.Primitive.BINARY ->
|
KotlinIr.IrCall.Primitive.BINARY ->
|
||||||
IrBinaryPrimitiveImpl(start, end, type, null, symbol)
|
IrBinaryPrimitiveImpl(start, end, type, null, symbol)
|
||||||
else -> TODO("Unexpected primitive IrCall.")
|
else -> TODO("Unexpected primitive IrCall.")
|
||||||
}
|
}
|
||||||
@@ -265,7 +275,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeComposite(proto: IrKlibProtoBuf.IrComposite, start: Int, end: Int, type: IrType): IrComposite {
|
private fun deserializeComposite(proto: KotlinIr.IrComposite, start: Int, end: Int, type: IrType): IrComposite {
|
||||||
val statements = mutableListOf<IrStatement>()
|
val statements = mutableListOf<IrStatement>()
|
||||||
val statementProtos = proto.statementList
|
val statementProtos = proto.statementList
|
||||||
statementProtos.forEach {
|
statementProtos.forEach {
|
||||||
@@ -275,7 +285,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeDelegatingConstructorCall(
|
private fun deserializeDelegatingConstructorCall(
|
||||||
proto: IrKlibProtoBuf.IrDelegatingConstructorCall,
|
proto: KotlinIr.IrDelegatingConstructorCall,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int
|
end: Int
|
||||||
): IrDelegatingConstructorCall {
|
): IrDelegatingConstructorCall {
|
||||||
@@ -296,7 +306,7 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
|
|
||||||
fun deserializeEnumConstructorCall(
|
fun deserializeEnumConstructorCall(
|
||||||
proto: IrKlibProtoBuf.IrEnumConstructorCall,
|
proto: KotlinIr.IrEnumConstructorCall,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
@@ -316,7 +326,7 @@ abstract class IrModuleDeserializer(
|
|||||||
|
|
||||||
|
|
||||||
private fun deserializeFunctionReference(
|
private fun deserializeFunctionReference(
|
||||||
proto: IrKlibProtoBuf.IrFunctionReference,
|
proto: KotlinIr.IrFunctionReference,
|
||||||
start: Int, end: Int, type: IrType
|
start: Int, end: Int, type: IrType
|
||||||
): IrFunctionReference {
|
): IrFunctionReference {
|
||||||
|
|
||||||
@@ -336,12 +346,12 @@ abstract class IrModuleDeserializer(
|
|||||||
return callable
|
return callable
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetClass(proto: IrKlibProtoBuf.IrGetClass, start: Int, end: Int, type: IrType): IrGetClass {
|
private fun deserializeGetClass(proto: KotlinIr.IrGetClass, start: Int, end: Int, type: IrType): IrGetClass {
|
||||||
val argument = deserializeExpression(proto.argument)
|
val argument = deserializeExpression(proto.argument)
|
||||||
return IrGetClassImpl(start, end, type, argument)
|
return IrGetClassImpl(start, end, type, argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetField(proto: IrKlibProtoBuf.IrGetField, start: Int, end: Int, type: IrType): IrGetField {
|
private fun deserializeGetField(proto: KotlinIr.IrGetField, start: Int, end: Int, type: IrType): IrGetField {
|
||||||
val access = proto.fieldAccess
|
val access = proto.fieldAccess
|
||||||
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
||||||
val superQualifier = if (access.hasSuper()) {
|
val superQualifier = if (access.hasSuper()) {
|
||||||
@@ -354,24 +364,24 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrGetFieldImpl(start, end, symbol, type, receiver, null, superQualifier)
|
return IrGetFieldImpl(start, end, symbol, type, receiver, null, superQualifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetValue(proto: IrKlibProtoBuf.IrGetValue, start: Int, end: Int, type: IrType): IrGetValue {
|
private fun deserializeGetValue(proto: KotlinIr.IrGetValue, start: Int, end: Int, type: IrType): IrGetValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrValueSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrValueSymbol
|
||||||
// TODO: origin!
|
// TODO: origin!
|
||||||
return IrGetValueImpl(start, end, type, symbol, null)
|
return IrGetValueImpl(start, end, type, symbol, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetEnumValue(proto: IrKlibProtoBuf.IrGetEnumValue, start: Int, end: Int, type: IrType): IrGetEnumValue {
|
private fun deserializeGetEnumValue(proto: KotlinIr.IrGetEnumValue, start: Int, end: Int, type: IrType): IrGetEnumValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrEnumEntrySymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrEnumEntrySymbol
|
||||||
return IrGetEnumValueImpl(start, end, type, symbol)
|
return IrGetEnumValueImpl(start, end, type, symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeGetObject(proto: IrKlibProtoBuf.IrGetObject, start: Int, end: Int, type: IrType): IrGetObjectValue {
|
private fun deserializeGetObject(proto: KotlinIr.IrGetObject, start: Int, end: Int, type: IrType): IrGetObjectValue {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
||||||
return IrGetObjectValueImpl(start, end, type, symbol)
|
return IrGetObjectValueImpl(start, end, type, symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeInstanceInitializerCall(
|
private fun deserializeInstanceInitializerCall(
|
||||||
proto: IrKlibProtoBuf.IrInstanceInitializerCall,
|
proto: KotlinIr.IrInstanceInitializerCall,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int
|
end: Int
|
||||||
): IrInstanceInitializerCall {
|
): IrInstanceInitializerCall {
|
||||||
@@ -382,7 +392,7 @@ abstract class IrModuleDeserializer(
|
|||||||
private val getterToPropertyDescriptorMap = mutableMapOf<IrSimpleFunctionSymbol, WrappedPropertyDescriptor>()
|
private val getterToPropertyDescriptorMap = mutableMapOf<IrSimpleFunctionSymbol, WrappedPropertyDescriptor>()
|
||||||
|
|
||||||
private fun deserializePropertyReference(
|
private fun deserializePropertyReference(
|
||||||
proto: IrKlibProtoBuf.IrPropertyReference,
|
proto: KotlinIr.IrPropertyReference,
|
||||||
start: Int, end: Int, type: IrType
|
start: Int, end: Int, type: IrType
|
||||||
): IrPropertyReference {
|
): IrPropertyReference {
|
||||||
|
|
||||||
@@ -409,13 +419,13 @@ abstract class IrModuleDeserializer(
|
|||||||
return callable
|
return callable
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeReturn(proto: IrKlibProtoBuf.IrReturn, start: Int, end: Int, type: IrType): IrReturn {
|
private fun deserializeReturn(proto: KotlinIr.IrReturn, start: Int, end: Int, type: IrType): IrReturn {
|
||||||
val symbol = deserializeIrSymbol(proto.returnTarget) as IrReturnTargetSymbol
|
val symbol = deserializeIrSymbol(proto.returnTarget) as IrReturnTargetSymbol
|
||||||
val value = deserializeExpression(proto.value)
|
val value = deserializeExpression(proto.value)
|
||||||
return IrReturnImpl(start, end, builtIns.nothingType, symbol, value)
|
return IrReturnImpl(start, end, builtIns.nothingType, symbol, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSetField(proto: IrKlibProtoBuf.IrSetField, start: Int, end: Int): IrSetField {
|
private fun deserializeSetField(proto: KotlinIr.IrSetField, start: Int, end: Int): IrSetField {
|
||||||
val access = proto.fieldAccess
|
val access = proto.fieldAccess
|
||||||
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
val symbol = deserializeIrSymbol(access.symbol) as IrFieldSymbol
|
||||||
val superQualifier = if (access.hasSuper()) {
|
val superQualifier = if (access.hasSuper()) {
|
||||||
@@ -429,19 +439,19 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrSetFieldImpl(start, end, symbol, receiver, value, builtIns.unitType, null, superQualifier)
|
return IrSetFieldImpl(start, end, symbol, receiver, value, builtIns.unitType, null, superQualifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSetVariable(proto: IrKlibProtoBuf.IrSetVariable, start: Int, end: Int): IrSetVariable {
|
private fun deserializeSetVariable(proto: KotlinIr.IrSetVariable, start: Int, end: Int): IrSetVariable {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrVariableSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrVariableSymbol
|
||||||
val value = deserializeExpression(proto.value)
|
val value = deserializeExpression(proto.value)
|
||||||
return IrSetVariableImpl(start, end, builtIns.unitType, symbol, value, null)
|
return IrSetVariableImpl(start, end, builtIns.unitType, symbol, value, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeSpreadElement(proto: IrKlibProtoBuf.IrSpreadElement): IrSpreadElement {
|
private fun deserializeSpreadElement(proto: KotlinIr.IrSpreadElement): IrSpreadElement {
|
||||||
val expression = deserializeExpression(proto.expression)
|
val expression = deserializeExpression(proto.expression)
|
||||||
return IrSpreadElementImpl(proto.coordinates.startOffset, proto.coordinates.endOffset, expression)
|
return IrSpreadElementImpl(proto.coordinates.startOffset, proto.coordinates.endOffset, expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeStringConcat(
|
private fun deserializeStringConcat(
|
||||||
proto: IrKlibProtoBuf.IrStringConcat,
|
proto: KotlinIr.IrStringConcat,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
type: IrType
|
type: IrType
|
||||||
@@ -455,11 +465,11 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrStringConcatenationImpl(start, end, type, arguments)
|
return IrStringConcatenationImpl(start, end, type, arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeThrow(proto: IrKlibProtoBuf.IrThrow, start: Int, end: Int, type: IrType): IrThrowImpl {
|
private fun deserializeThrow(proto: KotlinIr.IrThrow, start: Int, end: Int, type: IrType): IrThrowImpl {
|
||||||
return IrThrowImpl(start, end, builtIns.nothingType, deserializeExpression(proto.value))
|
return IrThrowImpl(start, end, builtIns.nothingType, deserializeExpression(proto.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeTry(proto: IrKlibProtoBuf.IrTry, start: Int, end: Int, type: IrType): IrTryImpl {
|
private fun deserializeTry(proto: KotlinIr.IrTry, start: Int, end: Int, type: IrType): IrTryImpl {
|
||||||
val result = deserializeExpression(proto.result)
|
val result = deserializeExpression(proto.result)
|
||||||
val catches = mutableListOf<IrCatch>()
|
val catches = mutableListOf<IrCatch>()
|
||||||
proto.catchList.forEach {
|
proto.catchList.forEach {
|
||||||
@@ -470,28 +480,28 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrTryImpl(start, end, type, result, catches, finallyExpression)
|
return IrTryImpl(start, end, type, result, catches, finallyExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeTypeOperator(operator: IrKlibProtoBuf.IrTypeOperator) = when (operator) {
|
private fun deserializeTypeOperator(operator: KotlinIr.IrTypeOperator) = when (operator) {
|
||||||
IrKlibProtoBuf.IrTypeOperator.CAST
|
KotlinIr.IrTypeOperator.CAST
|
||||||
-> IrTypeOperator.CAST
|
-> IrTypeOperator.CAST
|
||||||
IrKlibProtoBuf.IrTypeOperator.IMPLICIT_CAST
|
KotlinIr.IrTypeOperator.IMPLICIT_CAST
|
||||||
-> IrTypeOperator.IMPLICIT_CAST
|
-> IrTypeOperator.IMPLICIT_CAST
|
||||||
IrKlibProtoBuf.IrTypeOperator.IMPLICIT_NOTNULL
|
KotlinIr.IrTypeOperator.IMPLICIT_NOTNULL
|
||||||
-> IrTypeOperator.IMPLICIT_NOTNULL
|
-> IrTypeOperator.IMPLICIT_NOTNULL
|
||||||
IrKlibProtoBuf.IrTypeOperator.IMPLICIT_COERCION_TO_UNIT
|
KotlinIr.IrTypeOperator.IMPLICIT_COERCION_TO_UNIT
|
||||||
-> IrTypeOperator.IMPLICIT_COERCION_TO_UNIT
|
-> IrTypeOperator.IMPLICIT_COERCION_TO_UNIT
|
||||||
IrKlibProtoBuf.IrTypeOperator.IMPLICIT_INTEGER_COERCION
|
KotlinIr.IrTypeOperator.IMPLICIT_INTEGER_COERCION
|
||||||
-> IrTypeOperator.IMPLICIT_INTEGER_COERCION
|
-> IrTypeOperator.IMPLICIT_INTEGER_COERCION
|
||||||
IrKlibProtoBuf.IrTypeOperator.SAFE_CAST
|
KotlinIr.IrTypeOperator.SAFE_CAST
|
||||||
-> IrTypeOperator.SAFE_CAST
|
-> IrTypeOperator.SAFE_CAST
|
||||||
IrKlibProtoBuf.IrTypeOperator.INSTANCEOF
|
KotlinIr.IrTypeOperator.INSTANCEOF
|
||||||
-> IrTypeOperator.INSTANCEOF
|
-> IrTypeOperator.INSTANCEOF
|
||||||
IrKlibProtoBuf.IrTypeOperator.NOT_INSTANCEOF
|
KotlinIr.IrTypeOperator.NOT_INSTANCEOF
|
||||||
-> IrTypeOperator.NOT_INSTANCEOF
|
-> IrTypeOperator.NOT_INSTANCEOF
|
||||||
IrKlibProtoBuf.IrTypeOperator.SAM_CONVERSION
|
KotlinIr.IrTypeOperator.SAM_CONVERSION
|
||||||
-> IrTypeOperator.SAM_CONVERSION
|
-> IrTypeOperator.SAM_CONVERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeTypeOp(proto: IrKlibProtoBuf.IrTypeOp, start: Int, end: Int, type: IrType): IrTypeOperatorCall {
|
private fun deserializeTypeOp(proto: KotlinIr.IrTypeOp, start: Int, end: Int, type: IrType): IrTypeOperatorCall {
|
||||||
val operator = deserializeTypeOperator(proto.operator)
|
val operator = deserializeTypeOperator(proto.operator)
|
||||||
val operand = deserializeIrType(proto.operand)//.brokenIr
|
val operand = deserializeIrType(proto.operand)//.brokenIr
|
||||||
val argument = deserializeExpression(proto.argument)
|
val argument = deserializeExpression(proto.argument)
|
||||||
@@ -501,7 +511,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeVararg(proto: IrKlibProtoBuf.IrVararg, start: Int, end: Int, type: IrType): IrVararg {
|
private fun deserializeVararg(proto: KotlinIr.IrVararg, start: Int, end: Int, type: IrType): IrVararg {
|
||||||
val elementType = deserializeIrType(proto.elementType)
|
val elementType = deserializeIrType(proto.elementType)
|
||||||
|
|
||||||
val elements = mutableListOf<IrVarargElement>()
|
val elements = mutableListOf<IrVarargElement>()
|
||||||
@@ -511,18 +521,18 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrVarargImpl(start, end, type, elementType, elements)
|
return IrVarargImpl(start, end, type, elementType, elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeVarargElement(element: IrKlibProtoBuf.IrVarargElement): IrVarargElement {
|
private fun deserializeVarargElement(element: KotlinIr.IrVarargElement): IrVarargElement {
|
||||||
return when (element.varargElementCase) {
|
return when (element.varargElementCase) {
|
||||||
IrKlibProtoBuf.IrVarargElement.VarargElementCase.EXPRESSION
|
VarargElementCase.EXPRESSION
|
||||||
-> deserializeExpression(element.expression)
|
-> deserializeExpression(element.expression)
|
||||||
IrKlibProtoBuf.IrVarargElement.VarargElementCase.SPREAD_ELEMENT
|
VarargElementCase.SPREAD_ELEMENT
|
||||||
-> deserializeSpreadElement(element.spreadElement)
|
-> deserializeSpreadElement(element.spreadElement)
|
||||||
else
|
else
|
||||||
-> TODO("Unexpected vararg element")
|
-> TODO("Unexpected vararg element")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeWhen(proto: IrKlibProtoBuf.IrWhen, start: Int, end: Int, type: IrType): IrWhen {
|
private fun deserializeWhen(proto: KotlinIr.IrWhen, start: Int, end: Int, type: IrType): IrWhen {
|
||||||
val branches = mutableListOf<IrBranch>()
|
val branches = mutableListOf<IrBranch>()
|
||||||
|
|
||||||
proto.branchList.forEach {
|
proto.branchList.forEach {
|
||||||
@@ -533,12 +543,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return IrWhenImpl(start, end, type, null, branches)
|
return IrWhenImpl(start, end, type, null, branches)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val loopIndex = mutableMapOf<Int, IrLoop>()
|
private fun deserializeLoop(proto: KotlinIr.Loop, loop: IrLoopBase): IrLoopBase {
|
||||||
|
|
||||||
private fun deserializeLoop(proto: IrKlibProtoBuf.Loop, loop: IrLoopBase): IrLoopBase {
|
|
||||||
val loopId = proto.loopId
|
|
||||||
loopIndex.getOrPut(loopId) { loop }
|
|
||||||
|
|
||||||
val label = if (proto.hasLabel()) deserializeString(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)
|
||||||
@@ -550,96 +555,88 @@ abstract class IrModuleDeserializer(
|
|||||||
return loop
|
return loop
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeDoWhile(proto: IrKlibProtoBuf.IrDoWhile, start: Int, end: Int, type: IrType): IrDoWhileLoop {
|
// we create the loop before deserializing the body, so that
|
||||||
// we create the loop before deserializing the body, so that
|
// IrBreak statements have something to put into 'loop' field.
|
||||||
// IrBreak statements have something to put into 'loop' field.
|
private fun deserializeDoWhile(proto: KotlinIr.IrDoWhile, start: Int, end: Int, type: IrType) =
|
||||||
val loop = IrDoWhileLoopImpl(start, end, type, null)
|
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrDoWhileLoopImpl(start, end, type, null) })
|
||||||
deserializeLoop(proto.loop, loop)
|
|
||||||
return loop
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeWhile(proto: IrKlibProtoBuf.IrWhile, start: Int, end: Int, type: IrType): IrWhileLoop {
|
private fun deserializeWhile(proto: KotlinIr.IrWhile, start: Int, end: Int, type: IrType) =
|
||||||
// we create the loop before deserializing the body, so that
|
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrWhileLoopImpl(start, end, type, null) })
|
||||||
// IrBreak statements have something to put into 'loop' field.
|
|
||||||
val loop = IrWhileLoopImpl(start, end, type, null)
|
|
||||||
deserializeLoop(proto.loop, loop)
|
|
||||||
return loop
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deserializeDynamicMemberExpression(proto: IrKlibProtoBuf.IrDynamicMemberExpression, start: Int, end: Int, type: IrType) =
|
private fun deserializeDynamicMemberExpression(proto: KotlinIr.IrDynamicMemberExpression, start: Int, end: Int, type: IrType) =
|
||||||
IrDynamicMemberExpressionImpl(start, end, type, deserializeString(proto.memberName), deserializeExpression(proto.receiver))
|
IrDynamicMemberExpressionImpl(start, end, type, deserializeString(proto.memberName), deserializeExpression(proto.receiver))
|
||||||
|
|
||||||
private fun deserializeDynamicOperatorExpression(proto: IrKlibProtoBuf.IrDynamicOperatorExpression, start: Int, end: Int, type: IrType) =
|
private fun deserializeDynamicOperatorExpression(proto: KotlinIr.IrDynamicOperatorExpression, start: Int, end: Int, type: IrType) =
|
||||||
IrDynamicOperatorExpressionImpl(start, end, type, deserializeDynamicOperator(proto.operator)).apply {
|
IrDynamicOperatorExpressionImpl(start, end, type, deserializeDynamicOperator(proto.operator)).apply {
|
||||||
receiver = deserializeExpression(proto.receiver)
|
receiver = deserializeExpression(proto.receiver)
|
||||||
proto.argumentList.mapTo(arguments) { deserializeExpression(it) }
|
proto.argumentList.mapTo(arguments) { deserializeExpression(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeDynamicOperator(operator: IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator) = when (operator) {
|
private fun deserializeDynamicOperator(operator: KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator) = when (operator) {
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_PLUS -> IrDynamicOperator.UNARY_PLUS
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_PLUS -> IrDynamicOperator.UNARY_PLUS
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_MINUS -> IrDynamicOperator.UNARY_MINUS
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.UNARY_MINUS -> IrDynamicOperator.UNARY_MINUS
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCL -> IrDynamicOperator.EXCL
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EXCL -> IrDynamicOperator.EXCL
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_INCREMENT -> IrDynamicOperator.PREFIX_INCREMENT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_INCREMENT -> IrDynamicOperator.PREFIX_INCREMENT
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_DECREMENT -> IrDynamicOperator.PREFIX_DECREMENT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.PREFIX_DECREMENT -> IrDynamicOperator.PREFIX_DECREMENT
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_INCREMENT -> IrDynamicOperator.POSTFIX_INCREMENT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_INCREMENT -> IrDynamicOperator.POSTFIX_INCREMENT
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_DECREMENT -> IrDynamicOperator.POSTFIX_DECREMENT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.POSTFIX_DECREMENT -> IrDynamicOperator.POSTFIX_DECREMENT
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_PLUS -> IrDynamicOperator.BINARY_PLUS
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_PLUS -> IrDynamicOperator.BINARY_PLUS
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_MINUS -> IrDynamicOperator.BINARY_MINUS
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.BINARY_MINUS -> IrDynamicOperator.BINARY_MINUS
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MUL -> IrDynamicOperator.MUL
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.MUL -> IrDynamicOperator.MUL
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.DIV -> IrDynamicOperator.DIV
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.DIV -> IrDynamicOperator.DIV
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MOD -> IrDynamicOperator.MOD
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.MOD -> IrDynamicOperator.MOD
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.GT -> IrDynamicOperator.GT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.GT -> IrDynamicOperator.GT
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.LT -> IrDynamicOperator.LT
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.LT -> IrDynamicOperator.LT
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.GE -> IrDynamicOperator.GE
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.GE -> IrDynamicOperator.GE
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.LE -> IrDynamicOperator.LE
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.LE -> IrDynamicOperator.LE
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQEQ -> IrDynamicOperator.EQEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EQEQ -> IrDynamicOperator.EQEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQ -> IrDynamicOperator.EXCLEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQ -> IrDynamicOperator.EXCLEQ
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQEQEQ -> IrDynamicOperator.EQEQEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EQEQEQ -> IrDynamicOperator.EQEQEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQEQ -> IrDynamicOperator.EXCLEQEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EXCLEQEQ -> IrDynamicOperator.EXCLEQEQ
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.ANDAND -> IrDynamicOperator.ANDAND
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.ANDAND -> IrDynamicOperator.ANDAND
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.OROR -> IrDynamicOperator.OROR
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.OROR -> IrDynamicOperator.OROR
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.EQ -> IrDynamicOperator.EQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.EQ -> IrDynamicOperator.EQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.PLUSEQ -> IrDynamicOperator.PLUSEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.PLUSEQ -> IrDynamicOperator.PLUSEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MINUSEQ -> IrDynamicOperator.MINUSEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.MINUSEQ -> IrDynamicOperator.MINUSEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MULEQ -> IrDynamicOperator.MULEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.MULEQ -> IrDynamicOperator.MULEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.DIVEQ -> IrDynamicOperator.DIVEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.DIVEQ -> IrDynamicOperator.DIVEQ
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.MODEQ -> IrDynamicOperator.MODEQ
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.MODEQ -> IrDynamicOperator.MODEQ
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.ARRAY_ACCESS -> IrDynamicOperator.ARRAY_ACCESS
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.ARRAY_ACCESS -> IrDynamicOperator.ARRAY_ACCESS
|
||||||
|
|
||||||
IrKlibProtoBuf.IrDynamicOperatorExpression.IrDynamicOperator.INVOKE -> IrDynamicOperator.INVOKE
|
KotlinIr.IrDynamicOperatorExpression.IrDynamicOperator.INVOKE -> IrDynamicOperator.INVOKE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeBreak(proto: IrKlibProtoBuf.IrBreak, start: Int, end: Int, type: IrType): IrBreak {
|
private fun deserializeBreak(proto: KotlinIr.IrBreak, start: Int, end: Int, type: IrType): IrBreak {
|
||||||
val label = if (proto.hasLabel()) deserializeString(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 = deserializeLoopHeader(loopId) { error("break clause before loop header") }
|
||||||
val irBreak = IrBreakImpl(start, end, type, loop)
|
val irBreak = IrBreakImpl(start, end, type, loop)
|
||||||
irBreak.label = label
|
irBreak.label = label
|
||||||
|
|
||||||
return irBreak
|
return irBreak
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeContinue(proto: IrKlibProtoBuf.IrContinue, start: Int, end: Int, type: IrType): IrContinue {
|
private fun deserializeContinue(proto: KotlinIr.IrContinue, start: Int, end: Int, type: IrType): IrContinue {
|
||||||
val label = if (proto.hasLabel()) deserializeString(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 = deserializeLoopHeader(loopId) { error("continue clause before loop header") }
|
||||||
val irContinue = IrContinueImpl(start, end, type, loop)
|
val irContinue = IrContinueImpl(start, end, type, loop)
|
||||||
irContinue.label = label
|
irContinue.label = label
|
||||||
|
|
||||||
return irContinue
|
return irContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeConst(proto: IrKlibProtoBuf.IrConst, start: Int, end: Int, type: IrType): IrExpression =
|
private fun deserializeConst(proto: KotlinIr.IrConst, start: Int, end: Int, type: IrType): IrExpression =
|
||||||
when (proto.valueCase) {
|
when (proto.valueCase) {
|
||||||
NULL
|
NULL
|
||||||
-> IrConstImpl.constNull(start, end, type)
|
-> IrConstImpl.constNull(start, end, type)
|
||||||
@@ -665,7 +662,7 @@ abstract class IrModuleDeserializer(
|
|||||||
-> error("Const deserialization error: ${proto.valueCase} ")
|
-> error("Const deserialization error: ${proto.valueCase} ")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeOperation(proto: IrKlibProtoBuf.IrOperation, start: Int, end: Int, type: IrType): IrExpression =
|
private fun deserializeOperation(proto: KotlinIr.IrOperation, start: Int, end: Int, type: IrType): IrExpression =
|
||||||
when (proto.operationCase) {
|
when (proto.operationCase) {
|
||||||
BLOCK
|
BLOCK
|
||||||
-> deserializeBlock(proto.block, start, end, type)
|
-> deserializeBlock(proto.block, start, end, type)
|
||||||
@@ -731,7 +728,7 @@ abstract class IrModuleDeserializer(
|
|||||||
-> error("Expression deserialization not implemented: ${proto.operationCase}")
|
-> error("Expression deserialization not implemented: ${proto.operationCase}")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeExpression(proto: IrKlibProtoBuf.IrExpression): IrExpression {
|
private fun deserializeExpression(proto: KotlinIr.IrExpression): IrExpression {
|
||||||
val start = proto.coordinates.startOffset
|
val start = proto.coordinates.startOffset
|
||||||
val end = proto.coordinates.endOffset
|
val end = proto.coordinates.endOffset
|
||||||
val type = deserializeIrType(proto.type)
|
val type = deserializeIrType(proto.type)
|
||||||
@@ -743,13 +740,13 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrTypeParameter(
|
private fun deserializeIrTypeParameter(
|
||||||
proto: IrKlibProtoBuf.IrTypeParameter,
|
proto: KotlinIr.IrTypeParameter,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
): IrTypeParameter {
|
): IrTypeParameter {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
|
||||||
val name = Name.identifier(deserializeString(proto.name))
|
val name = deserializeName(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,
|
||||||
@@ -765,7 +762,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrTypeParameterContainer(
|
private fun deserializeIrTypeParameterContainer(
|
||||||
proto: IrKlibProtoBuf.IrTypeParameterContainer,
|
proto: KotlinIr.IrTypeParameterContainer,
|
||||||
parent: IrDeclarationParent
|
parent: IrDeclarationParent
|
||||||
): List<IrTypeParameter> {
|
): List<IrTypeParameter> {
|
||||||
return proto.typeParameterList.map {
|
return proto.typeParameterList.map {
|
||||||
@@ -776,17 +773,17 @@ abstract class IrModuleDeserializer(
|
|||||||
} // TODO: we need proper start, end and origin here?
|
} // TODO: we need proper start, end and origin here?
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeClassKind(kind: IrKlibProtoBuf.ClassKind) = when (kind) {
|
private fun deserializeClassKind(kind: KotlinIr.ClassKind) = when (kind) {
|
||||||
IrKlibProtoBuf.ClassKind.CLASS -> ClassKind.CLASS
|
KotlinIr.ClassKind.CLASS -> ClassKind.CLASS
|
||||||
IrKlibProtoBuf.ClassKind.INTERFACE -> ClassKind.INTERFACE
|
KotlinIr.ClassKind.INTERFACE -> ClassKind.INTERFACE
|
||||||
IrKlibProtoBuf.ClassKind.ENUM_CLASS -> ClassKind.ENUM_CLASS
|
KotlinIr.ClassKind.ENUM_CLASS -> ClassKind.ENUM_CLASS
|
||||||
IrKlibProtoBuf.ClassKind.ENUM_ENTRY -> ClassKind.ENUM_ENTRY
|
KotlinIr.ClassKind.ENUM_ENTRY -> ClassKind.ENUM_ENTRY
|
||||||
IrKlibProtoBuf.ClassKind.ANNOTATION_CLASS -> ClassKind.ANNOTATION_CLASS
|
KotlinIr.ClassKind.ANNOTATION_CLASS -> ClassKind.ANNOTATION_CLASS
|
||||||
IrKlibProtoBuf.ClassKind.OBJECT -> ClassKind.OBJECT
|
KotlinIr.ClassKind.OBJECT -> ClassKind.OBJECT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrValueParameter(
|
private fun deserializeIrValueParameter(
|
||||||
proto: IrKlibProtoBuf.IrValueParameter,
|
proto: KotlinIr.IrValueParameter,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
@@ -798,7 +795,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IrValueParameterImpl(
|
IrValueParameterImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
paramSymbol,
|
paramSymbol,
|
||||||
deserializeString(proto.name).let { if (paramSymbol.descriptor is ReceiverParameterDescriptor) Name.special(it) else Name.identifier(it) },
|
deserializeName(proto.name),
|
||||||
proto.index,
|
proto.index,
|
||||||
deserializeIrType(proto.type),
|
deserializeIrType(proto.type),
|
||||||
varargElementType,
|
varargElementType,
|
||||||
@@ -814,7 +811,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return parameter
|
return parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrClass(proto: IrKlibProtoBuf.IrClass, start: Int, end: Int, origin: IrDeclarationOrigin): IrClass {
|
private fun deserializeIrClass(proto: KotlinIr.IrClass, start: Int, end: Int, origin: IrDeclarationOrigin): IrClass {
|
||||||
|
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
||||||
|
|
||||||
@@ -824,7 +821,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IrClassImpl(
|
IrClassImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
it,
|
it,
|
||||||
deserializeString(proto.name).let { if (it.startsWith('<')) Name.special(it) else Name.identifier(it) },
|
deserializeName(proto.name),
|
||||||
deserializeClassKind(proto.kind),
|
deserializeClassKind(proto.kind),
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
modality,
|
modality,
|
||||||
@@ -854,7 +851,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrFunctionBase(
|
private fun deserializeIrFunctionBase(
|
||||||
base: IrKlibProtoBuf.IrFunctionBase,
|
base: KotlinIr.IrFunctionBase,
|
||||||
function: IrFunctionBase,
|
function: IrFunctionBase,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
@@ -878,8 +875,8 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrFunction(
|
private fun deserializeIrFunction(
|
||||||
proto: IrKlibProtoBuf.IrFunction,
|
proto: KotlinIr.IrFunction,
|
||||||
start: Int, end: Int, origin: IrDeclarationOrigin, isAccessor: Boolean
|
start: Int, end: Int, origin: IrDeclarationOrigin
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
|
|
||||||
logger.log { "### deserializing IrFunction ${proto.base.name}" }
|
logger.log { "### deserializing IrFunction ${proto.base.name}" }
|
||||||
@@ -889,7 +886,7 @@ abstract class IrModuleDeserializer(
|
|||||||
symbol.descriptor, {
|
symbol.descriptor, {
|
||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
start, end, origin, it,
|
start, end, origin, it,
|
||||||
deserializeString(proto.base.name).let { if (isAccessor) Name.special(it) else Name.identifier(it) },
|
deserializeName(proto.base.name),
|
||||||
deserializeVisibility(proto.base.visibility),
|
deserializeVisibility(proto.base.visibility),
|
||||||
deserializeModality(proto.modality),
|
deserializeModality(proto.modality),
|
||||||
deserializeIrType(proto.base.returnType),
|
deserializeIrType(proto.base.returnType),
|
||||||
@@ -910,7 +907,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrVariable(
|
private fun deserializeIrVariable(
|
||||||
proto: IrKlibProtoBuf.IrVariable,
|
proto: KotlinIr.IrVariable,
|
||||||
start: Int, end: Int, origin: IrDeclarationOrigin
|
start: Int, end: Int, origin: IrDeclarationOrigin
|
||||||
): IrVariable {
|
): IrVariable {
|
||||||
|
|
||||||
@@ -926,7 +923,7 @@ abstract class IrModuleDeserializer(
|
|||||||
end,
|
end,
|
||||||
origin,
|
origin,
|
||||||
symbol,
|
symbol,
|
||||||
Name.identifier(deserializeString(proto.name)),
|
deserializeName(proto.name),
|
||||||
type,
|
type,
|
||||||
proto.isVar,
|
proto.isVar,
|
||||||
proto.isConst,
|
proto.isConst,
|
||||||
@@ -937,7 +934,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrEnumEntry(
|
private fun deserializeIrEnumEntry(
|
||||||
proto: IrKlibProtoBuf.IrEnumEntry,
|
proto: KotlinIr.IrEnumEntry,
|
||||||
start: Int, end: Int, origin: IrDeclarationOrigin
|
start: Int, end: Int, origin: IrDeclarationOrigin
|
||||||
): IrEnumEntry {
|
): IrEnumEntry {
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrEnumEntrySymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrEnumEntrySymbol
|
||||||
@@ -948,7 +945,7 @@ abstract class IrModuleDeserializer(
|
|||||||
irrelevantOrigin,
|
irrelevantOrigin,
|
||||||
symbol.descriptor
|
symbol.descriptor
|
||||||
) {
|
) {
|
||||||
IrEnumEntryImpl(start, end, origin, it, Name.identifier(deserializeString(proto.name)))
|
IrEnumEntryImpl(start, end, origin, it, deserializeName(proto.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto.hasCorrespondingClass()) {
|
if (proto.hasCorrespondingClass()) {
|
||||||
@@ -962,7 +959,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrAnonymousInit(
|
private fun deserializeIrAnonymousInit(
|
||||||
proto: IrKlibProtoBuf.IrAnonymousInit,
|
proto: KotlinIr.IrAnonymousInit,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
@@ -973,7 +970,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return initializer
|
return initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeVisibility(value: IrKlibProtoBuf.Visibility): Visibility { // TODO: switch to enum
|
private fun deserializeVisibility(value: KotlinIr.Visibility): Visibility { // TODO: switch to enum
|
||||||
return when (deserializeString(value.name)) {
|
return when (deserializeString(value.name)) {
|
||||||
"public" -> Visibilities.PUBLIC
|
"public" -> Visibilities.PUBLIC
|
||||||
"private" -> Visibilities.PRIVATE
|
"private" -> Visibilities.PRIVATE
|
||||||
@@ -987,7 +984,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrConstructor(
|
private fun deserializeIrConstructor(
|
||||||
proto: IrKlibProtoBuf.IrConstructor,
|
proto: KotlinIr.IrConstructor,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
@@ -999,7 +996,7 @@ abstract class IrModuleDeserializer(
|
|||||||
IrConstructorImpl(
|
IrConstructorImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
it,
|
it,
|
||||||
Name.special(deserializeString(proto.base.name)),
|
deserializeName(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,
|
||||||
@@ -1013,7 +1010,7 @@ abstract class IrModuleDeserializer(
|
|||||||
return constructor
|
return constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrField(proto: IrKlibProtoBuf.IrField, start: Int, end: Int, origin: IrDeclarationOrigin): IrField {
|
private fun deserializeIrField(proto: KotlinIr.IrField, start: Int, end: Int, origin: IrDeclarationOrigin): IrField {
|
||||||
|
|
||||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFieldSymbol
|
val symbol = deserializeIrSymbol(proto.symbol) as IrFieldSymbol
|
||||||
val type = deserializeIrType(proto.type)
|
val type = deserializeIrType(proto.type)
|
||||||
@@ -1025,7 +1022,7 @@ abstract class IrModuleDeserializer(
|
|||||||
{ IrFieldImpl(
|
{ IrFieldImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
it,
|
it,
|
||||||
Name.identifier(deserializeString(proto.name)),
|
deserializeName(proto.name),
|
||||||
type,
|
type,
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
proto.isFinal,
|
proto.isFinal,
|
||||||
@@ -1041,23 +1038,23 @@ abstract class IrModuleDeserializer(
|
|||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeModality(modality: IrKlibProtoBuf.ModalityKind) = when (modality) {
|
private fun deserializeModality(modality: KotlinIr.ModalityKind) = when (modality) {
|
||||||
IrKlibProtoBuf.ModalityKind.OPEN_MODALITY -> Modality.OPEN
|
KotlinIr.ModalityKind.OPEN_MODALITY -> Modality.OPEN
|
||||||
IrKlibProtoBuf.ModalityKind.SEALED_MODALITY -> Modality.SEALED
|
KotlinIr.ModalityKind.SEALED_MODALITY -> Modality.SEALED
|
||||||
IrKlibProtoBuf.ModalityKind.FINAL_MODALITY -> Modality.FINAL
|
KotlinIr.ModalityKind.FINAL_MODALITY -> Modality.FINAL
|
||||||
IrKlibProtoBuf.ModalityKind.ABSTRACT_MODALITY -> Modality.ABSTRACT
|
KotlinIr.ModalityKind.ABSTRACT_MODALITY -> Modality.ABSTRACT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrProperty(
|
private fun deserializeIrProperty(
|
||||||
proto: IrKlibProtoBuf.IrProperty,
|
proto: KotlinIr.IrProperty,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
): IrProperty {
|
): IrProperty {
|
||||||
|
|
||||||
val backingField = if (proto.hasBackingField()) deserializeIrField(proto.backingField, start, end, origin) else null
|
val backingField = if (proto.hasBackingField()) deserializeIrField(proto.backingField, start, end, origin) else null
|
||||||
val getter = if (proto.hasGetter()) deserializeIrFunction(proto.getter, start, end, origin, true) else null
|
val getter = if (proto.hasGetter()) deserializeIrFunction(proto.getter, start, end, origin) else null
|
||||||
val setter = if (proto.hasSetter()) deserializeIrFunction(proto.setter, start, end, origin, true) else null
|
val setter = if (proto.hasSetter()) deserializeIrFunction(proto.setter, start, end, origin) else null
|
||||||
|
|
||||||
backingField?.let { (it.descriptor as? WrappedFieldDescriptor)?.bind(it) }
|
backingField?.let { (it.descriptor as? WrappedFieldDescriptor)?.bind(it) }
|
||||||
getter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
getter?.let { (it.descriptor as? WrappedSimpleFunctionDescriptor)?.bind(it) }
|
||||||
@@ -1073,7 +1070,7 @@ abstract class IrModuleDeserializer(
|
|||||||
val property = IrPropertyImpl(
|
val property = IrPropertyImpl(
|
||||||
start, end, origin,
|
start, end, origin,
|
||||||
descriptor,
|
descriptor,
|
||||||
Name.identifier(deserializeString(proto.name)),
|
deserializeName(proto.name),
|
||||||
deserializeVisibility(proto.visibility),
|
deserializeVisibility(proto.visibility),
|
||||||
deserializeModality(proto.modality),
|
deserializeModality(proto.modality),
|
||||||
proto.isVar,
|
proto.isVar,
|
||||||
@@ -1097,7 +1094,7 @@ abstract class IrModuleDeserializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun deserializeIrTypeAlias(
|
private fun deserializeIrTypeAlias(
|
||||||
proto: IrKlibProtoBuf.IrTypeAlias,
|
proto: KotlinIr.IrTypeAlias,
|
||||||
start: Int,
|
start: Int,
|
||||||
end: Int,
|
end: Int,
|
||||||
origin: IrDeclarationOrigin
|
origin: IrDeclarationOrigin
|
||||||
@@ -1109,9 +1106,9 @@ 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)]!!
|
fun deserializeIrDeclarationOrigin(proto: KotlinIr.IrDeclarationOrigin) = originIndex[deserializeString(proto.custom)]!!
|
||||||
|
|
||||||
protected fun deserializeDeclaration(proto: IrKlibProtoBuf.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration {
|
protected fun deserializeDeclaration(proto: KotlinIr.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration {
|
||||||
|
|
||||||
val start = proto.coordinates.startOffset
|
val start = proto.coordinates.startOffset
|
||||||
val end = proto.coordinates.endOffset
|
val end = proto.coordinates.endOffset
|
||||||
@@ -1129,7 +1126,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, false)
|
-> deserializeIrFunction(declarator.irFunction, start, end, origin)
|
||||||
IR_PROPERTY
|
IR_PROPERTY
|
||||||
-> deserializeIrProperty(declarator.irProperty, start, end, origin)
|
-> deserializeIrProperty(declarator.irProperty, start, end, origin)
|
||||||
IR_TYPE_ALIAS
|
IR_TYPE_ALIAS
|
||||||
+294
-242
File diff suppressed because it is too large
Load Diff
+3
-4
@@ -3,10 +3,9 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
class SerializedIr (
|
class SerializedIr (
|
||||||
val module: ByteArray,
|
val module: ByteArray,
|
||||||
val declarations: Map<UniqId, ByteArray>,
|
val combinedDeclarationFilePath: String
|
||||||
val debugIndex: Map<UniqId, String>
|
)
|
||||||
)
|
|
||||||
+61319
File diff suppressed because it is too large
Load Diff
+62
-70
@@ -3,153 +3,132 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
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.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.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
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrLoopBase
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
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.protobuf.ExtensionRegistryLite.*
|
||||||
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
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IrKlibProtoBufModuleDeserializer(
|
abstract class KotlinIrLinker(
|
||||||
currentModule: ModuleDescriptor,
|
currentModule: ModuleDescriptor,
|
||||||
logger: LoggingContext,
|
logger: LoggingContext,
|
||||||
builtIns: IrBuiltIns,
|
builtIns: IrBuiltIns,
|
||||||
symbolTable: SymbolTable,
|
symbolTable: SymbolTable,
|
||||||
private val forwardModuleDescriptor: ModuleDescriptor?)
|
private val forwardModuleDescriptor: ModuleDescriptor?)
|
||||||
: IrModuleDeserializer(logger, builtIns, symbolTable) {
|
: IrModuleDeserializer(logger, builtIns, symbolTable),
|
||||||
|
DescriptorUniqIdAware {
|
||||||
|
|
||||||
private val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>()
|
protected val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>()
|
||||||
val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>()
|
|
||||||
private val reachableTopLevels = mutableSetOf<UniqIdKey>()
|
private val reachableTopLevels = mutableSetOf<UniqIdKey>()
|
||||||
private val deserializedTopLevels = mutableSetOf<UniqIdKey>()
|
private val deserializedTopLevels = mutableSetOf<UniqIdKey>()
|
||||||
private val forwardDeclarations = mutableSetOf<IrSymbol>()
|
private val forwardDeclarations = mutableSetOf<IrSymbol>()
|
||||||
|
|
||||||
private var deserializedModuleDescriptor: ModuleDescriptor? = null
|
private var deserializedModuleDescriptor: ModuleDescriptor? = null
|
||||||
private var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
|
private var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, KotlinIr.IrSymbolTable>()
|
||||||
private var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>()
|
private var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, KotlinIr.StringTable>()
|
||||||
private var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
|
private var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, KotlinIr.IrTypeTable>()
|
||||||
|
private var deserializedModuleLoops = mutableMapOf<Pair<ModuleDescriptor, Int>, IrLoopBase>()
|
||||||
|
|
||||||
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
|
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
|
||||||
|
|
||||||
private val descriptorReferenceDeserializer = object : DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations) {
|
abstract protected val descriptorReferenceDeserializer: DescriptorReferenceDeserializer
|
||||||
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>()
|
private val descriptorToDirectoryMap = mutableMapOf<ModuleDescriptor, File>()
|
||||||
|
|
||||||
private fun irDirectory(m: ModuleDescriptor): File = descriptorToDirectoryMap[m]!!
|
private fun irDirectory(m: ModuleDescriptor): File = descriptorToDirectoryMap[m]!!
|
||||||
|
|
||||||
private val FUNCTION_INDEX_START: Long
|
private fun referenceDeserializedSymbol(proto: KotlinIr.IrSymbolData, descriptor: DeclarationDescriptor?): IrSymbol = when (proto.kind) {
|
||||||
|
KotlinIr.IrSymbolKind.ANONYMOUS_INIT_SYMBOL ->
|
||||||
init {
|
|
||||||
// TODO: think about order
|
|
||||||
var currentIndex = 0x1_0000_0000L
|
|
||||||
builtIns.knownBuiltins.forEach {
|
|
||||||
require(it is IrFunction)
|
|
||||||
deserializedSymbols.put(UniqIdKey(null, UniqId(currentIndex, isLocal = false)), it.symbol)
|
|
||||||
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it.symbol)
|
|
||||||
currentIndex++
|
|
||||||
}
|
|
||||||
|
|
||||||
FUNCTION_INDEX_START = currentIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun referenceDeserializedSymbol(proto: IrKlibProtoBuf.IrSymbolData, descriptor: DeclarationDescriptor?): IrSymbol = when (proto.kind) {
|
|
||||||
IrKlibProtoBuf.IrSymbolKind.ANONYMOUS_INIT_SYMBOL ->
|
|
||||||
IrAnonymousInitializerSymbolImpl(
|
IrAnonymousInitializerSymbolImpl(
|
||||||
descriptor as ClassDescriptor?
|
descriptor as ClassDescriptor?
|
||||||
?: WrappedClassDescriptor()
|
?: WrappedClassDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.CLASS_SYMBOL ->
|
KotlinIr.IrSymbolKind.CLASS_SYMBOL ->
|
||||||
symbolTable.referenceClass(
|
symbolTable.referenceClass(
|
||||||
descriptor as ClassDescriptor?
|
descriptor as ClassDescriptor?
|
||||||
?: WrappedClassDescriptor()
|
?: WrappedClassDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.CONSTRUCTOR_SYMBOL ->
|
KotlinIr.IrSymbolKind.CONSTRUCTOR_SYMBOL ->
|
||||||
symbolTable.referenceConstructor(
|
symbolTable.referenceConstructor(
|
||||||
descriptor as ClassConstructorDescriptor?
|
descriptor as ClassConstructorDescriptor?
|
||||||
?: WrappedClassConstructorDescriptor()
|
?: WrappedClassConstructorDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.TYPE_PARAMETER_SYMBOL ->
|
KotlinIr.IrSymbolKind.TYPE_PARAMETER_SYMBOL ->
|
||||||
symbolTable.referenceTypeParameter(
|
symbolTable.referenceTypeParameter(
|
||||||
descriptor as TypeParameterDescriptor?
|
descriptor as TypeParameterDescriptor?
|
||||||
?: WrappedTypeParameterDescriptor()
|
?: WrappedTypeParameterDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.ENUM_ENTRY_SYMBOL ->
|
KotlinIr.IrSymbolKind.ENUM_ENTRY_SYMBOL ->
|
||||||
symbolTable.referenceEnumEntry(
|
symbolTable.referenceEnumEntry(
|
||||||
descriptor as ClassDescriptor?
|
descriptor as ClassDescriptor?
|
||||||
?: WrappedEnumEntryDescriptor()
|
?: WrappedEnumEntryDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.STANDALONE_FIELD_SYMBOL ->
|
KotlinIr.IrSymbolKind.STANDALONE_FIELD_SYMBOL ->
|
||||||
symbolTable.referenceField(WrappedFieldDescriptor())
|
symbolTable.referenceField(WrappedFieldDescriptor())
|
||||||
|
|
||||||
IrKlibProtoBuf.IrSymbolKind.FIELD_SYMBOL ->
|
KotlinIr.IrSymbolKind.FIELD_SYMBOL ->
|
||||||
symbolTable.referenceField(
|
symbolTable.referenceField(
|
||||||
descriptor as PropertyDescriptor?
|
descriptor as PropertyDescriptor?
|
||||||
?: WrappedPropertyDescriptor()
|
?: WrappedPropertyDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.FUNCTION_SYMBOL ->
|
KotlinIr.IrSymbolKind.FUNCTION_SYMBOL ->
|
||||||
symbolTable.referenceSimpleFunction(
|
symbolTable.referenceSimpleFunction(
|
||||||
descriptor as FunctionDescriptor?
|
descriptor as FunctionDescriptor?
|
||||||
?: WrappedSimpleFunctionDescriptor()
|
?: WrappedSimpleFunctionDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.VARIABLE_SYMBOL ->
|
KotlinIr.IrSymbolKind.VARIABLE_SYMBOL ->
|
||||||
IrVariableSymbolImpl(
|
IrVariableSymbolImpl(
|
||||||
descriptor as VariableDescriptor?
|
descriptor as VariableDescriptor?
|
||||||
?: WrappedVariableDescriptor()
|
?: WrappedVariableDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.VALUE_PARAMETER_SYMBOL ->
|
KotlinIr.IrSymbolKind.VALUE_PARAMETER_SYMBOL ->
|
||||||
IrValueParameterSymbolImpl(
|
IrValueParameterSymbolImpl(
|
||||||
descriptor as ParameterDescriptor?
|
descriptor as ParameterDescriptor?
|
||||||
?: WrappedValueParameterDescriptor()
|
?: WrappedValueParameterDescriptor()
|
||||||
)
|
)
|
||||||
IrKlibProtoBuf.IrSymbolKind.RECEIVER_PARAMETER_SYMBOL ->
|
KotlinIr.IrSymbolKind.RECEIVER_PARAMETER_SYMBOL ->
|
||||||
IrValueParameterSymbolImpl(
|
IrValueParameterSymbolImpl(
|
||||||
descriptor as ParameterDescriptor? ?: WrappedReceiverParameterDescriptor()
|
descriptor as ParameterDescriptor? ?: WrappedReceiverParameterDescriptor()
|
||||||
)
|
)
|
||||||
else -> TODO("Unexpected classifier symbol kind: ${proto.kind}")
|
else -> TODO("Unexpected classifier symbol kind: ${proto.kind}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeIrSymbol(proto: IrKlibProtoBuf.IrSymbol): IrSymbol {
|
override fun deserializeIrSymbol(proto: KotlinIr.IrSymbol): IrSymbol {
|
||||||
val symbolData =
|
val symbolData =
|
||||||
deserializedModuleProtoSymbolTables[deserializedModuleDescriptor]!!.getSymbols(proto.index)
|
deserializedModuleProtoSymbolTables[deserializedModuleDescriptor]!!.getSymbols(proto.index)
|
||||||
return deserializeIrSymbolData(symbolData)
|
return deserializeIrSymbolData(symbolData)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeIrType(proto: IrKlibProtoBuf.IrTypeIndex): IrType {
|
override fun deserializeIrType(proto: KotlinIr.IrTypeIndex): IrType {
|
||||||
val typeData =
|
val typeData =
|
||||||
deserializedModuleProtoTypeTables[deserializedModuleDescriptor]!!.getTypes(proto.index)
|
deserializedModuleProtoTypeTables[deserializedModuleDescriptor]!!.getTypes(proto.index)
|
||||||
return deserializeIrTypeData(typeData)
|
return deserializeIrTypeData(typeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeString(proto: IrKlibProtoBuf.String) =
|
override fun deserializeString(proto: KotlinIr.String) =
|
||||||
deserializedModuleProtoStringTables[deserializedModuleDescriptor]!!.getStrings(proto.index)
|
deserializedModuleProtoStringTables[deserializedModuleDescriptor]!!.getStrings(proto.index)
|
||||||
|
|
||||||
fun deserializeIrSymbolData(proto: IrKlibProtoBuf.IrSymbolData): IrSymbol {
|
override fun deserializeLoopHeader(loopIndex: Int, loopBuilder: () -> IrLoopBase) =
|
||||||
|
deserializedModuleLoops.getOrPut(deserializedModuleDescriptor!! to loopIndex, loopBuilder)
|
||||||
|
|
||||||
|
fun deserializeIrSymbolData(proto: KotlinIr.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!!)
|
||||||
|
|
||||||
@@ -168,10 +147,9 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
|
|
||||||
referenceDeserializedSymbol(proto, descriptor)
|
referenceDeserializedSymbol(proto, descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.descriptor is ClassDescriptor &&
|
if (symbol.descriptor is ClassDescriptor &&
|
||||||
symbol.descriptor !is WrappedDeclarationDescriptor<*>/* &&
|
symbol.descriptor !is WrappedDeclarationDescriptor<*> &&
|
||||||
symbol.descriptor.module.isForwardDeclarationModule*/
|
symbol.descriptor.module.isForwardDeclarationModule
|
||||||
) {
|
) {
|
||||||
forwardDeclarations.add(symbol)
|
forwardDeclarations.add(symbol)
|
||||||
}
|
}
|
||||||
@@ -179,7 +157,7 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeDescriptorReference(proto: IrKlibProtoBuf.DescriptorReference) =
|
override fun deserializeDescriptorReference(proto: KotlinIr.DescriptorReference) =
|
||||||
descriptorReferenceDeserializer.deserializeDescriptorReference(
|
descriptorReferenceDeserializer.deserializeDescriptorReference(
|
||||||
deserializeString(proto.packageFqName),
|
deserializeString(proto.packageFqName),
|
||||||
deserializeString(proto.classFqName),
|
deserializeString(proto.classFqName),
|
||||||
@@ -209,16 +187,18 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
val proto = loadTopLevelDeclarationProto(uniqIdKey)
|
val proto = loadTopLevelDeclarationProto(uniqIdKey)
|
||||||
return deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!)
|
return deserializeDeclaration(proto, reversedFileIndex[uniqIdKey]!!)
|
||||||
}
|
}
|
||||||
|
protected abstract fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray
|
||||||
|
|
||||||
private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): IrKlibProtoBuf.IrDeclaration {
|
private fun loadTopLevelDeclarationProto(uniqIdKey: UniqIdKey): KotlinIr.IrDeclaration {
|
||||||
val file = File(irDirectory(deserializedModuleDescriptor!!), uniqIdKey.uniqId.declarationFileName)
|
val stream = reader(uniqIdKey.moduleOfOrigin!!, uniqIdKey.uniqId).codedInputStream
|
||||||
return IrKlibProtoBuf.IrDeclaration.parseFrom(file.readBytes().codedInputStream, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
return KotlinIr.IrDeclaration.parseFrom(stream, newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findDeserializedDeclarationForDescriptor(descriptor: DeclarationDescriptor): DeclarationDescriptor? {
|
private fun findDeserializedDeclarationForDescriptor(descriptor: DeclarationDescriptor): DeclarationDescriptor? {
|
||||||
val topLevelDescriptor = descriptor.findTopLevelDescriptor()
|
val topLevelDescriptor = descriptor.findTopLevelDescriptor()
|
||||||
|
|
||||||
// if (topLevelDescriptor.module.isForwardDeclarationModule) return null
|
// This is Native specific. Try to eliminate.
|
||||||
|
if (topLevelDescriptor.module.isForwardDeclarationModule) return null
|
||||||
|
|
||||||
if (topLevelDescriptor !is DeserializedClassDescriptor && topLevelDescriptor !is DeserializedCallableMemberDescriptor) {
|
if (topLevelDescriptor !is DeserializedClassDescriptor && topLevelDescriptor !is DeserializedCallableMemberDescriptor) {
|
||||||
return null
|
return null
|
||||||
@@ -226,7 +206,7 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
|
|
||||||
val descriptorUniqId = topLevelDescriptor.getUniqId()
|
val descriptorUniqId = topLevelDescriptor.getUniqId()
|
||||||
?: error("could not get descriptor uniq id for $topLevelDescriptor")
|
?: error("could not get descriptor uniq id for $topLevelDescriptor")
|
||||||
val uniqId = UniqId(descriptorUniqId.index, isLocal = false)
|
val uniqId = UniqId(descriptorUniqId, isLocal = false)
|
||||||
val topLevelKey = UniqIdKey(topLevelDescriptor.module, uniqId)
|
val topLevelKey = UniqIdKey(topLevelDescriptor.module, uniqId)
|
||||||
|
|
||||||
// This top level descriptor doesn't have a serialized IR declaration.
|
// This top level descriptor doesn't have a serialized IR declaration.
|
||||||
@@ -313,7 +293,7 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrFile(fileProto: IrKlibProtoBuf.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile {
|
fun deserializeIrFile(fileProto: KotlinIr.IrFile, moduleDescriptor: ModuleDescriptor, deseralizationStrategy: DeserializationStrategy): IrFile {
|
||||||
val fileEntry = NaiveSourceBasedFileEntryImpl(
|
val fileEntry = NaiveSourceBasedFileEntryImpl(
|
||||||
deserializeString(fileProto.fileEntry.name),
|
deserializeString(fileProto.fileEntry.name),
|
||||||
fileProto.fileEntry.lineStartOffsetsList.toIntArray()
|
fileProto.fileEntry.lineStartOffsetsList.toIntArray()
|
||||||
@@ -331,15 +311,22 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
val uniqIdKey = it.uniqIdKey(moduleDescriptor)
|
val uniqIdKey = it.uniqIdKey(moduleDescriptor)
|
||||||
reversedFileIndex.put(uniqIdKey, file)
|
reversedFileIndex.put(uniqIdKey, file)
|
||||||
|
|
||||||
if (deserializeAllDeclarations) {
|
if (deseralizationStrategy == DeserializationStrategy.ALL) {
|
||||||
file.declarations.add(deserializeTopLevelDeclaration(uniqIdKey))
|
file.declarations.add(deserializeTopLevelDeclaration(uniqIdKey))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val annotations = deserializeAnnotations(fileProto.annotations)
|
||||||
|
file.annotations.addAll(annotations)
|
||||||
|
|
||||||
|
|
||||||
|
if (deseralizationStrategy == DeserializationStrategy.EXPLICITLY_EXPORTED)
|
||||||
|
fileProto.explicitlyExportedToCompilerList.forEach { deserializeIrSymbol(it) }
|
||||||
|
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModule(proto: IrKlibProtoBuf.IrModule, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrModuleFragment {
|
fun deserializeIrModuleHeader(proto: KotlinIr.IrModule, moduleDescriptor: ModuleDescriptor, deserializationStrategy: DeserializationStrategy): IrModuleFragment {
|
||||||
|
|
||||||
deserializedModuleDescriptor = moduleDescriptor
|
deserializedModuleDescriptor = moduleDescriptor
|
||||||
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
|
||||||
@@ -347,16 +334,21 @@ class IrKlibProtoBufModuleDeserializer(
|
|||||||
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
|
||||||
|
|
||||||
val files = proto.fileList.map {
|
val files = proto.fileList.map {
|
||||||
deserializeIrFile(it, moduleDescriptor, deserializeAllDeclarations)
|
deserializeIrFile(it, moduleDescriptor, deserializationStrategy)
|
||||||
}
|
}
|
||||||
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
val module = IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
||||||
module.patchDeclarationParents(null)
|
module.patchDeclarationParents(null)
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deserializeIrModule(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, klibLocation: File, deserializeAllDeclarations: Boolean = false): IrModuleFragment {
|
fun deserializeIrModuleHeader(moduleDescriptor: ModuleDescriptor, byteArray: ByteArray, deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED): IrModuleFragment {
|
||||||
descriptorToDirectoryMap[moduleDescriptor] = File(klibLocation, "ir/")
|
val proto = KotlinIr.IrModule.parseFrom(byteArray.codedInputStream, newInstance())
|
||||||
val proto = IrKlibProtoBuf.IrModule.parseFrom(byteArray.codedInputStream, JsKlibMetadataSerializerProtocol.extensionRegistry)
|
return deserializeIrModuleHeader(proto, moduleDescriptor, deserializationStrategy)
|
||||||
return deserializeIrModule(proto, moduleDescriptor, deserializeAllDeclarations)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class DeserializationStrategy {
|
||||||
|
ONLY_REFERENCED,
|
||||||
|
ALL,
|
||||||
|
EXPLICITLY_EXPORTED
|
||||||
|
}
|
||||||
+265
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.ir.backend.common.serialization.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
|
import org.jetbrains.kotlin.ir.util.isInlined
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
interface KotlinMangler {
|
||||||
|
val String.hashMangle: Long
|
||||||
|
val IrDeclaration.hashedMangle: Long
|
||||||
|
fun IrDeclaration.isExported(): Boolean
|
||||||
|
val IrFunction.functionName: String
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KotlinManglerImpl: KotlinMangler {
|
||||||
|
override val IrDeclaration.hashedMangle: Long
|
||||||
|
get() = this.uniqSymbolName().hashMangle
|
||||||
|
|
||||||
|
|
||||||
|
// We can't call "with (super) { this.isExported() }" in children.
|
||||||
|
// So provide a hook.
|
||||||
|
protected open fun IrDeclaration.isPlatformSpecificExported(): Boolean = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines whether the declaration is exported, i.e. visible from other modules.
|
||||||
|
*
|
||||||
|
* Exported declarations must have predictable and stable ABI
|
||||||
|
* that doesn't depend on any internal transformations (e.g. IR lowering),
|
||||||
|
* and so should be computable from the descriptor itself without checking a backend state.
|
||||||
|
*/
|
||||||
|
override tailrec fun IrDeclaration.isExported(): Boolean {
|
||||||
|
// TODO: revise
|
||||||
|
val descriptorAnnotations = this.descriptor.annotations
|
||||||
|
|
||||||
|
if (this.isPlatformSpecificExported()) return true
|
||||||
|
|
||||||
|
if (descriptorAnnotations.hasAnnotation(publishedApiAnnotation)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isAnonymousObject)
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (this is IrConstructor && constructedClass.kind.isSingleton) {
|
||||||
|
// Currently code generator can access the constructor of the singleton,
|
||||||
|
// so ignore visibility of the constructor itself.
|
||||||
|
return constructedClass.isExported()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is IrFunction) {
|
||||||
|
val descriptor = this.descriptor
|
||||||
|
// TODO: this code is required because accessor doesn't have a reference to property.
|
||||||
|
if (descriptor is PropertyAccessorDescriptor) {
|
||||||
|
val property = descriptor.correspondingProperty
|
||||||
|
if (property.annotations.hasAnnotation(publishedApiAnnotation)) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val visibility = when (this) {
|
||||||
|
is IrClass -> this.visibility
|
||||||
|
is IrFunction -> this.visibility
|
||||||
|
is IrProperty -> this.visibility
|
||||||
|
is IrField -> this.visibility
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* note: about INTERNAL - with support of friend modules we let frontend to deal with internal declarations.
|
||||||
|
*/
|
||||||
|
if (visibility != null && !visibility.isPublicAPI && visibility != Visibilities.INTERNAL) {
|
||||||
|
// If the declaration is explicitly marked as non-public,
|
||||||
|
// then it must not be accessible from other modules.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val parent = this.parent
|
||||||
|
if (parent is IrDeclaration) {
|
||||||
|
return parent.isExported()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private val publishedApiAnnotation = FqName("kotlin.PublishedApi")
|
||||||
|
|
||||||
|
protected fun acyclicTypeMangler(visited: MutableSet<IrTypeParameter>, type: IrType): String {
|
||||||
|
val descriptor = (type.classifierOrNull as? IrTypeParameterSymbol)?.owner
|
||||||
|
if (descriptor != null) {
|
||||||
|
val upperBounds = if (visited.contains(descriptor)) "" else {
|
||||||
|
|
||||||
|
visited.add(descriptor)
|
||||||
|
|
||||||
|
descriptor.superTypes.map {
|
||||||
|
val bound = acyclicTypeMangler(visited, it)
|
||||||
|
if (bound == "kotlin.Any?") "" else "_$bound"
|
||||||
|
}.joinToString("")
|
||||||
|
}
|
||||||
|
return "#GENERIC${if (type.isMarkedNullable()) "?" else ""}$upperBounds"
|
||||||
|
}
|
||||||
|
|
||||||
|
var hashString = type.getClass()?.run { fqNameSafe.asString() } ?: "<dynamic>"
|
||||||
|
|
||||||
|
when (type) {
|
||||||
|
is IrSimpleType -> {
|
||||||
|
if (!type.arguments.isEmpty()) {
|
||||||
|
hashString += "<${type.arguments.map {
|
||||||
|
when (it) {
|
||||||
|
is IrStarProjection -> "#STAR"
|
||||||
|
is IrTypeProjection -> {
|
||||||
|
val variance = it.variance.label
|
||||||
|
val projection = if (variance == "") "" else "${variance}_"
|
||||||
|
projection + acyclicTypeMangler(visited, it.type)
|
||||||
|
}
|
||||||
|
else -> error(it)
|
||||||
|
}
|
||||||
|
}.joinToString(",")}>"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.hasQuestionMark) hashString += "?"
|
||||||
|
}
|
||||||
|
!is IrDynamicType -> {
|
||||||
|
error(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashString
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun typeToHashString(type: IrType) = acyclicTypeMangler(mutableSetOf(), type)
|
||||||
|
|
||||||
|
val IrValueParameter.extensionReceiverNamePart: String
|
||||||
|
get() = "@${typeToHashString(this.type)}."
|
||||||
|
|
||||||
|
open val IrFunction.argsPart get() = this.valueParameters.map {
|
||||||
|
"${typeToHashString(it.type)}${if (it.isVararg) "_VarArg" else ""}"
|
||||||
|
}.joinToString(";")
|
||||||
|
|
||||||
|
open val IrFunction.signature: String
|
||||||
|
get() {
|
||||||
|
val extensionReceiverPart = this.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
||||||
|
val argsPart = this.argsPart
|
||||||
|
// Distinguish value types and references - it's needed for calling virtual methods through bridges.
|
||||||
|
// Also is function has type arguments - frontend allows exactly matching overrides.
|
||||||
|
val signatureSuffix =
|
||||||
|
when {
|
||||||
|
this.typeParameters.isNotEmpty() -> "Generic"
|
||||||
|
returnType.isInlined() -> "ValueType"
|
||||||
|
!returnType.isUnitOrNullableUnit() -> typeToHashString(returnType)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
return "$extensionReceiverPart($argsPart)$signatureSuffix"
|
||||||
|
}
|
||||||
|
|
||||||
|
open val IrFunction.platformSpecificFunctionName: String? get() = null
|
||||||
|
|
||||||
|
// TODO: rename to indicate that it has signature included
|
||||||
|
override val IrFunction.functionName: String
|
||||||
|
get() {
|
||||||
|
// TODO: Again. We can't call super in children, so provide a hook for now.
|
||||||
|
this.platformSpecificFunctionName ?. let { return it }
|
||||||
|
val name = this.name.mangleIfInternal(this.module, this.visibility)
|
||||||
|
return "$name$signature"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility: Visibility): String =
|
||||||
|
if (visibility != Visibilities.INTERNAL) {
|
||||||
|
this.asString()
|
||||||
|
} else {
|
||||||
|
val moduleName = moduleDescriptor.name.asString()
|
||||||
|
.let { it.substring(1, it.lastIndex) } // Remove < and >.
|
||||||
|
|
||||||
|
"$this\$$moduleName"
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrField.symbolName: String
|
||||||
|
get() {
|
||||||
|
val containingDeclarationPart = parent.fqNameSafe.let {
|
||||||
|
if (it.isRoot) "" else "$it."
|
||||||
|
}
|
||||||
|
return "kfield:$containingDeclarationPart$name"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val IrClass.typeInfoSymbolName: String
|
||||||
|
get() {
|
||||||
|
assert(this.isExported())
|
||||||
|
return "ktype:" + this.fqNameSafe.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This is a little extension over what's used in real mangling
|
||||||
|
// since some declarations never appear in the bitcode symbols.
|
||||||
|
|
||||||
|
internal fun IrDeclaration.uniqSymbolName(): String = when (this) {
|
||||||
|
is IrFunction
|
||||||
|
-> this.uniqFunctionName
|
||||||
|
is IrProperty
|
||||||
|
-> this.symbolName
|
||||||
|
is IrClass
|
||||||
|
-> this.typeInfoSymbolName
|
||||||
|
is IrField
|
||||||
|
-> this.symbolName
|
||||||
|
is IrEnumEntry
|
||||||
|
-> this.symbolName
|
||||||
|
else -> error("Unexpected exported declaration: $this")
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrDeclarationParent.fqNameUnique: FqName
|
||||||
|
get() = when (this) {
|
||||||
|
is IrPackageFragment -> this.fqName
|
||||||
|
is IrDeclaration -> this.parent.fqNameUnique.child(this.uniqName)
|
||||||
|
else -> error(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrDeclaration.uniqName: Name
|
||||||
|
get() = when (this) {
|
||||||
|
is IrSimpleFunction -> Name.special("<${this.uniqFunctionName}>")
|
||||||
|
else -> this.name
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrProperty.symbolName: String
|
||||||
|
get() {
|
||||||
|
val extensionReceiver: String = getter!!.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
||||||
|
|
||||||
|
val containingDeclarationPart = parent.fqNameSafe.let {
|
||||||
|
if (it.isRoot) "" else "$it."
|
||||||
|
}
|
||||||
|
return "kprop:$containingDeclarationPart$extensionReceiver$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val IrEnumEntry.symbolName: String
|
||||||
|
get() {
|
||||||
|
val containingDeclarationPart = parent.fqNameSafe.let {
|
||||||
|
if (it.isRoot) "" else "$it."
|
||||||
|
}
|
||||||
|
return "kenumentry:$containingDeclarationPart$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is basicly the same as .symbolName, but disambiguates external functions with the same C name.
|
||||||
|
// In addition functions appearing in fq sequence appear as <full signature>.
|
||||||
|
private val IrFunction.uniqFunctionName: String
|
||||||
|
get() {
|
||||||
|
val parent = this.parent
|
||||||
|
|
||||||
|
val containingDeclarationPart = parent.fqNameUnique.let {
|
||||||
|
if (it.isRoot) "" else "$it."
|
||||||
|
}
|
||||||
|
|
||||||
|
return "kfun:$containingDeclarationPart#$functionName"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+24
-2
@@ -3,7 +3,7 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.propertyIfAccessor
|
import org.jetbrains.kotlin.backend.common.descriptors.propertyIfAccessor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -11,6 +11,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||||
|
|
||||||
internal val DeclarationDescriptor.isExpectMember: Boolean
|
internal val DeclarationDescriptor.isExpectMember: Boolean
|
||||||
get() = this is MemberDescriptor && this.isExpect
|
get() = this is MemberDescriptor && this.isExpect
|
||||||
@@ -26,4 +29,23 @@ tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescrip
|
|||||||
fun DeclarationDescriptor.findTopLevelDescriptor(): DeclarationDescriptor {
|
fun DeclarationDescriptor.findTopLevelDescriptor(): DeclarationDescriptor {
|
||||||
return if (this.containingDeclaration is org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor) this.propertyIfAccessor
|
return if (this.containingDeclaration is org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor) this.propertyIfAccessor
|
||||||
else this.containingDeclaration!!.findTopLevelDescriptor()
|
else this.containingDeclaration!!.findTopLevelDescriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: this method is actually a part of resolve and probably duplicates another one
|
||||||
|
*/
|
||||||
|
internal fun <T : CallableMemberDescriptor> T.resolveFakeOverrideMaybeAbstract(): Set<T> {
|
||||||
|
if (this.kind.isReal) {
|
||||||
|
return setOf(this)
|
||||||
|
} else {
|
||||||
|
val overridden = OverridingUtil.getOverriddenDeclarations(this)
|
||||||
|
val filtered = OverridingUtil.filterOutOverridden(overridden)
|
||||||
|
// TODO: is it correct to take first?
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return filtered as Set<T>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is Native specific. Try to eliminate.
|
||||||
|
val ModuleDescriptor.isForwardDeclarationModule get() =
|
||||||
|
name == Name.special("<forward declarations>")
|
||||||
+9
-5
@@ -3,24 +3,28 @@
|
|||||||
* that can be found in the license/LICENSE.txt file.
|
* that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.backend.common.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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, val serializeString: (String) -> IrKlibProtoBuf.String) {
|
open class DescriptorReferenceSerializer(
|
||||||
|
val declarationTable: DeclarationTable,
|
||||||
|
val serializeString: (String) -> KotlinIr.String,
|
||||||
|
mangler: KotlinMangler): KotlinMangler by mangler {
|
||||||
|
|
||||||
// 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.
|
||||||
// So we record the uniq id of some other "discoverable" descriptor for which we know for sure that it will be
|
// So we record the uniq id of some other "discoverable" descriptor for which we know for sure that it will be
|
||||||
// available as deserialized descriptor, plus the path to find the needed descriptor from that one.
|
// available as deserialized descriptor, plus the path to find the needed descriptor from that one.
|
||||||
fun serializeDescriptorReference(declaration: IrDeclaration): IrKlibProtoBuf.DescriptorReference? {
|
fun serializeDescriptorReference(declaration: IrDeclaration): KotlinIr.DescriptorReference? {
|
||||||
|
|
||||||
val descriptor = declaration.descriptor
|
val descriptor = declaration.descriptor
|
||||||
|
|
||||||
if (!declaration.isExported() && !((declaration as? IrDeclarationWithVisibility)?.visibility == Visibilities.INVISIBLE_FAKE)) {
|
if (!declaration.isExported() &&
|
||||||
|
!((declaration as? IrDeclarationWithVisibility)?.visibility == Visibilities.INVISIBLE_FAKE)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (declaration is IrAnonymousInitializer) return null
|
if (declaration is IrAnonymousInitializer) return null
|
||||||
@@ -71,7 +75,7 @@ class DescriptorReferenceSerializer(val declarationTable: DeclarationTable, val
|
|||||||
val uniqId = discoverableDescriptorsDeclaration?.let { declarationTable.uniqIdByDeclaration(it) }
|
val uniqId = discoverableDescriptorsDeclaration?.let { declarationTable.uniqIdByDeclaration(it) }
|
||||||
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
|
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
|
||||||
|
|
||||||
val proto = IrKlibProtoBuf.DescriptorReference.newBuilder()
|
val proto = KotlinIr.DescriptorReference.newBuilder()
|
||||||
.setPackageFqName(serializeString(packageFqName))
|
.setPackageFqName(serializeString(packageFqName))
|
||||||
.setClassFqName(serializeString(classFqName))
|
.setClassFqName(serializeString(classFqName))
|
||||||
.setName(serializeString(descriptor.name.toString()))
|
.setName(serializeString(descriptor.name.toString()))
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
//import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
||||||
|
|
||||||
|
// This is an abstract uniqIdIndex any serialized IR declarations gets.
|
||||||
|
// It is either isLocal and then just gets and ordinary number within its module.
|
||||||
|
// Or is visible across modules and then gets a hash of mangled name as its index.
|
||||||
|
data class UniqId (
|
||||||
|
val index: Long,
|
||||||
|
val isLocal: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun protoUniqId(uniqId: UniqId): KotlinIr.UniqId =
|
||||||
|
KotlinIr.UniqId.newBuilder()
|
||||||
|
.setIndex(uniqId.index)
|
||||||
|
.setIsLocal(uniqId.isLocal)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun KotlinIr.UniqId.uniqId(): UniqId = UniqId(this.index, this.isLocal)
|
||||||
|
fun KotlinIr.UniqId.uniqIdKey(moduleDescriptor: ModuleDescriptor) =
|
||||||
|
UniqIdKey(moduleDescriptor, this.uniqId())
|
||||||
|
|
||||||
|
fun <T, M:GeneratedMessageLite.ExtendableMessage<M>> M.tryGetExtension(extension: GeneratedMessageLite.GeneratedExtension<M, T>)
|
||||||
|
= if (this.hasExtension(extension)) this.getExtension<T>(extension) else null
|
||||||
|
|
||||||
|
interface DescriptorUniqIdAware {
|
||||||
|
fun DeclarationDescriptor.getUniqId(): Long?
|
||||||
|
}
|
||||||
|
|
||||||
|
//val UniqId.declarationFileName: String get() = "$index${if (isLocal) "L" else "G"}.kjd"
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* 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.common.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -8,6 +8,7 @@ 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.LoggingContext
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||||
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
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
@@ -17,8 +18,12 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols
|
import org.jetbrains.kotlin.ir.backend.js.lower.inline.replaceUnboundSymbols
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.*
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsDeclarationTable
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.newJsDescriptorUniqId
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataModuleDescriptor
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataModuleDescriptor
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializationUtil
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializationUtil
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataVersion
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataVersion
|
||||||
@@ -38,6 +43,9 @@ import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
|||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
|
||||||
class CompiledModule(
|
class CompiledModule(
|
||||||
val moduleName: String,
|
val moduleName: String,
|
||||||
@@ -56,7 +64,6 @@ enum class CompilationMode(val generateJS: Boolean, val generateKlib: Boolean) {
|
|||||||
|
|
||||||
private val moduleHeaderFileName = "module.kji"
|
private val moduleHeaderFileName = "module.kji"
|
||||||
private val declarationsDirName = "ir/"
|
private val declarationsDirName = "ir/"
|
||||||
private val debugDataFileName = "debug.txt"
|
|
||||||
private val logggg = object : LoggingContext {
|
private val logggg = object : LoggingContext {
|
||||||
override var inVerbosePhase: Boolean
|
override var inVerbosePhase: Boolean
|
||||||
get() = TODO("not implemented")
|
get() = TODO("not implemented")
|
||||||
@@ -73,7 +80,7 @@ data class JsKlib(
|
|||||||
val moduleIr: IrModuleFragment,
|
val moduleIr: IrModuleFragment,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
val irBuiltIns: IrBuiltIns,
|
val irBuiltIns: IrBuiltIns,
|
||||||
val deserializer: IrKlibProtoBufModuleDeserializer
|
val deserializer: JsIrLinker
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -108,14 +115,14 @@ private fun deserializeModuleFromKlib(
|
|||||||
val irBuiltIns = IrBuiltIns(md.builtIns, typeTranslator, st)
|
val irBuiltIns = IrBuiltIns(md.builtIns, typeTranslator, st)
|
||||||
|
|
||||||
val moduleFile = File(klibDirFile, moduleHeaderFileName)
|
val moduleFile = File(klibDirFile, moduleHeaderFileName)
|
||||||
val deserializer = IrKlibProtoBufModuleDeserializer(md, logggg, irBuiltIns, st, null)
|
val deserializer = JsIrLinker(md, logggg, irBuiltIns, st)
|
||||||
|
|
||||||
dependencies.forEach {
|
dependencies.forEach {
|
||||||
val dependencyKlibDir = File(it.klibPath, moduleHeaderFileName)
|
val dependencyKlibDir = File(it.klibPath, moduleHeaderFileName)
|
||||||
deserializer.deserializeIrModule(it.moduleDescriptor!!, dependencyKlibDir.readBytes(), File(it.klibPath), false)
|
deserializer.deserializeIrModuleHeader(it.moduleDescriptor!!, dependencyKlibDir.readBytes(), File(it.klibPath), DeserializationStrategy.ONLY_REFERENCED)
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleFragment = deserializer.deserializeIrModule(md, moduleFile.readBytes(), klibDirFile, true)
|
val moduleFragment = deserializer.deserializeIrModuleHeader(md, moduleFile.readBytes(), klibDirFile, DeserializationStrategy.ALL)
|
||||||
|
|
||||||
return JsKlib(md, moduleFragment, st, irBuiltIns, deserializer)
|
return JsKlib(md, moduleFragment, st, irBuiltIns, deserializer)
|
||||||
}
|
}
|
||||||
@@ -160,11 +167,11 @@ fun compile(
|
|||||||
val psi2IrContext = psi2IrTranslator.createGeneratorContext(moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
val psi2IrContext = psi2IrTranslator.createGeneratorContext(moduleDescriptor, analysisResult.bindingContext, symbolTable)
|
||||||
val irBuiltIns = psi2IrContext.irBuiltIns
|
val irBuiltIns = psi2IrContext.irBuiltIns
|
||||||
|
|
||||||
var deserializer = IrKlibProtoBufModuleDeserializer(moduleDescriptor, logggg, irBuiltIns, symbolTable, null)
|
var deserializer = JsIrLinker(moduleDescriptor, logggg, irBuiltIns, symbolTable)
|
||||||
|
|
||||||
val deserializedModuleFragments = sortedDeps.map {
|
val deserializedModuleFragments = sortedDeps.map {
|
||||||
val moduleFile = File(it.klibPath, moduleHeaderFileName)
|
val moduleFile = File(it.klibPath, moduleHeaderFileName)
|
||||||
deserializer.deserializeIrModule(it.moduleDescriptor!!, moduleFile.readBytes(), File(it.klibPath), false)
|
deserializer.deserializeIrModuleHeader(it.moduleDescriptor!!, moduleFile.readBytes(), File(it.klibPath), DeserializationStrategy.ONLY_REFERENCED)
|
||||||
}
|
}
|
||||||
|
|
||||||
var moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files, deserializer)
|
var moduleFragment = psi2IrTranslator.generateModuleFragment(psi2IrContext, files, deserializer)
|
||||||
@@ -321,9 +328,9 @@ fun serializeModuleIntoKlib(
|
|||||||
dependencies: List<CompiledModule>,
|
dependencies: List<CompiledModule>,
|
||||||
moduleFragment: IrModuleFragment
|
moduleFragment: IrModuleFragment
|
||||||
) {
|
) {
|
||||||
val declarationTable = DeclarationTable(moduleFragment.irBuiltins, DescriptorTable(), symbolTable)
|
val declarationTable = JsDeclarationTable(moduleFragment.irBuiltins, DescriptorTable()).apply { loadKnownBuiltins() }
|
||||||
|
|
||||||
val serializedIr = IrModuleSerializer(logggg, declarationTable/*, onlyForInlines = false*/).serializedIrModule(moduleFragment)
|
val serializedIr = JsIrModuleSerializer(logggg, declarationTable).serializedIrModule(moduleFragment)
|
||||||
val serializer = JsKlibMetadataSerializationUtil
|
val serializer = JsKlibMetadataSerializationUtil
|
||||||
|
|
||||||
val moduleDescription =
|
val moduleDescription =
|
||||||
@@ -335,7 +342,7 @@ fun serializeModuleIntoKlib(
|
|||||||
metadataVersion
|
metadataVersion
|
||||||
) { declarationDescriptor ->
|
) { declarationDescriptor ->
|
||||||
val index = declarationTable.descriptorTable.get(declarationDescriptor)
|
val index = declarationTable.descriptorTable.get(declarationDescriptor)
|
||||||
index?.let { newDescriptorUniqId(it) }
|
index?.let { newJsDescriptorUniqId(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val klibDir = File(klibPath).also {
|
val klibDir = File(klibPath).also {
|
||||||
@@ -347,20 +354,8 @@ fun serializeModuleIntoKlib(
|
|||||||
moduleFile.writeBytes(serializedIr.module)
|
moduleFile.writeBytes(serializedIr.module)
|
||||||
|
|
||||||
val irDeclarationDir = File(klibDir, declarationsDirName).also { it.mkdir() }
|
val irDeclarationDir = File(klibDir, declarationsDirName).also { it.mkdir() }
|
||||||
|
val irCombinedFile = File(irDeclarationDir, "irCombined.knd")
|
||||||
for ((id, data) in serializedIr.declarations) {
|
Files.copy(Paths.get(serializedIr.combinedDeclarationFilePath), Paths.get(irCombinedFile.path), StandardCopyOption.REPLACE_EXISTING)
|
||||||
val file = File(irDeclarationDir, id.declarationFileName)
|
|
||||||
file.writeBytes(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
val debugFile = File(klibDir, debugDataFileName)
|
|
||||||
|
|
||||||
for ((id, data) in serializedIr.debugIndex) {
|
|
||||||
debugFile.appendText(id.toString())
|
|
||||||
debugFile.appendText(" --- ")
|
|
||||||
debugFile.appendText(data)
|
|
||||||
debugFile.appendText("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
File(klibDir, "${moduleDescription.name}.${JsKlibMetadataSerializationUtil.CLASS_METADATA_FILE_EXTENSION}").also {
|
File(klibDir, "${moduleDescription.name}.${JsKlibMetadataSerializationUtil.CLASS_METADATA_FILE_EXTENSION}").also {
|
||||||
it.writeBytes(serializedData.asByteArray())
|
it.writeBytes(serializedData.asByteArray())
|
||||||
|
|||||||
-2
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
|||||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
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.backend.common.reportWarning
|
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
@@ -20,7 +19,6 @@ 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.backend.js.lower.serialization.ir.fileEntry
|
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||||
|
|||||||
-100
@@ -1,100 +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.ir.SourceManager
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
val IrConstructor.constructedClass get() = this.parent as IrClass
|
|
||||||
|
|
||||||
val <T : IrDeclaration> T.original get() = this
|
|
||||||
|
|
||||||
val IrDeclarationParent.fqNameSafe: FqName
|
|
||||||
get() = when (this) {
|
|
||||||
is IrPackageFragment -> this.fqName
|
|
||||||
is IrDeclaration -> this.parent.fqNameSafe.child(this.name)
|
|
||||||
|
|
||||||
else -> error(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
val IrClass.classId: ClassId?
|
|
||||||
get() {
|
|
||||||
val parent = this.parent
|
|
||||||
return when (parent) {
|
|
||||||
is IrClass -> parent.classId?.createNestedClassId(this.name)
|
|
||||||
is IrPackageFragment -> ClassId.topLevel(parent.fqName.child(this.name))
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val IrDeclaration.name: Name
|
|
||||||
get() = when (this) {
|
|
||||||
is IrSimpleFunction -> this.name
|
|
||||||
is IrClass -> this.name
|
|
||||||
is IrEnumEntry -> this.name
|
|
||||||
is IrProperty -> this.name
|
|
||||||
is IrLocalDelegatedProperty -> this.name
|
|
||||||
is IrField -> this.name
|
|
||||||
is IrVariable -> this.name
|
|
||||||
is IrConstructor -> SPECIAL_INIT_NAME
|
|
||||||
is IrValueParameter -> this.name
|
|
||||||
else -> error(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val SPECIAL_INIT_NAME = Name.special("<init>")
|
|
||||||
|
|
||||||
val IrValueParameter.isVararg get() = this.varargElementType != null
|
|
||||||
|
|
||||||
val IrFunction.isSuspend get() = this is IrSimpleFunction && this.isSuspend
|
|
||||||
|
|
||||||
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
|
|
||||||
|
|
||||||
fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
|
|
||||||
if (this == other) return true
|
|
||||||
|
|
||||||
this.overriddenSymbols.forEach {
|
|
||||||
if (it.owner.overrides(other)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrCall.annotationClass
|
|
||||||
get() = (this.symbol.owner as IrConstructor).constructedClass
|
|
||||||
|
|
||||||
fun List<IrCall>.hasAnnotation(fqName: FqName): Boolean =
|
|
||||||
this.any { it.annotationClass.fqNameSafe == fqName }
|
|
||||||
|
|
||||||
fun IrAnnotationContainer.hasAnnotation(fqName: FqName) =
|
|
||||||
this.annotations.hasAnnotation(fqName)
|
|
||||||
|
|
||||||
fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
|
|
||||||
it.annotationClass.fqNameSafe == fqName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrClass.companionObject() = this.declarations.singleOrNull {it is IrClass && it.isCompanion }
|
|
||||||
|
|
||||||
val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.getter
|
|
||||||
|
|
||||||
val IrDeclaration.isSetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.setter
|
|
||||||
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-71
@@ -5,13 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.name
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.ir.SourceManager
|
|
||||||
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
@@ -19,75 +18,8 @@ import org.jetbrains.kotlin.ir.util.parentAsClass
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi2ir.findFirstFunction
|
import org.jetbrains.kotlin.psi2ir.findFirstFunction
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import java.io.File
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
internal val IrDeclaration.isAnonymousObject get() = DescriptorUtils.isAnonymousObject(this.descriptor)
|
|
||||||
internal val IrDeclaration.isLocal get() = DescriptorUtils.isLocal(this.descriptor)
|
|
||||||
|
|
||||||
internal val IrDeclaration.module get() = this.descriptor.module
|
|
||||||
|
|
||||||
internal const val SYNTHETIC_OFFSET = -2
|
|
||||||
|
|
||||||
val File.lineStartOffsets: IntArray
|
|
||||||
get() {
|
|
||||||
// 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()
|
|
||||||
// as in PSI.
|
|
||||||
val separatorLength = System.lineSeparator().length
|
|
||||||
val buffer = mutableListOf<Int>()
|
|
||||||
var currentOffset = 0
|
|
||||||
this.forEachLine { line ->
|
|
||||||
buffer.add(currentOffset)
|
|
||||||
currentOffset += line.length + separatorLength
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
assert(offset != UNDEFINED_OFFSET)
|
|
||||||
if (offset == SYNTHETIC_OFFSET) return 0
|
|
||||||
val index = lineStartOffsets.binarySearch(offset)
|
|
||||||
return if (index >= 0) index else -index - 2
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override fun getColumnNumber(offset: Int): Int {
|
|
||||||
assert(offset != UNDEFINED_OFFSET)
|
|
||||||
if (offset == SYNTHETIC_OFFSET) return 0
|
|
||||||
var lineNumber = getLineNumber(offset)
|
|
||||||
return offset - lineStartOffsets[lineNumber]
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
override val maxOffset: Int
|
|
||||||
//get() = TODO("not implemented")
|
|
||||||
get() = UNDEFINED_OFFSET
|
|
||||||
|
|
||||||
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo {
|
|
||||||
//TODO("not implemented")
|
|
||||||
return SourceRangeInfo(name, beginOffset, -1, -1, endOffset, -1, -1)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private val functionPattern = Pattern.compile("^K?(Suspend)?Function\\d+$")
|
private val functionPattern = Pattern.compile("^K?(Suspend)?Function\\d+$")
|
||||||
|
|
||||||
private val kotlinFqn = FqName("kotlin")
|
private val kotlinFqn = FqName("kotlin")
|
||||||
@@ -158,4 +90,4 @@ internal fun builtInFunctionId(value: DeclarationDescriptor): Long = when (value
|
|||||||
BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.findFirstFunction("invoke") { true })
|
BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.findFirstFunction("invoke") { true })
|
||||||
}
|
}
|
||||||
else -> error("Only class or function is expected")
|
else -> error("Only class or function is expected")
|
||||||
}
|
}
|
||||||
|
|||||||
-227
@@ -1,227 +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.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
|
||||||
import org.jetbrains.kotlin.ir.util.isInlined
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
|
|
||||||
// This file describes the ABI for Kotlin descriptors of exported declarations.
|
|
||||||
// TODO: revise the naming scheme to ensure it produces unique names.
|
|
||||||
// TODO: do not serialize descriptors of non-exported declarations.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines whether the declaration is exported, i.e. visible from other modules.
|
|
||||||
*
|
|
||||||
* Exported declarations must have predictable and stable ABI
|
|
||||||
* that doesn't depend on any internal transformations (e.g. IR lowering),
|
|
||||||
* and so should be computable from the descriptor itself without checking a backend state.
|
|
||||||
*/
|
|
||||||
internal tailrec fun IrDeclaration.isExported(): Boolean {
|
|
||||||
// TODO: revise
|
|
||||||
val descriptorAnnotations = this.descriptor.annotations
|
|
||||||
// if (descriptorAnnotations.hasAnnotation(symbolNameAnnotation)) {
|
|
||||||
// // Treat any `@SymbolName` declaration as exported.
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if (descriptorAnnotations.hasAnnotation(exportForCppRuntimeAnnotation)) {
|
|
||||||
// // Treat any `@ExportForCppRuntime` declaration as exported.
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if (descriptorAnnotations.hasAnnotation(cnameAnnotation)) {
|
|
||||||
// // Treat `@CName` declaration as exported.
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// if (descriptorAnnotations.hasAnnotation(exportForCompilerAnnotation)) {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
if (descriptorAnnotations.hasAnnotation(publishedApiAnnotation)){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.isAnonymousObject)
|
|
||||||
return false
|
|
||||||
|
|
||||||
if (this is IrConstructor && constructedClass.kind.isSingleton) {
|
|
||||||
// Currently code generator can access the constructor of the singleton,
|
|
||||||
// so ignore visibility of the constructor itself.
|
|
||||||
return constructedClass.isExported()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this is IrFunction) {
|
|
||||||
val descriptor = this.descriptor
|
|
||||||
// TODO: this code is required because accessor doesn't have a reference to property.
|
|
||||||
if (descriptor is PropertyAccessorDescriptor) {
|
|
||||||
val property = descriptor.correspondingProperty
|
|
||||||
if (property.annotations.hasAnnotation(publishedApiAnnotation)) return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val visibility = when (this) {
|
|
||||||
is IrClass -> this.visibility
|
|
||||||
is IrFunction -> this.visibility
|
|
||||||
is IrProperty -> this.visibility
|
|
||||||
is IrField -> this.visibility
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* note: about INTERNAL - with support of friend modules we let frontend to deal with internal declarations.
|
|
||||||
*/
|
|
||||||
if (visibility != null && !visibility.isPublicAPI && visibility != Visibilities.INTERNAL) {
|
|
||||||
// If the declaration is explicitly marked as non-public,
|
|
||||||
// then it must not be accessible from other modules.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val parent = this.parent
|
|
||||||
if (parent is IrDeclaration) {
|
|
||||||
return parent.isExported()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private val publishedApiAnnotation = FqName("kotlin.PublishedApi")
|
|
||||||
|
|
||||||
private fun acyclicTypeMangler(visited: MutableSet<IrTypeParameter>, type: IrType): String {
|
|
||||||
val descriptor = (type.classifierOrNull as? IrTypeParameterSymbol)?.owner
|
|
||||||
if (descriptor != null) {
|
|
||||||
val upperBounds = if (visited.contains(descriptor)) "" else {
|
|
||||||
|
|
||||||
visited.add(descriptor)
|
|
||||||
|
|
||||||
descriptor.superTypes.map {
|
|
||||||
val bound = acyclicTypeMangler(visited, it)
|
|
||||||
if (bound == "kotlin.Any?") "" else "_$bound"
|
|
||||||
}.joinToString("")
|
|
||||||
}
|
|
||||||
return "#GENERIC${if (type.isMarkedNullable()) "?" else ""}$upperBounds"
|
|
||||||
}
|
|
||||||
|
|
||||||
var hashString = type.getClass()?.run { fqNameSafe.asString() } ?: "<dynamic>"
|
|
||||||
// if (type !is IrSimpleType) error(type)
|
|
||||||
when (type) {
|
|
||||||
is IrSimpleType -> {
|
|
||||||
if (!type.arguments.isEmpty()) {
|
|
||||||
hashString += "<${type.arguments.map {
|
|
||||||
when (it) {
|
|
||||||
is IrStarProjection -> "#STAR"
|
|
||||||
is IrTypeProjection -> {
|
|
||||||
val variance = it.variance.label
|
|
||||||
val projection = if (variance == "") "" else "${variance}_"
|
|
||||||
projection + acyclicTypeMangler(visited, it.type)
|
|
||||||
}
|
|
||||||
else -> error(it)
|
|
||||||
}
|
|
||||||
}.joinToString(",")}>"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.hasQuestionMark) hashString += "?"
|
|
||||||
}
|
|
||||||
!is IrDynamicType -> { error(type) }
|
|
||||||
}
|
|
||||||
return hashString
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun typeToHashString(type: IrType) = acyclicTypeMangler(mutableSetOf(), type)
|
|
||||||
|
|
||||||
internal val IrValueParameter.extensionReceiverNamePart: String
|
|
||||||
get() = "@${typeToHashString(this.type)}."
|
|
||||||
|
|
||||||
private val IrFunction.signature: String
|
|
||||||
get() {
|
|
||||||
val extensionReceiverPart = this.extensionReceiverParameter?.extensionReceiverNamePart ?: ""
|
|
||||||
val argsPart = this.valueParameters.map {
|
|
||||||
|
|
||||||
// TODO: there are clashes originating from ObjectiveC interop.
|
|
||||||
// kotlinx.cinterop.ObjCClassOf<T>.create(format: kotlin.String): T defined in platform.Foundation in file Foundation.kt
|
|
||||||
// and
|
|
||||||
// kotlinx.cinterop.ObjCClassOf<T>.create(string: kotlin.String): T defined in platform.Foundation in file Foundation.kt
|
|
||||||
|
|
||||||
val argName = /*if (this.hasObjCMethodAnnotation || this.hasObjCFactoryAnnotation || this.isObjCClassMethod()) "${it.name}:" else */""
|
|
||||||
"$argName${typeToHashString(it.type)}${if (it.isVararg) "_VarArg" else ""}"
|
|
||||||
}.joinToString(";")
|
|
||||||
// Distinguish value types and references - it's needed for calling virtual methods through bridges.
|
|
||||||
// Also is function has type arguments - frontend allows exactly matching overrides.
|
|
||||||
val signatureSuffix =
|
|
||||||
when {
|
|
||||||
this.typeParameters.isNotEmpty() -> "Generic"
|
|
||||||
returnType.isInlined() -> "ValueType"
|
|
||||||
!returnType.isUnitOrNullableUnit() -> typeToHashString(returnType)
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
return "$extensionReceiverPart($argsPart)$signatureSuffix"
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: rename to indicate that it has signature included
|
|
||||||
internal val IrFunction.functionName: String
|
|
||||||
get() {
|
|
||||||
with(this.original) { // basic support for generics
|
|
||||||
// (if (this is IrConstructor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo()?.let {
|
|
||||||
// return buildString {
|
|
||||||
// if (extensionReceiverParameter != null) {
|
|
||||||
// append(extensionReceiverParameter!!.type.getClass()!!.name)
|
|
||||||
// append(".")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// append("objc:")
|
|
||||||
// append(it.selector)
|
|
||||||
// if (this@with is IrConstructor && this@with.isObjCConstructor) append("#Constructor")
|
|
||||||
//
|
|
||||||
// // We happen to have the clashing combinations such as
|
|
||||||
// //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1165")
|
|
||||||
// //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit
|
|
||||||
// //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1172")
|
|
||||||
// //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit
|
|
||||||
// // So disambiguate by the name of the bridge for now.
|
|
||||||
// // TODO: idealy we'd never generate such identical declarations.
|
|
||||||
//
|
|
||||||
// if (this@with is IrSimpleFunction && this@with.hasObjCMethodAnnotation()) {
|
|
||||||
// this@with.objCMethodArgValue("selector") ?.let { append("#$it") }
|
|
||||||
// this@with.objCMethodArgValue("bridge") ?.let { append("#$it") }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
val name = this.name.mangleIfInternal(this.module, this.visibility)
|
|
||||||
|
|
||||||
return "$name$signature"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility: Visibility): String =
|
|
||||||
if (visibility != Visibilities.INTERNAL) {
|
|
||||||
this.asString()
|
|
||||||
} else {
|
|
||||||
val moduleName = moduleDescriptor.name.asString()
|
|
||||||
.let { it.substring(1, it.lastIndex) } // Remove < and >.
|
|
||||||
|
|
||||||
"$this\$$moduleName"
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val IrField.symbolName: String
|
|
||||||
get() {
|
|
||||||
val containingDeclarationPart = parent.fqNameSafe.let {
|
|
||||||
if (it.isRoot) "" else "$it."
|
|
||||||
}
|
|
||||||
return "kfield:$containingDeclarationPart$name"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val IrClass.typeInfoSymbolName: String
|
|
||||||
get() {
|
|
||||||
assert (this.isExported())
|
|
||||||
return "ktype:" + this.fqNameSafe.toString()
|
|
||||||
}
|
|
||||||
-40
@@ -1,40 +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.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
|
||||||
|
|
||||||
// TODO: move me somewhere
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of given method.
|
|
||||||
*
|
|
||||||
* TODO: this method is actually a part of resolve and probably duplicates another one
|
|
||||||
*/
|
|
||||||
internal fun IrSimpleFunction.resolveFakeOverrideMaybeAbstract() = this.resolveFakeOverride(allowAbstract = true)
|
|
||||||
|
|
||||||
internal fun IrProperty.resolveFakeOverrideMaybeAbstract() = this.getter!!.resolveFakeOverrideMaybeAbstract().correspondingProperty!!
|
|
||||||
|
|
||||||
internal fun IrField.resolveFakeOverrideMaybeAbstract() = this.correspondingProperty!!.getter!!.resolveFakeOverrideMaybeAbstract().correspondingProperty!!.backingField
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of given method.
|
|
||||||
*
|
|
||||||
* TODO: this method is actually a part of resolve and probably duplicates another one
|
|
||||||
*/
|
|
||||||
internal fun <T : CallableMemberDescriptor> T.resolveFakeOverrideMaybeAbstract(): Set<T> {
|
|
||||||
if (this.kind.isReal) {
|
|
||||||
return setOf(this)
|
|
||||||
} else {
|
|
||||||
val overridden = OverridingUtil.getOverriddenDeclarations(this)
|
|
||||||
val filtered = OverridingUtil.filterOutOverridden(overridden)
|
|
||||||
// TODO: is it correct to take first?
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return filtered as Set<T>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.UniqId
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
|
||||||
|
class JsDeclarationTable(builtIns: IrBuiltIns, descriptorTable: DescriptorTable)
|
||||||
|
: DeclarationTable(builtIns, descriptorTable, JsMangler) {
|
||||||
|
|
||||||
|
override var currentIndex = 0x1_0000_0000L
|
||||||
|
|
||||||
|
private /* lateinit */ var FUNCTION_INDEX_START: Long = 0xdeadbeefL
|
||||||
|
|
||||||
|
override fun loadKnownBuiltins() {
|
||||||
|
super.loadKnownBuiltins()
|
||||||
|
FUNCTION_INDEX_START = currentIndex
|
||||||
|
currentIndex += BUILT_IN_UNIQ_ID_GAP
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun computeUniqIdByDeclaration(value: IrDeclaration) =
|
||||||
|
if (isBuiltInFunction(value)) {
|
||||||
|
UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false)
|
||||||
|
} else super.computeUniqIdByDeclaration(value)
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.UniqId
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.UniqIdKey
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
|
||||||
|
class JsDescriptorReferenceDeserializer(
|
||||||
|
currentModule: ModuleDescriptor,
|
||||||
|
val builtIns: IrBuiltIns,
|
||||||
|
val FUNCTION_INDEX_START: Long) :
|
||||||
|
DescriptorReferenceDeserializer(currentModule, mutableMapOf<UniqIdKey, UniqIdKey>()),
|
||||||
|
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
|
||||||
|
|
||||||
|
val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.tryGetExtension
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||||
|
|
||||||
|
object JsDescriptorUniqIdAware: DescriptorUniqIdAware {
|
||||||
|
override fun DeclarationDescriptor.getUniqId(): Long? = when (this) {
|
||||||
|
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(JsKlibMetadataProtoBuf.classUniqId)
|
||||||
|
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.functionUniqId)
|
||||||
|
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.propertyUniqId)
|
||||||
|
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.constructorUniqId)
|
||||||
|
else -> null
|
||||||
|
}?.index
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newJsDescriptorUniqId(index: Long): JsKlibMetadataProtoBuf.DescriptorUniqId =
|
||||||
|
JsKlibMetadataProtoBuf.DescriptorUniqId.newBuilder().setIndex(index).build()
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.library.CombinedIrFileReader
|
||||||
|
import org.jetbrains.kotlin.backend.common.library.DeclarationId
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.knownBuiltins
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class JsIrLinker(
|
||||||
|
currentModule: ModuleDescriptor,
|
||||||
|
logger: LoggingContext,
|
||||||
|
builtIns: IrBuiltIns,
|
||||||
|
symbolTable: SymbolTable) :
|
||||||
|
KotlinIrLinker(currentModule, logger, builtIns, symbolTable, null),
|
||||||
|
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
|
||||||
|
|
||||||
|
private val FUNCTION_INDEX_START: Long
|
||||||
|
val moduleToReaderMap = mutableMapOf<ModuleDescriptor, CombinedIrFileReader>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
// TODO: think about order
|
||||||
|
var currentIndex = 0x1_0000_0000L
|
||||||
|
builtIns.knownBuiltins.forEach {
|
||||||
|
require(it is IrFunction)
|
||||||
|
deserializedSymbols.put(UniqIdKey(null, UniqId(currentIndex, isLocal = false)), it.symbol)
|
||||||
|
assert(symbolTable.referenceSimpleFunction(it.descriptor) == it.symbol)
|
||||||
|
currentIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_INDEX_START = currentIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPrimitiveTypeOrNull(symbol: IrClassifierSymbol, hasQuestionMark: Boolean) =
|
||||||
|
builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, hasQuestionMark)
|
||||||
|
|
||||||
|
override val descriptorReferenceDeserializer =
|
||||||
|
JsDescriptorReferenceDeserializer(currentModule, builtIns, FUNCTION_INDEX_START)
|
||||||
|
|
||||||
|
override fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId) =
|
||||||
|
moduleToReaderMap[moduleDescriptor]!!.declarationBytes(DeclarationId(uniqId.index, uniqId.isLocal))
|
||||||
|
|
||||||
|
fun deserializeIrModuleHeader(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
byteArray: ByteArray,
|
||||||
|
klibLocation: File,
|
||||||
|
deserializationStrategy: DeserializationStrategy
|
||||||
|
): IrModuleFragment {
|
||||||
|
val irFile = File(klibLocation, "ir/irCombined.knd")
|
||||||
|
moduleToReaderMap[moduleDescriptor] = CombinedIrFileReader(irFile)
|
||||||
|
return deserializeIrModuleHeader(moduleDescriptor, byteArray, deserializationStrategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.IrModuleSerializer
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
|
||||||
|
|
||||||
|
class JsIrModuleSerializer(
|
||||||
|
logger: LoggingContext,
|
||||||
|
declarationTable: DeclarationTable,
|
||||||
|
bodiesOnlyForInlines: Boolean = false
|
||||||
|
) : IrModuleSerializer(logger, declarationTable, JsMangler, bodiesOnlyForInlines)
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* 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.backend.common.serialization.KotlinManglerImpl
|
||||||
|
|
||||||
|
object JsMangler: KotlinManglerImpl() {
|
||||||
|
// TODO: think about this
|
||||||
|
override val String.hashMangle: Long get() = this.hashCode().toLong()
|
||||||
|
}
|
||||||
|
|
||||||
-61
@@ -1,61 +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.ir.backend.js.lower.serialization.metadata.JsKlibMetadataProtoBuf
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
|
||||||
|
|
||||||
// This is an abstract uniqIdIndex any serialized IR declarations gets.
|
|
||||||
// It is either isLocal and then just gets and ordinary number within its module.
|
|
||||||
// Or is visible across modules and then gets a hash of mangled name as its index.
|
|
||||||
data class UniqId (
|
|
||||||
val index: Long,
|
|
||||||
val isLocal: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
fun protoUniqId(uniqId: UniqId): IrKlibProtoBuf.UniqId =
|
|
||||||
IrKlibProtoBuf.UniqId.newBuilder()
|
|
||||||
.setIndex(uniqId.index)
|
|
||||||
.setIsLocal(uniqId.isLocal)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
fun IrKlibProtoBuf.UniqId.uniqId(): UniqId = UniqId(this.index, this.isLocal)
|
|
||||||
fun IrKlibProtoBuf.UniqId.uniqIdKey(moduleDescriptor: ModuleDescriptor) =
|
|
||||||
UniqIdKey(moduleDescriptor, this.uniqId())
|
|
||||||
|
|
||||||
fun <T, M:GeneratedMessageLite.ExtendableMessage<M>> M.tryGetExtension(extension: GeneratedMessageLite.GeneratedExtension<M, T>)
|
|
||||||
= if (this.hasExtension(extension)) this.getExtension<T>(extension) else null
|
|
||||||
|
|
||||||
fun DeclarationDescriptor.getUniqId(): JsKlibMetadataProtoBuf.DescriptorUniqId? = when (this) {
|
|
||||||
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(JsKlibMetadataProtoBuf.classUniqId)
|
|
||||||
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.functionUniqId)
|
|
||||||
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.propertyUniqId)
|
|
||||||
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(JsKlibMetadataProtoBuf.constructorUniqId)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun newDescriptorUniqId(index: Long): JsKlibMetadataProtoBuf.DescriptorUniqId =
|
|
||||||
JsKlibMetadataProtoBuf.DescriptorUniqId.newBuilder().setIndex(index).build()
|
|
||||||
|
|
||||||
val UniqId.declarationFileName: String get() = "$index${if (isLocal) "L" else "G"}.kjd"
|
|
||||||
-71
@@ -1,71 +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.ir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
// This is a little extension over what's used in real mangling
|
|
||||||
// since some declarations never appear in the bitcode symbols.
|
|
||||||
|
|
||||||
internal fun IrDeclaration.uniqSymbolName(): String = when (this) {
|
|
||||||
is IrFunction
|
|
||||||
-> this.uniqFunctionName
|
|
||||||
is IrProperty
|
|
||||||
-> this.symbolName
|
|
||||||
is IrClass
|
|
||||||
-> this.typeInfoSymbolName
|
|
||||||
is IrField
|
|
||||||
-> this.symbolName
|
|
||||||
is IrEnumEntry
|
|
||||||
-> this.symbolName
|
|
||||||
else -> error("Unexpected exported declaration: $this")
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrDeclarationParent.fqNameUnique: FqName
|
|
||||||
get() = when(this) {
|
|
||||||
is IrPackageFragment -> this.fqName
|
|
||||||
is IrDeclaration -> this.parent.fqNameUnique.child(this.uniqName)
|
|
||||||
else -> error(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrDeclaration.uniqName: Name
|
|
||||||
get() = when (this) {
|
|
||||||
is IrSimpleFunction -> Name.special("<${this.uniqFunctionName}>")
|
|
||||||
else -> this.name
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrProperty.symbolName: String
|
|
||||||
get() {
|
|
||||||
val extensionReceiver: String = getter!!.extensionReceiverParameter ?. extensionReceiverNamePart ?: ""
|
|
||||||
|
|
||||||
val containingDeclarationPart = parent.fqNameSafe.let {
|
|
||||||
if (it.isRoot) "" else "$it."
|
|
||||||
}
|
|
||||||
return "kprop:$containingDeclarationPart$extensionReceiver$name"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrEnumEntry.symbolName: String
|
|
||||||
get() {
|
|
||||||
val containingDeclarationPart = parent.fqNameSafe.let {
|
|
||||||
if (it.isRoot) "" else "$it."
|
|
||||||
}
|
|
||||||
return "kenumentry:$containingDeclarationPart$name"
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is basicly the same as .symbolName, but disambiguates external functions with the same C name.
|
|
||||||
// In addition functions appearing in fq sequence appear as <full signature>.
|
|
||||||
private val IrFunction.uniqFunctionName: String
|
|
||||||
get() {
|
|
||||||
val parent = this.parent
|
|
||||||
|
|
||||||
val containingDeclarationPart = parent.fqNameUnique.let {
|
|
||||||
if (it.isRoot) "" else "$it."
|
|
||||||
}
|
|
||||||
|
|
||||||
return "kfun:$containingDeclarationPart#$functionName"
|
|
||||||
}
|
|
||||||
@@ -58,8 +58,9 @@ val PROTO_PATHS: List<ProtoPath> = listOf(
|
|||||||
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_metadata.proto"),
|
||||||
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
ProtoPath("core/metadata.jvm/src/jvm_module.proto"),
|
||||||
ProtoPath("build-common/src/java_descriptors.proto"),
|
ProtoPath("build-common/src/java_descriptors.proto"),
|
||||||
ProtoPath("compiler/ir/backend.js/src/ir.proto", false),
|
//ProtoPath("compiler/ir/backend.js/src/ir.proto", false),
|
||||||
ProtoPath("compiler/ir/backend.js/src/js.proto", false)
|
ProtoPath("compiler/ir/backend.js/src/js.proto", false),
|
||||||
|
ProtoPath("compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIr.proto", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val EXT_OPTIONS_PROTO_PATH = ProtoPath("core/metadata/src/ext_options.proto")
|
private val EXT_OPTIONS_PROTO_PATH = ProtoPath("core/metadata/src/ext_options.proto")
|
||||||
|
|||||||
Reference in New Issue
Block a user