From 59069606904d297a5b4c9a8a95ad88eb30f7fd4f Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 20 Dec 2017 22:27:47 +0300 Subject: [backport] Make KotlinLanguageService render parameters Original: 7899f8e --- core/src/main/kotlin/Kotlin/KotlinLanguageService.kt | 1 + 1 file changed, 1 insertion(+) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index f33c8c96..708facdb 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -17,6 +17,7 @@ class KotlinLanguageService : LanguageService { NodeKind.EnumItem, NodeKind.ExternalClass -> if (renderMode == RenderMode.FULL) identifier(node.name) + NodeKind.Parameter -> renderParameter(node, renderMode) NodeKind.TypeParameter -> renderTypeParameter(node, renderMode) NodeKind.Type, NodeKind.UpperBound -> renderType(node, renderMode) -- cgit From 63ab561b66974c52a7d13e0823bf94329c0cd7f7 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 15 Dec 2017 22:05:21 +0300 Subject: [backport] Make possible to generate signatures on output format side Original: 4469044 --- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 1 + .../main/kotlin/Kotlin/KotlinLanguageService.kt | 28 ++++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index 7b50fff5..99d4d888 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -234,6 +234,7 @@ class DocumentationBuilder val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor) if (externalLink != null) { node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link) + node.append(DocumentationNode(classifierDescriptor.fqNameUnsafe.asString(), Content.Empty, NodeKind.QualifiedName), RefKind.Detail) } else { link(node, classifierDescriptor, if (classifierDescriptor.isBoringBuiltinClass()) RefKind.HiddenLink else RefKind.Link) diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index 708facdb..b6f44716 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -48,8 +48,7 @@ class KotlinLanguageService : LanguageService { val typeParameter = functionWithTypeParameter.details(NodeKind.TypeParameter).first() if (functionWithTypeParameter.kind == NodeKind.Function) { renderFunction(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) - } - else { + } else { renderProperty(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) } } @@ -103,7 +102,7 @@ class KotlinLanguageService : LanguageService { fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) } - private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String): SignatureMapper { + private class SummarizingMapper(val kind: ReceiverKind, val typeParameterName: String) : SignatureMapper { override fun renderReceiver(receiver: DocumentationNode, to: ContentBlock) { to.append(ContentIdentifier(kind.receiverName, IdentifierKind.SummarizedTypeName)) to.text("<$typeParameterName>") @@ -117,7 +116,7 @@ class KotlinLanguageService : LanguageService { } private fun ContentBlock.renderList(nodes: List, separator: String = ", ", - noWrap: Boolean = false, renderItem: (T) -> Unit) { + noWrap: Boolean = false, renderItem: (T) -> Unit) { if (nodes.none()) return renderItem(nodes.first()) @@ -132,7 +131,7 @@ class KotlinLanguageService : LanguageService { } } - private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode)->Unit) { + private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode) -> Unit) { val to = node.links.firstOrNull() if (to == null) body(node) @@ -216,13 +215,13 @@ class KotlinLanguageService : LanguageService { private fun ContentBlock.renderModifier(node: DocumentationNode, nowrap: Boolean = false) { when (node.name) { - "final", "public", "var" -> {} + "final", "public", "var" -> { + } else -> { keyword(node.name) if (nowrap) { nbsp() - } - else { + } else { text(" ") } } @@ -239,11 +238,12 @@ class KotlinLanguageService : LanguageService { nbsp() symbol(":") nbsp() - renderList(constraints, noWrap=true) { + renderList(constraints, noWrap = true) { renderType(it, renderMode) } } } + private fun ContentBlock.renderParameter(node: DocumentationNode, renderMode: RenderMode) { if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) @@ -402,8 +402,7 @@ class KotlinLanguageService : LanguageService { symbol(")") symbol(": ") renderType(node.detail(NodeKind.Type), renderMode) - } - else { + } else { symbol(")") } renderExtraTypeParameterConstraints(node, renderMode) @@ -429,7 +428,7 @@ class KotlinLanguageService : LanguageService { } } - private fun needReturnType(node: DocumentationNode) = when(node.kind) { + private fun needReturnType(node: DocumentationNode) = when (node.kind) { NodeKind.Constructor -> false else -> !node.isUnitReturnType() } @@ -476,4 +475,7 @@ class KotlinLanguageService : LanguageService { } } -fun DocumentationNode.qualifiedNameFromType() = (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() ?: name +fun DocumentationNode.qualifiedNameFromType() = + details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name + ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() + ?: name -- cgit From c776aaab9af80987e3c073a40f92de748dbd38ca Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 11 Jan 2018 22:22:36 +0300 Subject: [backport] Support deep inheritance with external classes Original: 9e65c3d --- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 70 ++++++++++++++-------- .../main/kotlin/Kotlin/KotlinLanguageService.kt | 2 +- 2 files changed, 45 insertions(+), 27 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index 99d4d888..11a36a4f 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -103,6 +103,10 @@ interface DefaultPlatformsProvider { fun getDefaultPlatforms(descriptor: DeclarationDescriptor): List } +val ignoredSupertypes = setOf( + "kotlin.Annotation", "kotlin.Enum", "kotlin.Any" +) + class DocumentationBuilder @Inject constructor(val resolutionFacade: DokkaResolutionFacade, val descriptorDocumentationParser: DescriptorDocumentationParser, @@ -173,7 +177,7 @@ class DocumentationBuilder val unwrappedType = superType.unwrap() if (unwrappedType is AbbreviatedType) { appendSupertype(descriptor, unwrappedType.abbreviation) - } else if (!ignoreSupertype(unwrappedType)) { + } else { appendType(unwrappedType, NodeKind.Supertype) val superclass = unwrappedType.constructor.declarationDescriptor link(superclass, descriptor, RefKind.Inheritor) @@ -181,15 +185,6 @@ class DocumentationBuilder } } - 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: NodeKind = NodeKind.Type) { if (projection.isStarProjection) { appendTextNode("*", NodeKind.Type) @@ -233,14 +228,25 @@ class DocumentationBuilder if (classifierDescriptor != null) { val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor) if (externalLink != null) { + val targetNode = refGraph.lookup(classifierDescriptor.signature()) ?: classifierDescriptor.build(true) node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link) - node.append(DocumentationNode(classifierDescriptor.fqNameUnsafe.asString(), Content.Empty, NodeKind.QualifiedName), RefKind.Detail) + node.append(targetNode, RefKind.ExternalType) } 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 + ) + } } + append(node, RefKind.Detail) node.appendAnnotations(kotlinType) for (typeArgument in kotlinType.arguments) { @@ -496,34 +502,42 @@ class DocumentationBuilder } fun DeclarationDescriptor.build(): DocumentationNode = when (this) { - is ClassDescriptor -> build() + is ClassifierDescriptor -> build() is ConstructorDescriptor -> build() is PropertyDescriptor -> build() is FunctionDescriptor -> build() - is TypeParameterDescriptor -> build() is ValueParameterDescriptor -> build() is ReceiverParameterDescriptor -> build() - is TypeAliasDescriptor -> build() else -> throw IllegalStateException("Descriptor $this is not known") } - fun TypeAliasDescriptor.build(): DocumentationNode { + fun ClassifierDescriptor.build(external: Boolean = false): DocumentationNode = when (this) { + is ClassDescriptor -> build(external) + is TypeAliasDescriptor -> build(external) + is TypeParameterDescriptor -> build() + else -> throw IllegalStateException("Descriptor $this is not known") + } + + fun TypeAliasDescriptor.build(external: Boolean = false): DocumentationNode { val node = nodeForDescriptor(this, NodeKind.TypeAlias) - node.appendAnnotations(this) + if (!external) { + node.appendAnnotations(this) + } node.appendModifiers(this) node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail) node.appendType(underlyingType, NodeKind.TypeAliasUnderlyingType) - node.appendSourceLink(source) - node.appendDefaultPlatforms(this) - + if (!external) { + node.appendSourceLink(source) + node.appendDefaultPlatforms(this) + } register(this, node) return node } - fun ClassDescriptor.build(): DocumentationNode { + fun ClassDescriptor.build(external: Boolean = false): DocumentationNode { val kind = when { kind == ClassKind.OBJECT -> NodeKind.Object kind == ClassKind.INTERFACE -> NodeKind.Interface @@ -534,20 +548,24 @@ class DocumentationBuilder else -> NodeKind.Class } val node = nodeForDescriptor(this, kind) + register(this, node) typeConstructor.supertypes.forEach { node.appendSupertype(this, it) } if (getKind() != ClassKind.OBJECT && getKind() != ClassKind.ENUM_ENTRY) { node.appendInPageChildren(typeConstructor.parameters, RefKind.Detail) } - for ((descriptor, inheritedLinkKind, extraModifier) in collectMembersToDocument()) { - node.appendClassMember(descriptor, inheritedLinkKind, extraModifier) + if (!external) { + for ((descriptor, inheritedLinkKind, extraModifier) in collectMembersToDocument()) { + node.appendClassMember(descriptor, inheritedLinkKind, extraModifier) + } + node.appendAnnotations(this) } - node.appendAnnotations(this) node.appendModifiers(this) - node.appendSourceLink(source) - node.appendDefaultPlatforms(this) - register(this, node) + if (!external) { + node.appendSourceLink(source) + node.appendDefaultPlatforms(this) + } return node } diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index b6f44716..aa185de7 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -291,7 +291,7 @@ class KotlinLanguageService : LanguageService { } private fun ContentBlock.renderSupertypesForNode(node: DocumentationNode, renderMode: RenderMode) { - val supertypes = node.details(NodeKind.Supertype) + val supertypes = node.details(NodeKind.Supertype).filterNot { it.qualifiedNameFromType() in ignoredSupertypes } if (supertypes.any()) { nbsp() symbol(":") -- cgit From 1391dcca35a871881420c53755fed08bf47e4087 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 17 Jan 2018 20:01:20 +0300 Subject: [backport] Support propagating inherited extensions from libraries Original: bf2945d --- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 200 ++++++++++++++++----- .../Kotlin/ExternalDocumentationLinkResolver.kt | 2 +- 2 files changed, 155 insertions(+), 47 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index 11a36a4f..125f9fd4 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -11,6 +11,9 @@ 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 @@ -25,10 +28,11 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.findTopMostOverriddenDescriptors import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver +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.isSubtypeOf import org.jetbrains.kotlin.types.typeUtil.supertypes import java.io.File import java.nio.file.Path @@ -53,7 +57,8 @@ class DocumentationOptions(val outputDir: String, val languageVersion: String?, val apiVersion: String?, cacheRoot: String? = null, - val suppressedFiles: Set = emptySet()) { + val suppressedFiles: Set = emptySet(), + val collectInheritedExtensionsFromLibraries: Boolean = false) { init { if (perPackageOptions.any { it.prefix == "" }) throw IllegalArgumentException("Please do not register packageOptions with all match pattern, use global settings instead") @@ -138,8 +143,20 @@ class DocumentationBuilder refGraph.register(descriptor.signature(), node) } - fun nodeForDescriptor(descriptor: T, kind: NodeKind): DocumentationNode where T : DeclarationDescriptor, T : Named { - val (doc, callback) = descriptorDocumentationParser.parseDocumentationAndDetails(descriptor, kind == NodeKind.Parameter) + fun 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) @@ -226,14 +243,20 @@ class DocumentationBuilder node.appendTextNode("?", NodeKind.NullabilityModifier) } if (classifierDescriptor != null) { - val externalLink = linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor) + val externalLink = + linkResolver.externalDocumentationLinkResolver.buildExternalDocumentationLink(classifierDescriptor) if (externalLink != null) { - val targetNode = refGraph.lookup(classifierDescriptor.signature()) ?: classifierDescriptor.build(true) - node.append(DocumentationNode(externalLink, Content.Empty, NodeKind.ExternalLink), RefKind.Link) - node.append(targetNode, RefKind.ExternalType) + 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) + link( + node, classifierDescriptor, + if (classifierDescriptor.isBoringBuiltinClass()) RefKind.HiddenLink else RefKind.Link + ) } if (classifierDescriptor !is TypeParameterDescriptor) { node.append( @@ -280,6 +303,17 @@ class DocumentationBuilder } } + 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) @@ -426,15 +460,44 @@ class DocumentationBuilder declarations, allFqNames) } - propagateExtensionFunctionsToSubclasses(fragments) } - private fun propagateExtensionFunctionsToSubclasses(fragments: Collection) { - val allDescriptors = fragments.flatMap { it.getMemberScope().getContributedDescriptors() } - val allClasses = allDescriptors.filterIsInstance() - val classHierarchy = buildClassHierarchy(allClasses) + fun propagateExtensionFunctionsToSubclasses( + fragments: Collection, + resolutionFacade: DokkaResolutionFacade + ) { + + val moduleDescriptor = resolutionFacade.moduleDescriptor + + // Wide-collect all view descriptors + val allPackageViewDescriptors = generateSequence(listOf(moduleDescriptor.getPackage(FqName.ROOT))) { packages -> + packages + .flatMap { pkg -> + moduleDescriptor.getSubPackagesOf(pkg.fqName) { true } + }.map { fqName -> + moduleDescriptor.getPackage(fqName) + }.takeUnless { it.isEmpty() } + }.flatten() + + val allDescriptors = + if (options.collectInheritedExtensionsFromLibraries) { + allPackageViewDescriptors.map { it.memberScope } + } else { + fragments.asSequence().map { it.getMemberScope() } + }.flatMap { + it.getDescriptorsFiltered( + DescriptorKindFilter.CALLABLES + ).asSequence() + } + - val allExtensionFunctions = allDescriptors + val documentingDescriptors = fragments.flatMap { it.getMemberScope().getContributedDescriptors() } + val documentingClasses = documentingDescriptors.filterIsInstance() + + val classHierarchy = buildClassHierarchy(documentingClasses) + + val allExtensionFunctions = + allDescriptors .filterIsInstance() .filter { it.extensionReceiverParameter != null } val extensionFunctionsByName = allExtensionFunctions.groupBy { it.name } @@ -442,15 +505,31 @@ class DocumentationBuilder for (extensionFunction in allExtensionFunctions) { if (extensionFunction.dispatchReceiverParameter != null) continue val possiblyShadowingFunctions = extensionFunctionsByName[extensionFunction.name] - ?.filter { fn -> fn.canShadow(extensionFunction) } + ?.filter { fn -> fn.canShadow(extensionFunction) } ?: emptyList() if (extensionFunction.extensionReceiverParameter?.type?.isDynamic() == true) continue - val classDescriptor = extensionFunction.getExtensionClassDescriptor() ?: continue - val subclasses = classHierarchy[classDescriptor] ?: continue - subclasses.forEach { subclass -> + 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) }) { + 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) } } @@ -458,12 +537,9 @@ class DocumentationBuilder } private fun ClassDescriptor.isExtensionApplicable(extensionFunction: CallableMemberDescriptor): Boolean { - val receiverType = extensionFunction.extensionReceiverParameter!!.type - if (receiverType.arguments.any { it.type.constructor.declarationDescriptor is TypeParameterDescriptor }) { - val receiverClass = receiverType.constructor.declarationDescriptor - return receiverClass is ClassDescriptor && DescriptorUtils.isSubclass(this, receiverClass) - } - return defaultType.isSubtypeOf(receiverType) + val receiverType = extensionFunction.fuzzyExtensionReceiverType()?.makeNotNullable() + val classType = defaultType.toFuzzyType(declaredTypeParameters) + return receiverType != null && classType.checkIsSubtypeOf(receiverType) != null } private fun buildClassHierarchy(classes: List): Map> { @@ -511,6 +587,24 @@ 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) @@ -547,7 +641,7 @@ class DocumentationBuilder isSubclassOfThrowable() -> NodeKind.Exception else -> NodeKind.Class } - val node = nodeForDescriptor(this, kind) + val node = nodeForDescriptor(this, kind, external) register(this, node) typeConstructor.supertypes.forEach { node.appendSupertype(this, it) @@ -632,12 +726,12 @@ class DocumentationBuilder return (receiver?.type?.constructor?.declarationDescriptor as? ClassDescriptor)?.isCompanionObject ?: false } - fun FunctionDescriptor.build(): DocumentationNode { + 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) + val node = nodeForDescriptor(this, if (inCompanionObject()) NodeKind.CompanionObjectFunction else NodeKind.Function, external) node.appendInPageChildren(typeParameters, RefKind.Detail) extensionReceiverParameter?.let { node.appendChild(it, RefKind.Detail) } @@ -645,8 +739,12 @@ class DocumentationBuilder node.appendType(returnType) node.appendAnnotations(this) node.appendModifiers(this) - node.appendSourceLink(source) - node.appendDefaultPlatforms(this) + if (!external) { + node.appendSourceLink(source) + node.appendDefaultPlatforms(this) + } else { + node.appendExternalLink(this) + } overriddenDescriptors.forEach { addOverrideLink(it, this) @@ -667,32 +765,42 @@ class DocumentationBuilder } } - fun PropertyDescriptor.build(): DocumentationNode { - val node = nodeForDescriptor(this, if (inCompanionObject()) NodeKind.CompanionObjectProperty else NodeKind.Property) + 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) node.appendAnnotations(this) node.appendModifiers(this) - node.appendSourceLink(source) - if (isVar) { - node.appendTextNode("var", NodeKind.Modifier) - } - getter?.let { - if (!it.isDefault) { - node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Getter") + if (!external) { + node.appendSourceLink(source) + if (isVar) { + node.appendTextNode("var", NodeKind.Modifier) } - } - setter?.let { - if (!it.isDefault) { - node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Setter") + + 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) } - node.appendDefaultPlatforms(this) register(this, node) return node diff --git a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt index e19ecf76..400326d2 100644 --- a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt +++ b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt @@ -155,8 +155,8 @@ class ExternalDocumentationLinkResolver @Inject constructor( fun buildExternalDocumentationLink(symbol: DeclarationDescriptor): String? { val packageFqName: FqName = when (symbol) { - is DeclarationDescriptorNonRoot -> symbol.parents.firstOrNull { it is PackageFragmentDescriptor }?.fqNameSafe ?: return null is PackageFragmentDescriptor -> symbol.fqName + is DeclarationDescriptorNonRoot -> symbol.parents.firstOrNull { it is PackageFragmentDescriptor }?.fqNameSafe ?: return null else -> return null } -- cgit From 2f1512f5ec7f23181cf5fcad96d9ee66507de472 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 20 Jan 2018 16:44:35 +0300 Subject: [backport] Add value for constants from Kotlin Original: fab0890 --- core/src/main/kotlin/Kotlin/DocumentationBuilder.kt | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index 125f9fd4..39202173 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -23,6 +23,7 @@ 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.KtVariableDeclaration import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.descriptorUtil.* @@ -781,6 +782,11 @@ class DocumentationBuilder if (isVar) { node.appendTextNode("var", NodeKind.Modifier) } + if (isConst) { + val psi = sourcePsi() as? KtVariableDeclaration + val text = psi?.initializer?.text + text?.let { node.appendTextNode(it, NodeKind.Value) } + } getter?.let { if (!it.isDefault) { -- cgit From 85d2ea3a100001d3e5555786202e64ef3ea1679e Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 20 Jan 2018 17:26:00 +0300 Subject: [backport] Support constants from Java in KK mode Original: 7723826 --- core/src/main/kotlin/Kotlin/DocumentationBuilder.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index 39202173..d22c48f9 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka import com.google.inject.Inject import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiField import com.intellij.psi.PsiJavaFile import org.jetbrains.dokka.DokkaConfiguration.* import org.jetbrains.dokka.Kotlin.DescriptorDocumentationParser @@ -782,12 +783,18 @@ class DocumentationBuilder if (isVar) { node.appendTextNode("var", NodeKind.Modifier) } + if (isConst) { - val psi = sourcePsi() as? KtVariableDeclaration - val text = psi?.initializer?.text - text?.let { node.appendTextNode(it, NodeKind.Value) } + val psi = sourcePsi() + val valueText = when (psi) { + is KtVariableDeclaration -> psi.initializer?.text + is PsiField -> psi.initializer?.text + else -> null + } + valueText?.let { node.appendTextNode(it, NodeKind.Value) } } + getter?.let { if (!it.isDefault) { node.addAccessorDocumentation(descriptorDocumentationParser.parseDocumentation(it), "Getter") -- cgit From f1252678883133709f13fa2d6b7adbce3156f112 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 31 Jan 2018 23:49:51 +0300 Subject: Refactor selecting of inbound link resolvers --- .../Kotlin/ExternalDocumentationLinkResolver.kt | 43 +++++++++++++++++----- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt index 400326d2..7be37177 100644 --- a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt +++ b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt @@ -4,6 +4,10 @@ import com.google.inject.Inject import com.google.inject.Singleton import com.intellij.psi.PsiMethod import com.intellij.util.io.* +import org.jetbrains.dokka.Formats.FileGeneratorBasedFormatDescriptor +import org.jetbrains.dokka.Formats.FormatDescriptor +import org.jetbrains.dokka.Utilities.ServiceLocator +import org.jetbrains.dokka.Utilities.lookup import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor @@ -21,6 +25,7 @@ import java.net.URL import java.net.URLConnection import java.nio.file.Path import java.security.MessageDigest +import kotlin.reflect.full.findAnnotation fun ByteArray.toHexString() = this.joinToString(separator = "") { "%02x".format(it) } @@ -129,13 +134,22 @@ class ExternalDocumentationLinkResolver @Inject constructor( .map { (key, value) -> key to value } .toMap() - val resolver = if (format == "javadoc") { - InboundExternalLinkResolutionService.Javadoc() - } else { - val linkExtension = paramsMap["linkExtension"]?.singleOrNull() ?: - throw RuntimeException("Failed to parse package list from $packageListUrl") - InboundExternalLinkResolutionService.Dokka(linkExtension) - } + + val defaultResolverDesc = services["dokka-default"]!! + val resolverDesc = services[format] + ?: defaultResolverDesc.takeIf { format in formatsWithDefaultResolver } + ?: defaultResolverDesc.also { + logger.warn("Couldn't find InboundExternalLinkResolutionService(format = `$format`) for $link, using Dokka default") + } + + + val resolverClass = javaClass.classLoader.loadClass(resolverDesc.className).kotlin + + val constructors = resolverClass.constructors + + val constructor = constructors.singleOrNull() + ?: constructors.first { it.findAnnotation() != null } + val resolver = constructor.call(paramsMap) as InboundExternalLinkResolutionService val rootInfo = ExternalDocumentationRoot(link.url, resolver, locations) @@ -170,6 +184,15 @@ class ExternalDocumentationLinkResolver @Inject constructor( companion object { const val DOKKA_PARAM_PREFIX = "\$dokka." + val services = ServiceLocator.allServices("inbound-link-resolver").associateBy { it.name } + private val formatsWithDefaultResolver = + ServiceLocator + .allServices("format") + .filter { + val desc = ServiceLocator.lookup(it) as? FileGeneratorBasedFormatDescriptor + desc?.generatorServiceClass == FileGenerator::class + }.map { it.name } + .toSet() } } @@ -177,7 +200,7 @@ class ExternalDocumentationLinkResolver @Inject constructor( interface InboundExternalLinkResolutionService { fun getPath(symbol: DeclarationDescriptor): String? - class Javadoc : InboundExternalLinkResolutionService { + class Javadoc(paramsMap: Map>) : InboundExternalLinkResolutionService { override fun getPath(symbol: DeclarationDescriptor): String? { if (symbol is EnumEntrySyntheticClassDescriptor) { return getPath(symbol.containingDeclaration)?.let { it + "#" + symbol.name.asString() } @@ -203,7 +226,9 @@ interface InboundExternalLinkResolutionService { } } - class Dokka(val extension: String) : InboundExternalLinkResolutionService { + class Dokka(val paramsMap: Map>) : InboundExternalLinkResolutionService { + val extension = paramsMap["linkExtension"]?.singleOrNull() ?: error("linkExtension not provided for Dokka resolver") + override fun getPath(symbol: DeclarationDescriptor): String? { val leafElement = when (symbol) { is CallableDescriptor, is TypeAliasDescriptor -> true -- cgit From 3e8448bf5d3f00cfaa7d4d6b4fbbf678aebc37b7 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 12 Apr 2018 03:06:15 +0300 Subject: [backport] Make possible to group extensions by receiver Original: d8e03a3 --- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 42 ++++++++++++---------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index d22c48f9..d7d30ebb 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -934,6 +934,30 @@ class DocumentationBuilder DocumentationNode(valueString, Content.Empty, NodeKind.Value) } } + + + fun DocumentationNode.getParentForPackageMember(descriptor: DeclarationDescriptor, + externalClassNodes: MutableMap, + allFqNames: Collection): 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) + newNode + }) + } + } + return this + } + } val visibleToDocumentation = setOf(Visibilities.PROTECTED, Visibilities.PUBLIC) @@ -1033,24 +1057,6 @@ 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, - allFqNames: Collection): 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) - append(newNode, RefKind.Member) - newNode - }) - } - } - return this -} - fun CallableMemberDescriptor.getExtensionClassDescriptor(): ClassifierDescriptor? { val extensionReceiver = extensionReceiverParameter if (extensionReceiver != null) { -- cgit From 8883839b8796589a1fa02b3dca5d1aae172b5c56 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Fri, 13 Apr 2018 19:47:07 +0300 Subject: [backport] Fix problems in as-java java-layout-html mode Extract common part of LanguageServices & other improvements Original: 853262e --- .../main/kotlin/Kotlin/DeclarationLinkResolver.kt | 2 +- .../main/kotlin/Kotlin/KotlinLanguageService.kt | 164 ++++++++++----------- 2 files changed, 75 insertions(+), 91 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt index ffef399d..ec474900 100644 --- a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt +++ b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt @@ -41,7 +41,7 @@ class DeclarationLinkResolver val target = refGraph.lookup(signature) if (target == null) { - logger.warn("Can't find node by signature $signature, referenced at $referencedAt") + logger.warn("Can't find node by signature `$signature`, referenced at $referencedAt") } target }) diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index aa185de7..69a97848 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -5,8 +5,9 @@ import org.jetbrains.dokka.LanguageService.RenderMode /** * Implements [LanguageService] and provides rendering of symbols in Kotlin language */ -class KotlinLanguageService : LanguageService { - private val fullOnlyModifiers = setOf("public", "protected", "private", "inline", "noinline", "crossinline", "reified") +class KotlinLanguageService : CommonLanguageService() { + private val fullOnlyModifiers = + setOf("public", "protected", "private", "inline", "noinline", "crossinline", "reified") override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode { return content { @@ -22,7 +23,7 @@ class KotlinLanguageService : LanguageService { NodeKind.Type, NodeKind.UpperBound -> renderType(node, renderMode) - NodeKind.Modifier -> renderModifier(node) + NodeKind.Modifier -> renderModifier(this, node) NodeKind.Constructor, NodeKind.Function, NodeKind.CompanionObjectFunction -> renderFunction(node, renderMode) @@ -33,12 +34,6 @@ class KotlinLanguageService : LanguageService { } } - override fun renderName(node: DocumentationNode): String { - return when (node.kind) { - NodeKind.Constructor -> node.owner!!.name - else -> node.name - } - } override fun summarizeSignatures(nodes: List): ContentNode? { if (nodes.size < 2) return null @@ -47,9 +42,17 @@ class KotlinLanguageService : LanguageService { return content { val typeParameter = functionWithTypeParameter.details(NodeKind.TypeParameter).first() if (functionWithTypeParameter.kind == NodeKind.Function) { - renderFunction(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) + renderFunction( + functionWithTypeParameter, + RenderMode.SUMMARY, + SummarizingMapper(receiverKind, typeParameter.name) + ) } else { - renderProperty(functionWithTypeParameter, RenderMode.SUMMARY, SummarizingMapper(receiverKind, typeParameter.name)) + renderProperty( + functionWithTypeParameter, + RenderMode.SUMMARY, + SummarizingMapper(receiverKind, typeParameter.name) + ) } } } @@ -70,26 +73,27 @@ class KotlinLanguageService : LanguageService { companion object { private val arrayClasses = setOf( - "kotlin.Array", - "kotlin.BooleanArray", - "kotlin.ByteArray", - "kotlin.CharArray", - "kotlin.ShortArray", - "kotlin.IntArray", - "kotlin.LongArray", - "kotlin.FloatArray", - "kotlin.DoubleArray" + "kotlin.Array", + "kotlin.BooleanArray", + "kotlin.ByteArray", + "kotlin.CharArray", + "kotlin.ShortArray", + "kotlin.IntArray", + "kotlin.LongArray", + "kotlin.FloatArray", + "kotlin.DoubleArray" ) private val arrayOrListClasses = setOf("kotlin.List") + arrayClasses private val iterableClasses = setOf( - "kotlin.Collection", - "kotlin.Sequence", - "kotlin.Iterable", - "kotlin.Map", - "kotlin.String", - "kotlin.CharSequence") + arrayOrListClasses + "kotlin.Collection", + "kotlin.Sequence", + "kotlin.Iterable", + "kotlin.Map", + "kotlin.String", + "kotlin.CharSequence" + ) + arrayOrListClasses } private enum class ReceiverKind(val receiverName: String, val classes: Collection) { @@ -109,46 +113,14 @@ class KotlinLanguageService : LanguageService { } } - private fun ContentBlock.renderPackage(node: DocumentationNode) { - keyword("package") - text(" ") - identifier(node.name) - } - - private fun ContentBlock.renderList(nodes: List, separator: String = ", ", - noWrap: Boolean = false, renderItem: (T) -> Unit) { - if (nodes.none()) - return - renderItem(nodes.first()) - nodes.drop(1).forEach { - if (noWrap) { - symbol(separator.removeSuffix(" ")) - nbsp() - } else { - symbol(separator) - } - renderItem(it) - } - } - - private fun ContentBlock.renderLinked(node: DocumentationNode, body: ContentBlock.(DocumentationNode) -> Unit) { - val to = node.links.firstOrNull() - if (to == null) - body(node) - else - link(to) { - body(node) - } - } - private fun ContentBlock.renderFunctionalTypeParameterName(node: DocumentationNode, renderMode: RenderMode) { node.references(RefKind.HiddenAnnotation).map { it.to } - .find { it.name == "ParameterName" }?.let { - val parameterNameValue = it.detail(NodeKind.Parameter).detail(NodeKind.Value) - identifier(parameterNameValue.name.removeSurrounding("\""), IdentifierKind.ParameterName) - symbol(":") - nbsp() - } + .find { it.name == "ParameterName" }?.let { + val parameterNameValue = it.detail(NodeKind.Parameter).detail(NodeKind.Value) + identifier(parameterNameValue.name.removeSurrounding("\""), IdentifierKind.ParameterName) + symbol(":") + nbsp() + } } private fun ContentBlock.renderFunctionalType(node: DocumentationNode, renderMode: RenderMode) { @@ -198,7 +170,7 @@ class KotlinLanguageService : LanguageService { renderAnnotationsForNode(node) } renderModifiersForNode(node, renderMode, true) - renderLinked(node) { identifier(it.name, IdentifierKind.TypeName) } + renderLinked(this, node) { identifier(it.name, IdentifierKind.TypeName) } val typeArguments = node.details(NodeKind.Type) if (typeArguments.isNotEmpty()) { symbol("<") @@ -213,17 +185,16 @@ class KotlinLanguageService : LanguageService { } } - private fun ContentBlock.renderModifier(node: DocumentationNode, nowrap: Boolean = false) { + override fun renderModifier( + block: ContentBlock, + node: DocumentationNode, + nowrap: Boolean + ) { when (node.name) { "final", "public", "var" -> { } else -> { - keyword(node.name) - if (nowrap) { - nbsp() - } else { - text(" ") - } + super.renderModifier(block, node, nowrap) } } } @@ -275,9 +246,12 @@ class KotlinLanguageService : LanguageService { } private fun ContentBlock.renderExtraTypeParameterConstraints(node: DocumentationNode, renderMode: RenderMode) { - val parametersWithMultipleConstraints = node.details(NodeKind.TypeParameter).filter { it.details(NodeKind.UpperBound).size > 1 } + val parametersWithMultipleConstraints = + node.details(NodeKind.TypeParameter).filter { it.details(NodeKind.UpperBound).size > 1 } val parametersWithConstraints = parametersWithMultipleConstraints - .flatMap { parameter -> parameter.details(NodeKind.UpperBound).map { constraint -> parameter to constraint } } + .flatMap { parameter -> + parameter.details(NodeKind.UpperBound).map { constraint -> parameter to constraint } + } if (parametersWithMultipleConstraints.isNotEmpty()) { keyword(" where ") renderList(parametersWithConstraints) { @@ -303,9 +277,11 @@ class KotlinLanguageService : LanguageService { } } - private fun ContentBlock.renderModifiersForNode(node: DocumentationNode, - renderMode: RenderMode, - nowrap: Boolean = false) { + private fun ContentBlock.renderModifiersForNode( + node: DocumentationNode, + renderMode: RenderMode, + nowrap: Boolean = false + ) { val modifiers = node.details(NodeKind.Modifier) for (it in modifiers) { if (node.kind == org.jetbrains.dokka.NodeKind.Interface && it.name == "abstract") @@ -313,7 +289,7 @@ class KotlinLanguageService : LanguageService { if (renderMode == RenderMode.SUMMARY && it.name in fullOnlyModifiers) { continue } - renderModifier(it, nowrap) + renderModifier(this, it, nowrap) } } @@ -366,9 +342,11 @@ class KotlinLanguageService : LanguageService { } } - private fun ContentBlock.renderFunction(node: DocumentationNode, - renderMode: RenderMode, - signatureMapper: SignatureMapper? = null) { + private fun ContentBlock.renderFunction( + node: DocumentationNode, + renderMode: RenderMode, + signatureMapper: SignatureMapper? = null + ) { if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) } @@ -408,7 +386,11 @@ class KotlinLanguageService : LanguageService { renderExtraTypeParameterConstraints(node, renderMode) } - private fun ContentBlock.renderReceiver(node: DocumentationNode, renderMode: RenderMode, signatureMapper: SignatureMapper?) { + private fun ContentBlock.renderReceiver( + node: DocumentationNode, + renderMode: RenderMode, + signatureMapper: SignatureMapper? + ) { val receiver = node.details(NodeKind.Receiver).singleOrNull() if (receiver != null) { if (signatureMapper != null) { @@ -434,11 +416,13 @@ class KotlinLanguageService : LanguageService { } fun DocumentationNode.isUnitReturnType(): Boolean = - detail(NodeKind.Type).hiddenLinks.firstOrNull()?.qualifiedName() == "kotlin.Unit" + detail(NodeKind.Type).hiddenLinks.firstOrNull()?.qualifiedName() == "kotlin.Unit" - private fun ContentBlock.renderProperty(node: DocumentationNode, - renderMode: RenderMode, - signatureMapper: SignatureMapper? = null) { + private fun ContentBlock.renderProperty( + node: DocumentationNode, + renderMode: RenderMode, + signatureMapper: SignatureMapper? = null + ) { if (renderMode == RenderMode.FULL) { renderAnnotationsForNode(node) } @@ -462,7 +446,7 @@ class KotlinLanguageService : LanguageService { } fun DocumentationNode.getPropertyKeyword() = - if (details(NodeKind.Modifier).any { it.name == "var" }) "var" else "val" + if (details(NodeKind.Modifier).any { it.name == "var" }) "var" else "val" fun ContentBlock.identifierOrDeprecated(node: DocumentationNode) { if (node.deprecation != null) { @@ -476,6 +460,6 @@ class KotlinLanguageService : LanguageService { } fun DocumentationNode.qualifiedNameFromType() = - details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name - ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() - ?: name + details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name + ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() + ?: name -- cgit From 31a4a3804020130e7caf5826b317aaee5547c0d0 Mon Sep 17 00:00:00 2001 From: Douglas Sigelbaum Date: Fri, 20 Apr 2018 18:09:36 -0700 Subject: [backport] Use expression body Original: d889d4e --- core/src/main/kotlin/Kotlin/KotlinLanguageService.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt index 69a97848..79350237 100644 --- a/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt +++ b/core/src/main/kotlin/Kotlin/KotlinLanguageService.kt @@ -459,7 +459,8 @@ class KotlinLanguageService : CommonLanguageService() { } } -fun DocumentationNode.qualifiedNameFromType() = - details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name +fun DocumentationNode.qualifiedNameFromType(): String { + return details.firstOrNull { it.kind == NodeKind.QualifiedName }?.name ?: (links.firstOrNull() ?: hiddenLinks.firstOrNull())?.qualifiedName() ?: name +} -- cgit From a3f16fd75c200020465f79563ca58b2833236865 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 24 Apr 2018 20:35:42 +0300 Subject: [backport] Stabilize signatures to fix linking from Java to Kotlin Basically there is 2 ways to get signature, from PSI and from descriptors, and there should be only one way in one session Original: adc09f2 --- .../main/kotlin/Kotlin/DeclarationLinkResolver.kt | 7 ++--- .../kotlin/Kotlin/DescriptorDocumentationParser.kt | 6 +++-- .../src/main/kotlin/Kotlin/DocumentationBuilder.kt | 23 +++++++--------- .../KotlinAsJavaDescriptorSignatureProvider.kt | 22 --------------- .../Kotlin/KotlinAsJavaElementSignatureProvider.kt | 25 +++++++++++++++++ .../Kotlin/KotlinDescriptorSignatureProvider.kt | 9 ------- .../Kotlin/KotlinElementSignatureProvider.kt | 31 ++++++++++++++++++++++ 7 files changed, 71 insertions(+), 52 deletions(-) delete mode 100644 core/src/main/kotlin/Kotlin/KotlinAsJavaDescriptorSignatureProvider.kt create mode 100644 core/src/main/kotlin/Kotlin/KotlinAsJavaElementSignatureProvider.kt delete mode 100644 core/src/main/kotlin/Kotlin/KotlinDescriptorSignatureProvider.kt create mode 100644 core/src/main/kotlin/Kotlin/KotlinElementSignatureProvider.kt (limited to 'core/src/main/kotlin/Kotlin') diff --git a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt index ec474900..d73bef4a 100644 --- a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt +++ b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt @@ -1,13 +1,10 @@ package org.jetbrains.dokka import com.google.inject.Inject -import org.jetbrains.dokka.Model.DescriptorSignatureProvider import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink -import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi -import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi class DeclarationLinkResolver @Inject constructor(val resolutionFacade: DokkaResolutionFacade, @@ -15,7 +12,7 @@ class DeclarationLinkResolver val logger: DokkaLogger, val options: DocumentationOptions, val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver, - val descriptorSignatureProvider: DescriptorSignatureProvider) { + val elementSignatureProvider: ElementSignatureProvider) { fun tryResolveContentLink(fromDescriptor: DeclarationDescriptor, href: String): ContentBlock? { @@ -34,7 +31,7 @@ class DeclarationLinkResolver if (externalHref != null) { return ContentExternalLink(externalHref) } - val signature = descriptorSignatureProvider.signature(symbol) + val signature = elementSignatureProvider.signature(symbol) val referencedAt = fromDescriptor.signatureWithSourceLocation() return ContentNodeLazyLink(href, { -> diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt index 6e44df74..5f1118e8 100644 --- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt +++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt @@ -33,7 +33,9 @@ class DescriptorDocumentationParser val linkResolver: DeclarationLinkResolver, val resolutionFacade: DokkaResolutionFacade, val refGraph: NodeReferenceGraph, - val sampleService: SampleProcessingService) + val sampleService: SampleProcessingService, + val signatureProvider: KotlinElementSignatureProvider + ) { fun parseDocumentation(descriptor: DeclarationDescriptor, inline: Boolean = false): Content = parseDocumentationAndDetails(descriptor, inline).first @@ -129,7 +131,7 @@ class DescriptorDocumentationParser fun parseJavadoc(descriptor: DeclarationDescriptor): Pair Unit> { val psi = ((descriptor as? DeclarationDescriptorWithSource)?.source as? PsiSourceElement)?.psi if (psi is PsiDocCommentOwner) { - val parseResult = JavadocParser(refGraph, logger).parseDocumentation(psi as PsiNamedElement) + val parseResult = JavadocParser(refGraph, logger, signatureProvider).parseDocumentation(psi as PsiNamedElement) return parseResult.content to { node -> parseResult.deprecatedContent?.let { val deprecationNode = DocumentationNode("", it, NodeKind.Modifier) diff --git a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt index d7d30ebb..05bd2cc7 100644 --- a/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt +++ b/core/src/main/kotlin/Kotlin/DocumentationBuilder.kt @@ -18,7 +18,6 @@ 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.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -29,7 +28,6 @@ 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.jet