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

org.jetbrains.kotlin.psi2ir.generators.ExpectDependencyGenerator.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.psi2ir.generators

import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.resolve.multiplatform.findExpects

// Need to create unbound symbols for expects corresponding to actuals of the currently compiled module.
// This is necessary because there are no explicit links between expects and actuals
// neither in descriptors nor in IR.
internal fun referenceExpectsForUsedActuals(
    expectDescriptorToSymbol: MutableMap,
    symbolTable: SymbolTable,
    element: IrElement,
) {
    element.acceptVoid(ExpectDependencyGenerator(expectDescriptorToSymbol, symbolTable))
}

private class ExpectDependencyGenerator(
    private val expectDescriptorToSymbol: MutableMap,
    private val symbolTable: SymbolTable,
) : IrElementVisitorVoid {
    private fun  T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T : IrDeclaration {
        this.descriptor.findExpects().forEach {
            body(it)
        }
    }

    override fun visitElement(element: IrElement) {
        element.acceptChildrenVoid(this)
    }

    override fun visitClass(declaration: IrClass) {
        declaration.forEachExpect { expectDescriptor ->
            val symbol = symbolTable.referenceClass(expectDescriptor as ClassDescriptor)
            expectDescriptorToSymbol[expectDescriptor] = symbol
            expectDescriptor.constructors.forEach {
                expectDescriptorToSymbol[it] = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
            }
        }
        super.visitDeclaration(declaration)
    }

    override fun visitSimpleFunction(declaration: IrSimpleFunction) {
        declaration.forEachExpect {
            val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor)
            expectDescriptorToSymbol[it] = symbol
        }
        super.visitDeclaration(declaration)
    }

    override fun visitConstructor(declaration: IrConstructor) {
        declaration.forEachExpect {
            val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor)
            expectDescriptorToSymbol[it] = symbol

        }
        super.visitDeclaration(declaration)
    }

    override fun visitProperty(declaration: IrProperty) {
        declaration.forEachExpect {
            val symbol = symbolTable.referenceProperty(it as PropertyDescriptor)
            expectDescriptorToSymbol[it] = symbol
        }
        super.visitDeclaration(declaration)
    }

    override fun visitEnumEntry(declaration: IrEnumEntry) {
        declaration.forEachExpect {
            val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor)
            expectDescriptorToSymbol[it] = symbol

        }
        super.visitDeclaration(declaration)
    }

    override fun visitTypeAlias(declaration: IrTypeAlias) {
        declaration.forEachExpect {
            val symbol = when (it) {
                is ClassDescriptor -> symbolTable.referenceClass(it)
                else -> error("Unexpected expect for actual type alias: $it")
            }
            expectDescriptorToSymbol[it] = symbol

        }
        super.visitDeclaration(declaration)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy