aboutsummaryrefslogtreecommitdiff
path: root/src/Kotlin/DocumentationBuilder.kt
diff options
context:
space:
mode:
authorDmitry Jemerov <yole@jetbrains.com>2015-12-03 16:22:11 +0100
committerDmitry Jemerov <yole@jetbrains.com>2015-12-03 16:22:49 +0100
commit39631054c58df5841ea268b7002b820ec55f6e0a (patch)
treecefedd8411c859243bd181568e16fcdd372a38c8 /src/Kotlin/DocumentationBuilder.kt
parent797cb4732c53bf1e3b2091add8cf731fc436607f (diff)
downloaddokka-39631054c58df5841ea268b7002b820ec55f6e0a.tar.gz
dokka-39631054c58df5841ea268b7002b820ec55f6e0a.tar.bz2
dokka-39631054c58df5841ea268b7002b820ec55f6e0a.zip
restructure Dokka build to use Gradle for everything except for the Maven plugin
Diffstat (limited to 'src/Kotlin/DocumentationBuilder.kt')
-rw-r--r--src/Kotlin/DocumentationBuilder.kt653
1 files changed, 0 insertions, 653 deletions
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt
deleted file mode 100644
index 6551ded6..00000000
--- a/src/Kotlin/DocumentationBuilder.kt
+++ /dev/null
@@ -1,653 +0,0 @@
-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.DocumentationNode.Kind
-import org.jetbrains.dokka.Kotlin.DescriptorDocumentationParser
-import org.jetbrains.kotlin.builtins.KotlinBuiltIns
-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.caches.resolve.KotlinCacheService
-import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfo
-import org.jetbrains.kotlin.idea.kdoc.KDocFinder
-import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtModifierListOwner
-import org.jetbrains.kotlin.psi.KtParameter
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
-import org.jetbrains.kotlin.resolve.constants.ConstantValue
-import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.isDocumentedAnnotation
-import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
-import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
-import org.jetbrains.kotlin.resolve.source.PsiSourceElement
-import org.jetbrains.kotlin.resolve.source.getPsi
-import org.jetbrains.kotlin.types.ErrorUtils
-import org.jetbrains.kotlin.types.KotlinType
-import org.jetbrains.kotlin.types.TypeProjection
-
-public data class DocumentationOptions(val outputDir: String,
- val outputFormat: String,
- val includeNonPublic: Boolean = false,
- val reportUndocumented: Boolean = true,
- val skipEmptyPackages: Boolean = true,
- val skipDeprecated: Boolean = false,
- val sourceLinks: List<SourceLinkDefinition>)
-
-private fun isSamePackage(descriptor1: DeclarationDescriptor, descriptor2: DeclarationDescriptor): Boolean {
- val package1 = DescriptorUtils.getParentOfType(descriptor1, PackageFragmentDescriptor::class.java)
- val package2 = DescriptorUtils.getParentOfType(descriptor2, PackageFragmentDescriptor::class.java)
- return package1 != null && package2 != null && package1.fqName == package2.fqName
-}
-
-interface PackageDocumentationBuilder {
- fun buildPackageDocumentation(documentationBuilder: DocumentationBuilder,
- packageName: FqName,
- packageNode: DocumentationNode,
- declarations: List<DeclarationDescriptor>)
-}
-
-class DocumentationBuilder
- @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val descriptorDocumentationParser: DescriptorDocumentationParser,
- val options: DocumentationOptions,
- val refGraph: NodeReferenceGraph,
- val logger: DokkaLogger)
-{
- val visibleToDocumentation = setOf(Visibilities.PROTECTED, Visibilities.PUBLIC)
- 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)
-
- fun link(node: DocumentationNode, descriptor: DeclarationDescriptor, kind: DocumentationReference.Kind) {
- refGraph.link(node, descriptor.signature(), kind)
- }
-
- fun link(fromDescriptor: DeclarationDescriptor?, toDescriptor: DeclarationDescriptor?, kind: DocumentationReference.Kind) {
- 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: Kind): DocumentationNode where T : DeclarationDescriptor, T : Named {
- val (doc, callback) = descriptorDocumentationParser.parseDocumentationAndDetails(descriptor, kind == Kind.Parameter)
- val node = DocumentationNode(descriptor.name.asString(), doc, kind).withModifiers(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
- }
-
- 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, DocumentationNode.Kind.Modifier)
- }
-
- fun DocumentationNode.appendVisibility(descriptor: DeclarationDescriptorWithVisibility) {
- val modifier = descriptor.visibility.normalize().displayName
- appendTextNode(modifier, DocumentationNode.Kind.Modifier)
- }
-
- fun DocumentationNode.appendSupertypes(descriptor: ClassDescriptor) {
- val superTypes = descriptor.typeConstructor.supertypes
- for (superType in superTypes) {
- if (!ignoreSupertype(superType)) {
- appendType(superType, DocumentationNode.Kind.Supertype)
- val superclass = superType?.constructor?.declarationDescriptor
- link(superclass, descriptor, DocumentationReference.Kind.Inheritor)
- link(descriptor, superclass, DocumentationReference.Kind.Superclass)
- }
- }
- }
-
- private fun ignoreSupertype(superType: KotlinType): Boolean {
- val superClass = superType.constructor.declarationDescriptor as? ClassDescriptor
- if (superClass != null) {
- val fqName = DescriptorUtils.getFqNameSafe(superClass).asString()
- return fqName == "kotlin.Annotation" || fqName == "kotlin.Enum" || fqName == "kotlin.Any"
- }
- return false
- }
-
- fun DocumentationNode.appendProjection(projection: TypeProjection, kind: DocumentationNode.Kind = DocumentationNode.Kind.Type) {
- if (projection.isStarProjection) {
- appendTextNode("*", Kind.Type)
- }
- else {
- appendType(projection.type, kind, projection.projectionKind.label)
- }
- }
-
- fun DocumentationNode.appendType(kotlinType: KotlinType?, kind: DocumentationNode.Kind = DocumentationNode.Kind.Type, prefix: String = "") {
- if (kotlinType == null)
- return
- val classifierDescriptor = kotlinType.constructor.declarationDescriptor
- val name = when (classifierDescriptor) {
- is ClassDescriptor -> {
- if (classifierDescriptor.isCompanionObject) {
- classifierDescriptor.containingDeclaration.name.asString() +
- "." + classifierDescriptor.name.asString()
- }
- else {
- classifierDescriptor.name.asString()
- }
- }
- is Named -> classifierDescriptor.name.asString()
- else -> "<anonymous>"
- }
- val node = DocumentationNode(name, Content.Empty, kind)
- if (prefix != "") {
- node.appendTextNode(prefix, Kind.Modifier)
- }
- if (kotlinType.isMarkedNullable) {
- node.appendTextNode("?", Kind.NullabilityModifier)
- }
- if (classifierDescriptor != null) {
- link(node, classifierDescriptor,
- if (classifierDescriptor.isBoringBuiltinClass()) DocumentationReference.Kind.HiddenLink else DocumentationReference.Kind.Link)
- }
-
- append(node, DocumentationReference.Kind.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.filter { it.isDocumented() }.forEach {
- val annotationNode = it.build()
- if (annotationNode != null) {
- append(annotationNode,
- if (annotationNode.isDeprecation()) DocumentationReference.Kind.Deprecation else DocumentationReference.Kind.Annotation)
- }
- }
- }
-
- fun DocumentationNode.appendModifiers(descriptor: DeclarationDescriptor) {
- val psi = (descriptor as DeclarationDescriptorWithSource).source.getPsi() as? KtModifierListOwner ?: return
- KtTokens.MODIFIER_KEYWORDS_ARRAY.filter { it !in knownModifiers }.forEach {
- if (psi.hasModifier(it)) {
- appendTextNode(it.value, Kind.Modifier)
- }
- }
- }
-
- fun DocumentationNode.isDeprecation() = name == "Deprecated" || name == "deprecated"
-
- fun DocumentationNode.appendSourceLink(sourceElement: SourceElement) {
- appendSourceLink(sourceElement.getPsi(), options.sourceLinks)
- }
-
- fun DocumentationNode.appendChild(descriptor: DeclarationDescriptor, kind: DocumentationReference.Kind): DocumentationNode? {
- // do not include generated code
- if (descriptor is CallableMemberDescriptor && descriptor.kind != CallableMemberDescriptor.Kind.DECLARATION)
- return null
-
- if (descriptor.isDocumented()) {
- val node = descriptor.build()
- append(node, kind)
- return node
- }
- return null
- }
-
- fun DeclarationDescriptor.isDocumented(): Boolean {
- return (options.includeNonPublic
- || this !is MemberDescriptor
- || this.visibility in visibleToDocumentation) &&
- !isDocumentationSuppressed() &&
- (!options.skipDeprecated || !isDeprecated())
- }
-
- fun DocumentationNode.appendMembers(descriptors: Iterable<DeclarationDescriptor>): List<DocumentationNode> {
- val nodes = descriptors.map { descriptor ->
- if (descriptor is CallableMemberDescriptor && descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
- val baseDescriptor = descriptor.overriddenDescriptors.firstOrNull()
- if (baseDescriptor != null) {
- link(this, baseDescriptor, DocumentationReference.Kind.InheritedMember)
- }
- null
- }
- else {
- val descriptorToUse = if (descriptor is ConstructorDescriptor) descriptor else descriptor.original
- appendChild(descriptorToUse, DocumentationReference.Kind.Member)
- }
- }
- return nodes.filterNotNull()
- }
-
- fun DocumentationNode.appendInPageChildren(descriptors: Iterable<DeclarationDescriptor>, kind: DocumentationReference.Kind) {
- descriptors.forEach { descriptor ->
- val node = appendChild(descriptor, kind)
- node?.addReferenceTo(this, DocumentationReference.Kind.TopLevelPage)
- }
- }
-
- fun DocumentationModule.appendFragments(fragments: Collection<PackageFragmentDescriptor>,
- packageContent: Map<String, Content>,
- packageDocumentationBuilder: PackageDocumentationBuilder) {
- val allFqNames = fragments.map { it.fqName }.distinct()
-
- for (packageName in allFqNames) {
- val declarations = fragments.filter { it.fqName == packageName }.flatMap { it.getMemberScope().getContributedDescriptors() }
-
- if (options.skipEmptyPackages && declarations.none { it.isDocumented() }) continue
- logger.info(" package $packageName: ${declarations.count()} declarations")
- val packageNode = findOrCreatePackageNode(packageName.asString(), packageContent)
- packageDocumentationBuilder.buildPackageDocumentation(this@DocumentationBuilder, packageName, packageNode, declarations)
- }
- }
-
- fun DeclarationDescriptor.build(): DocumentationNode = when (this) {
- is ClassDescriptor -> build()
- is ConstructorDescriptor -> build()
- is PropertyDescriptor -> build()
- is FunctionDescriptor -> build()
- is TypeParameterDescriptor -> build()
- is ValueParameterDescriptor -> build()
- is ReceiverParameterDescriptor -> build()
- else -> throw IllegalStateException("Descriptor $this is not known")
- }
-
- fun ClassDescriptor.build(): DocumentationNode {
- val kind = when (kind) {
- ClassKind.OBJECT -> Kind.Object
- ClassKind.INTERFACE -> Kind.Interface
- ClassKind.ENUM_CLASS -> Kind.Enum
- ClassKind.ANNOTATION_CLASS -> Kind.AnnotationClass
- ClassKind.ENUM_ENTRY -> Kind.EnumItem
- else -> Kind.Class
- }
- val node = nodeForDescriptor(this, kind)
- node.appendSupertypes(this)
- if (getKind() != ClassKind.OBJECT && getKind() != ClassKind.ENUM_ENTRY) {
- node.appendInPageChildren(typeConstructor.parameters, DocumentationReference.Kind.Detail)
- val constructorsToDocument = if (getKind() == ClassKind.ENUM_CLASS)
- constructors.filter { it.valueParameters.size > 0 }
- else
- constructors
- node.appendMembers(constructorsToDocument)
- }
- val members = defaultType.memberScope.getContributedDescriptors().filter { it != companionObjectDescriptor }
- node.appendMembers(members)
- node.appendMembers(staticScope.getContributedDescriptors()).forEach {
- it.appendTextNode("static", Kind.Modifier)
- }
- val companionObjectDescriptor = companionObjectDescriptor
- if (companionObjectDescriptor != null) {
- node.appendMembers(companionObjectDescriptor.defaultType.memberScope.getContributedDescriptors())
- }
- node.appendAnnotations(this)
- node.appendModifiers(this)
- node.appendSourceLink(source)
- register(this, node)
- return node
- }
-
- fun ConstructorDescriptor.build(): DocumentationNode {
- val node = nodeForDescriptor(this, Kind.Constructor)
- node.appendInPageChildren(valueParameters, DocumentationReference.Kind.Detail)
- register(this, node)
- return node
- }
-
- private fun CallableMemberDescriptor.inCompanionObject(): Boolean {
- val containingDeclaration = containingDeclaration
- if ((containingDeclaration as? ClassDescriptor)?.isCompanionObject ?: false) {
- return true
- }
- val receiver = extensionReceiverParameter
- return (receiver?.type?.constructor?.declarationDescriptor as? ClassDescriptor)?.isCompanionObject ?: false
- }
-
- fun FunctionDescriptor.build(): DocumentationNode {
- if (ErrorUtils.containsErrorType(this)) {
- logger.warn("Found an unresolved type in ${signatureWithSourceLocation()}")
- }
-
- val node = nodeForDescriptor(this, if (inCompanionObject()) Kind.CompanionObjectFunction else Kind.Function)
-
- node.appendInPageChildren(typeParameters, DocumentationReference.Kind.Detail)
- extensionReceiverParameter?.let { node.appendChild(it, DocumentationReference.Kind.Detail) }
- node.appendInPageChildren(valueParameters, DocumentationReference.Kind.Detail)
- node.appendType(returnType)
- node.appendAnnotations(this)
- node.appendModifiers(this)
- node.appendSourceLink(source)
-
- 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, DocumentationReference.Kind.Override)
- } else {
- baseClassFunction.overriddenDescriptors.forEach {
- addOverrideLink(it, overridingFunction)
- }
- }
- }
-
- fun PropertyDescriptor.build(): DocumentationNode {
- val node = nodeForDescriptor(this, if (inCompanionObject()) Kind.CompanionObjectProperty else Kind.Property)
- node.appendInPageChildren(typeParameters, DocumentationReference.Kind.Detail)
- extensionReceiverParameter?.let { node.appendChild(it, DocumentationReference.Kind.Detail) }
- node.appendType(returnType)
- node.appendAnnotations(this)
- node.appendModifiers(this)
- node.appendSourceLink(source)
- if (isVar) {
- node.appendTextNode("var", DocumentationNode.Kind.Modifier)
- }
- getter?.let {
- if (!it.isDefault) {
- node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Getter")
- }
- }
- setter?.let {
- if (!it.isDefault) {
- node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Setter")
- }
- }
-
- 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, Kind.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, Kind.Value)
- }
- }
- }
- node.appendAnnotations(this)
- node.appendModifiers(this)
- if (varargElementType != null && node.details(Kind.Modifier).none { it.name == "vararg" }) {
- node.appendTextNode("vararg", Kind.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, DocumentationNode.Kind.TypeParameter)
- if (prefix != "") {
- node.appendTextNode(prefix, Kind.Modifier)
- }
- if (isReified) {
- node.appendTextNode("reified", Kind.Modifier)
- }
-
- for (constraint in upperBounds) {
- if (KotlinBuiltIns.isDefaultBound(constraint)) {
- continue
- }
- node.appendType(constraint, Kind.UpperBound)
- }
-
- for (constraint in lowerBounds) {
- if (KotlinBuiltIns.isNothing(constraint))
- continue
- node.appendType(constraint, Kind.LowerBound)
- }
- return node
- }
-
- fun ReceiverParameterDescriptor.build(): DocumentationNode {
- var receiverClass: DeclarationDescriptor = type.constructor.declarationDescriptor!!
- if ((receiverClass as? ClassDescriptor)?.isCompanionObject ?: false) {
- receiverClass = receiverClass.containingDeclaration!!
- }
- link(receiverClass,
- containingDeclaration,
- DocumentationReference.Kind.Extension)
-
- val node = DocumentationNode(name.asString(), Content.Empty, Kind.Receiver)
- node.appendType(type)
- 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, DocumentationNode.Kind.Annotation)
- val arguments = allValueArguments.toList().sortedBy { it.first.index }
- arguments.forEach {
- val valueNode = it.second.toDocumentationNode()
- if (valueNode != null) {
- val paramNode = DocumentationNode(it.first.name.asString(), Content.Empty, DocumentationNode.Kind.Parameter)
- paramNode.append(valueNode, DocumentationReference.Kind.Detail)
- node.append(paramNode, DocumentationReference.Kind.Detail)
- }
- }
- return node
- }
-
- fun CompileTimeConstant<Any?>.build(): DocumentationNode? = when (this) {
- is TypedCompileTimeConstant -> constantValue.toDocumentationNode()
- else -> null
- }
-
- fun ConstantValue<*>.toDocumentationNode(): DocumentationNode? = value?.let { value ->
- when (value) {
- is String ->
- "\"" + StringUtil.escapeStringCharacters(value) + "\""
- is EnumEntrySyntheticClassDescriptor ->
- value.containingDeclaration.name.asString() + "." + value.name.asString()
- else -> value.toString()
- }.let { valueString ->
- DocumentationNode(valueString, Content.Empty, DocumentationNode.Kind.Value)
- }
- }
-}
-
-class KotlinPackageDocumentationBuilder : PackageDocumentationBuilder {
- override fun buildPackageDocumentation(documentationBuilder: DocumentationBuilder,
- packageName: FqName,
- packageNode: DocumentationNode,
- declarations: List<DeclarationDescriptor>) {
- val externalClassNodes = hashMapOf<FqName, DocumentationNode>()
- declarations.forEach { descriptor ->
- with(documentationBuilder) {
- if (descriptor.isDocumented()) {
- val parent = packageNode.getParentForPackageMember(descriptor, externalClassNodes)
- parent.appendChild(descriptor, DocumentationReference.Kind.Member)
- }
- }
- }
- }
-}
-
-class KotlinJavaDocumentationBuilder
- @Inject constructor(val documentationBuilder: DocumentationBuilder,
- val logger: DokkaLogger) : JavaDocumentationBuilder
-{
- override fun appendFile(file: PsiJavaFile, module: DocumentationModule, packageContent: Map<String, Content>) {
- val packageNode = module.findOrCreatePackageNode(file.packageName, packageContent)
-
- file.classes.forEach {
- val javaDescriptorResolver = KotlinCacheService.getInstance(file.project).getProjectService(JvmPlatform,
- it.getModuleInfo(), JavaDescriptorResolver::class.java)
-
- val descriptor = javaDescriptorResolver.resolveClass(JavaClassImpl(it))
- if (descriptor == null) {
- logger.warn("Cannot find descriptor for Java class ${it.qualifiedName}")
- }
- else {
- with(documentationBuilder) {
- packageNode.appendChild(descriptor, DocumentationReference.Kind.Member)
- }
- }
- }
- }
-}
-
-private fun AnnotationDescriptor.isDocumented(): Boolean {
- if (source.getPsi() != null && mustBeDocumented()) return true
- val annotationClassName = type.constructor.declarationDescriptor?.fqNameSafe?.asString()
- return annotationClassName == "kotlin.Extension"
-}
-
-fun AnnotationDescriptor.mustBeDocumented(): Boolean {
- val annotationClass = type.constructor.declarationDescriptor as? Annotated ?: return false
- return annotationClass.isDocumentedAnnotation()
-}
-
-fun DeclarationDescriptor.isDocumentationSuppressed(): Boolean {
- val doc = KDocFinder.findKDoc(this)
- return doc is KDocSection && doc.findTagByName("suppress") != null
-}
-
-fun DeclarationDescriptor.isDeprecated(): Boolean = annotations.any {
- DescriptorUtils.getFqName(it.type.constructor.declarationDescriptor!!).asString() == "kotlin.Deprecated"
-} || (this is ConstructorDescriptor && containingDeclaration.isDeprecated())
-
-fun DocumentationNode.getParentForPackageMember(descriptor: DeclarationDescriptor,
- externalClassNodes: MutableMap<FqName, DocumentationNode>): DocumentationNode {
- if (descriptor is CallableMemberDescriptor) {
- val extensionClassDescriptor = descriptor.getExtensionClassDescriptor()
- if (extensionClassDescriptor != null && !isSamePackage(descriptor, extensionClassDescriptor) &&
- !ErrorUtils.isError(extensionClassDescriptor)) {
- val fqName = DescriptorUtils.getFqNameSafe(extensionClassDescriptor)
- return externalClassNodes.getOrPut(fqName, {
- val newNode = DocumentationNode(fqName.asString(), Content.Empty, Kind.ExternalClass)
- append(newNode, DocumentationReference.Kind.Member)
- newNode
- })
- }
- }
- return this
-}
-
-fun CallableMemberDescriptor.getExtensionClassDescriptor(): ClassifierDescriptor? {
- val extensionReceiver = extensionReceiverParameter
- if (extensionReceiver != null) {
- val type = extensionReceiver.type
- return type.constructor.declarationDescriptor as? ClassDescriptor
- }
- return null
-}
-
-fun DeclarationDescriptor.signature(): String = when(this) {
- is ClassDescriptor, is PackageFragmentDescriptor -> DescriptorUtils.getFqName(this).asString()
- is PropertyDescriptor -> containingDeclaration.signature() + "#" + name + receiverSignature()
- is FunctionDescriptor -> containingDeclaration.signature() + "#" + name + parameterSignature()
- is ValueParameterDescriptor -> containingDeclaration.signature() + ":" + name
- is TypeParameterDescriptor -> containingDeclaration.signature() + "<" + name
-
- else -> throw UnsupportedOperationException("Don't know how to calculate signature for $this")
-}
-
-fun PropertyDescriptor.receiverSignature(): String {
- val receiver = extensionReceiverParameter
- if (receiver != null) {
- return "#" + receiver.type.signature()
- }
- return ""
-}
-
-fun CallableMemberDescriptor.parameterSignature(): String {
- val params = valueParameters.map { it.type }.toArrayList()
- val extensionReceiver = extensionReceiverParameter
- if (extensionReceiver != null) {
- params.add(0, extensionReceiver.type)
- }
- return "(" + params.map { it.signature() }.joinToString() + ")"
-}
-
-fun KotlinType.signature(): String {
- val declarationDescriptor = constructor.declarationDescriptor ?: return "<null>"
- val typeName = DescriptorUtils.getFqName(declarationDescriptor).asString()
- if (typeName == "Array" && arguments.size == 1) {
- return "Array<" + arguments.first().type.signature() + ">"
- }
- return typeName
-}
-
-fun DeclarationDescriptor.signatureWithSourceLocation(): String {
- val signature = signature()
- val sourceLocation = sourceLocation()
- return if (sourceLocation != null) "$signature ($sourceLocation)" else signature
-}
-
-fun DeclarationDescriptor.sourceLocation(): String? {
- if (this is DeclarationDescriptorWithSource) {
- val psi = (this.source as? PsiSourceElement)?.getPsi()
- if (psi != null) {
- val fileName = psi.containingFile.name
- val lineNumber = psi.lineNumber()
- return if (lineNumber != null) "$fileName:$lineNumber" else fileName
- }
- }
- return null
-}