diff options
author | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2018-01-17 20:01:20 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2018-07-13 18:30:33 +0300 |
commit | 1391dcca35a871881420c53755fed08bf47e4087 (patch) | |
tree | 8b0c4906722a86afca0b8a8b5834494c73c0a2af | |
parent | c776aaab9af80987e3c073a40f92de748dbd38ca (diff) | |
download | dokka-1391dcca35a871881420c53755fed08bf47e4087.tar.gz dokka-1391dcca35a871881420c53755fed08bf47e4087.tar.bz2 dokka-1391dcca35a871881420c53755fed08bf47e4087.zip |
[backport] Support propagating inherited extensions from libraries
Original: bf2945d
-rw-r--r-- | core/src/main/kotlin/DokkaBootstrapImpl.kt | 3 | ||||
-rw-r--r-- | core/src/main/kotlin/Generation/DokkaGenerator.kt | 2 | ||||
-rw-r--r-- | core/src/main/kotlin/Generation/configurationImpl.kt | 47 | ||||
-rw-r--r-- | core/src/main/kotlin/Kotlin/DocumentationBuilder.kt | 200 | ||||
-rw-r--r-- | core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt | 2 | ||||
-rw-r--r-- | core/src/main/kotlin/Model/DocumentationNode.kt | 2 | ||||
-rw-r--r-- | core/src/test/kotlin/TestAPI.kt | 32 | ||||
-rw-r--r-- | integration/src/main/kotlin/org/jetbrains/dokka/configuration.kt | 48 | ||||
-rw-r--r-- | runners/cli/src/main/kotlin/cli/main.kt | 28 | ||||
-rw-r--r-- | runners/gradle-plugin/src/main/kotlin/main.kt | 51 |
10 files changed, 273 insertions, 142 deletions
diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index aeaca8be..b7787be8 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -69,7 +69,8 @@ class DokkaBootstrapImpl : DokkaBootstrap { languageVersion, apiVersion, cacheRoot, - suppressedFiles.map { File(it) }.toSet() + suppressedFiles.map { File(it) }.toSet(), + collectInheritedExtensionsFromLibraries ) ) } diff --git a/core/src/main/kotlin/Generation/DokkaGenerator.kt b/core/src/main/kotlin/Generation/DokkaGenerator.kt index 09e5cedf..33170f35 100644 --- a/core/src/main/kotlin/Generation/DokkaGenerator.kt +++ b/core/src/main/kotlin/Generation/DokkaGenerator.kt @@ -160,6 +160,8 @@ fun buildDocumentationModule(injector: Injector, with(injector.getInstance(DocumentationBuilder::class.java)) { documentationModule.appendFragments(fragments, packageDocs.packageContent, injector.getInstance(PackageDocumentationBuilder::class.java)) + + propagateExtensionFunctionsToSubclasses(fragments, resolutionFacade) } val javaFiles = coreEnvironment.getJavaSourceFiles().filter(filesToDocumentFilter) diff --git a/core/src/main/kotlin/Generation/configurationImpl.kt b/core/src/main/kotlin/Generation/configurationImpl.kt index 34d4154e..52e8446f 100644 --- a/core/src/main/kotlin/Generation/configurationImpl.kt +++ b/core/src/main/kotlin/Generation/configurationImpl.kt @@ -36,27 +36,28 @@ data class PackageOptionsImpl(override val prefix: String, override val suppress: Boolean = false) : DokkaConfiguration.PackageOptions data class DokkaConfigurationImpl( - override val moduleName: String, - override val classpath: List<String>, - override val sourceRoots: List<SourceRootImpl>, - override val samples: List<String>, - override val includes: List<String>, - override val outputDir: String, - override val format: String, - override val includeNonPublic: Boolean, - override val includeRootPackage: Boolean, - override val reportUndocumented: Boolean, - override val skipEmptyPackages: Boolean, - override val skipDeprecated: Boolean, - override val jdkVersion: Int, - override val generateIndexPages: Boolean, - override val sourceLinks: List<SourceLinkDefinitionImpl>, - override val impliedPlatforms: List<String>, - override val perPackageOptions: List<PackageOptionsImpl>, - override val externalDocumentationLinks: List<ExternalDocumentationLinkImpl>, - override val noStdlibLink: Boolean, - override val cacheRoot: String?, - override val suppressedFiles: List<String>, - override val languageVersion: String?, - override val apiVersion: String? + override val moduleName: String, + override val classpath: List<String>, + override val sourceRoots: List<SourceRootImpl>, + override val samples: List<String>, + override val includes: List<String>, + override val outputDir: String, + override val format: String, + override val includeNonPublic: Boolean, + override val includeRootPackage: Boolean, + override val reportUndocumented: Boolean, + override val skipEmptyPackages: Boolean, + override val skipDeprecated: Boolean, + override val jdkVersion: Int, + override val generateIndexPages: Boolean, + override val sourceLinks: List<SourceLinkDefinitionImpl>, + override val impliedPlatforms: List<String>, + override val perPackageOptions: List<PackageOptionsImpl>, + override val externalDocumentationLinks: List<ExternalDocumentationLinkImpl>, + override val noStdlibLink: Boolean, + override val cacheRoot: String?, + override val suppressedFiles: List<String>, + override val languageVersion: String?, + override val apiVersion: String?, + override val collectInheritedExtensionsFromLibraries: Boolean ) : DokkaConfiguration
\ No newline at end of file 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<File> = emptySet()) { + val suppressedFiles: Set<File> = 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 <T> nodeForDescriptor(descriptor: T, kind: NodeKind): DocumentationNode where T : DeclarationDescriptor, T : Named { - val (doc, callback) = descriptorDocumentationParser.parseDocumentationAndDetails(descriptor, kind == NodeKind.Parameter) + 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) @@ -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<PackageFragmentDescriptor>) { - val allDescriptors = fragments.flatMap { it.getMemberScope().getContributedDescriptors() } - val allClasses = allDescriptors.filterIsInstance<ClassDescriptor>() - val classHierarchy = buildClassHierarchy(allClasses) + fun propagateExtensionFunctionsToSubclasses( + fragments: Collection<PackageFragmentDescriptor>, + 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<ClassDescriptor>() + + val classHierarchy = buildClassHierarchy(documentingClasses) + + val allExtensionFunctions = + allDescriptors .filterIsInstance<CallableMemberDescriptor>() .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<ClassDescriptor>): Map<ClassDescriptor, List<ClassDescriptor>> { @@ -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 } diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt index a792460f..85ecdf87 100644 --- a/core/src/main/kotlin/Model/DocumentationNode.kt +++ b/core/src/main/kotlin/Model/DocumentationNode.kt @@ -209,6 +209,8 @@ fun DocumentationNode.appendTextNode(text: String, fun DocumentationNode.qualifiedName(): String { if (kind == NodeKind.Type) { return qualifiedNameFromType() + } else if (kind == NodeKind.Package) { + return name } return path.drop(1).map { it.name }.filter { it.length > 0 }.joinToString(".") } diff --git a/core/src/test/kotlin/TestAPI.kt b/core/src/test/kotlin/TestAPI.kt index 559b715e..aeff9284 100644 --- a/core/src/test/kotlin/TestAPI.kt +++ b/core/src/test/kotlin/TestAPI.kt @@ -25,22 +25,24 @@ fun verifyModel(vararg roots: ContentRoot, includeNonPublic: Boolean = true, perPackageOptions: List<DokkaConfiguration.PackageOptions> = emptyList(), noStdlibLink: Boolean = true, + collectInheritedExtensionsFromLibraries: Boolean = false, verifier: (DocumentationModule) -> Unit) { val documentation = DocumentationModule("test") val options = DocumentationOptions( - "", - format, - includeNonPublic = includeNonPublic, - skipEmptyPackages = false, - includeRootPackage = true, - sourceLinks = listOf(), - perPackageOptions = perPackageOptions, - generateIndexPages = false, - noStdlibLink = noStdlibLink, - cacheRoot = "default", - languageVersion = null, - apiVersion = null + "", + format, + includeNonPublic = includeNonPublic, + skipEmptyPackages = false, + includeRootPackage = true, + sourceLinks = listOf(), + perPackageOptions = perPackageOptions, + generateIndexPages = false, + noStdlibLink = noStdlibLink, + cacheRoot = "default", + languageVersion = null, + apiVersion = null, + collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries ) appendDocumentation(documentation, *roots, @@ -162,6 +164,7 @@ fun verifyOutput(roots: Array<ContentRoot>, format: String = "html", includeNonPublic: Boolean = true, noStdlibLink: Boolean = true, + collectInheritedExtensionsFromLibraries: Boolean = false, outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { verifyModel( *roots, @@ -169,7 +172,8 @@ fun verifyOutput(roots: Array<ContentRoot>, withKotlinRuntime = withKotlinRuntime, format = format, includeNonPublic = includeNonPublic, - noStdlibLink = noStdlibLink + noStdlibLink = noStdlibLink, + collectInheritedExtensionsFromLibraries = collectInheritedExtensionsFromLibraries ) { verifyModelOutput(it, outputExtension, roots.first().path, outputGenerator) } @@ -194,6 +198,7 @@ fun verifyOutput( format: String = "html", includeNonPublic: Boolean = true, noStdlibLink: Boolean = true, + collectInheritedExtensionsFromLibraries: Boolean = false, outputGenerator: (DocumentationModule, StringBuilder) -> Unit ) { verifyOutput( @@ -204,6 +209,7 @@ fun verifyOutput( format, includeNonPublic, noStdlibLink, + collectInheritedExtensionsFromLibraries, outputGenerator ) } diff --git a/integration/src/main/kotlin/org/jetbrains/dokka/configuration.kt b/integration/src/main/kotlin/org/jetbrains/dokka/configuration.kt index 90e5b5fc..46a57278 100644 --- a/integration/src/main/kotlin/org/jetbrains/dokka/configuration.kt +++ b/integration/src/main/kotlin/org/jetbrains/dokka/configuration.kt @@ -41,6 +41,7 @@ interface DokkaConfiguration { val noStdlibLink: Boolean val cacheRoot: String? val suppressedFiles: List<String> + val collectInheritedExtensionsFromLibraries: Boolean interface SourceRoot { val path: String @@ -82,29 +83,30 @@ interface DokkaConfiguration { } data class SerializeOnlyDokkaConfiguration( - override val moduleName: String, - override val classpath: List<String>, - override val sourceRoots: List<DokkaConfiguration.SourceRoot>, - override val samples: List<String>, - override val includes: List<String>, - override val outputDir: String, - override val format: String, - override val includeNonPublic: Boolean, - override val includeRootPackage: Boolean, - override val reportUndocumented: Boolean, - override val skipEmptyPackages: Boolean, - override val skipDeprecated: Boolean, - override val jdkVersion: Int, - override val generateIndexPages: Boolean, - override val sourceLinks: List<DokkaConfiguration.SourceLinkDefinition>, - override val impliedPlatforms: List<String>, - override val perPackageOptions: List<DokkaConfiguration.PackageOptions>, - override val externalDocumentationLinks: List<DokkaConfiguration.ExternalDocumentationLink>, - override val noStdlibLink: Boolean, - override val cacheRoot: String?, - override val suppressedFiles: List<String>, - override val languageVersion: String?, - override val apiVersion: String? + override val moduleName: String, + override val classpath: List<String>, + override val sourceRoots: List<DokkaConfiguration.SourceRoot>, + override val samples: List<String>, + override val includes: List<String>, + override val outputDir: String, + override val format: String, + override val includeNonPublic: Boolean, + override val includeRootPackage: Boolean, + override val reportUndocumented: Boolean, + override val skipEmptyPackages: Boolean, + override val skipDeprecated: Boolean, + override val jdkVersion: Int, + override val generateIndexPages: Boolean, + override val sourceLinks: List<DokkaConfiguration.SourceLinkDefinition>, + override val impliedPlatforms: List<String>, + override val perPackageOptions: List<DokkaConfiguration.PackageOptions>, + override val externalDocumentationLinks: List<DokkaConfiguration.ExternalDocumentationLink>, + override val noStdlibLink: Boolean, + override val cacheRoot: String?, + override val suppressedFiles: List<String>, + override val languageVersion: String?, + override val apiVersion: String?, + override val collectInheritedExtensionsFromLibraries: Boolean ) : DokkaConfiguration diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index fe945ed3..111e1420 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -62,6 +62,9 @@ class DokkaArguments { @set:Argument(value = "apiVersion", description = "Kotlin Api Version to pass to Kotlin Analysis") var apiVersion: String? = null + @set:Argument(value = "collectInheritedExtensionsFromLibraries", description = "Search for applicable extensions in libraries") + var collectInheritedExtensionsFromLibraries: Boolean = false + } @@ -106,18 +109,19 @@ object MainKt { val classPath = arguments.classpath.split(File.pathSeparatorChar).toList() val documentationOptions = DocumentationOptions( - arguments.outputDir.let { if (it.endsWith('/')) it else it + '/' }, - arguments.outputFormat, - skipDeprecated = arguments.nodeprecated, - sourceLinks = sourceLinks, - impliedPlatforms = arguments.impliedPlatforms.split(','), - perPackageOptions = parsePerPackageOptions(arguments.packageOptions), - jdkVersion = arguments.jdkVersion, - externalDocumentationLinks = parseLinks(arguments.links), - noStdlibLink = arguments.noStdlibLink, - cacheRoot = arguments.cacheRoot, - languageVersion = arguments.languageVersion, - apiVersion = arguments.apiVersion + arguments.outputDir.let { if (it.endsWith('/')) it else it + '/' }, + arguments.outputFormat, + skipDeprecated = arguments.nodeprecated, + sourceLinks = sourceLinks, + impliedPlatforms = arguments.impliedPlatforms.split(','), + perPackageOptions = parsePerPackageOptions(arguments.packageOptions), + jdkVersion = arguments.jdkVersion, + externalDocumentationLinks = parseLinks(arguments.links), + noStdlibLink = arguments.noStdlibLink, + cacheRoot = arguments.cacheRoot, + languageVersion = arguments.languageVersion, + apiVersion = arguments.apiVersion, + collectInheritedExtensionsFromLibraries = arguments.collectInheritedExtensionsFromLibraries ) val generator = DokkaGenerator( diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt index 5f02cd0e..4812e217 100644 --- a/runners/gradle-plugin/src/main/kotlin/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/main.kt @@ -134,6 +134,9 @@ open class DokkaTask : DefaultTask() { @Optional @Input var apiVersion: String? = null + @Input + var collectInheritedExtensionsFromLibraries: Boolean = false + @get:Internal internal val kotlinCompileBasedClasspathAndSourceRoots: ClasspathAndSourceRoots by lazy { extractClasspathAndSourceRootsFromKotlinTasks() } @@ -287,29 +290,31 @@ open class DokkaTask : DefaultTask() { val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(javaClass.classLoader, bootstrapInstance) val configuration = SerializeOnlyDokkaConfiguration( - moduleName, - fullClasspath.map { it.absolutePath }, - sourceRoots, - samples.filterNotNull().map { project.file(it).absolutePath }, - includes.filterNotNull().map { project.file(it).absolutePath }, - outputDirectory, - outputFormat, - includeNonPublic, - false, - reportUndocumented, - skipEmptyPackages, - skipDeprecated, - jdkVersion, - true, - linkMappings, - impliedPlatforms, - perPackageOptions, - externalDocumentationLinks, - noStdlibLink, - cacheRoot, - collectSuppressedFiles(sourceRoots), - languageVersion, - apiVersion) + moduleName, + fullClasspath.map { it.absolutePath }, + sourceRoots, + samples.filterNotNull().map { project.file(it).absolutePath }, + includes.filterNotNull().map { project.file(it).absolutePath }, + outputDirectory, + outputFormat, + includeNonPublic, + false, + reportUndocumented, + skipEmptyPackages, + skipDeprecated, + jdkVersion, + true, + linkMappings, + impliedPlatforms, + perPackageOptions, + externalDocumentationLinks, + noStdlibLink, + cacheRoot, + collectSuppressedFiles(sourceRoots), + languageVersion, + apiVersion, + collectInheritedExtensionsFromLibraries + ) bootstrapProxy.configure( |