org.jetbrains.kotlin.sir.providers.impl.PackageFlatteningSirDeclarationProvider.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sir-providers Show documentation
Show all versions of sir-providers Show documentation
SIR Providers - family of classes, that transforms KaSymbol into corresponding SIR nodes
The newest version!
/*
* Copyright 2010-2024 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.sir.providers.impl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.sir.*
import org.jetbrains.kotlin.sir.builder.buildTypealias
import org.jetbrains.kotlin.sir.providers.SirEnumGenerator
import org.jetbrains.kotlin.sir.providers.SirSession
import org.jetbrains.kotlin.sir.providers.SirTrampolineDeclarationsProvider
import org.jetbrains.kotlin.sir.providers.impl.nodes.SirTrampolineFunction
import org.jetbrains.kotlin.sir.providers.impl.nodes.SirTrampolineVariable
public class SirTrampolineDeclarationsProviderImpl(
private val sirSession: SirSession,
private val targetPackageFqName: FqName?,
) : SirTrampolineDeclarationsProvider {
private val generatedDeclarations: MutableMap> = mutableMapOf()
override fun SirDeclaration.trampolineDeclarations(): List = generateDeclarations(this)
private fun generateDeclarations(declaration: SirDeclaration): List = generatedDeclarations.getOrPut(declaration) {
if (targetPackageFqName == null)
return emptyList()
with(sirSession) {
val targetEnum = if (declaration is SirEnum && declaration.isNamespace(targetPackageFqName)) {
declaration // avoid recursion
} else {
with(enumGenerator) { targetPackageFqName.sirPackageEnum() }
}
val shouldExportToRoot = when (val parent = declaration.parent) {
is SirEnum -> parent == targetEnum
is SirExtension -> parent.extendedType == SirNominalType(targetEnum)
else -> false
}
return listOfNotNull(declaration.takeIf { shouldExportToRoot }?.trampolineDeclaration())
}
}
private fun SirDeclaration.containingModule(): SirModule = when (val parent = parent) {
is SirModule -> parent
is SirDeclaration -> parent.containingModule()
}
private fun SirDeclaration.trampolineDeclaration(): SirDeclaration? = when (val declaration = this@trampolineDeclaration) {
is SirNamedDeclaration -> {
buildTypealias {
origin = SirOrigin.Trampoline(declaration)
visibility = declaration.visibility
documentation = declaration.documentation
name = declaration.name
type = SirNominalType(declaration)
}
}
is SirFunction -> SirTrampolineFunction(declaration)
is SirVariable -> SirTrampolineVariable(declaration)
else -> null
}?.also { it.parent = this.containingModule() }
}
private fun SirEnum.isNamespace(fqName: FqName): Boolean = (this.origin as? SirOrigin.Namespace)?.path?.let {
val path = fqName.pathSegments()
it.size == path.size && (it zip path).all { it.first == it.second.toString() }
} ?: false