All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.backend.common.serialization.IncrementalCompilationSupport.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.backend.common.serialization

import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.library.SerializedIrFile
import org.jetbrains.kotlin.library.impl.*


class ICKotlinLibrary(private val icData: List) : IrLibrary {
    override val dataFlowGraph: ByteArray? = null

    private inline fun > Array.itemBytes(fileIndex: Int, key: K, factory: () -> R): ByteArray {
        val reader = this[fileIndex] ?: factory().also { this[fileIndex] = it }

        return reader.tableItemBytes(key)
    }

    private inline fun  Array.itemBytes(fileIndex: Int, index: Int, factory: () -> R): ByteArray {
        val reader = this[fileIndex] ?: factory().also { this[fileIndex] = it }

        return reader.tableItemBytes(index)
    }

    private val indexedDeclarations = arrayOfNulls(icData.size)
    private val indexedTypes = arrayOfNulls(icData.size)
    private val indexedSignatures = arrayOfNulls(icData.size)
    private val indexedStrings = arrayOfNulls(icData.size)
    private val indexedBodies = arrayOfNulls(icData.size)

    override fun irDeclaration(index: Int, fileIndex: Int): ByteArray =
        indexedDeclarations.itemBytes(fileIndex, DeclarationId(index)) {
            DeclarationIrTableMemoryReader(icData[fileIndex].declarations)
        }

    override fun type(index: Int, fileIndex: Int): ByteArray =
        indexedTypes.itemBytes(fileIndex, index) {
            IrArrayMemoryReader(icData[fileIndex].types)
        }

    override fun signature(index: Int, fileIndex: Int): ByteArray =
        indexedSignatures.itemBytes(fileIndex, index) {
            IrArrayMemoryReader(icData[fileIndex].signatures)
        }

    override fun string(index: Int, fileIndex: Int): ByteArray =
        indexedStrings.itemBytes(fileIndex, index) {
            IrArrayMemoryReader(icData[fileIndex].strings)
        }

    override fun body(index: Int, fileIndex: Int): ByteArray =
        indexedBodies.itemBytes(fileIndex, index) {
            IrArrayMemoryReader(icData[fileIndex].bodies)
        }

    override fun file(index: Int): ByteArray = icData[index].fileData

    override fun fileCount(): Int = icData.size
}

class CurrentModuleWithICDeserializer(
    private val delegate: IrModuleDeserializer,
    private val symbolTable: SymbolTable,
    private val irBuiltIns: IrBuiltIns,
    icData: List,
    icReaderFactory: (IrLibrary) -> IrModuleDeserializer) :
    IrModuleDeserializer(delegate.moduleDescriptor) {

    private val dirtyDeclarations = mutableMapOf()
    private val icKlib = ICKotlinLibrary(icData)

    private val icDeserializer: IrModuleDeserializer = icReaderFactory(icKlib)

    override fun contains(idSig: IdSignature): Boolean {
        return idSig in dirtyDeclarations || idSig.topLevelSignature() in icDeserializer || idSig in delegate
    }

    override fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
        dirtyDeclarations[idSig]?.let { return it }

        if (idSig.topLevelSignature() in icDeserializer) return icDeserializer.deserializeIrSymbol(idSig, symbolKind)

        return delegate.deserializeIrSymbol(idSig, symbolKind)
    }

    override fun addModuleReachableTopLevel(idSig: IdSignature) {
        assert(idSig in icDeserializer)
        icDeserializer.addModuleReachableTopLevel(idSig)
    }

    override fun deserializeReachableDeclarations() {
        icDeserializer.deserializeReachableDeclarations()
    }

    private fun DeclarationDescriptor.isDirtyDescriptor(): Boolean {
        if (this is PropertyAccessorDescriptor) return correspondingProperty.isDirtyDescriptor()
        // Since descriptors for FO methods of `kotlin.Any` (toString, equals, hashCode) are Deserialized even in
        // dirty files make test more precise checking containing declaration for non-static members
        if (this is CallableMemberDescriptor && dispatchReceiverParameter != null) {
            return containingDeclaration.isDirtyDescriptor()
        }
        return this !is DeserializedDescriptor
    }

    override fun init(delegate: IrModuleDeserializer) {
        val knownBuiltIns = irBuiltIns.knownBuiltins.map { (it as IrSymbolOwner).symbol }.toSet()
        symbolTable.forEachPublicSymbol {
            if (it.descriptor.isDirtyDescriptor()) { // public && non-deserialized should be dirty symbol
                if (it !in knownBuiltIns) {
                    dirtyDeclarations[it.signature] = it
                }
            }
        }

        icDeserializer.init(delegate)
    }

    override val klib: IrLibrary
        get() = icDeserializer.klib

    override val moduleFragment: IrModuleFragment
        get() = delegate.moduleFragment
    override val moduleDependencies: Collection
        get() = delegate.moduleDependencies
    override val isCurrent: Boolean
        get() = delegate.isCurrent
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy