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

org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer.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.fir.signaturer

import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.Fir2IrSignatureComposer
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.ir.util.IdSignature

@NoMutableState
class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatureComposer {
    inner class SignatureBuilder : FirVisitorVoid() {
        var hashId: Long? = null
        var mask = 0L

        private fun setExpected(f: Boolean) {
            mask = mask or IdSignature.Flags.IS_EXPECT.encode(f)
        }

        override fun visitElement(element: FirElement) {
            TODO("Should not be here")
        }

        override fun visitRegularClass(regularClass: FirRegularClass) {
            setExpected(regularClass.isExpect)
            //platformSpecificClass(descriptor)
        }

        override fun visitTypeAlias(typeAlias: FirTypeAlias) {
            setExpected(typeAlias.isExpect)
        }

        override fun visitConstructor(constructor: FirConstructor) {
            hashId = mangler.run { constructor.signatureMangle }
            setExpected(constructor.isExpect)
        }

        override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
            hashId = mangler.run { simpleFunction.signatureMangle }
            setExpected(simpleFunction.isExpect)
        }

        override fun visitProperty(property: FirProperty) {
            hashId = mangler.run { property.signatureMangle }
            setExpected(property.isExpect)
        }

        override fun visitEnumEntry(enumEntry: FirEnumEntry) {
            setExpected(enumEntry.isExpect)
        }
    }

    override fun composeSignature(declaration: FirDeclaration, containingClass: ConeClassLikeLookupTag?): IdSignature? {
        if (declaration is FirAnonymousObject || declaration is FirAnonymousFunction) return null
        if (declaration is FirRegularClass && declaration.classId.isLocal) return null
        if (declaration is FirCallableMemberDeclaration<*>) {
            if (declaration.visibility == Visibilities.Local) return null
            if (declaration.symbol.dispatchReceiverClassOrNull()?.classId?.isLocal == true || containingClass?.classId?.isLocal == true) return null
        }
        val builder = SignatureBuilder()
        try {
            declaration.accept(builder)
        } catch (t: Throwable) {
            throw IllegalStateException("Error while composing signature for ${declaration.render()}", t)
        }
        return when (declaration) {
            is FirRegularClass -> {
                // TODO: private classes are probably not acceptable here too
                val classId = declaration.classId
                IdSignature.PublicSignature(
                    classId.packageFqName.asString(), classId.relativeClassName.asString(), builder.hashId, builder.mask
                )
            }
            is FirTypeAlias -> {
                if (declaration.visibility == Visibilities.Private) return null
                val classId = declaration.symbol.classId
                IdSignature.PublicSignature(
                    classId.packageFqName.asString(), classId.relativeClassName.asString(), builder.hashId, builder.mask
                )
            }
            is FirCallableMemberDeclaration<*> -> {
                if (declaration.visibility == Visibilities.Private) return null
                val containingClassId = containingClass?.classId

                val classId = containingClassId ?: declaration.containingClass()?.classId
                val packageName = classId?.packageFqName ?: declaration.symbol.callableId.packageName
                val callableName = declaration.symbol.callableId.callableName

                IdSignature.PublicSignature(
                    packageName.asString(),
                    classId?.relativeClassName?.child(callableName)?.asString() ?: callableName.asString(),
                    builder.hashId, builder.mask
                )
            }
            else -> error("Unsupported FIR declaration in signature composer: ${declaration.render()}")
        }
    }

    override fun composeAccessorSignature(
        property: FirProperty,
        isSetter: Boolean,
        containingClass: ConeClassLikeLookupTag?
    ): IdSignature? {
        val propertySignature = composeSignature(property, containingClass) as? IdSignature.PublicSignature ?: return null
        val accessorFqName = if (isSetter) {
            propertySignature.declarationFqName + "."
        } else {
            propertySignature.declarationFqName + "."
        }
        return IdSignature.PublicSignature(propertySignature.packageFqName, accessorFqName, propertySignature.id, propertySignature.mask)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy