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

org.jetbrains.dokka.analysis.DRIFactory.kt Maven / Gradle / Ivy

Go to download

Dokka is an API documentation engine for Kotlin and Java, performing the same function as Javadoc for Java

There is a newer version: 1.8.20
Show newest version
package org.jetbrains.dokka.analysis

import com.intellij.psi.*
import org.jetbrains.dokka.links.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs

fun DRI.Companion.from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run {
    val parameter = firstIsInstanceOrNull()
    val callable = parameter?.containingDeclaration ?: firstIsInstanceOrNull()

    DRI(
        packageName = firstIsInstanceOrNull()?.fqName?.asString() ?: "",
        classNames = (filterIsInstance() + filterIsInstance()).toList()
            .takeIf { it.isNotEmpty() }
            ?.asReversed()
            ?.joinToString(separator = ".") { it.name.asString() },
        callable = callable?.let { Callable.from(it) },
        target = DriTarget.from(parameter ?: descriptor),
        extra = if (descriptor is EnumEntrySyntheticClassDescriptor || descriptor.safeAs()?.kind == ClassKind.ENUM_ENTRY)
            DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode()
        else null
    )
}

fun DRI.Companion.from(psi: PsiElement) = psi.parentsWithSelf.run {
    val psiMethod = firstIsInstanceOrNull()
    val psiField = firstIsInstanceOrNull()
    val classes = filterIsInstance().filterNot { it is PsiTypeParameter }
        .toList() // We only want exact PsiClass types, not PsiTypeParameter subtype
    val additionalClasses = if (psi is PsiEnumConstant) listOfNotNull(psiField?.name) else emptyList()
    DRI(
        packageName = classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', "") ?: "",
        classNames = (additionalClasses + classes.mapNotNull { it.name }).takeIf { it.isNotEmpty() }
            ?.asReversed()?.joinToString("."),
        // The fallback strategy test whether psi is not `PsiEnumConstant`. The reason behind this is that
        // we need unified DRI for both Java and Kotlin enums, so we can link them properly and treat them alike.
        // To achieve that, we append enum name to classNames list and leave the callable part set to null. For Kotlin enums
        // it is by default, while for Java enums we have to explicitly test for that in this `takeUnless` condition.
        callable = psiMethod?.let { Callable.from(it) } ?: psiField?.takeUnless { psi is PsiEnumConstant }?.let { Callable.from(it) },
        target = DriTarget.from(psi),
        extra = if (psi is PsiEnumConstant)
            DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode()
        else null
    )
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy