diff options
author | Ignat Beresnev <ignat.beresnev@jetbrains.com> | 2023-11-10 11:46:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-10 11:46:54 +0100 |
commit | 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 (patch) | |
tree | 1b915207b2b9f61951ddbf0ff2e687efd053d555 /subprojects/analysis-kotlin-symbols/src/main/kotlin/org | |
parent | a44efd4ba0c2e4ab921ff75e0f53fc9335aa79db (diff) | |
download | dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.gz dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.tar.bz2 dokka-8e5c63d035ef44a269b8c43430f43f5c8eebfb63.zip |
Restructure the project to utilize included builds (#3174)
* Refactor and simplify artifact publishing
* Update Gradle to 8.4
* Refactor and simplify convention plugins and build scripts
Fixes #3132
---------
Co-authored-by: Adam <897017+aSemy@users.noreply.github.com>
Co-authored-by: Oleg Yukhnevich <whyoleg@gmail.com>
Diffstat (limited to 'subprojects/analysis-kotlin-symbols/src/main/kotlin/org')
37 files changed, 0 insertions, 3408 deletions
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt deleted file mode 100644 index d8a4e476..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc - -import com.intellij.psi.PsiNamedElement -import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.dokka.analysis.java.parsers.JavadocParser -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.api.KDoc -import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.getChildOfType -import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType -import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter -import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly - -internal fun KtAnalysisSession.getJavaDocDocumentationFrom( - symbol: KtSymbol, - javadocParser: JavadocParser -): DocumentationNode? { - if (symbol.origin == KtSymbolOrigin.JAVA) { - return (symbol.psi as? PsiNamedElement)?.let { - javadocParser.parseDocumentation(it) - } - } else if (symbol.origin == KtSymbolOrigin.SOURCE && symbol is KtCallableSymbol) { - // Note: javadocParser searches in overridden JAVA declarations for JAVA method, not Kotlin - symbol.getAllOverriddenSymbols().forEach { overrider -> - if (overrider.origin == KtSymbolOrigin.JAVA) - return@getJavaDocDocumentationFrom (overrider.psi as? PsiNamedElement)?.let { - javadocParser.parseDocumentation(it) - } - } - } - return null -} - -internal fun KtAnalysisSession.getKDocDocumentationFrom(symbol: KtSymbol, logger: DokkaLogger) = findKDoc(symbol)?.let { kDocContent -> - - val ktElement = symbol.psi - val kdocLocation = ktElement?.containingFile?.name?.let { - val name = when(symbol) { - is KtCallableSymbol -> symbol.callableIdIfNonLocal?.toString() - is KtClassOrObjectSymbol -> symbol.classIdIfNonLocal?.toString() - is KtNamedSymbol -> symbol.name.asString() - else -> null - }?.replace('/', '.') // replace to be compatible with K1 - - if (name != null) "$it/$name" - else it - } - - - parseFromKDocTag( - kDocTag = kDocContent.contentTag, - externalDri = { link -> resolveKDocLink(link).ifUnresolved { logger.logUnresolvedLink(link.getLinkText(), kdocLocation) } }, - kdocLocation = kdocLocation - ) -} - - - - -// ----------- copy-paste from IDE ---------------------------------------------------------------------------- - -internal data class KDocContent( - val contentTag: KDocTag, - val sections: List<KDocSection> -) - -internal fun KtAnalysisSession.findKDoc(symbol: KtSymbol): KDocContent? { - // for generated function (e.g. `copy`) psi returns class, see test `data class kdocs over generated methods` - if (symbol.origin != KtSymbolOrigin.SOURCE) return null - val ktElement = symbol.psi as? KtElement - ktElement?.findKDoc()?.let { - return it - } - - if (symbol is KtCallableSymbol) { - symbol.getAllOverriddenSymbols().forEach { overrider -> - findKDoc(overrider)?.let { - return it - } - } - } - return null -} - - -internal fun KtElement.findKDoc(): KDocContent? = this.lookupOwnedKDoc() - ?: this.lookupKDocInContainer() - - - -private fun KtElement.lookupOwnedKDoc(): KDocContent? { - // KDoc for primary constructor is located inside of its class KDoc - val psiDeclaration = when (this) { - is KtPrimaryConstructor -> getContainingClassOrObject() - else -> this - } - - if (psiDeclaration is KtDeclaration) { - val kdoc = psiDeclaration.docComment - if (kdoc != null) { - if (this is KtConstructor<*>) { - // ConstructorDescriptor resolves to the same JetDeclaration - val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR) - if (constructorSection != null) { - // if annotated with @constructor tag and the caret is on constructor definition, - // then show @constructor description as the main content, and additional sections - // that contain @param tags (if any), as the most relatable ones - // practical example: val foo = Fo<caret>o("argument") -- show @constructor and @param content - val paramSections = kdoc.findSectionsContainingTag(KDocKnownTag.PARAM) - return KDocContent(constructorSection, paramSections) - } - } - return KDocContent(kdoc.getDefaultSection(), kdoc.getAllSections()) - } - } - - return null -} - -/** - * Looks for sections that have a deeply nested [tag], - * as opposed to [KDoc.findSectionByTag], which only looks among the top level - */ -private fun KDoc.findSectionsContainingTag(tag: KDocKnownTag): List<KDocSection> { - return getChildrenOfType<KDocSection>() - .filter { it.findTagByName(tag.name.toLowerCaseAsciiOnly()) != null } -} - -private fun KtElement.lookupKDocInContainer(): KDocContent? { - val subjectName = name - val containingDeclaration = - PsiTreeUtil.findFirstParent(this, true) { - it is KtDeclarationWithBody && it !is KtPrimaryConstructor - || it is KtClassOrObject - } - - val containerKDoc = containingDeclaration?.getChildOfType<KDoc>() - if (containerKDoc == null || subjectName == null) return null - val propertySection = containerKDoc.findSectionByTag(KDocKnownTag.PROPERTY, subjectName) - val paramTag = - containerKDoc.findDescendantOfType<KDocTag> { it.knownTag == KDocKnownTag.PARAM && it.getSubjectName() == subjectName } - - val primaryContent = when { - // class Foo(val <caret>s: String) - this is KtParameter && this.isPropertyParameter() -> propertySection ?: paramTag - // fun some(<caret>f: String) || class Some<<caret>T: Base> || Foo(<caret>s = "argument") - this is KtParameter || this is KtTypeParameter -> paramTag - // if this property is declared separately (outside primary constructor), but it's for some reason - // annotated as @property in class's description, instead of having its own KDoc - this is KtProperty && containingDeclaration is KtClassOrObject -> propertySection - else -> null - } - return primaryContent?.let { - // makes little sense to include any other sections, since we found - // documentation for a very specific element, like a property/param - KDocContent(it, sections = emptyList()) - } -} - diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KdocMarkdownParser.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KdocMarkdownParser.kt deleted file mode 100644 index ad29f5f0..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KdocMarkdownParser.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser.Companion.fqDeclarationName -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.doc.Suppress -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink -import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.psiUtil.allChildren - -internal fun parseFromKDocTag( - kDocTag: KDocTag?, - externalDri: (KDocLink) -> DRI?, - kdocLocation: String?, - parseWithChildren: Boolean = true -): DocumentationNode { - return if (kDocTag == null) { - DocumentationNode(emptyList()) - } else { - fun parseStringToDocNode(text: String, externalDRIProvider: (String) -> DRI?) = - MarkdownParser(externalDRIProvider, kdocLocation).parseStringToDocNode(text) - - fun pointedLink(tag: KDocTag): DRI? = tag.getSubjectLink()?.let(externalDri) - - val allTags = - listOf(kDocTag) + if (kDocTag.canHaveParent() && parseWithChildren) getAllKDocTags(findParent(kDocTag)) else emptyList() - DocumentationNode( - allTags.map { tag -> - val links = tag.allChildren.filterIsInstance<KDocLink>().associate { it.getLinkText() to externalDri(it) } - val externalDRIProvider = { linkText: String -> links[linkText] } - - when (tag.knownTag) { - null -> if (tag.name == null) Description(parseStringToDocNode(tag.getContent(), externalDRIProvider)) else CustomTagWrapper( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - tag.name!! - ) - KDocKnownTag.AUTHOR -> Author(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - KDocKnownTag.THROWS -> { - val dri = pointedLink(tag) - Throws( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - dri?.fqDeclarationName() ?: tag.getSubjectName().orEmpty(), - dri, - ) - } - KDocKnownTag.EXCEPTION -> { - val dri = pointedLink(tag) - Throws( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - dri?.fqDeclarationName() ?: tag.getSubjectName().orEmpty(), - dri - ) - } - KDocKnownTag.PARAM -> Param( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - tag.getSubjectName().orEmpty() - ) - KDocKnownTag.RECEIVER -> Receiver(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - KDocKnownTag.RETURN -> Return(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - KDocKnownTag.SEE -> { - val dri = pointedLink(tag) - See( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - dri?.fqDeclarationName() ?: tag.getSubjectName().orEmpty(), - dri, - ) - } - KDocKnownTag.SINCE -> Since(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - KDocKnownTag.CONSTRUCTOR -> Constructor(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - KDocKnownTag.PROPERTY -> Property( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - tag.getSubjectName().orEmpty() - ) - KDocKnownTag.SAMPLE -> Sample( - parseStringToDocNode(tag.getContent(), externalDRIProvider), - tag.getSubjectName().orEmpty() - ) - KDocKnownTag.SUPPRESS -> Suppress(parseStringToDocNode(tag.getContent(), externalDRIProvider)) - } - } - ) - } -} - -private fun findParent(kDoc: PsiElement): PsiElement = - if (kDoc.canHaveParent()) findParent(kDoc.parent) else kDoc - -private fun PsiElement.canHaveParent(): Boolean = this is KDocSection && knownTag != KDocKnownTag.PROPERTY - -private fun getAllKDocTags(kDocImpl: PsiElement): List<KDocTag> = - kDocImpl.children.filterIsInstance<KDocTag>().filterNot { it is KDocSection } + kDocImpl.children.flatMap { - getAllKDocTags(it) - } diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/ResolveKDocLink.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/ResolveKDocLink.kt deleted file mode 100644 index 9a0b81bd..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/ResolveKDocLink.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getDRIFromSymbol -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.kdoc.psi.api.KDoc -import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink -import org.jetbrains.kotlin.kdoc.psi.impl.KDocName -import org.jetbrains.kotlin.psi.KtPsiFactory - -/** - * Util to print a message about unresolved [link] - */ -internal fun DokkaLogger.logUnresolvedLink(link: String, location: String?) { - warn("Couldn't resolve link for $link" + if (location != null) " in $location" else "") -} - -internal inline fun DRI?.ifUnresolved(action: () -> Unit): DRI? = this ?: run { - action() - null -} - -/** - * Resolves KDoc link via creating PSI. - * If the [link] is ambiguous, i.e. leads to more than one declaration, - * it returns deterministically any declaration. - * - * @return [DRI] or null if the [link] is unresolved - */ -internal fun KtAnalysisSession.resolveKDocTextLink(link: String, context: PsiElement? = null): DRI? { - val psiFactory = context?.let { KtPsiFactory.contextual(it) } ?: KtPsiFactory(this.useSiteModule.project) - val kDoc = psiFactory.createComment( - """ - /** - * [$link] - */ - """.trimIndent() - ) as? KDoc - val kDocLink = kDoc?.getDefaultSection()?.children?.filterIsInstance<KDocLink>()?.singleOrNull() - return kDocLink?.let { resolveKDocLink(it) } -} - -/** - * If the [link] is ambiguous, i.e. leads to more than one declaration, - * it returns deterministically any declaration. - * - * @return [DRI] or null if the [link] is unresolved - */ -internal fun KtAnalysisSession.resolveKDocLink(link: KDocLink): DRI? { - val lastNameSegment = link.children.filterIsInstance<KDocName>().lastOrNull() - val linkedSymbol = lastNameSegment?.mainReference?.resolveToSymbols()?.firstOrNull() - return if (linkedSymbol == null) null - else getDRIFromSymbol(linkedSymbol) -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/SyntheticKDocProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/SyntheticKDocProvider.kt deleted file mode 100644 index 4622ffd8..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/SyntheticKDocProvider.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc - -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol -import org.jetbrains.kotlin.builtins.StandardNames - -private const val ENUM_ENTRIES_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumEntries.kt.template" -private const val ENUM_VALUEOF_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumValueOf.kt.template" -private const val ENUM_VALUES_TEMPLATE_PATH = "/dokka/docs/kdoc/EnumValues.kt.template" - -internal fun KtAnalysisSession.hasGeneratedKDocDocumentation(symbol: KtSymbol): Boolean = - getDocumentationTemplatePath(symbol) != null - -private fun KtAnalysisSession.getDocumentationTemplatePath(symbol: KtSymbol): String? = - when (symbol) { - is KtPropertySymbol -> if (isEnumEntriesProperty(symbol)) ENUM_ENTRIES_TEMPLATE_PATH else null - is KtFunctionSymbol -> { - when { - isEnumValuesMethod(symbol) -> ENUM_VALUES_TEMPLATE_PATH - isEnumValueOfMethod(symbol) -> ENUM_VALUEOF_TEMPLATE_PATH - else -> null - } - } - - else -> null - } - -private fun KtAnalysisSession.isEnumSpecialMember(symbol: KtPossibleMemberSymbol): Boolean = - symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED - && (symbol.getContainingSymbol() as? KtClassOrObjectSymbol)?.classKind == KtClassKind.ENUM_CLASS - -private fun KtAnalysisSession.isEnumEntriesProperty(symbol: KtPropertySymbol): Boolean = - symbol.name == StandardNames.ENUM_ENTRIES && isEnumSpecialMember(symbol) - -private fun KtAnalysisSession.isEnumValuesMethod(symbol: KtFunctionSymbol): Boolean = - symbol.name == StandardNames.ENUM_VALUES && isEnumSpecialMember(symbol) - -private fun KtAnalysisSession.isEnumValueOfMethod(symbol: KtFunctionSymbol): Boolean = - symbol.name == StandardNames.ENUM_VALUE_OF && isEnumSpecialMember(symbol) - -internal fun KtAnalysisSession.getGeneratedKDocDocumentationFrom(symbol: KtSymbol): DocumentationNode? { - val templatePath = getDocumentationTemplatePath(symbol) ?: return null - return loadTemplate(templatePath) -} - -private fun KtAnalysisSession.loadTemplate(filePath: String): DocumentationNode? { - val kdoc = loadContent(filePath) ?: return null - val externalDriProvider = { link: String -> - resolveKDocTextLink(link) - } - - val parser = MarkdownParser(externalDriProvider, filePath) - return parser.parse(kdoc) -} - -private fun loadContent(filePath: String): String? = - SymbolsAnalysisPlugin::class.java.getResource(filePath)?.readText() diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorDocumentationContent.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorDocumentationContent.kt deleted file mode 100644 index 4db17b28..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorDocumentationContent.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java - -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.dokka.analysis.java.JavadocTag -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag - -internal data class DescriptorDocumentationContent( - val resolveDocContext: ResolveDocContext, - val element: KDocTag, - override val tag: JavadocTag, -) : DocumentationContent { - override fun resolveSiblings(): List<DocumentationContent> { - return listOf(this) - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorKotlinDocCommentCreator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorKotlinDocCommentCreator.kt deleted file mode 100644 index 7a43972c..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/DescriptorKotlinDocCommentCreator.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java - -import com.intellij.psi.PsiNamedElement -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.doccomment.DocCommentCreator -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.findKDoc -import org.jetbrains.kotlin.psi.KtElement - -internal class DescriptorKotlinDocCommentCreator : DocCommentCreator { - override fun create(element: PsiNamedElement): DocComment? { - val ktElement = element.navigationElement as? KtElement ?: return null - val kdoc = ktElement.findKDoc() ?: return null - - return KotlinDocComment(kdoc.contentTag, ResolveDocContext(ktElement)) - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocComment.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocComment.kt deleted file mode 100644 index 63c55869..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocComment.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java - -import org.jetbrains.dokka.analysis.java.* -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.psi.KtElement - -internal class ResolveDocContext(val ktElement: KtElement) - -internal class KotlinDocComment( - val comment: KDocTag, - val resolveDocContext: ResolveDocContext -) : DocComment { - - private val tagsWithContent: List<KDocTag> = comment.children.mapNotNull { (it as? KDocTag) } - - override fun hasTag(tag: JavadocTag): Boolean { - return when (tag) { - is DescriptionJavadocTag -> comment.getContent().isNotEmpty() - is ThrowingExceptionJavadocTag -> tagsWithContent.any { it.hasException(tag) } - else -> tagsWithContent.any { it.text.startsWith("@${tag.name}") } - } - } - - private fun KDocTag.hasException(tag: ThrowingExceptionJavadocTag) = - text.startsWith("@${tag.name}") && getSubjectName() == tag.exceptionQualifiedName - - override fun resolveTag(tag: JavadocTag): List<DocumentationContent> { - return when (tag) { - is DescriptionJavadocTag -> listOf(DescriptorDocumentationContent(resolveDocContext, comment, tag)) - is ParamJavadocTag -> { - val resolvedContent = resolveGeneric(tag) - listOf(resolvedContent[tag.paramIndex]) - } - - is ThrowsJavadocTag -> resolveThrowingException(tag) - is ExceptionJavadocTag -> resolveThrowingException(tag) - else -> resolveGeneric(tag) - } - } - - private fun resolveThrowingException(tag: ThrowingExceptionJavadocTag): List<DescriptorDocumentationContent> { - val exceptionName = tag.exceptionQualifiedName ?: return resolveGeneric(tag) - - return comment.children - .filterIsInstance<KDocTag>() - .filter { it.name == tag.name && it.getSubjectName() == exceptionName } - .map { DescriptorDocumentationContent(resolveDocContext, it, tag) } - } - - private fun resolveGeneric(tag: JavadocTag): List<DescriptorDocumentationContent> { - return comment.children.mapNotNull { element -> - if (element is KDocTag && element.name == tag.name) { - DescriptorDocumentationContent(resolveDocContext, element, tag) - } else { - null - } - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as KotlinDocComment - - if (comment != other.comment) return false - //if (resolveDocContext.name != other.resolveDocContext.name) return false - if (tagsWithContent != other.tagsWithContent) return false - - return true - } - - override fun hashCode(): Int { - var result = comment.hashCode() - // result = 31 * result + resolveDocContext.name.hashCode() - result = 31 * result + tagsWithContent.hashCode() - return result - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocCommentParser.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocCommentParser.kt deleted file mode 100644 index 0ee95e45..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinDocCommentParser.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java - -import com.intellij.psi.PsiNamedElement -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.java.doccomment.DocComment -import org.jetbrains.dokka.analysis.java.parsers.DocCommentParser -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.* -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.logUnresolvedLink -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.parseFromKDocTag -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocLink -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.kotlin.analysis.api.analyze - -internal class KotlinDocCommentParser( - private val context: DokkaContext -) : DocCommentParser { - - override fun canParse(docComment: DocComment): Boolean { - return docComment is KotlinDocComment - } - - override fun parse(docComment: DocComment, context: PsiNamedElement): DocumentationNode { - val kotlinDocComment = docComment as KotlinDocComment - return parseDocumentation(kotlinDocComment) - } - - fun parseDocumentation(element: KotlinDocComment, parseWithChildren: Boolean = true): DocumentationNode { - val sourceSet = context.configuration.sourceSets.let { sourceSets -> - sourceSets.firstOrNull { it.sourceSetID.sourceSetName == "jvmMain" } - ?: sourceSets.first { it.analysisPlatform == Platform.jvm } - } - val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - val elementName = element.resolveDocContext.ktElement.name - return analyze(kotlinAnalysis.getModule(sourceSet)) { - parseFromKDocTag( - kDocTag = element.comment, - externalDri = { link -> resolveKDocLink(link).ifUnresolved { context.logger.logUnresolvedLink(link.getLinkText(), elementName) } }, - kdocLocation = null, - parseWithChildren = parseWithChildren - ) - } - } -} - diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinInheritDocTagContentProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinInheritDocTagContentProvider.kt deleted file mode 100644 index 4c2b7afd..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/java/KotlinInheritDocTagContentProvider.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java - -import org.jetbrains.dokka.analysis.java.doccomment.DocumentationContent -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.java.parsers.doctag.DocTagParserContext -import org.jetbrains.dokka.analysis.java.parsers.doctag.InheritDocTagContentProvider -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query - -internal class KotlinInheritDocTagContentProvider( - context: DokkaContext -) : InheritDocTagContentProvider { - - val parser: KotlinDocCommentParser by lazy { - context.plugin<JavaAnalysisPlugin>().query { docCommentParsers } - .single { it is KotlinDocCommentParser } as KotlinDocCommentParser - } - - override fun canConvert(content: DocumentationContent): Boolean = content is DescriptorDocumentationContent - - override fun convertToHtml(content: DocumentationContent, docTagParserContext: DocTagParserContext): String { - val descriptorContent = content as DescriptorDocumentationContent - val inheritedDocNode = parser.parseDocumentation( - KotlinDocComment(descriptorContent.element, descriptorContent.resolveDocContext), - parseWithChildren = false - ) - val id = docTagParserContext.store(inheritedDocNode) - return """<inheritdoc id="$id"/>""" - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/IllegalModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/IllegalModuleAndPackageDocumentation.kt deleted file mode 100644 index a090e4d5..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/IllegalModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import org.jetbrains.dokka.DokkaException - -internal class IllegalModuleAndPackageDocumentation( - source: ModuleAndPackageDocumentationSource, message: String -) : DokkaException("[$source] $message") diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentation.kt deleted file mode 100644 index 4036d3d0..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import org.jetbrains.dokka.model.doc.DocumentationNode - -internal data class ModuleAndPackageDocumentation( - val name: String, - val classifier: Classifier, - val documentation: DocumentationNode -) { - enum class Classifier { Module, Package } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationFragment.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationFragment.kt deleted file mode 100644 index be7c915c..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationFragment.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - - -internal data class ModuleAndPackageDocumentationFragment( - val name: String, - val classifier: ModuleAndPackageDocumentation.Classifier, - val documentation: String, - val source: ModuleAndPackageDocumentationSource -) diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationParsingContext.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationParsingContext.kt deleted file mode 100644 index f5cfbdb9..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationParsingContext.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.ifUnresolved -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.logUnresolvedLink -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.KotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Package -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.resolveKDocTextLink -import org.jetbrains.dokka.analysis.markdown.jb.MarkdownParser -import org.jetbrains.dokka.model.doc.DocumentationNode -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.name.FqName - -internal fun interface ModuleAndPackageDocumentationParsingContext { - fun markdownParserFor(fragment: ModuleAndPackageDocumentationFragment, location: String): MarkdownParser -} - -internal fun ModuleAndPackageDocumentationParsingContext.parse( - fragment: ModuleAndPackageDocumentationFragment -): DocumentationNode { - return markdownParserFor(fragment, fragment.source.sourceDescription).parse(fragment.documentation) -} - -internal fun ModuleAndPackageDocumentationParsingContext( - logger: DokkaLogger, - kotlinAnalysis: KotlinAnalysis? = null, - sourceSet: DokkaConfiguration.DokkaSourceSet? = null -) = ModuleAndPackageDocumentationParsingContext { fragment, sourceLocation -> - - if (kotlinAnalysis == null || sourceSet == null) { - MarkdownParser(externalDri = { null }, sourceLocation) - } else { - val sourceModule = kotlinAnalysis.getModule(sourceSet) - val contextPsi = analyze(sourceModule) { - val contextSymbol = when (fragment.classifier) { - Module -> ROOT_PACKAGE_SYMBOL - Package -> getPackageSymbolIfPackageExists(FqName(fragment.name)) - } - contextSymbol?.psi - } - MarkdownParser( - externalDri = { link -> - analyze(sourceModule) { - resolveKDocTextLink( - link, - contextPsi - ).ifUnresolved { - logger.logUnresolvedLink(link, fragment.name.ifBlank { "module documentation" }) - } - - } - }, - sourceLocation - ) - - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationReader.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationReader.kt deleted file mode 100644 index ef79e885..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationReader.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.model.DModule -import org.jetbrains.dokka.model.DPackage -import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.doc.Deprecated -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.utilities.associateWithNotNull -import org.jetbrains.dokka.analysis.kotlin.internal.ModuleAndPackageDocumentationReader - -internal fun ModuleAndPackageDocumentationReader(context: DokkaContext): ModuleAndPackageDocumentationReader = - ContextModuleAndPackageDocumentationReader(context) - -private class ContextModuleAndPackageDocumentationReader( - private val context: DokkaContext -) : ModuleAndPackageDocumentationReader { - - private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - - private val documentationFragments: SourceSetDependent<List<ModuleAndPackageDocumentationFragment>> = - context.configuration.sourceSets.associateWith { sourceSet -> - sourceSet.includes.flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } - } - - private fun findDocumentationNodes( - sourceSets: Set<DokkaConfiguration.DokkaSourceSet>, - predicate: (ModuleAndPackageDocumentationFragment) -> Boolean - ): SourceSetDependent<DocumentationNode> { - return sourceSets.associateWithNotNull { sourceSet -> - val fragments = documentationFragments[sourceSet].orEmpty().filter(predicate) - kotlinAnalysis.getModule(sourceSet)// test: to throw exception for unknown sourceSet - val documentations = fragments.map { fragment -> - parseModuleAndPackageDocumentation( - context = ModuleAndPackageDocumentationParsingContext(context.logger, kotlinAnalysis, sourceSet), - fragment = fragment - ) - } - when (documentations.size) { - 0 -> null - 1 -> documentations.single().documentation - else -> DocumentationNode(documentations.flatMap { it.documentation.children } - .mergeDocumentationNodes()) - } - } - } - - private val ModuleAndPackageDocumentationFragment.canonicalPackageName: String - get() { - check(classifier == Classifier.Package) - if (name == "[root]") return "" - return name - } - - override fun read(module: DModule): SourceSetDependent<DocumentationNode> { - return findDocumentationNodes(module.sourceSets) { fragment -> - fragment.classifier == Classifier.Module && (fragment.name == module.name) - } - } - - override fun read(pkg: DPackage): SourceSetDependent<DocumentationNode> { - return findDocumentationNodes(pkg.sourceSets) { fragment -> - fragment.classifier == Classifier.Package && fragment.canonicalPackageName == pkg.dri.packageName - } - } - - override fun read(module: DokkaConfiguration.DokkaModuleDescription): DocumentationNode? { - val parsingContext = ModuleAndPackageDocumentationParsingContext(context.logger) - - val documentationFragment = module.includes - .flatMap { include -> parseModuleAndPackageDocumentationFragments(include) } - .firstOrNull { fragment -> fragment.classifier == Classifier.Module && fragment.name == module.name } - ?: return null - - val moduleDocumentation = parseModuleAndPackageDocumentation(parsingContext, documentationFragment) - return moduleDocumentation.documentation - } - - private fun List<TagWrapper>.mergeDocumentationNodes(): List<TagWrapper> = - groupBy { it::class }.values.map { - it.reduce { acc, tagWrapper -> - val newRoot = CustomDocTag( - acc.children + tagWrapper.children, - name = (tagWrapper as? NamedTagWrapper)?.name.orEmpty() - ) - when (acc) { - is See -> acc.copy(newRoot) - is Param -> acc.copy(newRoot) - is Throws -> acc.copy(newRoot) - is Sample -> acc.copy(newRoot) - is Property -> acc.copy(newRoot) - is CustomTagWrapper -> acc.copy(newRoot) - is Description -> acc.copy(newRoot) - is Author -> acc.copy(newRoot) - is Version -> acc.copy(newRoot) - is Since -> acc.copy(newRoot) - is Return -> acc.copy(newRoot) - is Receiver -> acc.copy(newRoot) - is Constructor -> acc.copy(newRoot) - is Deprecated -> acc.copy(newRoot) - is org.jetbrains.dokka.model.doc.Suppress -> acc.copy(newRoot) - } - } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationSource.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationSource.kt deleted file mode 100644 index f994eb36..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/ModuleAndPackageDocumentationSource.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import java.io.File - -internal abstract class ModuleAndPackageDocumentationSource { - abstract val sourceDescription: String - abstract val documentation: String - override fun toString(): String = sourceDescription -} - -internal data class ModuleAndPackageDocumentationFile(private val file: File) : ModuleAndPackageDocumentationSource() { - override val sourceDescription: String = file.path - override val documentation: String by lazy(LazyThreadSafetyMode.PUBLICATION) { file.readText() } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentation.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentation.kt deleted file mode 100644 index 176a487b..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentation.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -internal fun parseModuleAndPackageDocumentation( - context: ModuleAndPackageDocumentationParsingContext, - fragment: ModuleAndPackageDocumentationFragment -): ModuleAndPackageDocumentation { - return ModuleAndPackageDocumentation( - name = fragment.name, - classifier = fragment.classifier, - documentation = context.parse(fragment) - ) -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentationFragments.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentationFragments.kt deleted file mode 100644 index 621b06f0..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/moduledocs/parseModuleAndPackageDocumentationFragments.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs - -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Module -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentation.Classifier.Package -import java.io.File - -internal fun parseModuleAndPackageDocumentationFragments(source: File): List<ModuleAndPackageDocumentationFragment> { - return parseModuleAndPackageDocumentationFragments(ModuleAndPackageDocumentationFile(source)) -} - -internal fun parseModuleAndPackageDocumentationFragments( - source: ModuleAndPackageDocumentationSource -): List<ModuleAndPackageDocumentationFragment> { - val fragmentStrings = source.documentation.split(Regex("(|^)#\\s*(?=(Module|Package))")) - return fragmentStrings - .filter(String::isNotBlank) - .map { fragmentString -> parseModuleAndPackageDocFragment(source, fragmentString) } -} - -private fun parseModuleAndPackageDocFragment( - source: ModuleAndPackageDocumentationSource, - fragment: String -): ModuleAndPackageDocumentationFragment { - val firstLineAndDocumentation = fragment.split("\r\n", "\n", "\r", limit = 2) - val firstLine = firstLineAndDocumentation[0] - - val classifierAndName = firstLine.split(Regex("\\s+"), limit = 2) - - val classifier = when (classifierAndName[0].trim()) { - "Module" -> Module - "Package" -> Package - else -> throw IllegalStateException( - """Unexpected classifier: "${classifierAndName[0]}", expected either "Module" or "Package". - |For more information consult the specification: https://kotlinlang.org/docs/dokka-module-and-package-docs.html""".trimMargin() - ) - } - - if (classifierAndName.size != 2 && classifier == Module) { - throw IllegalModuleAndPackageDocumentation(source, "Missing Module name") - } - - val name = classifierAndName.getOrNull(1)?.trim().orEmpty() - if (classifier == Package && name.contains(Regex("\\s"))) { - throw IllegalModuleAndPackageDocumentation( - source, "Package name cannot contain whitespace in '$firstLine'" - ) - } - - return ModuleAndPackageDocumentationFragment( - name = name, - classifier = classifier, - documentation = firstLineAndDocumentation.getOrNull(1)?.trim().orEmpty(), - source = source - ) -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt deleted file mode 100644 index 191c5f92..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.plugin - -import com.intellij.openapi.Disposable -import com.intellij.openapi.util.Disposer -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.model.SourceSetDependent -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.kotlin.analysis.api.standalone.StandaloneAnalysisAPISession -import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule -import java.io.Closeable - -internal fun SamplesKotlinAnalysis( - sourceSets: List<DokkaConfiguration.DokkaSourceSet>, - context: DokkaContext, -): KotlinAnalysis = createAnalysisSession( - sourceSets = sourceSets, - logger = context.logger, - isSampleProject = true -) - -internal fun ProjectKotlinAnalysis( - sourceSets: List<DokkaConfiguration.DokkaSourceSet>, - context: DokkaContext, -): KotlinAnalysis = createAnalysisSession( - sourceSets = sourceSets, - logger = context.logger -) - -internal class KotlinAnalysis( - private val sourceModules: SourceSetDependent<KtSourceModule>, - private val analysisSession: StandaloneAnalysisAPISession, - private val applicationDisposable: Disposable, - private val projectDisposable: Disposable -) : Closeable { - - fun getModule(sourceSet: DokkaConfiguration.DokkaSourceSet) = - sourceModules[sourceSet] ?: error("Missing a source module for sourceSet ${sourceSet.displayName} with id ${sourceSet.sourceSetID}") - - fun getModuleOrNull(sourceSet: DokkaConfiguration.DokkaSourceSet) = - sourceModules[sourceSet] - - val modulesWithFiles - get() = analysisSession.modulesWithFiles - - override fun close() { - Disposer.dispose(applicationDisposable) - Disposer.dispose(projectDisposable) - } -}
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt deleted file mode 100644 index e074a142..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.plugin - -import com.intellij.openapi.Disposable -import com.intellij.openapi.util.Disposer -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaSourceSetID -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider -import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider -import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession -import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule -import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleBuilder -import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule -import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSdkModule -import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModule -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.platform.CommonPlatforms -import org.jetbrains.kotlin.platform.js.JsPlatforms -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.platform.konan.NativePlatforms -import java.io.File - -internal fun Platform.toTargetPlatform() = when (this) { - Platform.js, Platform.wasm -> JsPlatforms.defaultJsPlatform - Platform.common -> CommonPlatforms.defaultCommonPlatform - Platform.native -> NativePlatforms.unspecifiedNativePlatform - Platform.jvm -> JvmPlatforms.defaultJvmPlatform -} - -private fun getJdkHomeFromSystemProperty(logger: DokkaLogger): File? { - val javaHome = File(System.getProperty("java.home")) - if (!javaHome.exists()) { - logger.error("Set existed java.home to use JDK") - return null - } - return javaHome -} - -internal fun getLanguageVersionSettings( - languageVersionString: String?, - apiVersionString: String? -): LanguageVersionSettingsImpl { - val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE - val apiVersion = - apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion) - return LanguageVersionSettingsImpl( - languageVersion = languageVersion, - apiVersion = apiVersion, analysisFlags = hashMapOf( - // special flag for Dokka - // force to resolve light classes (lazily by default) - AnalysisFlags.eagerResolveOfLightClasses to true - ) - ) -} - -@OptIn(KtAnalysisApiInternals::class) -internal fun createAnalysisSession( - sourceSets: List<DokkaConfiguration.DokkaSourceSet>, - logger: DokkaLogger, - applicationDisposable: Disposable = Disposer.newDisposable("StandaloneAnalysisAPISession.application"), - projectDisposable: Disposable = Disposer.newDisposable("StandaloneAnalysisAPISession.project"), - isSampleProject: Boolean = false -): KotlinAnalysis { - val sourcesModule = mutableMapOf<DokkaConfiguration.DokkaSourceSet, KtSourceModule>() - - val analysisSession = buildStandaloneAnalysisAPISession( - applicationDisposable = applicationDisposable, - projectDisposable = projectDisposable, - withPsiDeclarationFromBinaryModuleProvider = false - ) { - registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider()) - - val sortedSourceSets = topologicalSortByDependantSourceSets(sourceSets, logger) - - val sourcesModuleBySourceSetId = mutableMapOf<DokkaSourceSetID, KtSourceModule>() - - buildKtModuleProvider { - val jdkModule = getJdkHomeFromSystemProperty(logger)?.let { jdkHome -> - buildKtSdkModule { - this.platform = Platform.jvm.toTargetPlatform() - addBinaryRootsFromJdkHome(jdkHome.toPath(), isJre = true) - sdkName = "JDK" - } - } - - fun KtModuleBuilder.addModuleDependencies(sourceSet: DokkaConfiguration.DokkaSourceSet) { - val targetPlatform = sourceSet.analysisPlatform.toTargetPlatform() - addRegularDependency( - buildKtLibraryModule { - this.platform = targetPlatform - addBinaryRoots(sourceSet.classpath.map { it.toPath() }) - libraryName = "Library for ${sourceSet.displayName}" - } - ) - if (sourceSet.analysisPlatform == Platform.jvm) { - jdkModule?.let { addRegularDependency(it) } - } - sourceSet.dependentSourceSets.forEach { - addRegularDependency( - sourcesModuleBySourceSetId[it] - ?: error("There is no source module for $it") - ) - } - } - - for (sourceSet in sortedSourceSets) { - val targetPlatform = sourceSet.analysisPlatform.toTargetPlatform() - val sourceModule = buildKtSourceModule { - languageVersionSettings = - getLanguageVersionSettings(sourceSet.languageVersion, sourceSet.apiVersion) - platform = targetPlatform - moduleName = "<module ${sourceSet.displayName}>" - if (isSampleProject) - addSourceRoots(sourceSet.samples.map { it.toPath() }) - else - addSourceRoots(sourceSet.sourceRoots.map { it.toPath() }) - addModuleDependencies( - sourceSet, - ) - } - sourcesModule[sourceSet] = sourceModule - sourcesModuleBySourceSetId[sourceSet.sourceSetID] = sourceModule - addModule(sourceModule) - } - platform = sourceSets.map { it.analysisPlatform }.distinct().singleOrNull()?.toTargetPlatform() - ?: Platform.common.toTargetPlatform() - } - } - return KotlinAnalysis(sourcesModule, analysisSession, applicationDisposable, projectDisposable) -} - -private enum class State { - UNVISITED, - VISITING, - VISITED; -} - -internal fun topologicalSortByDependantSourceSets( - sourceSets: List<DokkaConfiguration.DokkaSourceSet>, - logger: DokkaLogger -): List<DokkaConfiguration.DokkaSourceSet> { - val result = mutableListOf<DokkaConfiguration.DokkaSourceSet>() - - val verticesAssociatedWithState = sourceSets.associateWithTo(mutableMapOf()) { State.UNVISITED } - fun dfs(souceSet: DokkaConfiguration.DokkaSourceSet) { - when (verticesAssociatedWithState[souceSet]) { - State.VISITED -> return - State.VISITING -> { - logger.error("Detected cycle in source set graph") - return - } - - else -> { - val dependentSourceSets = - souceSet.dependentSourceSets.mapNotNull { dependentSourceSetId -> - sourceSets.find { it.sourceSetID == dependentSourceSetId } - // just skip - ?: null.also { logger.error("Unknown source set Id $dependentSourceSetId in dependencies of ${souceSet.sourceSetID}") } - } - verticesAssociatedWithState[souceSet] = State.VISITING - dependentSourceSets.forEach(::dfs) - verticesAssociatedWithState[souceSet] = State.VISITED - result += souceSet - } - } - } - sourceSets.forEach(::dfs) - return result -}
\ No newline at end of file diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt deleted file mode 100644 index 122e0b10..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.plugin - -import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute -import com.intellij.psi.PsiAnnotation -import org.jetbrains.dokka.CoreExtensions -import org.jetbrains.dokka.analysis.java.BreakingAbstractionKotlinLightMethodChecker -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java.KotlinInheritDocTagContentProvider -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java.DescriptorKotlinDocCommentCreator -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.java.KotlinDocCommentParser -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.moduledocs.ModuleAndPackageDocumentationReader -import org.jetbrains.dokka.analysis.kotlin.symbols.services.KotlinAnalysisSourceRootsExtractor -import org.jetbrains.dokka.analysis.kotlin.symbols.services.* -import org.jetbrains.dokka.analysis.kotlin.symbols.services.KotlinDocumentableSourceLanguageParser -import org.jetbrains.dokka.analysis.kotlin.symbols.services.SymbolExternalDocumentablesProvider -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.DefaultSymbolToDocumentableTranslator -import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.DokkaPluginApiPreview -import org.jetbrains.dokka.plugability.PluginApiPreviewAcknowledgement -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.renderers.PostAction -import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation - -@Suppress("unused") -public class SymbolsAnalysisPlugin : DokkaPlugin() { - - internal val kotlinAnalysis by extensionPoint<KotlinAnalysis>() - - internal val defaultKotlinAnalysis by extending { - kotlinAnalysis providing { ctx -> - ProjectKotlinAnalysis( - sourceSets = ctx.configuration.sourceSets, - context = ctx - ) - } - } - - internal val disposeKotlinAnalysisPostAction by extending { - CoreExtensions.postActions with PostAction { querySingle { kotlinAnalysis }.close() } - } - - internal val symbolToDocumentableTranslator by extending { - CoreExtensions.sourceToDocumentableTranslator providing ::DefaultSymbolToDocumentableTranslator - } - - private val javaAnalysisPlugin by lazy { plugin<JavaAnalysisPlugin>() } - - internal val projectProvider by extending { - javaAnalysisPlugin.projectProvider providing { KotlinAnalysisProjectProvider() } - } - - internal val sourceRootsExtractor by extending { - javaAnalysisPlugin.sourceRootsExtractor providing { KotlinAnalysisSourceRootsExtractor() } - } - - internal val kotlinDocCommentCreator by extending { - javaAnalysisPlugin.docCommentCreators providing { - DescriptorKotlinDocCommentCreator() - } - } - - internal val kotlinDocCommentParser by extending { - javaAnalysisPlugin.docCommentParsers providing { context -> - KotlinDocCommentParser( - context - ) - } - } - internal val inheritDocTagProvider by extending { - javaAnalysisPlugin.inheritDocTagContentProviders providing ::KotlinInheritDocTagContentProvider - } - internal val kotlinLightMethodChecker by extending { - javaAnalysisPlugin.kotlinLightMethodChecker providing { - object : BreakingAbstractionKotlinLightMethodChecker { - override fun isLightAnnotation(annotation: PsiAnnotation): Boolean { - return annotation is KtLightAbstractAnnotation - } - - override fun isLightAnnotationAttribute(attribute: JvmAnnotationAttribute): Boolean { - return attribute is KtLightAbstractAnnotation - } - } - } - } - - - internal val symbolAnalyzerImpl by extending { - plugin<InternalKotlinAnalysisPlugin>().documentableSourceLanguageParser providing { KotlinDocumentableSourceLanguageParser() } - } - - internal val symbolFullClassHierarchyBuilder by extending { - plugin<InternalKotlinAnalysisPlugin>().fullClassHierarchyBuilder providing ::SymbolFullClassHierarchyBuilder - } - - internal val symbolSyntheticDocumentableDetector by extending { - plugin<InternalKotlinAnalysisPlugin>().syntheticDocumentableDetector providing { SymbolSyntheticDocumentableDetector() } - } - - internal val moduleAndPackageDocumentationReader by extending { - plugin<InternalKotlinAnalysisPlugin>().moduleAndPackageDocumentationReader providing ::ModuleAndPackageDocumentationReader - } - - internal val kotlinToJavaMapper by extending { - plugin<InternalKotlinAnalysisPlugin>().kotlinToJavaService providing { SymbolKotlinToJavaMapper() } - } - - internal val symbolInheritanceBuilder by extending { - plugin<InternalKotlinAnalysisPlugin>().inheritanceBuilder providing ::SymbolInheritanceBuilder - } - - internal val symbolExternalDocumentablesProvider by extending { - plugin<InternalKotlinAnalysisPlugin>().externalDocumentablesProvider providing ::SymbolExternalDocumentablesProvider - } - - internal val kotlinSampleProviderFactory by extending { - plugin<InternalKotlinAnalysisPlugin>().sampleProviderFactory providing ::KotlinSampleProviderFactory - } - - @OptIn(DokkaPluginApiPreview::class) - override fun pluginApiPreviewAcknowledgement(): PluginApiPreviewAcknowledgement = PluginApiPreviewAcknowledgement -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisProjectProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisProjectProvider.kt deleted file mode 100644 index 398d48ee..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisProjectProvider.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.openapi.project.Project -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.ProjectProvider -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle - -internal class KotlinAnalysisProjectProvider : ProjectProvider { - override fun getProject(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): Project { - val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - return kotlinAnalysis.getModule(sourceSet).project - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisSourceRootsExtractor.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisSourceRootsExtractor.kt deleted file mode 100644 index 01084eab..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinAnalysisSourceRootsExtractor.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.SourceRootsExtractor -import org.jetbrains.dokka.plugability.DokkaContext -import java.io.File - -internal class KotlinAnalysisSourceRootsExtractor : SourceRootsExtractor { - override fun extract(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): List<File> { - return sourceSet.sourceRoots.filter { directory -> directory.isDirectory || directory.extension == "java" } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinDocumentableSourceLanguageParser.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinDocumentableSourceLanguageParser.kt deleted file mode 100644 index ae0d79ee..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinDocumentableSourceLanguageParser.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.WithSources -import org.jetbrains.dokka.analysis.kotlin.internal.DocumentableLanguage -import org.jetbrains.dokka.analysis.kotlin.internal.DocumentableSourceLanguageParser - -internal class KotlinDocumentableSourceLanguageParser : DocumentableSourceLanguageParser { - - /** - * For members inherited from Java in Kotlin - it returns [DocumentableLanguage.KOTLIN] - */ - override fun getLanguage( - documentable: Documentable, - sourceSet: DokkaConfiguration.DokkaSourceSet, - ): DocumentableLanguage? { - val documentableSource = (documentable as? WithSources)?.sources?.get(sourceSet) ?: return null - return when (documentableSource) { - is PsiDocumentableSource -> DocumentableLanguage.JAVA - is KtPsiDocumentableSource -> DocumentableLanguage.KOTLIN - else -> error("Unknown language sources: ${documentableSource::class}") - } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinSampleProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinSampleProvider.kt deleted file mode 100644 index e453c72d..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KotlinSampleProvider.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.InternalDokkaApi -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.analysis.kotlin.internal.SampleProvider -import org.jetbrains.dokka.analysis.kotlin.internal.SampleProviderFactory -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SamplesKotlinAnalysis -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithBody -import org.jetbrains.kotlin.psi.KtFile - -public class KotlinSampleProviderFactory( - public val context: DokkaContext -): SampleProviderFactory { - override fun build(): SampleProvider { - return KotlinSampleProvider(context) - } - -} -/** - * It's declared as open since StdLib has its own sample transformer - * with [processBody] and [processImports] - */ -@InternalDokkaApi -public open class KotlinSampleProvider( - public val context: DokkaContext -): SampleProvider { - private val kotlinAnalysisOfRegularSources = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - - private val kotlinAnalysisOfSamples = SamplesKotlinAnalysis( - sourceSets = context.configuration.sourceSets, context = context - ) - - protected open fun processBody(psiElement: PsiElement): String { - val text = processSampleBody(psiElement).trim { it == '\n' || it == '\r' }.trimEnd() - val lines = text.split("\n") - val indent = lines.filter(String::isNotBlank).minOfOrNull { it.takeWhile(Char::isWhitespace).count() } ?: 0 - return lines.joinToString("\n") { it.drop(indent) } - } - - private fun processSampleBody(psiElement: PsiElement): String = when (psiElement) { - is KtDeclarationWithBody -> { - when (val bodyExpression = psiElement.bodyExpression) { - is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}") - else -> bodyExpression!!.text - } - } - else -> psiElement.text - } - - protected open fun processImports(psiElement: PsiElement): String { - val psiFile = psiElement.containingFile - return when(val text = (psiFile as? KtFile)?.importList?.text) { - is String -> text - else -> "" - } - } - - /** - * @return [SampleProvider.SampleSnippet] or null if it has not found by [fqLink] - */ - override fun getSample(sourceSet: DokkaConfiguration.DokkaSourceSet, fqLink: String): SampleProvider.SampleSnippet? { - return kotlinAnalysisOfSamples.getModuleOrNull(sourceSet)?.let { getSampleFromModule(it, fqLink) } - ?: getSampleFromModule( - kotlinAnalysisOfRegularSources.getModule(sourceSet), fqLink - ) - } - private fun getSampleFromModule(module: KtSourceModule, fqLink: String): SampleProvider.SampleSnippet? { - val psiElement = analyze(module) { - val lastDotIndex = fqLink.lastIndexOf('.') - - val functionName = if (lastDotIndex == -1) fqLink else fqLink.substring(lastDotIndex + 1, fqLink.length) - val packageName = if (lastDotIndex == -1) "" else fqLink.substring(0, lastDotIndex) - getTopLevelCallableSymbols(FqName(packageName), Name.identifier(functionName)).firstOrNull()?.psi - } - ?: return null.also { context.logger.warn("Cannot find PsiElement corresponding to $fqLink") } - val imports = - processImports(psiElement) - val body = processBody(psiElement) - - return SampleProvider.SampleSnippet(imports, body) - } - - override fun close() { - kotlinAnalysisOfSamples.close() - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KtPsiDocumentableSource.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KtPsiDocumentableSource.kt deleted file mode 100644 index 284da189..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/KtPsiDocumentableSource.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.model.DocumentableSource -import org.jetbrains.kotlin.lexer.KtTokens - - -internal class KtPsiDocumentableSource(val psi: PsiElement?) : DocumentableSource { - override val path = psi?.containingFile?.virtualFile?.path ?: "" - - override fun computeLineNumber(): Int? { - return psi?.let { - val range = it.node?.findChildByType(KtTokens.IDENTIFIER)?.textRange ?: it.textRange - val doc = PsiDocumentManager.getInstance(it.project).getDocument(it.containingFile) - // IJ uses 0-based line-numbers; external source browsers use 1-based - doc?.getLineNumber(range.startOffset)?.plus(1) - } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolExternalDocumentablesProvider.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolExternalDocumentablesProvider.kt deleted file mode 100644 index 1473a7da..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolExternalDocumentablesProvider.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.DokkaSymbolVisitor -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getClassIdFromDRI -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getDRIFromSymbol -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.DClasslike -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol -import org.jetbrains.dokka.analysis.kotlin.internal.ExternalDocumentablesProvider - -internal class SymbolExternalDocumentablesProvider(val context: DokkaContext) : ExternalDocumentablesProvider { - private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - - override fun findClasslike(dri: DRI, sourceSet: DokkaSourceSet): DClasslike? { - val classId = getClassIdFromDRI(dri) - - return analyze(kotlinAnalysis.getModule(sourceSet)) { - val symbol = getClassOrObjectSymbolByClassId(classId) as? KtNamedClassOrObjectSymbol?: return@analyze null - val translator = DokkaSymbolVisitor(sourceSet, sourceSet.displayName, kotlinAnalysis, logger = context.logger) - - val parentDRI = symbol.getContainingSymbol()?.let { getDRIFromSymbol(it) } ?: /* top level */ DRI(dri.packageName) - with(translator) { - return@analyze visitNamedClassOrObjectSymbol(symbol, parentDRI) - } - } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt deleted file mode 100644 index 0b68ac81..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.psi.PsiClass -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.analysis.java.util.from -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.getDRIFromClassLike -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.analyze -import org.jetbrains.kotlin.analysis.api.types.KtType -import org.jetbrains.dokka.analysis.kotlin.internal.ClassHierarchy -import org.jetbrains.dokka.analysis.kotlin.internal.FullClassHierarchyBuilder -import org.jetbrains.dokka.analysis.kotlin.internal.Supertypes -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.AnnotationTranslator -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.TypeTranslator -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.kotlin.psi.KtClassOrObject -import java.util.concurrent.ConcurrentHashMap - - -internal class SymbolFullClassHierarchyBuilder(context: DokkaContext) : FullClassHierarchyBuilder { - private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - - override suspend fun build(module: DModule): ClassHierarchy { - val map = module.sourceSets.associateWith { ConcurrentHashMap<DRI, List<DRI>>() } - module.packages.forEach { visitDocumentable(it, map) } - return map - } - - private fun KtAnalysisSession.collectSupertypesFromKtType( - driWithKType: Pair<DRI, KtType>, - supersMap: MutableMap<DRI, Supertypes> - ) { - val (dri, kotlinType) = driWithKType - if (supersMap[dri] == null) { - val supertypes = kotlinType.getDirectSuperTypes(shouldApproximate = true).filterNot { it.isAny } - val supertypesDriWithKType = supertypes.mapNotNull { supertype -> - supertype.expandedClassSymbol?.let { - getDRIFromClassLike(it) to supertype - } - } - supersMap[dri] = supertypesDriWithKType.map { it.first } - supertypesDriWithKType.forEach { collectSupertypesFromKtType(it, supersMap) } - } - } - - private fun collectSupertypesFromPsiClass( - driWithPsiClass: Pair<DRI, PsiClass>, - supersMap: MutableMap<DRI, Supertypes> - ) { - val (dri, psiClass) = driWithPsiClass - val supertypes = psiClass.superTypes.mapNotNull { it.resolve() } - .filterNot { it.qualifiedName == "java.lang.Object" } - val supertypesDriWithPsiClass = supertypes.map { DRI.from(it) to it } - - if (supersMap[dri] == null) { - supersMap[dri] = supertypesDriWithPsiClass.map { it.first } - supertypesDriWithPsiClass.forEach { collectSupertypesFromPsiClass(it, supersMap) } - } - } - - private fun visitDocumentable( - documentable: Documentable, - hierarchy: SourceSetDependent<MutableMap<DRI, List<DRI>>> - ) { - if (documentable is WithScope) { - documentable.classlikes.forEach { visitDocumentable(it, hierarchy) } - } - if (documentable is DClasslike) { - // to build a full class graph, - // using supertypes from Documentable is not enough since it keeps only one level of hierarchy - documentable.sources.forEach { (sourceSet, source) -> - if (source is KtPsiDocumentableSource) { - (source.psi as? KtClassOrObject)?.let { psi -> - analyze(kotlinAnalysis.getModule(sourceSet)) { - val type = psi.getNamedClassOrObjectSymbol()?.buildSelfClassType() ?: return@analyze - hierarchy[sourceSet]?.let { collectSupertypesFromKtType(documentable.dri to type, it) } - } - } - } else if (source is PsiDocumentableSource) { - val psi = source.psi as PsiClass - hierarchy[sourceSet]?.let { collectSupertypesFromPsiClass(documentable.dri to psi, it) } - } - } - } - } - - internal class SuperclassesWithKind( - val typeConstructorWithKind: TypeConstructorWithKind, - val superclasses: List<TypeConstructorWithKind> - ) - - /** - * Currently, it works only for Symbols - */ - internal fun collectKotlinSupertypesWithKind( - documentable: Iterable<Documentable>, - sourceSet: DokkaConfiguration.DokkaSourceSet - ): Map<DRI, SuperclassesWithKind> { - val typeTranslator = TypeTranslator(sourceSet, AnnotationTranslator()) - val hierarchy = mutableMapOf<DRI, SuperclassesWithKind>() - - analyze(kotlinAnalysis.getModule(sourceSet)) { - documentable.filterIsInstance<DClasslike>().forEach { - val source = it.sources[sourceSet] - if (source is KtPsiDocumentableSource) { - (source.psi as? KtClassOrObject)?.let { psi -> - val type = psi.getNamedClassOrObjectSymbol()?.buildSelfClassType() ?: return@analyze - collectSupertypesWithKindFromKtType(typeTranslator, with(typeTranslator) { - toTypeConstructorWithKindFrom(type) - } to type, hierarchy) - } - } // else if (source is PsiDocumentableSource) TODO val psi = source.psi as? PsiClass - } - } - return hierarchy - } - - private fun KtAnalysisSession.collectSupertypesWithKindFromKtType( - typeTranslator: TypeTranslator, - typeConstructorWithKindWithKType: Pair<TypeConstructorWithKind, KtType>, - supersMap: MutableMap<DRI, SuperclassesWithKind> - ) { - val (typeConstructorWithKind, kotlinType) = typeConstructorWithKindWithKType - - if (supersMap[typeConstructorWithKind.typeConstructor.dri] == null) { - val supertypes = kotlinType.getDirectSuperTypes(shouldApproximate = true).filterNot { it.isAny } - - val supertypesDriWithKType = supertypes.map { supertype -> - with(typeTranslator) { - toTypeConstructorWithKindFrom(supertype) - } to supertype - } - supersMap[typeConstructorWithKind.typeConstructor.dri] = - SuperclassesWithKind(typeConstructorWithKind, supertypesDriWithKType.map { it.first }) - supertypesDriWithKType.forEach { collectSupertypesWithKindFromKtType(typeTranslator, it, supersMap) } - } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolInheritanceBuilder.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolInheritanceBuilder.kt deleted file mode 100644 index 540f08a7..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolInheritanceBuilder.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.psi.PsiClass -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.analysis.java.util.from -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.analysis.kotlin.internal.InheritanceBuilder -import org.jetbrains.dokka.analysis.kotlin.internal.InheritanceNode -import org.jetbrains.dokka.analysis.kotlin.internal.InternalKotlinAnalysisPlugin -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.querySingle - -/** - * This is copy-pasted from org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.DescriptorInheritanceBuilder and adapted for symbols - */ -internal class SymbolInheritanceBuilder(context: DokkaContext) : InheritanceBuilder { - private val symbolFullClassHierarchyBuilder = - context.plugin<InternalKotlinAnalysisPlugin>().querySingle { fullClassHierarchyBuilder } - - override fun build(documentables: Map<DRI, Documentable>): List<InheritanceNode> { - - // this statement is copy-pasted from the version for Descriptors - val psiInheritanceTree = - documentables.flatMap { (_, v) -> (v as? WithSources)?.sources?.values.orEmpty() } - .filterIsInstance<PsiDocumentableSource>().mapNotNull { it.psi as? PsiClass } - .flatMap(::gatherPsiClasses) - .flatMap { entry -> entry.second.map { it to entry.first } } - .let { - it + it.map { it.second to null } - } - .groupBy({ it.first }) { it.second } - .map { it.key to it.value.filterNotNull().distinct() } - .map { (k, v) -> - InheritanceNode( - DRI.from(k), - v.map { InheritanceNode(DRI.from(it)) }, - k.supers.filter { it.isInterface }.map { DRI.from(it) }, - k.isInterface - ) - - } - - // copy-pasted from stdlib 1.5 - fun <T, R : Any> Iterable<T>.firstNotNullOfOrNull(transform: (T) -> R?): R? { - for (element in this) { - val result = transform(element) - if (result != null) { - return result - } - } - return null - } - - val jvmSourceSet = - documentables.values.firstNotNullOfOrNull { it.sourceSets.find { it.analysisPlatform == Platform.jvm } } - if (jvmSourceSet == null) - return psiInheritanceTree - - val typeConstructorsMap = - (symbolFullClassHierarchyBuilder as? SymbolFullClassHierarchyBuilder)?.collectKotlinSupertypesWithKind( - documentables.values, - jvmSourceSet - ) - ?: throw IllegalStateException("Unexpected symbolFullClassHierarchyBuildertype") // TODO: https://github.com/Kotlin/dokka/issues/3225 Unify FullClassHierarchyBuilder and InheritanceBuilder into one builder - - fun ClassKind.isInterface() = this == KotlinClassKindTypes.INTERFACE || this == JavaClassKindTypes.INTERFACE - val symbolsInheritanceTree = typeConstructorsMap.map { (dri, superclasses) -> - InheritanceNode( - dri, - superclasses.superclasses.map { InheritanceNode(it.typeConstructor.dri) }, - superclasses.superclasses.filter { it.kind.isInterface() }.map { it.typeConstructor.dri }, - isInterface = superclasses.typeConstructorWithKind.kind.isInterface() - ) - } - - return psiInheritanceTree + symbolsInheritanceTree - } - - private fun gatherPsiClasses(psi: PsiClass): List<Pair<PsiClass, List<PsiClass>>> = psi.supers.toList().let { l -> - listOf(psi to l) + l.flatMap { gatherPsiClasses(it) } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolKotlinToJavaMapper.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolKotlinToJavaMapper.kt deleted file mode 100644 index 77ede87f..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolKotlinToJavaMapper.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.PointingToDeclaration -import org.jetbrains.dokka.analysis.kotlin.internal.KotlinToJavaService -import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap // or import kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap see https://github.com/Kotlin/dokka/issues/3226 -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName - -/** - * This is copy-pasted from org.jetbrains.dokka.analysis.kotlin.descriptors.compiler.impl.DescriptorKotlinToJavaMapper - */ -internal class SymbolKotlinToJavaMapper : KotlinToJavaService { - - override fun findAsJava(kotlinDri: DRI): DRI? { - return kotlinDri.partialFqName().mapToJava()?.toDRI(kotlinDri) - } - - private fun DRI.partialFqName() = packageName?.let { "$it." } + classNames - - private fun String.mapToJava(): ClassId? = - JavaToKotlinClassMap.mapKotlinToJava(FqName(this).toUnsafe()) - - private fun ClassId.toDRI(dri: DRI?): DRI = DRI( - packageName = packageFqName.asString(), - classNames = classNames(), - callable = dri?.callable,//?.asJava(), TODO: check this - extra = null, - target = PointingToDeclaration - ) - - private fun ClassId.classNames(): String = - shortClassName.identifier + (outerClassId?.classNames()?.let { ".$it" } ?: "") -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolSyntheticDocumentableDetector.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolSyntheticDocumentableDetector.kt deleted file mode 100644 index d281e9c0..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolSyntheticDocumentableDetector.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.services - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.util.PsiDocumentableSource -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.InheritedMember -import org.jetbrains.dokka.model.WithSources -import org.jetbrains.dokka.model.properties.WithExtraProperties -import org.jetbrains.dokka.analysis.kotlin.internal.SyntheticDocumentableDetector - -internal class SymbolSyntheticDocumentableDetector : SyntheticDocumentableDetector { - - /** - * Currently, it's used only for [org.jetbrains.dokka.base.transformers.documentables.ReportUndocumentedTransformer] - * - * For so-called fake-ovveride declarations - we have [InheritedMember] extra. - * For synthesized declaration - we do not have PSI source. - * - * @see org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin.SOURCE_MEMBER_GENERATED - */ - override fun isSynthetic(documentable: Documentable, sourceSet: DokkaConfiguration.DokkaSourceSet): Boolean { - @Suppress("UNCHECKED_CAST") - val extra = (documentable as? WithExtraProperties<Documentable>)?.extra - val isInherited = extra?.get(InheritedMember)?.inheritedFrom?.get(sourceSet) != null - // TODO the same for JAVA? - val isSynthesized = documentable.getPsi(sourceSet) == null - return isInherited || isSynthesized - } - - private fun Documentable.getPsi(sourceSet: DokkaConfiguration.DokkaSourceSet): PsiElement? { - val documentableSource = (this as? WithSources)?.sources?.get(sourceSet) ?: return null - return when (documentableSource) { - is PsiDocumentableSource -> documentableSource.psi - is KtPsiDocumentableSource -> documentableSource.psi - else -> error("Unknown language sources: ${documentableSource::class}") - } - } - - -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/AnnotationTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/AnnotationTranslator.kt deleted file mode 100644 index c9882487..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/AnnotationTranslator.kt +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.withEnumEntryExtra -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.ClassValue -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.annotations.* -import org.jetbrains.kotlin.analysis.api.base.KtConstantValue -import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin -import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtFile - -/** - * Map [KtAnnotationApplication] to Dokka [Annotations.Annotation] - */ -internal class AnnotationTranslator { - private fun KtAnalysisSession.getFileLevelAnnotationsFrom(symbol: KtSymbol) = - if (symbol.origin != KtSymbolOrigin.SOURCE) - null - else - (symbol.psi?.containingFile as? KtFile)?.getFileSymbol()?.annotations - ?.map { toDokkaAnnotation(it) } - - private fun KtAnalysisSession.getDirectAnnotationsFrom(annotated: KtAnnotated) = - annotated.annotations.map { toDokkaAnnotation(it) } - - /** - * The examples of annotations from backing field are [JvmField], [JvmSynthetic]. - * - * @return direct annotations, annotations from backing field and file-level annotations - */ - fun KtAnalysisSession.getAllAnnotationsFrom(annotated: KtAnnotated): List<Annotations.Annotation> { - val directAnnotations = getDirectAnnotationsFrom(annotated) - val backingFieldAnnotations = - (annotated as? KtPropertySymbol)?.backingFieldSymbol?.let { getDirectAnnotationsFrom(it) }.orEmpty() - val fileLevelAnnotations = (annotated as? KtSymbol)?.let { getFileLevelAnnotationsFrom(it) }.orEmpty() - return directAnnotations + backingFieldAnnotations + fileLevelAnnotations - } - - private fun KtAnnotationApplication.isNoExistedInSource() = psi == null - private fun AnnotationUseSiteTarget.toDokkaAnnotationScope(): Annotations.AnnotationScope = when (this) { - AnnotationUseSiteTarget.PROPERTY_GETTER -> Annotations.AnnotationScope.DIRECT // due to compatibility with Dokka K1 - AnnotationUseSiteTarget.PROPERTY_SETTER -> Annotations.AnnotationScope.DIRECT // due to compatibility with Dokka K1 - AnnotationUseSiteTarget.FILE -> Annotations.AnnotationScope.FILE - else -> Annotations.AnnotationScope.DIRECT - } - - private fun KtAnalysisSession.mustBeDocumented(annotationApplication: KtAnnotationApplication): Boolean { - if (annotationApplication.isNoExistedInSource()) return false - val annotationClass = getClassOrObjectSymbolByClassId(annotationApplication.classId ?: return false) - return annotationClass?.hasAnnotation(mustBeDocumentedAnnotation) - ?: false - } - - private fun KtAnalysisSession.toDokkaAnnotation(annotationApplication: KtAnnotationApplication) = - Annotations.Annotation( - dri = annotationApplication.classId?.createDRI() - ?: DRI(packageName = "", classNames = ERROR_CLASS_NAME), // classId might be null on a non-existing annotation call, - params = if (annotationApplication is KtAnnotationApplicationWithArgumentsInfo) annotationApplication.arguments.associate { - it.name.asString() to toDokkaAnnotationValue( - it.expression - ) - } else emptyMap(), - mustBeDocumented = mustBeDocumented(annotationApplication), - scope = annotationApplication.useSiteTarget?.toDokkaAnnotationScope() ?: Annotations.AnnotationScope.DIRECT - ) - - @OptIn(ExperimentalUnsignedTypes::class) - private fun KtAnalysisSession.toDokkaAnnotationValue(annotationValue: KtAnnotationValue): AnnotationParameterValue = - when (annotationValue) { - is KtConstantAnnotationValue -> { - when (val value = annotationValue.constantValue) { - is KtConstantValue.KtNullConstantValue -> NullValue - is KtConstantValue.KtFloatConstantValue -> FloatValue(value.value) - is KtConstantValue.KtDoubleConstantValue -> DoubleValue(value.value) - is KtConstantValue.KtLongConstantValue -> LongValue(value.value) - is KtConstantValue.KtIntConstantValue -> IntValue(value.value) - is KtConstantValue.KtBooleanConstantValue -> BooleanValue(value.value) - is KtConstantValue.KtByteConstantValue -> IntValue(value.value.toInt()) - is KtConstantValue.KtCharConstantValue -> StringValue(value.value.toString()) - is KtConstantValue.KtErrorConstantValue -> StringValue(value.renderAsKotlinConstant()) - is KtConstantValue.KtShortConstantValue -> IntValue(value.value.toInt()) - is KtConstantValue.KtStringConstantValue -> StringValue(value.value) - is KtConstantValue.KtUnsignedByteConstantValue -> IntValue(value.value.toInt()) - is KtConstantValue.KtUnsignedIntConstantValue -> IntValue(value.value.toInt()) - is KtConstantValue.KtUnsignedLongConstantValue -> LongValue(value.value.toLong()) - is KtConstantValue.KtUnsignedShortConstantValue -> IntValue(value.value.toInt()) - } - } - - is KtEnumEntryAnnotationValue -> EnumValue( - with(annotationValue.callableId) { this?.className?.asString() + "." + this?.callableName?.asString() }, - getDRIFrom(annotationValue) - ) - - is KtArrayAnnotationValue -> ArrayValue(annotationValue.values.map { toDokkaAnnotationValue(it) }) - is KtAnnotationApplicationValue -> AnnotationValue(toDokkaAnnotation(annotationValue.annotationValue)) - is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> ClassValue( - annotationValue.classId.relativeClassName.asString(), - annotationValue.classId.createDRI() - ) - - is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> throw IllegalStateException("Unexpected a local class in annotation") - is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> ClassValue( - annotationValue.unresolvedQualifierName ?: "", - DRI(packageName = "", classNames = ERROR_CLASS_NAME) - ) - - KtUnsupportedAnnotationValue -> ClassValue( - "<Unsupported Annotation Value>", - DRI(packageName = "", classNames = ERROR_CLASS_NAME) - ) - } - - private fun getDRIFrom(enumEntry: KtEnumEntryAnnotationValue): DRI { - val callableId = - enumEntry.callableId ?: throw IllegalStateException("Can't get `callableId` for enum entry from annotation") - return DRI( - packageName = callableId.packageName.asString(), - classNames = callableId.className?.asString() + "." + callableId.callableName.asString(), - ).withEnumEntryExtra() - } - - companion object { - val mustBeDocumentedAnnotation = ClassId(FqName("kotlin.annotation"), FqName("MustBeDocumented"), false) - private val parameterNameAnnotation = ClassId(FqName("kotlin"), FqName("ParameterName"), false) - - /** - * Functional types can have **generated** [ParameterName] annotation - * @see ParameterName - */ - internal fun KtAnnotated.getPresentableName(): String? = - this.annotationsByClassId(parameterNameAnnotation) - .firstOrNull()?.arguments?.firstOrNull { it.name == Name.identifier("name") }?.expression?.let { it as? KtConstantAnnotationValue } - ?.let { it.constantValue.value.toString() } - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DRIFactory.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DRIFactory.kt deleted file mode 100644 index a2cb423a..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DRIFactory.kt +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - -import org.jetbrains.dokka.links.* -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithTypeParameters -import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType -import org.jetbrains.kotlin.name.CallableId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName - -internal fun ClassId.createDRI(): DRI = DRI( - packageName = this.packageFqName.asString(), classNames = this.relativeClassName.asString() -) - -private fun CallableId.createDRI(receiver: TypeReference?, params: List<TypeReference>): DRI = DRI( - packageName = this.packageName.asString(), - classNames = this.className?.asString(), - callable = Callable( - this.callableName.asString(), - params = params, - receiver = receiver - ) -) - -internal fun getDRIFromNonErrorClassType(nonErrorClassType: KtNonErrorClassType): DRI = - nonErrorClassType.classId.createDRI() - -private val KtCallableSymbol.callableId - get() = this.callableIdIfNonLocal ?: throw IllegalStateException("Can not get callable Id due to it is local") - -// because of compatibility with Dokka K1, DRI of entry is kept as non-callable -internal fun getDRIFromEnumEntry(symbol: KtEnumEntrySymbol): DRI = - symbol.callableId.let { - DRI( - packageName = it.packageName.asString(), - classNames = it.className?.asString() + "." + it.callableName.asString(), - ) - }.withEnumEntryExtra() - - -internal fun KtAnalysisSession.getDRIFromTypeParameter(symbol: KtTypeParameterSymbol): DRI { - val containingSymbol = - (symbol.getContainingSymbol() as? KtSymbolWithTypeParameters) - ?: throw IllegalStateException("Containing symbol is null for type parameter") - val typeParameters = containingSymbol.typeParameters - val index = typeParameters.indexOfFirst { symbol.name == it.name } - return getDRIFromSymbol(containingSymbol).copy(target = PointingToGenericParameters(index)) -} - -internal fun KtAnalysisSession.getDRIFromConstructor(symbol: KtConstructorSymbol): DRI = - (symbol.containingClassIdIfNonLocal - ?: throw IllegalStateException("Can not get class Id due to it is local")).createDRI().copy( - callable = Callable( - name = symbol.containingClassIdIfNonLocal?.relativeClassName?.asString() ?: "", - params = symbol.valueParameters.map { getTypeReferenceFrom(it.returnType) }) - ) - -internal fun KtAnalysisSession.getDRIFromVariableLike(symbol: KtVariableLikeSymbol): DRI { - val receiver = symbol.receiverType?.let { - getTypeReferenceFrom(it) - } - return symbol.callableId.createDRI(receiver, emptyList()) -} - -internal fun KtAnalysisSession.getDRIFromFunctionLike(symbol: KtFunctionLikeSymbol): DRI { - val params = symbol.valueParameters.map { getTypeReferenceFrom(it.returnType) } - val receiver = symbol.receiverType?.let { - getTypeReferenceFrom(it) - } - return symbol.callableIdIfNonLocal?.createDRI(receiver, params) - ?: getDRIFromLocalFunction(symbol) -} - -internal fun getDRIFromClassLike(symbol: KtClassLikeSymbol): DRI = - symbol.classIdIfNonLocal?.createDRI() ?: throw IllegalStateException("Can not get class Id due to it is local") - -internal fun getDRIFromPackage(symbol: KtPackageSymbol): DRI = - DRI(packageName = symbol.fqName.asString()) - -internal fun KtAnalysisSession.getDRIFromValueParameter(symbol: KtValueParameterSymbol): DRI { - val function = (symbol.getContainingSymbol() as? KtFunctionLikeSymbol) - ?: throw IllegalStateException("Containing symbol is null for type parameter") - val index = function.valueParameters.indexOfFirst { it.name == symbol.name } - val funDRI = getDRIFromFunctionLike(function) - return funDRI.copy(target = PointingToCallableParameters(index)) -} - -internal fun KtAnalysisSession.getDRIFromSymbol(symbol: KtSymbol): DRI = - when (symbol) { - is KtEnumEntrySymbol -> getDRIFromEnumEntry(symbol) - is KtTypeParameterSymbol -> getDRIFromTypeParameter(symbol) - is KtConstructorSymbol -> getDRIFromConstructor(symbol) - is KtValueParameterSymbol -> getDRIFromValueParameter(symbol) - is KtVariableLikeSymbol -> getDRIFromVariableLike(symbol) - is KtFunctionLikeSymbol -> getDRIFromFunctionLike(symbol) - is KtClassLikeSymbol -> getDRIFromClassLike(symbol) - is KtPackageSymbol -> getDRIFromPackage(symbol) - else -> throw IllegalStateException("Unknown symbol while creating DRI $symbol") - } - -private fun KtAnalysisSession.getDRIFromNonCallablePossibleLocalSymbol(symbol: KtSymbol): DRI { - if ((symbol as? KtSymbolWithKind)?.symbolKind == KtSymbolKind.LOCAL) { - return symbol.getContainingSymbol()?.let { getDRIFromNonCallablePossibleLocalSymbol(it) } - ?: throw IllegalStateException("Can't get containing symbol for local symbol") - } - return getDRIFromSymbol(symbol) -} - -/** - * Currently, it's used only for functions from enum entry, - * For its members: `memberSymbol.callableIdIfNonLocal=null` - */ -private fun KtAnalysisSession.getDRIFromLocalFunction(symbol: KtFunctionLikeSymbol): DRI { - /** - * A function is inside local object - */ - val containingSymbolDRI = symbol.getContainingSymbol()?.let { getDRIFromNonCallablePossibleLocalSymbol(it) } - ?: throw IllegalStateException("Can't get containing symbol for local function") - return containingSymbolDRI.copy( - callable = Callable( - (symbol as? KtNamedSymbol)?.name?.asString() ?: "", - params = symbol.valueParameters.map { getTypeReferenceFrom(it.returnType) }, - receiver = symbol.receiverType?.let { - getTypeReferenceFrom(it) - } - ) - ) -} - -// ----------- DRI => compiler identifiers ---------------------------------------------------------------------------- -internal fun getClassIdFromDRI(dri: DRI) = ClassId( - FqName(dri.packageName ?: ""), - FqName(dri.classNames ?: throw IllegalStateException("DRI must have `classNames` to get ClassID")), - false -) - diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt deleted file mode 100644 index 298d0182..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - - -import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.* -import com.intellij.psi.util.PsiLiteralUtil -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.java.JavaAnalysisPlugin -import org.jetbrains.dokka.analysis.java.parsers.JavadocParser -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.getGeneratedKDocDocumentationFrom -import org.jetbrains.dokka.analysis.kotlin.symbols.services.KtPsiDocumentableSource -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.getJavaDocDocumentationFrom -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.getKDocDocumentationFrom -import org.jetbrains.dokka.analysis.kotlin.symbols.kdoc.hasGeneratedKDocDocumentation -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.AnnotationTranslator.Companion.getPresentableName -import org.jetbrains.dokka.analysis.kotlin.symbols.utils.typeConstructorsBeingExceptions -import org.jetbrains.dokka.links.* -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.Visibility -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query -import org.jetbrains.dokka.plugability.querySingle -import org.jetbrains.dokka.transformers.sources.AsyncSourceToDocumentableTranslator -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.KtNodeTypes -import org.jetbrains.kotlin.analysis.api.* -import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotated -import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility -import org.jetbrains.kotlin.analysis.api.types.* -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.descriptors.java.JavaVisibilities -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier -import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier -import java.nio.file.Paths - -internal class DefaultSymbolToDocumentableTranslator(context: DokkaContext) : AsyncSourceToDocumentableTranslator { - private val kotlinAnalysis = context.plugin<SymbolsAnalysisPlugin>().querySingle { kotlinAnalysis } - private val javadocParser = JavadocParser( - docCommentParsers = context.plugin<JavaAnalysisPlugin>().query { docCommentParsers }, - docCommentFinder = context.plugin<JavaAnalysisPlugin>().docCommentFinder - ) - - override suspend fun invokeSuspending( - sourceSet: DokkaConfiguration.DokkaSourceSet, - context: DokkaContext - ): DModule { - val analysisContext = kotlinAnalysis - @Suppress("unused") - return DokkaSymbolVisitor( - sourceSet = sourceSet, - moduleName = context.configuration.moduleName, - analysisContext = analysisContext, - logger = context.logger, - javadocParser = javadocParser - ).visitModule() - } -} - -internal fun <T : Bound> T.wrapWithVariance(variance: org.jetbrains.kotlin.types.Variance) = - when (variance) { - org.jetbrains.kotlin.types.Variance.INVARIANT -> Invariance(this) - org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Contravariance(this) - org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Covariance(this) - } - -/** - * Maps [KtSymbol] to Documentable model [Documentable] - */ -internal class DokkaSymbolVisitor( - private val sourceSet: DokkaConfiguration.DokkaSourceSet, - private val moduleName: String, - private val analysisContext: KotlinAnalysis, - private val logger: DokkaLogger, - private val javadocParser: JavadocParser? = null -) { - private var annotationTranslator = AnnotationTranslator() - private var typeTranslator = TypeTranslator(sourceSet, annotationTranslator) - - /** - * To avoid recursive classes - * e.g. - * open class Klass() { - * object Default : Klass() - * } - */ - private val visitedNamedClassOrObjectSymbol: MutableSet<ClassId> = - mutableSetOf() - - private fun <T> T.toSourceSetDependent() = if (this != null) mapOf(sourceSet to this) else emptyMap() - - // KT-54846 will replace - private val KtDeclarationSymbol.isActual - get() = (psi as? KtModifierListOwner)?.hasActualModifier() == true - private val KtDeclarationSymbol.isExpect - get() = (psi as? KtModifierListOwner)?.hasExpectModifier() == true - - private fun <T : KtSymbol> Collection<T>.filterSymbolsInSourceSet() = filter { - it.psi?.containingFile?.virtualFile?.path?.let { path -> - path.isNotBlank() && sourceSet.sourceRoots.any { root -> - Paths.get(path).startsWith(root.toPath()) - } - } == true - } - - fun visitModule(): DModule { - val sourceModule = analysisContext.getModule(sourceSet) - val ktFiles = analysisContext.modulesWithFiles[sourceModule]?.filterIsInstance<KtFile>() ?: throw IllegalStateException("No source files for a source module ${sourceModule.moduleName} of source set ${sourceSet.sourceSetID}") - val processedPackages: MutableSet<FqName> = mutableSetOf() - return analyze(sourceModule) { - val packageSymbols: List<DPackage> = ktFiles - .mapNotNull { - if (processedPackages.contains(it.packageFqName)) - return@mapNotNull null - processedPackages.add(it.packageFqName) - getPackageSymbolIfPackageExists(it.packageFqName)?.let { it1 -> - visitPackageSymbol( - it1 - ) - } - } - - DModule( - name = moduleName, - packages = packageSymbols, - documentation = emptyMap(), - expectPresentInSet = null, - sourceSets = setOf(sourceSet) - ) - } - } - - private fun KtAnalysisSession.visitPackageSymbol(packageSymbol: KtPackageSymbol): DPackage { - val dri = getDRIFromPackage(packageSymbol) - val scope = packageSymbol.getPackageScope() - val callables = scope.getCallableSymbols().toList().filterSymbolsInSourceSet() - val classifiers = scope.getClassifierSymbols().toList().filterSymbolsInSourceSet() - - val functions = callables.filterIsInstance<KtFunctionSymbol>().map { visitFunctionSymbol(it, dri) } - val properties = callables.filterIsInstance<KtPropertySymbol>().map { visitPropertySymbol(it, dri) } - val classlikes = - classifiers.filterIsInstance<KtNamedClassOrObjectSymbol>() - .map { visitNamedClassOrObjectSymbol(it, dri) } - val typealiases = classifiers.filterIsInstance<KtTypeAliasSymbol>().map { visitTypeAliasSymbol(it, dri) } - - return DPackage( - dri = dri, - functions = functions, - properties = properties, - classlikes = classlikes, - typealiases = typealiases, - documentation = emptyMap(), - sourceSets = setOf(sourceSet) - ) - } - - private fun KtAnalysisSession.visitTypeAliasSymbol( - typeAliasSymbol: KtTypeAliasSymbol, - parent: DRI - ): DTypeAlias = withExceptionCatcher(typeAliasSymbol) { - val name = typeAliasSymbol.name.asString() - val dri = parent.withClass(name) - - val ancestryInfo = with(typeTranslator) { buildAncestryInformationFrom(typeAliasSymbol.expandedType) } - - val generics = - typeAliasSymbol.typeParameters.mapIndexed { index, symbol -> visitVariantTypeParameter(index, symbol, dri) } - - return DTypeAlias( - dri = dri, - name = name, - type = GenericTypeConstructor( - dri = dri, - projections = generics.map { it.variantTypeParameter }), // this property can be removed in DTypeAlias - expectPresentInSet = null, - underlyingType = toBoundFrom(typeAliasSymbol.expandedType).toSourceSetDependent(), - visibility = typeAliasSymbol.getDokkaVisibility().toSourceSetDependent(), - documentation = getDocumentation(typeAliasSymbol)?.toSourceSetDependent() ?: emptyMap(), - sourceSets = setOf(sourceSet), - generics = generics, - sources = typeAliasSymbol.getSource(), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(typeAliasSymbol)?.toSourceSetDependent()?.toAnnotations(), - ancestryInfo.exceptionInSupertypesOrNull(), - ) - ) - } - - fun KtAnalysisSession.visitNamedClassOrObjectSymbol( - namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol, - parent: DRI - ): DClasslike = withExceptionCatcher(namedClassOrObjectSymbol) { - namedClassOrObjectSymbol.classIdIfNonLocal?.let { visitedNamedClassOrObjectSymbol.add(it) } - - val name = namedClassOrObjectSymbol.name.asString() - val dri = parent.withClass(name) - - val isExpect = namedClassOrObjectSymbol.isExpect - val isActual = namedClassOrObjectSymbol.isActual - val documentation = getDocumentation(namedClassOrObjectSymbol)?.toSourceSetDependent() ?: emptyMap() - - val (constructors, functions, properties, classlikesWithoutCompanion) = getDokkaScopeFrom(namedClassOrObjectSymbol, dri) - - val companionObject = namedClassOrObjectSymbol.companionObject?.let { - visitNamedClassOrObjectSymbol( - it, - dri - ) - } as? DObject - val classlikes = if (companionObject == null) classlikesWithoutCompanion else classlikesWithoutCompanion + companionObject - - val generics = namedClassOrObjectSymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - val ancestryInfo = - with(typeTranslator) { buildAncestryInformationFrom(namedClassOrObjectSymbol.buildSelfClassType()) } - val supertypes = - //(ancestryInfo.interfaces.map{ it.typeConstructor } + listOfNotNull(ancestryInfo.superclass?.typeConstructor)) - namedClassOrObjectSymbol.superTypes.filterNot { it.isAny } - .map { with(typeTranslator) { toTypeConstructorWithKindFrom(it) } } - .toSourceSetDependent() - return@withExceptionCatcher when (namedClassOrObjectSymbol.classKind) { - KtClassKind.OBJECT, KtClassKind.COMPANION_OBJECT -> - DObject( - dri = dri, - name = name, - functions = functions, - properties = properties, - classlikes = classlikes, - sources = namedClassOrObjectSymbol.getSource(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = namedClassOrObjectSymbol.getDokkaVisibility().toSourceSetDependent(), - supertypes = supertypes, - documentation = documentation, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - namedClassOrObjectSymbol.additionalExtras()?.toSourceSetDependent() - ?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(namedClassOrObjectSymbol)?.toSourceSetDependent()?.toAnnotations(), - ImplementedInterfaces(ancestryInfo.allImplementedInterfaces().toSourceSetDependent()), - ancestryInfo.exceptionInSupertypesOrNull() - ) - ) - - KtClassKind.CLASS -> DClass( - dri = dri, - name = name, - constructors = constructors, - functions = functions, - properties = properties, - classlikes = classlikes, - sources = namedClassOrObjectSymbol.getSource(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = namedClassOrObjectSymbol.getDokkaVisibility().toSourceSetDependent(), - supertypes = supertypes, - generics = generics, - documentation = documentation, - modifier = namedClassOrObjectSymbol.getDokkaModality().toSourceSetDependent(), - companion = companionObject, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - namedClassOrObjectSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(namedClassOrObjectSymbol)?.toSourceSetDependent()?.toAnnotations(), - ImplementedInterfaces(ancestryInfo.allImplementedInterfaces().toSourceSetDependent()), - ancestryInfo.exceptionInSupertypesOrNull() - ) - ) - - KtClassKind.INTERFACE -> DInterface( - dri = dri, - name = name, - functions = functions, - properties = properties, - classlikes = classlikes, - sources = namedClassOrObjectSymbol.getSource(), // - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = namedClassOrObjectSymbol.getDokkaVisibility().toSourceSetDependent(), - supertypes = supertypes, - generics = generics, - documentation = documentation, - companion = companionObject, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - namedClassOrObjectSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(namedClassOrObjectSymbol)?.toSourceSetDependent()?.toAnnotations(), - ImplementedInterfaces(ancestryInfo.allImplementedInterfaces().toSourceSetDependent()), - ancestryInfo.exceptionInSupertypesOrNull() - ) - ) - - KtClassKind.ANNOTATION_CLASS -> DAnnotation( - dri = dri, - name = name, - documentation = documentation, - functions = functions, - properties = properties, - classlikes = classlikes, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - companion = companionObject, - visibility = namedClassOrObjectSymbol.getDokkaVisibility().toSourceSetDependent(), - generics = generics, - constructors = constructors, - sources = namedClassOrObjectSymbol.getSource(), - extra = PropertyContainer.withAll( - namedClassOrObjectSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(namedClassOrObjectSymbol)?.toSourceSetDependent()?.toAnnotations(), - ) - ) - - KtClassKind.ANONYMOUS_OBJECT -> throw NotImplementedError("ANONYMOUS_OBJECT does not support") - KtClassKind.ENUM_CLASS -> { - /** - * See https://github.com/Kotlin/dokka/issues/3129 - * - * e.g. the `A` enum entry in the `enum E` is - * ``` - * static val A: E = object : E() { - * val x: Int = 5 - * } - * ``` - * it needs to exclude all static members like `values` and `valueOf` from the enum class's scope - */ - val enumEntryScope = lazy { - getDokkaScopeFrom(namedClassOrObjectSymbol, dri, includeStaticScope = false).let { - it.copy( - functions = it.functions.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) }, - properties = it.properties.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) } - ) - } - } - - val entries = - namedClassOrObjectSymbol.getEnumEntries().map { - visitEnumEntrySymbol(it, enumEntryScope.value) - } - - DEnum( - dri = dri, - name = name, - entries = entries, - constructors = constructors, - functions = functions, - properties = properties, - classlikes = classlikes, - sources = namedClassOrObjectSymbol.getSource(), - expectPresentInSet = sourceSet.takeIf { isExpect }, - visibility = namedClassOrObjectSymbol.getDokkaVisibility().toSourceSetDependent(), - supertypes = supertypes, - documentation = documentation, - companion = namedClassOrObjectSymbol.companionObject?.let { - visitNamedClassOrObjectSymbol( - it, - dri - ) - } as? DObject, - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - namedClassOrObjectSymbol.additionalExtras()?.toSourceSetDependent() - ?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(namedClassOrObjectSymbol)?.toSourceSetDependent()?.toAnnotations(), - ImplementedInterfaces(ancestryInfo.allImplementedInterfaces().toSourceSetDependent()) - ) - ) - } - } - } - - private data class DokkaScope( - val constructors: List<DFunction>, - val functions: List<DFunction>, - val properties: List<DProperty>, - val classlikesWithoutCompanion: List<DClasslike> - ) - - /** - * @param includeStaticScope flag to add static members, e.g. `valueOf`, `values` and `entries` members for Enum - */ - private fun KtAnalysisSession.getDokkaScopeFrom( - namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol, - dri: DRI, - includeStaticScope: Boolean = true - ): DokkaScope { - // e.g. getStaticMemberScope contains `valueOf`, `values` and `entries` members for Enum - val scope = if(includeStaticScope) listOf(namedClassOrObjectSymbol.getMemberScope(), namedClassOrObjectSymbol.getStaticMemberScope()).asCompositeScope() else namedClassOrObjectSymbol.getMemberScope() - val constructors = scope.getConstructors().map { visitConstructorSymbol(it) }.toList() - - val callables = scope.getCallableSymbols().toList() - val classifiers = scope.getClassifierSymbols().toList() - - val syntheticJavaProperties = - namedClassOrObjectSymbol.buildSelfClassType().getSyntheticJavaPropertiesScope()?.getCallableSignatures() - ?.map { it.symbol } - ?.filterIsInstance<KtSyntheticJavaPropertySymbol>() ?: emptySequence() - - fun List<KtJavaFieldSymbol>.filterOutSyntheticJavaPropBackingField() = - filterNot { javaField -> syntheticJavaProperties.any { it.hasBackingField && javaField.name == it.name } } - - val javaFields = callables.filterIsInstance<KtJavaFieldSymbol>() - .filterOutSyntheticJavaPropBackingField() - - fun List<KtFunctionSymbol>.filterOutSyntheticJavaPropAccessors() = filterNot { fn -> - if (fn.origin == KtSymbolOrigin.JAVA && fn.callableIdIfNonLocal != null) - syntheticJavaProperties.any { fn.callableIdIfNonLocal == it.javaGetterSymbol.callableIdIfNonLocal || fn.callableIdIfNonLocal == it.javaSetterSymbol?.callableIdIfNonLocal } - else false - } - - val functions = callables.filterIsInstance<KtFunctionSymbol>() - .filterOutSyntheticJavaPropAccessors().map { visitFunctionSymbol(it, dri) } - - - val properties = callables.filterIsInstance<KtPropertySymbol>().map { visitPropertySymbol(it, dri) } + - syntheticJavaProperties.map { visitPropertySymbol(it, dri) } + - javaFields.map { visitJavaFieldSymbol(it, dri) } - - - fun List<KtNamedClassOrObjectSymbol>.filterOutCompanion() = - filterNot { - it.classKind == KtClassKind.COMPANION_OBJECT - } - - fun List<KtNamedClassOrObjectSymbol>.filterOutAndMarkAlreadyVisited() = filterNot { symbol -> - visitedNamedClassOrObjectSymbol.contains(symbol.classIdIfNonLocal) - .also { - if (!it) symbol.classIdIfNonLocal?.let { classId -> - visitedNamedClassOrObjectSymbol.add( - classId - ) - } - } - } - - val classlikes = classifiers.filterIsInstance<KtNamedClassOrObjectSymbol>() - .filterOutCompanion() // also, this is a hack to filter out companion for enum - .filterOutAndMarkAlreadyVisited() - .map { visitNamedClassOrObjectSymbol(it, dri) } - - return DokkaScope( - constructors = constructors, - functions = functions, - properties = properties, - classlikesWithoutCompanion = classlikes - ) - } - - private fun KtAnalysisSession.visitEnumEntrySymbol( - enumEntrySymbol: KtEnumEntrySymbol, scope: DokkaScope - ): DEnumEntry = withExceptionCatcher(enumEntrySymbol) { - val dri = getDRIFromEnumEntry(enumEntrySymbol) - val isExpect = false - - return DEnumEntry( - dri = dri, - name = enumEntrySymbol.name.asString(), - documentation = getDocumentation(enumEntrySymbol)?.toSourceSetDependent() ?: emptyMap(), - functions = scope.functions, - properties = scope.properties, - classlikes = emptyList(), // always empty, see https://github.com/Kotlin/dokka/issues/3129 - sourceSets = setOf(sourceSet), - expectPresentInSet = sourceSet.takeIf { isExpect }, - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(enumEntrySymbol)?.toSourceSetDependent()?.toAnnotations() - ) - ) - } - - private fun KtAnalysisSession.visitPropertySymbol(propertySymbol: KtPropertySymbol, parent: DRI): DProperty = - withExceptionCatcher(propertySymbol) { - val dri = createDRIWithOverridden(propertySymbol).origin - val inheritedFrom = dri.getInheritedFromDRI(parent) - val isExpect = propertySymbol.isExpect - val isActual = propertySymbol.isActual - val generics = - propertySymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - return DProperty( - dri = dri, - name = propertySymbol.name.asString(), - receiver = propertySymbol.receiverParameter?.let { - visitReceiverParameter( - it, - dri - ) - }, - sources = propertySymbol.getSource(), - getter = propertySymbol.getter?.let { visitPropertyAccessor(it, propertySymbol, dri) }, - setter = propertySymbol.setter?.let { visitPropertyAccessor(it, propertySymbol, dri) }, - visibility = propertySymbol.visibility.toDokkaVisibility().toSourceSetDependent(), - documentation = getDocumentation(propertySymbol)?.toSourceSetDependent() ?: emptyMap(), // TODO - modifier = propertySymbol.modality.toDokkaModifier().toSourceSetDependent(), - type = toBoundFrom(propertySymbol.returnType), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - generics = generics, - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - propertySymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(propertySymbol)?.toSourceSetDependent()?.toAnnotations(), - propertySymbol.getDefaultValue()?.let { DefaultValue(it.toSourceSetDependent()) }, - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - takeUnless { propertySymbol.isVal }?.let { IsVar }, - takeIf { propertySymbol.psi is KtParameter }?.let { IsAlsoParameter(listOf(sourceSet)) } - ) - ) - } - - private fun KtAnalysisSession.visitJavaFieldSymbol( - javaFieldSymbol: KtJavaFieldSymbol, - parent: DRI - ): DProperty = - withExceptionCatcher(javaFieldSymbol) { - val dri = createDRIWithOverridden(javaFieldSymbol).origin - val inheritedFrom = dri.getInheritedFromDRI(parent) - val isExpect = false - val isActual = false - val generics = - javaFieldSymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - return DProperty( - dri = dri, - name = javaFieldSymbol.name.asString(), - receiver = javaFieldSymbol.receiverParameter?.let { - visitReceiverParameter( - it, - dri - ) - }, - sources = javaFieldSymbol.getSource(), - getter = null, - setter = null, - visibility = javaFieldSymbol.getDokkaVisibility().toSourceSetDependent(), - documentation = getDocumentation(javaFieldSymbol)?.toSourceSetDependent() ?: emptyMap(), // TODO - modifier = javaFieldSymbol.modality.toDokkaModifier().toSourceSetDependent(), - type = toBoundFrom(javaFieldSymbol.returnType), - expectPresentInSet = sourceSet.takeIf { isExpect }, - sourceSets = setOf(sourceSet), - generics = generics, - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - javaFieldSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(javaFieldSymbol)?.toSourceSetDependent()?.toAnnotations(), - //javaFieldSymbol.getDefaultValue()?.let { DefaultValue(it.toSourceSetDependent()) }, - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - // non-final java property should be var - takeUnless { javaFieldSymbol.isVal }?.let { IsVar } - ) - ) - } - - private fun KtAnalysisSession.visitPropertyAccessor( - propertyAccessorSymbol: KtPropertyAccessorSymbol, - propertySymbol: KtPropertySymbol, - propertyDRI: DRI - ): DFunction = withExceptionCatcher(propertyAccessorSymbol) { - val isGetter = propertyAccessorSymbol is KtPropertyGetterSymbol - // it also covers @JvmName annotation - val name = (if (isGetter) propertySymbol.javaGetterName else propertySymbol.javaSetterName)?.asString() ?: "" - - // SyntheticJavaProperty has callableIdIfNonLocal, propertyAccessorSymbol.origin = JAVA_SYNTHETIC_PROPERTY - // For Kotlin properties callableIdIfNonLocal=null - val dri = if (propertyAccessorSymbol.callableIdIfNonLocal != null) - getDRIFromFunctionLike(propertyAccessorSymbol) - else - propertyDRI.copy( - callable = Callable(name, null, propertyAccessorSymbol.valueParameters.map { getTypeReferenceFrom(it.returnType) }) - ) - // for SyntheticJavaProperty - val inheritedFrom = if(propertyAccessorSymbol.origin == KtSymbolOrigin.JAVA_SYNTHETIC_PROPERTY) dri.copy(callable = null) else null - - val isExpect = propertyAccessorSymbol.isExpect - val isActual = propertyAccessorSymbol.isActual - - val generics = propertyAccessorSymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - return DFunction( - dri = dri, - name = name, - isConstructor = false, - receiver = propertyAccessorSymbol.receiverParameter?.let { - visitReceiverParameter( - it, - dri - ) - }, - parameters = propertyAccessorSymbol.valueParameters.mapIndexed { index, symbol -> - visitValueParameter(index, symbol, dri) - }, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sources = propertyAccessorSymbol.getSource(), - visibility = propertyAccessorSymbol.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = generics, - documentation = getDocumentation(propertyAccessorSymbol)?.toSourceSetDependent() ?: emptyMap(), - modifier = propertyAccessorSymbol.modality.toDokkaModifier().toSourceSetDependent(), - type = toBoundFrom(propertyAccessorSymbol.returnType), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - propertyAccessorSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - getDokkaAnnotationsFrom(propertyAccessorSymbol)?.toSourceSetDependent()?.toAnnotations() - ) - ) - } - - private fun KtAnalysisSession.visitConstructorSymbol( - constructorSymbol: KtConstructorSymbol - ): DFunction = withExceptionCatcher(constructorSymbol) { - val name = constructorSymbol.containingClassIdIfNonLocal?.shortClassName?.asString() - ?: throw IllegalStateException("Unknown containing class of constructor") - val dri = createDRIWithOverridden(constructorSymbol).origin - val isExpect = false // TODO - val isActual = false // TODO - - val generics = constructorSymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - val documentation = getDocumentation(constructorSymbol)?.let { docNode -> - if (constructorSymbol.isPrimary) { - docNode.copy(children = (docNode.children.find { it is Constructor }?.root?.let { constructor -> - listOf(Description(constructor)) - } ?: emptyList<TagWrapper>()) + docNode.children.filterIsInstance<Param>()) - } else { - docNode - } - }?.toSourceSetDependent() - - return DFunction( - dri = dri, - name = name, - isConstructor = true, - receiver = constructorSymbol.receiverParameter?.let { - visitReceiverParameter( - it, - dri - ) - }, - parameters = constructorSymbol.valueParameters.mapIndexed { index, symbol -> - visitValueParameter(index, symbol, dri) - }, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sources = constructorSymbol.getSource(), - visibility = constructorSymbol.visibility.toDokkaVisibility().toSourceSetDependent(), - generics = generics, - documentation = documentation ?: emptyMap(), - modifier = KotlinModifier.Empty.toSourceSetDependent(), - type = toBoundFrom(constructorSymbol.returnType), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(constructorSymbol)?.toSourceSetDependent()?.toAnnotations(), - takeIf { constructorSymbol.isPrimary }?.let { PrimaryConstructorExtra } - ) - ) - } - - private fun KtAnalysisSession.visitFunctionSymbol(functionSymbol: KtFunctionSymbol, parent: DRI): DFunction = - withExceptionCatcher(functionSymbol) { - val dri = createDRIWithOverridden(functionSymbol).origin - val inheritedFrom = dri.getInheritedFromDRI(parent) - val isExpect = functionSymbol.isExpect - val isActual = functionSymbol.isActual - - val generics = - functionSymbol.typeParameters.mapIndexed { index, symbol -> - visitVariantTypeParameter( - index, - symbol, - dri - ) - } - - return DFunction( - dri = dri, - name = functionSymbol.name.asString(), - isConstructor = false, - receiver = functionSymbol.receiverParameter?.let { - visitReceiverParameter( - it, - dri - ) - }, - parameters = functionSymbol.valueParameters.mapIndexed { index, symbol -> - visitValueParameter(index, symbol, dri) - }, - expectPresentInSet = sourceSet.takeIf { isExpect }, - sources = functionSymbol.getSource(), - visibility = functionSymbol.getDokkaVisibility().toSourceSetDependent(), - generics = generics, - documentation = getDocumentation(functionSymbol)?.toSourceSetDependent() ?: emptyMap(), - modifier = functionSymbol.getDokkaModality().toSourceSetDependent(), - type = toBoundFrom(functionSymbol.returnType), - sourceSets = setOf(sourceSet), - isExpectActual = (isExpect || isActual), - extra = PropertyContainer.withAll( - inheritedFrom?.let { InheritedMember(it.toSourceSetDependent()) }, - functionSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(functionSymbol) - ?.toSourceSetDependent()?.toAnnotations(), - ObviousMember.takeIf { isObvious(functionSymbol) }, - ) - ) - } - - private fun KtAnalysisSession.visitValueParameter( - index: Int, valueParameterSymbol: KtValueParameterSymbol, dri: DRI - ) = DParameter( - dri = dri.copy(target = PointingToCallableParameters(index)), - name = valueParameterSymbol.name.asString(), - type = toBoundFrom(valueParameterSymbol.returnType), - expectPresentInSet = null, - documentation = getDocumentation(valueParameterSymbol)?.toSourceSetDependent() ?: emptyMap(), - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll( - valueParameterSymbol.additionalExtras()?.toSourceSetDependent()?.toAdditionalModifiers(), - getDokkaAnnotationsFrom(valueParameterSymbol)?.toSourceSetDependent()?.toAnnotations(), - valueParameterSymbol.getDefaultValue()?.let { DefaultValue(it.toSourceSetDependent()) } - ) - ) - - private fun KtAnalysisSession.visitReceiverParameter( - receiverParameterSymbol: KtReceiverParameterSymbol, dri: DRI - ) = DParameter( - dri = dri.copy(target = PointingToDeclaration), - name = null, - type = toBoundFrom(receiverParameterSymbol.type), - expectPresentInSet = null, - documentation = getDocumentation(receiverParameterSymbol)?.toSourceSetDependent() ?: emptyMap(), - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(receiverParameterSymbol)?.toSourceSetDependent()?.toAnnotations() - ) - ) - - private fun KtValueParameterSymbol.getDefaultValue(): Expression? = - if (origin == KtSymbolOrigin.SOURCE) (psi as? KtParameter)?.defaultValue?.toDefaultValueExpression() - else null - - private fun KtPropertySymbol.getDefaultValue(): Expression? = - (initializer?.initializerPsi as? KtConstantExpression)?.toDefaultValueExpression() // TODO consider [KtConstantInitializerValue], but should we keep an original format, e.g. 0xff or 0b101? - - private fun KtExpression.toDefaultValueExpression(): Expression? = when (node?.elementType) { - KtNodeTypes.INTEGER_CONSTANT -> PsiLiteralUtil.parseLong(node?.text)?.let { IntegerConstant(it) } - KtNodeTypes.FLOAT_CONSTANT -> if (node?.text?.toLowerCase()?.endsWith('f') == true) - PsiLiteralUtil.parseFloat(node?.text)?.let { FloatConstant(it) } - else PsiLiteralUtil.parseDouble(node?.text)?.let { DoubleConstant(it) } - - KtNodeTypes.BOOLEAN_CONSTANT -> BooleanConstant(node?.text == "true") - KtNodeTypes.STRING_TEMPLATE -> StringConstant(node.findChildByType(KtNodeTypes.LITERAL_STRING_TEMPLATE_ENTRY)?.text.orEmpty()) - else -> node?.text?.let { ComplexExpression(it) } - } - - private fun KtAnalysisSession.visitVariantTypeParameter( - index: Int, - typeParameterSymbol: KtTypeParameterSymbol, - dri: DRI - ): DTypeParameter { - val upperBoundsOrNullableAny = - typeParameterSymbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.NULLABLE_ANY) - return DTypeParameter( - variantTypeParameter = TypeParameter( - dri = dri.copy(target = PointingToGenericParameters(index)), - name = typeParameterSymbol.name.asString(), - presentableName = typeParameterSymbol.getPresentableName() - ).wrapWithVariance(typeParameterSymbol.variance), - documentation = getDocumentation(typeParameterSymbol)?.toSourceSetDependent() ?: emptyMap(), - expectPresentInSet = null, - bounds = upperBoundsOrNullableAny.map { toBoundFrom(it) }, - sourceSets = setOf(sourceSet), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(typeParameterSymbol)?.toSourceSetDependent()?.toAnnotations() - ) - ) - } - // ----------- Utils ---------------------------------------------------------------------------- - - private fun KtAnalysisSession.getDokkaAnnotationsFrom(annotated: KtAnnotated): List<Annotations.Annotation>? = - with(annotationTranslator) { getAllAnnotationsFrom(annotated) }.takeUnless { it.isEmpty() } - - private fun KtAnalysisSession.toBoundFrom(type: KtType) = - with(typeTranslator) { toBoundFrom(type) } - - /** - * `createDRI` returns the DRI of the exact element and potential DRI of an element that is overriding it - * (It can be also FAKE_OVERRIDE which is in fact just inheritance of the symbol) - * - * Looking at what PSIs do, they give the DRI of the element within the classnames where it is actually - * declared and inheritedFrom as the same DRI but truncated callable part. - * Therefore, we set callable to null and take the DRI only if it is indeed coming from different class. - */ - private fun DRI.getInheritedFromDRI(dri: DRI): DRI? { - return this.copy(callable = null) - .takeIf { dri.classNames != this.classNames || dri.packageName != this.packageName } - } - - data class DRIWithOverridden(val origin: DRI, val overridden: DRI? = null) - - private fun KtAnalysisSession.createDRIWithOverridden( - callableSymbol: KtCallableSymbol, - wasOverriddenBy: DRI? = null - ): DRIWithOverridden { - if (callableSymbol is KtPropertySymbol && callableSymbol.isOverride - || callableSymbol is KtFunctionSymbol && callableSymbol.isOverride - ) { - return DRIWithOverridden(getDRIFromSymbol(callableSymbol), wasOverriddenBy) - } - - val overriddenSymbols = callableSymbol.getAllOverriddenSymbols() - // For already - return if (overriddenSymbols.isEmpty()) { - DRIWithOverridden(getDRIFromSymbol(callableSymbol), wasOverriddenBy) - } else { - createDRIWithOverridden(overriddenSymbols.first()) - } - } - - private fun KtAnalysisSession.getDocumentation(symbol: KtSymbol) = - if (symbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED) - getGeneratedKDocDocumentationFrom(symbol) - else - getKDocDocumentationFrom(symbol, logger) ?: javadocParser?.let { getJavaDocDocumentationFrom(symbol, it) } - - private fun KtAnalysisSession.isObvious(functionSymbol: KtFunctionSymbol): Boolean { - return functionSymbol.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED && !hasGeneratedKDocDocumentation(functionSymbol) || - !functionSymbol.isOverride && functionSymbol.callableIdIfNonLocal?.classId?.isObvious() == true - } - - private fun ClassId.isObvious(): Boolean = with(asString()) { - return this == "kotlin/Any" || this == "kotlin/Enum" - || this == "java.lang/Object" || this == "java.lang/Enum" - } - - private fun KtSymbol.getSource() = KtPsiDocumentableSource(psi).toSourceSetDependent() - - private fun AncestryNode.exceptionInSupertypesOrNull(): ExceptionInSupertypes? = - typeConstructorsBeingExceptions().takeIf { it.isNotEmpty() } - ?.let { ExceptionInSupertypes(it.toSourceSetDependent()) } - - - // ----------- Translators of modifiers ---------------------------------------------------------------------------- - private fun KtSymbolWithModality.getDokkaModality() = modality.toDokkaModifier() - private fun KtSymbolWithVisibility.getDokkaVisibility() = visibility.toDokkaVisibility() - private fun KtValueParameterSymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.NoInline.takeIf { isNoinline }, - ExtraModifiers.KotlinOnlyModifiers.CrossInline.takeIf { isCrossinline }, - ExtraModifiers.KotlinOnlyModifiers.VarArg.takeIf { isVararg } - ).toSet().takeUnless { it.isEmpty() } - - private fun KtPropertyAccessorSymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Inline.takeIf { isInline }, -//ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isJvmStaticInObjectOrClassOrInterface() }, - ExtraModifiers.KotlinOnlyModifiers.Override.takeIf { isOverride } - ).toSet().takeUnless { it.isEmpty() } - - private fun KtPropertySymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Const.takeIf { (this as? KtKotlinPropertySymbol)?.isConst == true }, - ExtraModifiers.KotlinOnlyModifiers.LateInit.takeIf { (this as? KtKotlinPropertySymbol)?.isLateInit == true }, - //ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isJvmStaticInObjectOrClassOrInterface() }, - //ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - //ExtraModifiers.KotlinOnlyModifiers.Static.takeIf { isStatic }, - ExtraModifiers.KotlinOnlyModifiers.Override.takeIf { isOverride } - ).toSet().takeUnless { it.isEmpty() } - - private fun KtJavaFieldSymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isStatic } - ).toSet().takeUnless { it.isEmpty() } - - private fun KtFunctionSymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Infix.takeIf { isInfix }, - ExtraModifiers.KotlinOnlyModifiers.Inline.takeIf { isInline }, - ExtraModifiers.KotlinOnlyModifiers.Suspend.takeIf { isSuspend }, - ExtraModifiers.KotlinOnlyModifiers.Operator.takeIf { isOperator }, -//ExtraModifiers.JavaOnlyModifiers.Static.takeIf { isJvmStaticInObjectOrClassOrInterface() }, - ExtraModifiers.KotlinOnlyModifiers.TailRec.takeIf { (psi as? KtNamedFunction)?.hasModifier(KtTokens.TAILREC_KEYWORD) == true }, - ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - ExtraModifiers.KotlinOnlyModifiers.Override.takeIf { isOverride } - ).toSet().takeUnless { it.isEmpty() } - - private fun KtNamedClassOrObjectSymbol.additionalExtras() = listOfNotNull( - ExtraModifiers.KotlinOnlyModifiers.Inline.takeIf { (this.psi as? KtClass)?.isInline() == true }, - ExtraModifiers.KotlinOnlyModifiers.Value.takeIf { (this.psi as? KtClass)?.isValue() == true }, - ExtraModifiers.KotlinOnlyModifiers.External.takeIf { isExternal }, - ExtraModifiers.KotlinOnlyModifiers.Inner.takeIf { isInner }, - ExtraModifiers.KotlinOnlyModifiers.Data.takeIf { isData }, - ExtraModifiers.KotlinOnlyModifiers.Fun.takeIf { isFun }, - ).toSet().takeUnless { it.isEmpty() } - - private fun Modality.toDokkaModifier() = when (this) { - Modality.FINAL -> KotlinModifier.Final - Modality.SEALED -> KotlinModifier.Sealed - Modality.OPEN -> KotlinModifier.Open - Modality.ABSTRACT -> KotlinModifier.Abstract - } - - - private fun org.jetbrains.kotlin.descriptors.Visibility.toDokkaVisibility(): Visibility = when (this) { - Visibilities.Public -> KotlinVisibility.Public - Visibilities.Protected -> KotlinVisibility.Protected - Visibilities.Internal -> KotlinVisibility.Internal - Visibilities.Private, Visibilities.PrivateToThis -> KotlinVisibility.Private - JavaVisibilities.ProtectedAndPackage -> KotlinVisibility.Protected - JavaVisibilities.ProtectedStaticVisibility -> KotlinVisibility.Protected - JavaVisibilities.PackageVisibility -> JavaVisibility.Default - else -> KotlinVisibility.Public - } -} - - - - - - diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TranslatorError.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TranslatorError.kt deleted file mode 100644 index eceb7a38..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TranslatorError.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol - -internal class TranslatorError(message: String, cause: Throwable?) : IllegalStateException(message, cause) - -internal inline fun <R> KtAnalysisSession.withExceptionCatcher(symbol: KtSymbol, action: KtAnalysisSession.() -> R): R = - try { - action() - } catch (e: TranslatorError) { - throw e - } catch (e: Throwable) { - val file = try { - symbol.psi?.containingFile?.virtualFile?.path - } catch (e: Throwable) { - "[$e]" - } - val textRange = try { - symbol.psi?.textRange.toString() - } catch (e: Throwable) { - "[$e]" - } - throw TranslatorError( - "Error in translating of symbol (${(symbol as? KtNamedSymbol)?.name}) $symbol in file: $file, $textRange", - e - ) - } diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeReferenceFactory.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeReferenceFactory.kt deleted file mode 100644 index ea9a18c9..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeReferenceFactory.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - -import org.jetbrains.dokka.links.* -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection -import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance -import org.jetbrains.kotlin.analysis.api.KtTypeProjection -import org.jetbrains.kotlin.analysis.api.types.* - -internal fun KtAnalysisSession.getTypeReferenceFrom(type: KtType): TypeReference = - getTypeReferenceFromPossiblyRecursive(type, emptyList()) - - -// see `deep recursive typebound #1342` test -private fun KtAnalysisSession.getTypeReferenceFromPossiblyRecursive( - type: KtType, - paramTrace: List<KtType> -): TypeReference { - if (type is KtTypeParameterType) { - // compare by symbol since, e.g. T? and T have the different KtType, but the same type parameter - paramTrace.indexOfFirst { it is KtTypeParameterType && type.symbol == it.symbol } - .takeIf { it >= 0 } - ?.let { return RecursiveType(it) } - } - - return when (type) { - is KtNonErrorClassType -> TypeConstructor( - type.classId.asFqNameString(), - type.ownTypeArguments.map { - getTypeReferenceFromTypeProjection( - it, - paramTrace - ) - } - ) - - is KtTypeParameterType -> { - val upperBoundsOrNullableAny = - type.symbol.upperBounds.takeIf { it.isNotEmpty() } ?: listOf(this.builtinTypes.NULLABLE_ANY) - - TypeParam(bounds = upperBoundsOrNullableAny.map { - getTypeReferenceFromPossiblyRecursive( - it, - paramTrace + type - ) - }) - } - - is KtClassErrorType -> TypeConstructor("$ERROR_CLASS_NAME $type", emptyList()) - is KtFlexibleType -> getTypeReferenceFromPossiblyRecursive( - type.upperBound, - paramTrace - ) - - is KtDefinitelyNotNullType -> getTypeReferenceFromPossiblyRecursive( - type.original, - paramTrace - ) - - is KtDynamicType -> TypeConstructor("[dynamic]", emptyList()) - is KtTypeErrorType -> TypeConstructor("$ERROR_CLASS_NAME $type", emptyList()) - is KtCapturedType -> throw NotImplementedError() - is KtIntegerLiteralType -> throw NotImplementedError() - is KtIntersectionType -> throw NotImplementedError() - }.let { - if (type.isMarkedNullable) Nullable(it) else it - } - -} - -private fun KtAnalysisSession.getTypeReferenceFromTypeProjection( - typeProjection: KtTypeProjection, - paramTrace: List<KtType> -): TypeReference = - when (typeProjection) { - is KtStarTypeProjection -> StarProjection - is KtTypeArgumentWithVariance -> getTypeReferenceFromPossiblyRecursive(typeProjection.type, paramTrace) - } diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeTranslator.kt deleted file mode 100644 index f7366294..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/TypeTranslator.kt +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.translators - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.analysis.kotlin.symbols.translators.AnnotationTranslator.Companion.getPresentableName -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection -import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance -import org.jetbrains.kotlin.analysis.api.KtTypeProjection -import org.jetbrains.kotlin.analysis.api.annotations.* -import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.types.* - -internal const val ERROR_CLASS_NAME = "<ERROR CLASS>" - -/** - * Maps [KtType] to Dokka [Bound] or [TypeConstructorWithKind]. - * - * Also, build [AncestryNode] tree from [KtType] - */ -internal class TypeTranslator( - private val sourceSet: DokkaConfiguration.DokkaSourceSet, - private val annotationTranslator: AnnotationTranslator -) { - - private fun <T> T.toSourceSetDependent() = if (this != null) mapOf(sourceSet to this) else emptyMap() - - private fun KtAnalysisSession.toProjection(typeProjection: KtTypeProjection): Projection = - when (typeProjection) { - is KtStarTypeProjection -> Star - is KtTypeArgumentWithVariance -> toBoundFrom(typeProjection.type).wrapWithVariance(typeProjection.variance) - } - - private fun KtAnalysisSession.toTypeConstructorFromTypeAliased(classType: KtUsualClassType): TypeAliased { - val classSymbol = classType.classSymbol - return if (classSymbol is KtTypeAliasSymbol) - TypeAliased( - typeAlias = GenericTypeConstructor( - dri = getDRIFromNonErrorClassType(classType), - projections = classType.ownTypeArguments.map { toProjection(it) }), - inner = toBoundFrom(classType.fullyExpandedType), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(classType)?.toSourceSetDependent()?.toAnnotations() - ) - ) else - throw IllegalStateException("Expected type alias symbol in type") - } - - private fun KtAnalysisSession.toTypeConstructorFrom(classType: KtNonErrorClassType) = - GenericTypeConstructor( - dri = getDRIFromNonErrorClassType(classType), - projections = classType.ownTypeArguments.map { toProjection(it) }, - presentableName = classType.getPresentableName(), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(classType)?.toSourceSetDependent()?.toAnnotations() - ) - ) - - private fun KtAnalysisSession.toFunctionalTypeConstructorFrom(functionalType: KtFunctionalType) = - FunctionalTypeConstructor( - dri = getDRIFromNonErrorClassType(functionalType), - projections = functionalType.ownTypeArguments.map { toProjection(it) }, - isExtensionFunction = functionalType.receiverType != null, - isSuspendable = functionalType.isSuspend, - presentableName = functionalType.getPresentableName(), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(functionalType)?.toSourceSetDependent()?.toAnnotations() - ) - ) - - fun KtAnalysisSession.toBoundFrom(type: KtType): Bound = - when (type) { - is KtUsualClassType -> { - if (type.classSymbol is KtTypeAliasSymbol) toTypeConstructorFromTypeAliased(type) - else toTypeConstructorFrom(type) - } - - is KtTypeParameterType -> TypeParameter( - dri = getDRIFromTypeParameter(type.symbol), - name = type.name.asString(), - presentableName = type.getPresentableName(), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(type)?.toSourceSetDependent()?.toAnnotations() - ) - ) - - is KtClassErrorType -> UnresolvedBound(type.toString()) - is KtFunctionalType -> { - /** - * For example - * `typealias CompletionHandler = (cause: Throwable?) -> Unit` - * has functional type with no type arguments in K2 - * In K1 we have a usual generic type - */ - if (type.ownTypeArguments.isEmpty()) - toTypeConstructorFrom(type) - else - toFunctionalTypeConstructorFrom(type) - } - is KtDynamicType -> Dynamic - is KtDefinitelyNotNullType -> DefinitelyNonNullable( - toBoundFrom(type.original) - ) - - is KtFlexibleType -> TypeAliased( - toBoundFrom(type.upperBound), - toBoundFrom(type.lowerBound), - extra = PropertyContainer.withAll( - getDokkaAnnotationsFrom(type)?.toSourceSetDependent()?.toAnnotations() - ) - ) - - is KtTypeErrorType -> UnresolvedBound(type.toString()) - is KtCapturedType -> throw NotImplementedError() - is KtIntegerLiteralType -> throw NotImplementedError() - is KtIntersectionType -> throw NotImplementedError() - }.let { - if (type.isMarkedNullable) Nullable(it) else it - } - - fun KtAnalysisSession.buildAncestryInformationFrom( - type: KtType - ): AncestryNode { - val (interfaces, superclass) = type.getDirectSuperTypes().filterNot { it.isAny } - .partition { - val typeConstructorWithKind = toTypeConstructorWithKindFrom(it) - typeConstructorWithKind.kind == KotlinClassKindTypes.INTERFACE || - typeConstructorWithKind.kind == JavaClassKindTypes.INTERFACE - } - - return AncestryNode( - typeConstructor = toTypeConstructorWithKindFrom(type).typeConstructor, - superclass = superclass.map { buildAncestryInformationFrom(it) }.singleOrNull(), - interfaces = interfaces.map { buildAncestryInformationFrom(it) } - ) - } - - internal fun KtAnalysisSession.toTypeConstructorWithKindFrom(type: KtType): TypeConstructorWithKind = when (type) { - is KtUsualClassType -> - when (val classSymbol = type.classSymbol) { - is KtNamedClassOrObjectSymbol -> TypeConstructorWithKind( - toTypeConstructorFrom(type), - classSymbol.classKind.toDokkaClassKind() - ) - - is KtAnonymousObjectSymbol -> throw NotImplementedError() - is KtTypeAliasSymbol -> toTypeConstructorWithKindFrom(classSymbol.expandedType) - } - - is KtClassErrorType -> TypeConstructorWithKind( - GenericTypeConstructor( - dri = DRI(packageName = "", classNames = "$ERROR_CLASS_NAME $type"), - projections = emptyList(), - - ), - KotlinClassKindTypes.CLASS - ) - - is KtTypeErrorType -> TypeConstructorWithKind( - GenericTypeConstructor( - dri = DRI(packageName = "", classNames = "$ERROR_CLASS_NAME $type"), - projections = emptyList(), - - ), - KotlinClassKindTypes.CLASS - ) - - is KtFunctionalType -> TypeConstructorWithKind( - toFunctionalTypeConstructorFrom(type), - KotlinClassKindTypes.CLASS - ) - - is KtDefinitelyNotNullType -> toTypeConstructorWithKindFrom(type.original) - - is KtCapturedType -> throw NotImplementedError() - is KtDynamicType -> throw NotImplementedError() - is KtFlexibleType -> throw NotImplementedError() - is KtIntegerLiteralType -> throw NotImplementedError() - is KtIntersectionType -> throw NotImplementedError() - is KtTypeParameterType -> throw NotImplementedError() - } - - private fun KtAnalysisSession.getDokkaAnnotationsFrom(annotated: KtAnnotated): List<Annotations.Annotation>? = - with(annotationTranslator) { getAllAnnotationsFrom(annotated) }.takeUnless { it.isEmpty() } - - private fun KtClassKind.toDokkaClassKind() = when (this) { - KtClassKind.CLASS -> KotlinClassKindTypes.CLASS - KtClassKind.ENUM_CLASS -> KotlinClassKindTypes.ENUM_CLASS - KtClassKind.ANNOTATION_CLASS -> KotlinClassKindTypes.ANNOTATION_CLASS - KtClassKind.OBJECT -> KotlinClassKindTypes.OBJECT - KtClassKind.COMPANION_OBJECT -> KotlinClassKindTypes.OBJECT - KtClassKind.INTERFACE -> KotlinClassKindTypes.INTERFACE - KtClassKind.ANONYMOUS_OBJECT -> KotlinClassKindTypes.OBJECT - } -} diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/utils/isException.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/utils/isException.kt deleted file mode 100644 index 08a2aaad..00000000 --- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/utils/isException.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. - */ - -package org.jetbrains.dokka.analysis.kotlin.symbols.utils - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.AncestryNode -import org.jetbrains.dokka.model.TypeConstructor - -internal fun AncestryNode.typeConstructorsBeingExceptions(): List<TypeConstructor> { - fun traverseSupertypes(ancestry: AncestryNode): List<TypeConstructor> = - listOf(ancestry.typeConstructor) + (ancestry.superclass?.let(::traverseSupertypes) ?: emptyList()) - - return traverseSupertypes(this).filter { type -> type.dri.isDirectlyAnException() } -} - -internal fun DRI.isDirectlyAnException(): Boolean = - toString().let { stringed -> - stringed == "kotlin/Exception///PointingToDeclaration/" || - stringed == "java.lang/Exception///PointingToDeclaration/" - } |