aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2018-01-11 22:22:36 +0300
committerSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2018-07-13 18:30:09 +0300
commitc776aaab9af80987e3c073a40f92de748dbd38ca (patch)
treee14827cc2d290c1d7bb8b0544495a31ba9328bfd /core/src
parentbd30fa4c84d749976568be00307297ab015d9b2e (diff)
downloaddokka-c776aaab9af80987e3c073a40f92de748dbd38ca.tar.gz
dokka-c776aaab9af80987e3c073a40f92de748dbd38ca.tar.bz2
dokka-c776aaab9af80987e3c073a40f92de748dbd38ca.zip
[backport] Support deep inheritance with external classes
Original: 9e65c3d
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/kotlin/Kotlin/DocumentationBuilder.kt70
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinLanguageService.kt2
-rw-r--r--core/src/main/kotlin/Model/DocumentationNode.kt19
-rw-r--r--core/src/main/kotlin/Model/DocumentationReference.kt3
-rw-r--r--core/src/test/kotlin/TestAPI.kt48
-rw-r--r--core/src/test/kotlin/model/JavaTest.kt2
6 files changed, 92 insertions, 52 deletions
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<String>
}
+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(":")
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index a145ae8d..a792460f 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -104,12 +104,27 @@ open class DocumentationNode(val name: String,
get() = references(RefKind.Deprecation).singleOrNull()?.to
val platforms: List<String>
get() = references(RefKind.Platform).map { it.to.name }
+ val externalType: DocumentationNode?
+ get() = references(RefKind.ExternalType).map { it.to }.firstOrNull()
val supertypes: List<DocumentationNode>
get() = details(NodeKind.Supertype)
- val superclass: DocumentationNode?
- get() = supertypes.firstOrNull { it.links.any { it.kind in NodeKind.classLike } }
+ val superclassType: DocumentationNode?
+ get() = when (kind) {
+ NodeKind.Supertype -> (links.firstOrNull { it.kind in NodeKind.classLike } ?: externalType)?.superclassType
+ NodeKind.Interface -> null
+ in NodeKind.classLike -> supertypes.firstOrNull {
+ it.links.any { it.kind in NodeKind.classLike } ||
+ it.externalType != null
+ }
+ else -> null
+ }
+
+ val superclassTypeSequence: Sequence<DocumentationNode>
+ get() = generateSequence(superclassType) {
+ it.superclassType
+ }
// TODO: Should we allow node mutation? Model merge will copy by ref, so references are transparent, which could nice
fun addReferenceTo(to: DocumentationNode, kind: RefKind) {
diff --git a/core/src/main/kotlin/Model/DocumentationReference.kt b/core/src/main/kotlin/Model/DocumentationReference.kt
index a968f400..b0f011be 100644
--- a/core/src/main/kotlin/Model/DocumentationReference.kt
+++ b/core/src/main/kotlin/Model/DocumentationReference.kt
@@ -18,7 +18,8 @@ enum class RefKind {
HiddenAnnotation,
Deprecation,
TopLevelPage,
- Platform
+ Platform,
+ ExternalType
}
data class DocumentationReference(val from: DocumentationNode, val to: DocumentationNode, val kind: RefKind) {
diff --git a/core/src/test/kotlin/TestAPI.kt b/core/src/test/kotlin/TestAPI.kt
index aa3eff48..559b715e 100644
--- a/core/src/test/kotlin/TestAPI.kt
+++ b/core/src/test/kotlin/TestAPI.kt
@@ -6,7 +6,6 @@ import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.rt.execution.junit.FileComparisonFailure
import org.jetbrains.dokka.*
-import org.jetbrains.dokka.DokkaConfiguration.SourceLinkDefinition
import org.jetbrains.dokka.Utilities.DokkaAnalysisModule
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
@@ -25,6 +24,7 @@ fun verifyModel(vararg roots: ContentRoot,
format: String = "html",
includeNonPublic: Boolean = true,
perPackageOptions: List<DokkaConfiguration.PackageOptions> = emptyList(),
+ noStdlibLink: Boolean = true,
verifier: (DocumentationModule) -> Unit) {
val documentation = DocumentationModule("test")
@@ -37,7 +37,7 @@ fun verifyModel(vararg roots: ContentRoot,
sourceLinks = listOf(),
perPackageOptions = perPackageOptions,
generateIndexPages = false,
- noStdlibLink = true,
+ noStdlibLink = noStdlibLink,
cacheRoot = "default",
languageVersion = null,
apiVersion = null
@@ -161,13 +161,15 @@ fun verifyOutput(roots: Array<ContentRoot>,
withKotlinRuntime: Boolean = false,
format: String = "html",
includeNonPublic: Boolean = true,
+ noStdlibLink: Boolean = true,
outputGenerator: (DocumentationModule, StringBuilder) -> Unit) {
verifyModel(
- *roots,
- withJdk = withJdk,
- withKotlinRuntime = withKotlinRuntime,
- format = format,
- includeNonPublic = includeNonPublic
+ *roots,
+ withJdk = withJdk,
+ withKotlinRuntime = withKotlinRuntime,
+ format = format,
+ includeNonPublic = includeNonPublic,
+ noStdlibLink = noStdlibLink
) {
verifyModelOutput(it, outputExtension, roots.first().path, outputGenerator)
}
@@ -184,21 +186,25 @@ fun verifyModelOutput(it: DocumentationModule,
assertEqualsIgnoringSeparators(expectedFile, output.toString())
}
-fun verifyOutput(path: String,
- outputExtension: String,
- withJdk: Boolean = false,
- withKotlinRuntime: Boolean = false,
- format: String = "html",
- includeNonPublic: Boolean = true,
- outputGenerator: (DocumentationModule, StringBuilder) -> Unit) {
+fun verifyOutput(
+ path: String,
+ outputExtension: String,
+ withJdk: Boolean = false,
+ withKotlinRuntime: Boolean = false,
+ format: String = "html",
+ includeNonPublic: Boolean = true,
+ noStdlibLink: Boolean = true,
+ outputGenerator: (DocumentationModule, StringBuilder) -> Unit
+) {
verifyOutput(
- arrayOf(contentRootFromPath(path)),
- outputExtension,
- withJdk,
- withKotlinRuntime,
- format,
- includeNonPublic,
- outputGenerator
+ arrayOf(contentRootFromPath(path)),
+ outputExtension,
+ withJdk,
+ withKotlinRuntime,
+ format,
+ includeNonPublic,
+ noStdlibLink,
+ outputGenerator
)
}
diff --git a/core/src/test/kotlin/model/JavaTest.kt b/core/src/test/kotlin/model/JavaTest.kt
index e6c22ee4..c2ede8f0 100644
--- a/core/src/test/kotlin/model/JavaTest.kt
+++ b/core/src/test/kotlin/model/JavaTest.kt
@@ -193,7 +193,7 @@ public class JavaTest {
@Test fun enumValues() {
verifyJavaPackageMember("testdata/java/enumValues.java") { cls ->
val superTypes = cls.details(NodeKind.Supertype)
- assertEquals(0, superTypes.size)
+ assertEquals(1, superTypes.size)
assertEquals(1, cls.members(NodeKind.EnumItem).size)
}
}