aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/Kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/kotlin/Kotlin')
-rw-r--r--core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt75
-rw-r--r--core/src/main/kotlin/Kotlin/DocumentationBuilder.kt914
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt3
3 files changed, 186 insertions, 806 deletions
diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
index ce20aeec..7c9f2d15 100644
--- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
+++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
@@ -30,20 +30,28 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
class DescriptorDocumentationParser
- @Inject constructor(val options: DokkaConfiguration.PassConfiguration,
- val logger: DokkaLogger,
- val linkResolver: DeclarationLinkResolver,
- val resolutionFacade: DokkaResolutionFacade,
- val refGraph: NodeReferenceGraph,
- val sampleService: SampleProcessingService,
- val signatureProvider: KotlinElementSignatureProvider,
- val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver
-)
-{
- fun parseDocumentation(descriptor: DeclarationDescriptor, inline: Boolean = false, isDefaultNoArgConstructor: Boolean = false): Content =
- parseDocumentationAndDetails(descriptor, inline, isDefaultNoArgConstructor).first
+@Inject constructor(
+ val options: DokkaConfiguration.PassConfiguration,
+ val logger: DokkaLogger,
+ val linkResolver: DeclarationLinkResolver,
+ val resolutionFacade: DokkaResolutionFacade,
+ val refGraph: NodeReferenceGraph,
+ val sampleService: SampleProcessingService,
+ val signatureProvider: KotlinElementSignatureProvider,
+ val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver
+) {
+ fun parseDocumentation(
+ descriptor: DeclarationDescriptor,
+ inline: Boolean = false,
+ isDefaultNoArgConstructor: Boolean = false
+ ): Content =
+ parseDocumentationAndDetails(descriptor, inline, isDefaultNoArgConstructor).first
- fun parseDocumentationAndDetails(descriptor: DeclarationDescriptor, inline: Boolean = false, isDefaultNoArgConstructor: Boolean = false): Pair<Content, (DocumentationNode) -> Unit> {
+ fun parseDocumentationAndDetails(
+ descriptor: DeclarationDescriptor,
+ inline: Boolean = false,
+ isDefaultNoArgConstructor: Boolean = false
+ ): Pair<Content, (DocumentationNode) -> Unit> {
if (descriptor is JavaClassDescriptor || descriptor is JavaCallableMemberDescriptor) {
return parseJavadoc(descriptor)
}
@@ -51,8 +59,8 @@ class DescriptorDocumentationParser
val kdoc = descriptor.findKDoc() ?: findStdlibKDoc(descriptor)
if (kdoc == null) {
if (options.effectivePackageOptions(descriptor.fqNameSafe).reportUndocumented && !descriptor.isDeprecated() &&
- descriptor !is ValueParameterDescriptor && descriptor !is TypeParameterDescriptor &&
- descriptor !is PropertyAccessorDescriptor && !descriptor.isSuppressWarning()) {
+ descriptor !is ValueParameterDescriptor && descriptor !is TypeParameterDescriptor &&
+ descriptor !is PropertyAccessorDescriptor && !descriptor.isSuppressWarning()) {
logger.warn("No documentation for ${descriptor.signatureWithSourceLocation()}")
}
return Content.Empty to { node -> }
@@ -62,7 +70,7 @@ class DescriptorDocumentationParser
(PsiTreeUtil.getParentOfType(kdoc, KDoc::class.java)?.context as? KtDeclaration)
?.takeIf { it != descriptor.original.sourcePsi() }
?.resolveToDescriptorIfAny()
- ?: descriptor
+ ?: descriptor
var kdocText = if (isDefaultNoArgConstructor) {
getConstructorTagContent(descriptor) ?: kdoc.getContent()
@@ -74,7 +82,11 @@ class DescriptorDocumentationParser
}
val tree = parseMarkdown(kdocText)
val linkMap = LinkMap.buildLinkMap(tree.node, kdocText)
- val content = buildContent(tree, LinkResolver(linkMap) { href -> linkResolver.resolveContentLink(contextDescriptor, href) }, inline)
+ val content = buildContent(
+ tree,
+ LinkResolver(linkMap) { href -> linkResolver.resolveContentLink(contextDescriptor, href) },
+ inline
+ )
if (kdoc is KDocSection) {
val tags = kdoc.getTags()
tags.forEach {
@@ -87,7 +99,10 @@ class DescriptorDocumentationParser
val section = content.addSection(javadocSectionDisplayName(it.name), it.getSubjectName())
val sectionContent = it.getContent()
val markdownNode = parseMarkdown(sectionContent)
- buildInlineContentTo(markdownNode, section, LinkResolver(linkMap) { href -> linkResolver.resolveContentLink(contextDescriptor, href) })
+ buildInlineContentTo(
+ markdownNode,
+ section,
+ LinkResolver(linkMap) { href -> linkResolver.resolveContentLink(contextDescriptor, href) })
}
}
}
@@ -102,7 +117,7 @@ class DescriptorDocumentationParser
}
- private fun DeclarationDescriptor.isSuppressWarning() : Boolean {
+ private fun DeclarationDescriptor.isSuppressWarning(): Boolean {
val suppressAnnotation = annotations.findAnnotation(FqName(Suppress::class.qualifiedName!!))
return if (suppressAnnotation != null) {
@Suppress("UNCHECKED_CAST")
@@ -126,11 +141,12 @@ class DescriptorDocumentationParser
}
if (DescriptorUtils.getFqName(deepestDescriptor.containingDeclaration).asString() == "kotlin.Any") {
val anyClassDescriptors = resolutionFacade.resolveSession.getTopLevelClassifierDescriptors(
- FqName.fromSegments(listOf("kotlin", "Any")), NoLookupLocation.FROM_IDE)
+ FqName.fromSegments(listOf("kotlin", "Any")), NoLookupLocation.FROM_IDE
+ )
anyClassDescriptors.forEach {
val anyMethod = (it as ClassDescriptor).getMemberScope(listOf())
- .getDescriptorsFiltered(DescriptorKindFilter.FUNCTIONS) { it == descriptor.name }
- .single()
+ .getDescriptorsFiltered(DescriptorKindFilter.FUNCTIONS) { it == descriptor.name }
+ .single()
val kdoc = anyMethod.findKDoc()
if (kdoc != null) {
return kdoc
@@ -145,17 +161,12 @@ class DescriptorDocumentationParser
val psi = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi
if (psi is PsiDocCommentOwner) {
val parseResult = JavadocParser(
- refGraph,
- logger,
- signatureProvider,
- externalDocumentationLinkResolver
+ refGraph,
+ logger,
+ signatureProvider,
+ externalDocumentationLinkResolver
).parseDocumentation(psi as PsiNamedElement)
- return parseResult.content to { node ->
- parseResult.deprecatedContent?.let {
- val deprecationNode = DocumentationNode("", it, NodeKind.Modifier)
- node.append(deprecationNode, RefKind.Deprecation)
- }
- }
+ return parseResult.content to { node -> }
}
return Content.Empty to { node -> }
}
diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
index 3168e033..6d258564 100644
--- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
+++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt
@@ -1,61 +1,51 @@
package org.jetbrains.dokka
import com.google.inject.Inject
-import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiJavaFile
import org.jetbrains.dokka.DokkaConfiguration.PassConfiguration
-import org.jetbrains.dokka.Kotlin.DescriptorDocumentationParser
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-import org.jetbrains.kotlin.coroutines.hasFunctionOrSuspendFunctionType
import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.annotations.Annotated
-import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
-import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
import org.jetbrains.kotlin.idea.kdoc.findKDoc
-import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
-import org.jetbrains.kotlin.idea.util.makeNotNullable
-import org.jetbrains.kotlin.idea.util.toFuzzyType
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtModifierListOwner
-import org.jetbrains.kotlin.psi.KtParameter
-import org.jetbrains.kotlin.psi.addRemoveModifier.MODIFIERS_ORDER
import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.findTopMostOverriddenDescriptors
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
-import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlin.util.supertypesWithAny
+import kotlin.reflect.KClass
import com.google.inject.name.Named as GuiceNamed
-private fun isExtensionForExternalClass(extensionFunctionDescriptor: DeclarationDescriptor,
- extensionReceiverDescriptor: DeclarationDescriptor,
- allFqNames: Collection<FqName>): Boolean {
- val extensionFunctionPackage = DescriptorUtils.getParentOfType(extensionFunctionDescriptor, PackageFragmentDescriptor::class.java)
- val extensionReceiverPackage = DescriptorUtils.getParentOfType(extensionReceiverDescriptor, PackageFragmentDescriptor::class.java)
+private fun isExtensionForExternalClass(
+ extensionFunctionDescriptor: DeclarationDescriptor,
+ extensionReceiverDescriptor: DeclarationDescriptor,
+ allFqNames: Collection<FqName>
+): Boolean {
+ val extensionFunctionPackage =
+ DescriptorUtils.getParentOfType(extensionFunctionDescriptor, PackageFragmentDescriptor::class.java)
+ val extensionReceiverPackage =
+ DescriptorUtils.getParentOfType(extensionReceiverDescriptor, PackageFragmentDescriptor::class.java)
return extensionFunctionPackage != null && extensionReceiverPackage != null &&
extensionFunctionPackage.fqName != extensionReceiverPackage.fqName &&
extensionReceiverPackage.fqName !in allFqNames
}
interface PackageDocumentationBuilder {
- fun buildPackageDocumentation(documentationBuilder: DocumentationBuilder,
- packageName: FqName,
- packageNode: DocumentationNode,
- declarations: List<DeclarationDescriptor>,
- allFqNames: Collection<FqName>)
+ fun buildPackageDocumentation(
+ documentationBuilder: DocumentationBuilder,
+ packageName: FqName,
+ packageNode: DocumentationNodes.Package,
+ declarations: List<DeclarationDescriptor>,
+ allFqNames: Collection<FqName>
+ )
}
interface DefaultPlatformsProvider {
@@ -67,121 +57,33 @@ val ignoredSupertypes = setOf(
)
class DocumentationBuilder
-@Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val descriptorDocumentationParser: DescriptorDocumentationParser,
- val passConfiguration: DokkaConfiguration.PassConfiguration,
- val refGraph: NodeReferenceGraph,
- val platformNodeRegistry: PlatformNodeRegistry,
- val logger: DokkaLogger,
- val linkResolver: DeclarationLinkResolver,
- val defaultPlatformsProvider: DefaultPlatformsProvider) {
- val boringBuiltinClasses = setOf(
- "kotlin.Unit", "kotlin.Byte", "kotlin.Short", "kotlin.Int", "kotlin.Long", "kotlin.Char", "kotlin.Boolean",
- "kotlin.Float", "kotlin.Double", "kotlin.String", "kotlin.Array", "kotlin.Any")
- val knownModifiers = setOf(
- KtTokens.PUBLIC_KEYWORD, KtTokens.PROTECTED_KEYWORD, KtTokens.INTERNAL_KEYWORD, KtTokens.PRIVATE_KEYWORD,
- KtTokens.OPEN_KEYWORD, KtTokens.FINAL_KEYWORD, KtTokens.ABSTRACT_KEYWORD, KtTokens.SEALED_KEYWORD,
- KtTokens.OVERRIDE_KEYWORD, KtTokens.INLINE_KEYWORD)
-
- fun link(node: DocumentationNode, descriptor: DeclarationDescriptor, kind: RefKind) {
- refGraph.link(node, descriptor.signature(), kind)
- }
-
- fun link(fromDescriptor: DeclarationDescriptor?, toDescriptor: DeclarationDescriptor?, kind: RefKind) {
- if (fromDescriptor != null && toDescriptor != null) {
- refGraph.link(fromDescriptor.signature(), toDescriptor.signature(), kind)
- }
- }
-
- fun register(descriptor: DeclarationDescriptor, node: DocumentationNode) {
- refGraph.register(descriptor.signature(), node)
- }
-
- fun <T> nodeForDescriptor(
- descriptor: T,
- kind: NodeKind,
- external: Boolean = false
- ): DocumentationNode where T : DeclarationDescriptor, T : Named {
- val (doc, callback) =
- if (external) {
- Content.Empty to { node -> }
- } else {
- descriptorDocumentationParser.parseDocumentationAndDetails(
- descriptor,
- kind == NodeKind.Parameter
- )
- }
- val node = DocumentationNode(descriptor.name.asString(), doc, kind).withModifiers(descriptor)
- node.appendSignature(descriptor)
- callback(node)
- return node
- }
-
- private fun DocumentationNode.withModifiers(descriptor: DeclarationDescriptor): DocumentationNode {
- if (descriptor is MemberDescriptor) {
- appendVisibility(descriptor)
- if (descriptor !is ConstructorDescriptor) {
- appendModality(descriptor)
- }
- }
- return this
- }
+@Inject constructor(
+ val resolutionFacade: DokkaResolutionFacade,
+ val passConfiguration: DokkaConfiguration.PassConfiguration,
+ val logger: DokkaLogger
+) {
- fun DocumentationNode.appendModality(descriptor: MemberDescriptor) {
- var modality = descriptor.modality
- if (modality == Modality.OPEN) {
- val containingClass = descriptor.containingDeclaration as? ClassDescriptor
- if (containingClass?.modality == Modality.FINAL) {
- modality = Modality.FINAL
- }
- }
- val modifier = modality.name.toLowerCase()
- appendTextNode(modifier, NodeKind.Modifier)
- }
-
- fun DocumentationNode.appendInline(descriptor: DeclarationDescriptor, psi: KtModifierListOwner) {
- if (!psi.hasModifier(KtTokens.INLINE_KEYWORD)) return
- if (descriptor is FunctionDescriptor
- && descriptor.valueParameters.none { it.hasFunctionOrSuspendFunctionType }) return
- appendTextNode(KtTokens.INLINE_KEYWORD.value, NodeKind.Modifier)
- }
-
- fun DocumentationNode.appendVisibility(descriptor: DeclarationDescriptorWithVisibility) {
- val modifier = descriptor.visibility.normalize().displayName
- appendTextNode(modifier, NodeKind.Modifier)
- }
-
- fun DocumentationNode.appendSupertype(descriptor: ClassDescriptor, superType: KotlinType, backref: Boolean) {
+ private fun DocumentationNodes.Class.appendSupertype(descriptor: ClassDescriptor, superType: KotlinType, backref: Boolean) {
val unwrappedType = superType.unwrap()
if (unwrappedType is AbbreviatedType) {
appendSupertype(descriptor, unwrappedType.abbreviation, backref)
} else {
- appendType(unwrappedType, NodeKind.Supertype)
- val superclass = unwrappedType.constructor.declarationDescriptor
- if (backref) {
- link(superclass, descriptor, RefKind.Inheritor)
- }
- link(descriptor, superclass, RefKind.Superclass)
+ appendType(unwrappedType, descriptor)
}
}
- fun DocumentationNode.appendProjection(projection: TypeProjection, kind: NodeKind = NodeKind.Type) {
- if (projection.isStarProjection) {
- appendTextNode("*", NodeKind.Type)
- } else {
- appendType(projection.type, kind, projection.projectionKind.label)
- }
- }
-
- fun DocumentationNode.appendType(kotlinType: KotlinType?, kind: NodeKind = NodeKind.Type, prefix: String = "") {
+ private fun DocumentationNodes.Class.appendType(
+ kotlinType: KotlinType?,
+ descriptor: ClassDescriptor?
+ ) {
if (kotlinType == null)
return
(kotlinType.unwrap() as? AbbreviatedType)?.let {
- return appendType(it.abbreviation)
+ return appendType(it.abbreviation, descriptor)
}
if (kotlinType.isDynamic()) {
- append(DocumentationNode("dynamic", Content.Empty, kind), RefKind.Detail)
+ append(kind.createNode("dynamic", descriptor), RefKind.Detail)
return
}
@@ -198,244 +100,80 @@ class DocumentationBuilder
is Named -> classifierDescriptor.name.asString()
else -> "<anonymous>"
}
- val node = DocumentationNode(name, Content.Empty, kind)
- if (prefix != "") {
- node.appendTextNode(prefix, NodeKind.Modifier)
- }
- if (kotlinType.isNullabilityFlexible()) {
- node.appendTextNode("!", NodeKind.NullabilityModifier)
- } else if (kotlinType.isMarkedNullable) {
- node.appendTextNode("?", NodeKind.NullabilityModifier)
- }
- if (classifierDescriptor != null) {
- val externalLink =
- linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor)
- if (externalLink != null) {
- if (classifierDescriptor !is TypeParameterDescriptor) {
- val targetNode =
- refGraph.lookup(classifierDescriptor.signature()) ?: classifierDescriptor.build(true)
- node.append(targetNode, RefKind.ExternalType)
- node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
- }
- } else {
- link(
- node, classifierDescriptor,
- if (classifierDescriptor.isBoringBuiltinClass()) RefKind.HiddenLink else RefKind.Link
- )
- }
- if (classifierDescriptor !is TypeParameterDescriptor) {
- node.append(
- DocumentationNode(
- classifierDescriptor.fqNameUnsafe.asString(),
- Content.Empty,
- NodeKind.QualifiedName
- ), RefKind.Detail
- )
- }
- }
-
+ val node = kind.createNode(name, descriptor)
append(node, RefKind.Detail)
- node.appendAnnotations(kotlinType)
for (typeArgument in kotlinType.arguments) {
- node.appendProjection(typeArgument)
- }
- }
-
- fun ClassifierDescriptor.isBoringBuiltinClass(): Boolean =
- DescriptorUtils.getFqName(this).asString() in boringBuiltinClasses
-
- fun DocumentationNode.appendAnnotations(annotated: Annotated) {
- annotated.annotations.forEach {
- it.build()?.let { annotationNode ->
- if (annotationNode.isSinceKotlin()) {
- appendSinceKotlin(annotationNode)
- }
- else {
- val refKind = when {
- it.isDocumented() ->
- when {
- annotationNode.isDeprecation() -> RefKind.Deprecation
- else -> RefKind.Annotation
- }
- it.isHiddenInDocumentation() -> RefKind.HiddenAnnotation
- else -> return@forEach
- }
- append(annotationNode, refKind)
- }
-
- }
- }
- }
-
- fun DocumentationNode.appendExternalLink(externalLink: String) {
- append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
- }
-
- fun DocumentationNode.appendExternalLink(descriptor: DeclarationDescriptor) {
- val target = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(descriptor)
- if (target != null) {
- appendExternalLink(target)
- }
- }
-
- fun DocumentationNode.appendSinceKotlin(annotation: DocumentationNode) {
- val kotlinVersion = annotation
- .detail(NodeKind.Parameter)
- .detail(NodeKind.Value)
- .name.removeSurrounding("\"")
-
- sinceKotlin = kotlinVersion
- }
-
- fun DocumentationNode.appendDefaultSinceKotlin() {
- if (sinceKotlin == null) {
- sinceKotlin = passConfiguration.sinceKotlin
- }
- }
-
- fun DocumentationNode.appendModifiers(descriptor: DeclarationDescriptor) {
- val psi = (descriptor as DeclarationDescriptorWithSource).source.getPsi() as? KtModifierListOwner ?: return
- KtTokens.MODIFIER_KEYWORDS_ARRAY.filter {
- it !in knownModifiers
- }.sortedBy {
- MODIFIERS_ORDER.indexOf(it)
- }.forEach {
- if (psi.hasModifier(it)) {
- appendTextNode(it.value, NodeKind.Modifier)
- }
+ node.appendProjection(typeArgument, null)
}
- appendInline(descriptor, psi)
}
- fun DocumentationNode.appendDefaultPlatforms(descriptor: DeclarationDescriptor) {
- for (platform in defaultPlatformsProvider.getDefaultPlatforms(descriptor)) {
- append(platformNodeRegistry[platform], RefKind.Platform)
- }
- }
-
- fun DocumentationNode.isDeprecation() = name == "Deprecated" || name == "deprecated"
-
- fun DocumentationNode.isSinceKotlin() = name == "SinceKotlin" && kind == NodeKind.Annotation
-
- fun DocumentationNode.appendSourceLink(sourceElement: SourceElement) {
- appendSourceLink(sourceElement.getPsi(), passConfiguration.sourceLinks)
- }
-
- fun DocumentationNode.appendSignature(descriptor: DeclarationDescriptor) {
- appendTextNode(descriptor.signature(), NodeKind.Signature, RefKind.Detail)
- }
-
- fun DocumentationNode.appendChild(descriptor: DeclarationDescriptor, kind: RefKind): DocumentationNode? {
+ fun DocumentationNode<*>.appendChild(descriptor: DeclarationDescriptor) {
if (!descriptor.isGenerated() && descriptor.isDocumented(passConfiguration)) {
val node = descriptor.build()
append(node, kind)
- return node
}
- return null
}
- fun createGroupNode(signature: String, nodes: List<DocumentationNode>) = (nodes.find { it.kind == NodeKind.GroupNode } ?:
- DocumentationNode(nodes.first().name, Content.Empty, NodeKind.GroupNode).apply {
- appendTextNode(signature, NodeKind.Signature, RefKind.Detail)
- })
- .also { groupNode ->
- nodes.forEach { node ->
- if (node != groupNode) {
- node.owner?.let { owner ->
- node.dropReferences { it.to == owner && it.kind == RefKind.Owner }
- owner.dropReferences { it.to == node && it.kind == RefKind.Member }
- owner.append(groupNode, RefKind.Member)
- }
- groupNode.append(node, RefKind.Member)
- }
- }
- }
-
-
- fun DocumentationNode.appendOrUpdateMember(descriptor: DeclarationDescriptor) {
- if (descriptor.isGenerated() || !descriptor.isDocumented(passConfiguration)) return
-
- val existingNode = refGraph.lookup(descriptor.signature())
- if (existingNode != null) {
- if (existingNode.kind == NodeKind.TypeAlias && descriptor is ClassDescriptor
- || existingNode.kind == NodeKind.Class && descriptor is TypeAliasDescriptor) {
- val node = createGroupNode(descriptor.signature(), listOf(existingNode, descriptor.build()))
- register(descriptor, node)
- return
- }
-
- existingNode.updatePlatforms(descriptor)
-
- if (descriptor is ClassDescriptor) {
- val membersToDocument = descriptor.collectMembersToDocument()
- for ((memberDescriptor, inheritedLinkKind, extraModifier) in membersToDocument) {
- if (memberDescriptor is ClassDescriptor) {
- existingNode.appendOrUpdateMember(memberDescriptor) // recurse into nested classes
- }
- else {
- val existingMemberNode = refGraph.lookup(memberDescriptor.signature())
- if (existingMemberNode != null) {
- existingMemberNode.updatePlatforms(memberDescriptor)
- }
- else {
- existingNode.appendClassMember(memberDescriptor, inheritedLinkKind, extraModifier)
+ fun DocumentationNode.appendMember(descriptor: DeclarationDescriptor) {
+ if (!descriptor.isGenerated() && descriptor.isDocumented(passConfiguration)) {
+ val existingNode = members.firstOrNull { it.descriptor?.fqNameSafe == descriptor.fqNameSafe }
+ if (existingNode != null) {
+ if (descriptor is ClassDescriptor) {
+ val membersToDocument = descriptor.collectMembersToDocument()
+ for ((memberDescriptor, _, _) in membersToDocument) {
+ if (memberDescriptor is ClassDescriptor) {
+ existingNode.appendMember(memberDescriptor) // recurse into nested classes
+ } else {
+ if (members.any { it.descriptor?.fqNameSafe == memberDescriptor.fqNameSafe }) {
+ existingNode.appendClassMember(memberDescriptor)
+ }
}
}
}
+ } else {
+ appendChild(descriptor, RefKind.Member)
}
}
- else {
- appendChild(descriptor, RefKind.Member)
- }
- }
-
- private fun DocumentationNode.updatePlatforms(descriptor: DeclarationDescriptor) {
- for (platform in defaultPlatformsProvider.getDefaultPlatforms(descriptor) - platforms) {
- append(platformNodeRegistry[platform], RefKind.Platform)
- }
}
- fun DocumentationNode.appendClassMember(descriptor: DeclarationDescriptor,
- inheritedLinkKind: RefKind = RefKind.InheritedMember,
- extraModifier: String?) {
- if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
- val baseDescriptor = descriptor.overriddenDescriptors.firstOrNull()
- if (baseDescriptor != null) {
- link(this, baseDescriptor, inheritedLinkKind)
- }
- } else {
+ private fun DocumentationNode.appendClassMember(descriptor: DeclarationDescriptor) {
+ if (descriptor !is CallableMemberDescriptor || descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
val descriptorToUse = if (descriptor is ConstructorDescriptor) descriptor else descriptor.original
- val child = appendChild(descriptorToUse, RefKind.Member)
- if (extraModifier != null) {
- child?.appendTextNode("static", NodeKind.Modifier)
- }
+ appendChild(descriptorToUse, RefKind.Member)
}
}
- fun DocumentationNode.appendInPageChildren(descriptors: Iterable<DeclarationDescriptor>, kind: RefKind) {
- descriptors.forEach { descriptor ->
- val node = appendChild(descriptor, kind)
- node?.addReferenceTo(this, RefKind.TopLevelPage)
- }
- }
-
- fun DocumentationModule.appendFragments(fragments: Collection<PackageFragmentDescriptor>,
- packageContent: Map<String, Content>,
- packageDocumentationBuilder: PackageDocumentationBuilder) {
- val allFqNames = fragments.filter{ it.isDocumented(passConfiguration) }.map { it.fqName }.distinct()
+ fun DocumentationNodes.Module.appendFragments(
+ fragments: Collection<PackageFragmentDescriptor>,
+ packageDocumentationBuilder: PackageDocumentationBuilder
+ ) {
+ val allFqNames = fragments.filter { it.isDocumented(passConfiguration) }.map { it.fqName }.distinct()
for (packageName in allFqNames) {
if (packageName.isRoot && !passConfiguration.includeRootPackage) continue
- val declarations = fragments.filter { it.fqName == packageName }.flatMap { it.getMemberScope().getContributedDescriptors() }
+ val declarations = fragments.filter { it.fqName == packageName }
+ .flatMap { it.getMemberScope().getContributedDescriptors() }
if (passConfiguration.skipEmptyPackages && declarations.none { it.isDocumented(passConfiguration) }) continue
logger.info(" package $packageName: ${declarations.count()} declarations")
- val packageNode = findOrCreatePackageNode(this, packageName.asString(), packageContent, this@DocumentationBuilder.refGraph)
- packageDocumentationBuilder.buildPackageDocumentation(this@DocumentationBuilder, packageName, packageNode,
- declarations, allFqNames)
+ val packageNode = findOrCreatePackageNode(this, packageName.asString())
+ packageDocumentationBuilder.buildPackageDocumentation(
+ this@DocumentationBuilder, packageName, packageNode,
+ declarations, allFqNames
+ )
}
+ }
+ fun findOrCreatePackageNode(
+ module: DocumentationNodes.Module,
+ packageName: String
+ ): DocumentationNode<*> {
+ val node = module?.member(DocumentationNodes.Package::class) ?: DocumentationNodes.Package(packageName)
+ if (module != null && node !in module.members) {
+ module.append(node, RefKind.Member)
+ }
+ return node
}
fun propagateExtensionFunctionsToSubclasses(
@@ -466,12 +204,6 @@ class DocumentationBuilder
).asSequence()
}
-
- val documentingDescriptors = fragments.flatMap { it.getMemberScope().getContributedDescriptors() }
- val documentingClasses = documentingDescriptors.filterIsInstance<ClassDescriptor>()
-
- val classHierarchy = buildClassHierarchy(documentingClasses)
-
val allExtensionFunctions =
allDescriptors
.filterIsInstance<CallableMemberDescriptor>()
@@ -479,9 +211,9 @@ class DocumentationBuilder
val extensionFunctionsByName = allExtensionFunctions.groupBy { it.name }
fun isIgnoredReceiverType(type: KotlinType) =
- type.isDynamic() ||
- type.isAnyOrNullableAny() ||
- (type.isTypeParameter() && type.immediateSupertypes().all { it.isAnyOrNullableAny() })
+ type.isDynamic() ||
+ type.isAnyOrNullableAny() ||
+ (type.isTypeParameter() && type.immediateSupertypes().all { it.isAnyOrNullableAny() })
for (extensionFunction in allExtensionFunctions) {
@@ -492,53 +224,9 @@ class DocumentationBuilder
?: emptyList()
if (isIgnoredReceiverType(extensionReceiverParameter.type)) continue
- val subclasses =
- classHierarchy.filter { (key) -> key.isExtensionApplicable(extensionFunction) }
- if (subclasses.isEmpty()) continue
- subclasses.values.flatten().forEach { subclass ->
- if (subclass.isExtensionApplicable(extensionFunction) &&
- possiblyShadowingFunctions.none { subclass.isExtensionApplicable(it) }) {
-
- val hasExternalLink =
- linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(
- extensionFunction
- ) != null
- if (hasExternalLink) {
- val containerDesc =
- extensionFunction.containingDeclaration as? PackageFragmentDescriptor
- if (containerDesc != null) {
- val container = refGraph.lookup(containerDesc.signature())
- ?: containerDesc.buildExternal()
- container.append(extensionFunction.buildExternal(), RefKind.Member)
- }
- }
-
- refGraph.link(subclass.signature(), extensionFunction.signature(), RefKind.Extension)
- }
- }
}
}
- private fun ClassDescriptor.isExtensionApplicable(extensionFunction: CallableMemberDescriptor): Boolean {
- val receiverType = extensionFunction.fuzzyExtensionReceiverType()?.makeNotNullable()
- val classType = defaultType.toFuzzyType(declaredTypeParameters)
- return receiverType != null && classType.checkIsSubtypeOf(receiverType) != null
- }
-
- private fun buildClassHierarchy(classes: List<ClassDescriptor>): Map<ClassDescriptor, List<ClassDescriptor>> {
- val result = hashMapOf<ClassDescriptor, MutableList<ClassDescriptor>>()
- classes.forEach { cls ->
- TypeUtils.getAllSupertypes(cls.defaultType).forEach { supertype ->
- val classDescriptor = supertype.constructor.declarationDescriptor as? ClassDescriptor
- if (classDescriptor != null) {
- val subtypesList = result.getOrPut(classDescriptor) { arrayListOf() }
- subtypesList.add(cls)
- }
- }
- }
- return result
- }
-
private fun CallableMemberDescriptor.canShadow(other: CallableMemberDescriptor): Boolean {
if (this == other) return false
if (this is PropertyDescriptor && other is PropertyDescriptor) {
@@ -570,89 +258,47 @@ class DocumentationBuilder
else -> throw IllegalStateException("Descriptor $this is not known")
}
- fun PackageFragmentDescriptor.buildExternal(): DocumentationNode {
- val node = DocumentationNode(fqName.asString(), Content.Empty, NodeKind.Package)
-
- val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(this)
- if (externalLink != null) {
- node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
- }
- register(this, node)
- return node
- }
-
- fun CallableDescriptor.buildExternal(): DocumentationNode = when(this) {
- is FunctionDescriptor -> build(true)
- is PropertyDescriptor -> build(true)
- else -> throw IllegalStateException("Descriptor $this is not known")
- }
-
-
fun ClassifierDescriptor.build(external: Boolean = false): DocumentationNode = when (this) {
- is ClassDescriptor -> build(external)
- is TypeAliasDescriptor -> build(external)
+ is ClassDescriptor -> build(this, external)
+ is TypeAliasDescriptor -> build()
is TypeParameterDescriptor -> build()
else -> throw IllegalStateException("Descriptor $this is not known")
}
- fun TypeAliasDescriptor.build(external: Boolean = false): DocumentationNode {
- val node = nodeForDescriptor(this, NodeKind.TypeAlias)
-
- if (!external) {
- node.appendDefaultSinceKotlin()
- node.appendAnnotations(this)
- }
- node.appendModifiers(this)
- node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail)
-
- node.appendType(underlyingType, NodeKind.TypeAliasUnderlyingType)
-
- if (!external) {
- node.appendSourceLink(source)
- node.appendDefaultPlatforms(this)
- }
- register(this, node)
+ fun TypeAliasDescriptor.build(): DocumentationNode {
+ val node = DocumentationNodes.TypeAlias(name.asString(), this)
+ node.appendType(underlyingType, this, DocumentationNodes.TypeAliasUnderlyingType::class)
return node
}
- fun ClassDescriptor.build(external: Boolean = false): DocumentationNode {
- val kind = when {
- kind == ClassKind.OBJECT -> NodeKind.Object
- kind == ClassKind.INTERFACE -> NodeKind.Interface
- kind == ClassKind.ENUM_CLASS -> NodeKind.Enum
- kind == ClassKind.ANNOTATION_CLASS -> NodeKind.AnnotationClass
- kind == ClassKind.ENUM_ENTRY -> NodeKind.EnumItem
- isSubclassOfThrowable() -> NodeKind.Exception
- else -> NodeKind.Class
+ fun ClassDescriptor.build(descriptor: DeclarationDescriptor, external: Boolean = false): DocumentationNode {
+ val node = when {
+ kind == ClassKind.OBJECT -> DocumentationNodes.Object(descriptor.name.asString(), descriptor)
+ kind == ClassKind.INTERFACE -> DocumentationNodes.Interface(descriptor.name.asString(), descriptor)
+ kind == ClassKind.ENUM_CLASS -> DocumentationNodes.Enum(descriptor.name.asString(), descriptor)
+ kind == ClassKind.ANNOTATION_CLASS -> DocumentationNodes.AnnotationClass(descriptor.name.asString(), descriptor)
+ kind == ClassKind.ENUM_ENTRY -> DocumentationNodes.EnumItem(descriptor.name.asString(), descriptor)
+ isSubclassOfThrowable() -> DocumentationNodes.Exception(descriptor.name.asString(), descriptor)
+ else -> DocumentationNodes.Class(descriptor.name.asString(), descriptor)
}
- val node = nodeForDescriptor(this, kind, external)
- register(this, node)
supertypesWithAnyPrecise().forEach {
node.appendSupertype(this, it, !external)
}
- if (getKind() != ClassKind.OBJECT && getKind() != ClassKind.ENUM_ENTRY) {
- node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail)
- }
if (!external) {
- for ((descriptor, inheritedLinkKind, extraModifier) in collectMembersToDocument()) {
- node.appendClassMember(descriptor, inheritedLinkKind, extraModifier)
+ for ((membersDescriptor, _, _) in collectMembersToDocument()) {
+ node.appendClassMember(membersDescriptor)
}
- node.appendDefaultSinceKotlin()
- node.appendAnnotations(this)
- }
- node.appendModifiers(this)
- if (!external) {
- node.appendSourceLink(source)
- node.appendDefaultPlatforms(this)
}
return node
}
- data class ClassMember(val descriptor: DeclarationDescriptor,
- val inheritedLinkKind: RefKind = RefKind.InheritedMember,
- val extraModifier: String? = null)
+ data class ClassMember(
+ val descriptor: DeclarationDescriptor,
+ val inheritedLinkKind: RefKind = RefKind.InheritedMember,
+ val extraModifier: String? = null
+ )
- fun ClassDescriptor.collectMembersToDocument(): List<ClassMember> {
+ private fun ClassDescriptor.collectMembersToDocument(): List<ClassMember> {
val result = arrayListOf<ClassMember>()
if (kind != ClassKind.OBJECT && kind != ClassKind.ENUM_ENTRY) {
val constructorsToDocument = if (kind == ClassKind.ENUM_CLASS)
@@ -663,11 +309,11 @@ class DocumentationBuilder
}
defaultType.memberScope.getContributedDescriptors()
- .filter { it != companionObjectDescriptor }
- .mapTo(result) { ClassMember(it) }
+ .filter { it != companionObjectDescriptor }
+ .mapTo(result) { ClassMember(it) }
staticScope.getContributedDescriptors()
- .mapTo(result) { ClassMember(it, extraModifier = "static") }
+ .mapTo(result) { ClassMember(it, extraModifier = "static") }
val companionObjectDescriptor = companionObjectDescriptor
if (companionObjectDescriptor != null && companionObjectDescriptor.isDocumented(passConfiguration)) {
@@ -678,274 +324,51 @@ class DocumentationBuilder
}
if (companionObjectDescriptor.getAllSuperclassesWithoutAny().isNotEmpty()
- || companionObjectDescriptor.getSuperInterfaces().isNotEmpty()) {
+ || companionObjectDescriptor.getSuperInterfaces().isNotEmpty()) {
result += ClassMember(companionObjectDescriptor)
}
}
return result
}
- fun CallableDescriptor.isInheritedFromAny(): Boolean {
+ private fun CallableDescriptor.isInheritedFromAny(): Boolean {
return findTopMostOverriddenDescriptors().any {
DescriptorUtils.getFqNameSafe(it.containingDeclaration).asString() == "kotlin.Any"
}
}
- fun ClassDescriptor.isSubclassOfThrowable(): Boolean =
- defaultType.supertypes().any { it.constructor.declarationDescriptor == builtIns.throwable }
+ private fun ClassDescriptor.isSubclassOfThrowable(): Boolean =
+ defaultType.supertypes().any { it.constructor.declarationDescriptor == builtIns.throwable }
- fun ConstructorDescriptor.build(): DocumentationNode {
- val node = nodeForDescriptor(this, NodeKind.Constructor)
- node.appendInPageChildren(valueParameters, RefKind.Detail)
- node.appendDefaultPlatforms(this)
- node.appendDefaultSinceKotlin()
- register(this, node)
- return node
- }
+ fun ConstructorDescriptor.build(): DocumentationNode =
+ DocumentationNodes.Constructor(name.asString(), this)
private fun CallableMemberDescriptor.inCompanionObject(): Boolean {
val containingDeclaration = containingDeclaration
- if ((containingDeclaration as? ClassDescriptor)?.isCompanionObject ?: false) {
+ if ((containingDeclaration as? ClassDescriptor)?.isCompanionObject == true) {
return true
}
val receiver = extensionReceiverParameter
return (receiver?.type?.constructor?.declarationDescriptor as? ClassDescriptor)?.isCompanionObject ?: false
}
- fun FunctionDescriptor.build(external: Boolean = false): DocumentationNode {
- if (ErrorUtils.containsErrorType(this)) {
- logger.warn("Found an unresolved type in ${signatureWithSourceLocation()}")
- }
-
- val node = nodeForDescriptor(this, if (inCompanionObject()) NodeKind.CompanionObjectFunction else NodeKind.Function, external)
-
- node.appendInPageChildren(typeParameters, RefKind.Detail)
- extensionReceiverParameter?.let { node.appendChild(it, RefKind.Detail) }
- node.appendInPageChildren(valueParameters, RefKind.Detail)
- node.appendType(returnType)
- if (!external) {
- node.appendDefaultSinceKotlin()
- }
- node.appendAnnotations(this)
- node.appendModifiers(this)
- if (!external) {
- node.appendSourceLink(source)
- node.appendDefaultPlatforms(this)
- } else {
- node.appendExternalLink(this)
- }
-
- overriddenDescriptors.forEach {
- addOverrideLink(it, this)
- }
-
- register(this, node)
- return node
- }
-
- fun addOverrideLink(baseClassFunction: CallableMemberDescriptor, overridingFunction: CallableMemberDescriptor) {
- val source = baseClassFunction.original.source.getPsi()
- if (source != null) {
- link(overridingFunction, baseClassFunction, RefKind.Override)
- } else {
- baseClassFunction.overriddenDescriptors.forEach {
- addOverrideLink(it, overridingFunction)
- }
- }
- }
-
- fun PropertyDescriptor.build(external: Boolean = false): DocumentationNode {
- val node = nodeForDescriptor(
- this,
- if (inCompanionObject()) NodeKind.CompanionObjectProperty else NodeKind.Property,
- external
- )
- node.appendInPageChildren(typeParameters, RefKind.Detail)
- extensionReceiverParameter?.let { node.appendChild(it, RefKind.Detail) }
- node.appendType(returnType)
- if (!external) {
- node.appendDefaultSinceKotlin()
- }
- node.appendAnnotations(this)
- node.appendModifiers(this)
- if (!external) {
- node.appendSourceLink(source)
- if (isVar) {
- node.appendTextNode("var", NodeKind.Modifier)
- }
-
- if (isConst) {
- this.compileTimeInitializer?.toDocumentationNode()?.let { node.append(it, RefKind.Detail) }
- }
-
-
- getter?.let {
- if (!it.isDefault) {
- node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Getter")
- }
- }
- setter?.let {
- if (!it.isDefault) {
- node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Setter")
- }
- }
- node.appendDefaultPlatforms(this)
- }
- if (external) {
- node.appendExternalLink(this)
- }
-
- overriddenDescriptors.forEach {
- addOverrideLink(it, this)
- }
-
- register(this, node)
- return node
- }
-
- fun DocumentationNode.addAccessorDocumentation(documentation: Content, prefix: String) {
- if (documentation == Content.Empty) return
- updateContent {
- if (!documentation.children.isEmpty()) {
- val section = addSection(prefix, null)
- documentation.children.forEach { section.append(it) }
- }
- documentation.sections.forEach {
- val section = addSection("$prefix ${it.tag}", it.subjectName)
- it.children.forEach { section.append(it) }
- }
- }
- }
-
- fun ValueParameterDescriptor.build(): DocumentationNode {
- val node = nodeForDescriptor(this, NodeKind.Parameter)
- node.appendType(varargElementType ?: type)
- if (declaresDefaultValue()) {
- val psi = source.getPsi() as? KtParameter
- if (psi != null) {
- val defaultValueText = psi.defaultValue?.text
- if (defaultValueText != null) {
- node.appendTextNode(defaultValueText, NodeKind.Value)
- }
- }
- }
- node.appendDefaultSinceKotlin()
- node.appendAnnotations(this)
- node.appendModifiers(this)
- if (varargElementType != null && node.details(NodeKind.Modifier).none { it.name == "vararg" }) {
- node.appendTextNode("vararg", NodeKind.Modifier)
- }
- register(this, node)
- return node
- }
-
- fun TypeParameterDescriptor.build(): DocumentationNode {
- val doc = descriptorDocumentationParser.parseDocumentation(this)
- val name = name.asString()
- val prefix = variance.label
-
- val node = DocumentationNode(name, doc, NodeKind.TypeParameter)
- if (prefix != "") {
- node.appendTextNode(prefix, NodeKind.Modifier)
- }
- if (isReified) {
- node.appendTextNode("reified", NodeKind.Modifier)
- }
-
- for (constraint in upperBounds) {
- if (KotlinBuiltIns.isDefaultBound(constraint)) {
- continue
- }
- node.appendType(constraint, NodeKind.UpperBound)
- }
- register(this, node)
- return node
- }
+ fun FunctionDescriptor.build(): DocumentationNode =
+ if (inCompanionObject())
+ DocumentationNodes.CompanionObjectFunction(name.asString(),this)
+ else
+ DocumentationNodes.Function(name.asString(),this)
- fun ReceiverParameterDescriptor.build(): DocumentationNode {
- var receiverClass: DeclarationDescriptor = type.constructor.declarationDescriptor!!
- if ((receiverClass as? ClassDescriptor)?.isCompanionObject ?: false) {
- receiverClass = receiverClass.containingDeclaration!!
- } else if (receiverClass is TypeParameterDescriptor) {
- val upperBoundClass = receiverClass.upperBounds.singleOrNull()?.constructor?.declarationDescriptor
- if (upperBoundClass != null) {
- receiverClass = upperBoundClass
- }
- }
+ fun PropertyDescriptor.build(): DocumentationNode =
+ DocumentationNodes.Property(name.asString(), this)
- if ((containingDeclaration as? FunctionDescriptor)?.dispatchReceiverParameter == null) {
- link(receiverClass, containingDeclaration, RefKind.Extension)
- }
-
- val node = DocumentationNode(name.asString(), Content.Empty, NodeKind.Receiver)
- node.appendType(type)
- register(this, node)
- return node
- }
-
- fun AnnotationDescriptor.build(): DocumentationNode? {
- val annotationClass = type.constructor.declarationDescriptor
- if (annotationClass == null || ErrorUtils.isError(annotationClass)) {
- return null
- }
- val node = DocumentationNode(annotationClass.name.asString(), Content.Empty, NodeKind.Annotation)
- allValueArguments.forEach { (name, value) ->
- val valueNode = value.toDocumentationNode()
- if (valueNode != null) {
- val paramNode = DocumentationNode(name.asString(), Content.Empty, NodeKind.Parameter)
- paramNode.append(valueNode, RefKind.Detail)
- node.append(paramNode, RefKind.Detail)
- }
- }
- return node
- }
-
- fun ConstantValue<*>.toDocumentationNode(): DocumentationNode? = value.let { value ->
- val text = when (value) {
- is String ->
- "\"" + StringUtil.escapeStringCharacters(value) + "\""
- is EnumEntrySyntheticClassDescriptor ->
- value.containingDeclaration.name.asString() + "." + value.name.asString()
- is Pair<*, *> -> {
- val (classId, name) = value
- if (classId is ClassId && name is Name) {
- classId.shortClassName.asString() + "." + name.asString()
- } else {
- value.toString()
- }
- }
- else -> "$value"
- }
- DocumentationNode(text, Content.Empty, NodeKind.Value)
- }
+ fun ValueParameterDescriptor.build(): DocumentationNode =
+ DocumentationNodes.Parameter(name.asString(), this)
+ fun TypeParameterDescriptor.build(): DocumentationNode =
+ DocumentationNodes.TypeParameter(name.asString(), this)
- fun DocumentationNode.getParentForPackageMember(
- descriptor: DeclarationDescriptor,
- externalClassNodes: MutableMap<FqName, DocumentationNode>,
- allFqNames: Collection<FqName>,
- packageName: FqName
- ): DocumentationNode {
- if (descriptor is CallableMemberDescriptor) {
- val extensionClassDescriptor = descriptor.getExtensionClassDescriptor()
- if (extensionClassDescriptor != null && isExtensionForExternalClass(descriptor, extensionClassDescriptor, allFqNames) &&
- !ErrorUtils.isError(extensionClassDescriptor)) {
- val fqName = DescriptorUtils.getFqNameSafe(extensionClassDescriptor)
- return externalClassNodes.getOrPut(fqName) {
- val newNode = DocumentationNode(fqName.asString(), Content.Empty, NodeKind.ExternalClass)
- val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(extensionClassDescriptor)
- if (externalLink != null) {
- newNode.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link)
- }
- append(newNode, RefKind.Member)
- refGraph.register("${packageName.asString()}:${extensionClassDescriptor.signature()}", newNode)
- newNode
- }
- }
- }
- return this
- }
-
+ fun ReceiverParameterDescriptor.build(): DocumentationNode =
+ DocumentationNodes.Receiver(name.asString(), this)
}
fun DeclarationDescriptor.isDocumented(passConfiguration: DokkaConfiguration.PassConfiguration): Boolean {
@@ -956,25 +379,22 @@ fun DeclarationDescriptor.isDocumented(passConfiguration: DokkaConfiguration.Pas
&& (!passConfiguration.effectivePackageOptions(fqNameSafe).skipDeprecated || !isDeprecated())
}
-private fun DeclarationDescriptor.isGenerated() = this is CallableMemberDescriptor && kind != CallableMemberDescriptor.Kind.DECLARATION
+private fun DeclarationDescriptor.isGenerated() =
+ this is CallableMemberDescriptor && kind != CallableMemberDescriptor.Kind.DECLARATION
class KotlinPackageDocumentationBuilder : PackageDocumentationBuilder {
- override fun buildPackageDocumentation(documentationBuilder: DocumentationBuilder,
- packageName: FqName,
- packageNode: DocumentationNode,
- declarations: List<DeclarationDescriptor>,
- allFqNames: Collection<FqName>) {
- val externalClassNodes = hashMapOf<FqName, DocumentationNode>()
+
+ override fun buildPackageDocumentation(
+ documentationBuilder: DocumentationBuilder,
+ packageName: FqName,
+ packageNode: DocumentationNode,
+ declarations: List<DeclarationDescriptor>,
+ allFqNames: Collection<FqName>
+ ) {
declarations.forEach { descriptor ->
with(documentationBuilder) {
if (descriptor.isDocumented(passConfiguration)) {
- val parent = packageNode.getParentForPackageMember(
- descriptor,
- externalClassNodes,
- allFqNames,
- packageName
- )
- parent.appendOrUpdateMember(descriptor)
+ packageNode.appendMember(descriptor)
}
}
}
@@ -982,17 +402,19 @@ class KotlinPackageDocumentationBuilder : PackageDocumentationBuilder {
}
class KotlinJavaDocumentationBuilder
-@Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val documentationBuilder: DocumentationBuilder,
- val passConfiguration: DokkaConfiguration.PassConfiguration,
- val logger: DokkaLogger) : JavaDocumentationBuilder {
+@Inject constructor(
+ val resolutionFacade: DokkaResolutionFacade,
+ val documentationBuilder: DocumentationBuilder,
+ val passConfiguration: DokkaConfiguration.PassConfiguration,
+ val logger: DokkaLogger
+) : JavaDocumentationBuilder {
override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) {
val classDescriptors = file.classes.map {
it.getJavaClassDescriptor(resolutionFacade)
}
if (classDescriptors.any { it != null && it.isDocumented(passConfiguration) }) {
- val packageNode = findOrCreatePackageNode(module, file.packageName, packageContent, documentationBuilder.refGraph)
+ val packageNode = documentationBuilder.findOrCreatePackageNode(module, file.packageName)
for (descriptor in classDescriptors.filterNotNull()) {
with(documentationBuilder) {
@@ -1003,24 +425,6 @@ class KotlinJavaDocumentationBuilder
}
}
-private val hiddenAnnotations = setOf(
- KotlinBuiltIns.FQ_NAMES.parameterName.asString()
-)
-
-private fun AnnotationDescriptor.isHiddenInDocumentation() =
- type.constructor.declarationDescriptor?.fqNameSafe?.asString() in hiddenAnnotations
-
-private fun AnnotationDescriptor.isDocumented(): Boolean {
- if (source.getPsi() != null && mustBeDocumented()) return true
- val annotationClassName = type.constructor.declarationDescriptor?.fqNameSafe?.asString()
- return annotationClassName == KotlinBuiltIns.FQ_NAMES.extensionFunctionType.asString()
-}
-
-fun AnnotationDescriptor.mustBeDocumented(): Boolean {
- val annotationClass = type.constructor.declarationDescriptor as? Annotated ?: return false
- return annotationClass.isDocumentedAnnotation()
-}
-
fun DeclarationDescriptor.isDocumentationSuppressed(passConfiguration: DokkaConfiguration.PassConfiguration): Boolean {
if (passConfiguration.effectivePackageOptions(fqNameSafe).suppress) return true
@@ -1037,25 +441,12 @@ fun DeclarationDescriptor.isDocumentationSuppressed(passConfiguration: DokkaConf
}
fun DeclarationDescriptor.sourcePsi() =
- ((original as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi
+ ((original as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi
fun DeclarationDescriptor.isDeprecated(): Boolean = annotations.any {
DescriptorUtils.getFqName(it.type.constructor.declarationDescriptor!!).asString() == "kotlin.Deprecated"
} || (this is ConstructorDescriptor && containingDeclaration.isDeprecated())
-fun CallableMemberDescriptor.getExtensionClassDescriptor(): ClassifierDescriptor? {
- val extensionReceiver = extensionReceiverParameter
- if (extensionReceiver != null) {
- val type = extensionReceiver.type
- val receiverClass = type.constructor.declarationDescriptor as? ClassDescriptor
- if (receiverClass?.isCompanionObject ?: false) {
- return receiverClass?.containingDeclaration as? ClassifierDescriptor
- }
- return receiverClass
- }
- return null
-}
-
fun DeclarationDescriptor.signature(): String {
if (this != original) return original.signature()
return when (this) {
@@ -1126,28 +517,6 @@ fun DeclarationDescriptor.sourceLocation(): String? {
return null
}
-fun DocumentationModule.prepareForGeneration(configuration: DokkaConfiguration) {
- if (configuration.generateIndexPages) {
- generateAllTypesNode()
- }
- nodeRefGraph.resolveReferences()
-}
-
-fun DocumentationNode.generateAllTypesNode() {
- val allTypes = members(NodeKind.Package)
- .flatMap { it.members.filter {
- it.kind in NodeKind.classLike || it.kind == NodeKind.ExternalClass
- || (it.kind == NodeKind.GroupNode && it.origins.all { it.kind in NodeKind.classLike }) } }
- .sortedBy { if (it.kind == NodeKind.ExternalClass) it.name.substringAfterLast('.').toLowerCase() else it.name.toLowerCase() }
-
- val allTypesNode = DocumentationNode("alltypes", Content.Empty, NodeKind.AllTypes)
- for (typeNode in allTypes) {
- allTypesNode.addReferenceTo(typeNode, RefKind.Member)
- }
-
- append(allTypesNode, RefKind.Member)
-}
-
fun ClassDescriptor.supertypesWithAnyPrecise(): Collection<KotlinType> {
if (KotlinBuiltIns.isAny(this)) {
return emptyList()
@@ -1160,5 +529,6 @@ fun PassConfiguration.effectivePackageOptions(pack: String): DokkaConfiguration.
return perPackageOptions.firstOrNull { pack == it.prefix || pack.startsWith(it.prefix + ".") } ?: rootPackageOptions
}
-fun PassConfiguration.effectivePackageOptions(pack: FqName): DokkaConfiguration.PackageOptions = effectivePackageOptions(pack.asString())
+fun PassConfiguration.effectivePackageOptions(pack: FqName): DokkaConfiguration.PackageOptions =
+ effectivePackageOptions(pack.asString())
diff --git a/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt
index ee9d8c51..70c04da6 100644
--- a/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt
+++ b/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt
@@ -30,8 +30,7 @@ class KotlinAsJavaDocumentationBuilder
return
}
- val javaDocumentationBuilder = JavaPsiDocumentationBuilder(documentationBuilder.passConfiguration,
- documentationBuilder.refGraph,
+ val javaDocumentationBuilder = JavaPsiDocumentationBuilder(documentationBuilder,
kotlinAsJavaDocumentationParser)
psiPackage.classes.filter { it is KtLightElement<*, *> }.filter { it.isVisibleInDocumentation() }.forEach {