diff options
author | Marcin Aman <maman@virtuslab.com> | 2020-07-02 13:21:00 +0200 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-07-13 14:47:37 +0200 |
commit | b67f44943bc80dedd70c4a9e120b9c6aec78ca72 (patch) | |
tree | 349a417b0ed67e1220b4d7c3c82800a7d3a956bd | |
parent | f042de920724f6e2ae4ccbcb21baed6b490290ab (diff) | |
download | dokka-b67f44943bc80dedd70c4a9e120b9c6aec78ca72.tar.gz dokka-b67f44943bc80dedd70c4a9e120b9c6aec78ca72.tar.bz2 dokka-b67f44943bc80dedd70c4a9e120b9c6aec78ca72.zip |
Draft for showing only first level of inheritance
13 files changed, 149 insertions, 170 deletions
diff --git a/core/src/main/kotlin/links/DRI.kt b/core/src/main/kotlin/links/DRI.kt index 3f6d886f..3892fc00 100644 --- a/core/src/main/kotlin/links/DRI.kt +++ b/core/src/main/kotlin/links/DRI.kt @@ -1,5 +1,9 @@ package org.jetbrains.dokka.links +import org.jetbrains.dokka.model.ClassKind +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.WithSupertypes + /** * [DRI] stands for DokkaResourceIdentifier */ @@ -100,3 +104,4 @@ fun DriTarget.nextTarget(): DriTarget = when (this) { else -> this } +data class DriWithKind(val dri: DRI, val kind: ClassKind) diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index 21660f86..2c3e1323 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka.model import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.DriWithKind import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.WithExtraProperties @@ -75,7 +76,7 @@ interface WithGenerics { } interface WithSupertypes { - val supertypes: SourceSetDependent<List<DRI>> + val supertypes: SourceSetDependent<List<DriWithKind>> } interface Callable : WithVisibility, WithType, WithAbstraction, WithExpectActual { @@ -128,7 +129,7 @@ data class DClass( override val visibility: SourceSetDependent<Visibility>, override val companion: DObject?, override val generics: List<DTypeParameter>, - override val supertypes: SourceSetDependent<List<DRI>>, + override val supertypes: SourceSetDependent<List<DriWithKind>>, override val documentation: SourceSetDependent<DocumentationNode>, override val expectPresentInSet: DokkaSourceSet?, override val modifier: SourceSetDependent<Modifier>, @@ -156,7 +157,7 @@ data class DEnum( override val visibility: SourceSetDependent<Visibility>, override val companion: DObject?, override val constructors: List<DFunction>, - override val supertypes: SourceSetDependent<List<DRI>>, + override val supertypes: SourceSetDependent<List<DriWithKind>>, override val sourceSets: Set<DokkaSourceSet>, override val extra: PropertyContainer<DEnum> = PropertyContainer.empty() ) : DClasslike(), WithCompanion, WithConstructors, WithSupertypes, WithExtraProperties<DEnum> { @@ -217,7 +218,7 @@ data class DInterface( override val visibility: SourceSetDependent<Visibility>, override val companion: DObject?, override val generics: List<DTypeParameter>, - override val supertypes: SourceSetDependent<List<DRI>>, + override val supertypes: SourceSetDependent<List<DriWithKind>>, override val sourceSets: Set<DokkaSourceSet>, override val extra: PropertyContainer<DInterface> = PropertyContainer.empty() ) : DClasslike(), WithCompanion, WithGenerics, WithSupertypes, WithExtraProperties<DInterface> { @@ -237,7 +238,7 @@ data class DObject( override val properties: List<DProperty>, override val classlikes: List<DClasslike>, override val visibility: SourceSetDependent<Visibility>, - override val supertypes: SourceSetDependent<List<DRI>>, + override val supertypes: SourceSetDependent<List<DriWithKind>>, override val sourceSets: Set<DokkaSourceSet>, override val extra: PropertyContainer<DObject> = PropertyContainer.empty() ) : DClasslike(), WithSupertypes, WithExtraProperties<DObject> { diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 14c130a2..37e0ea83 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -184,7 +184,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog if (c is WithSupertypes) { c.supertypes.filter { it.key == sourceSet }.map { (s, dris) -> list(dris, prefix = " : ", sourceSets = setOf(s)) { - link(it.sureClassNames, it, sourceSets = setOf(s)) + link(it.dri.sureClassNames, it.dri, sourceSets = setOf(s)) } } } diff --git a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt index f1bccd66..85256d51 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/InheritorsExtractorTransformer.kt @@ -63,7 +63,7 @@ class InheritorsExtractorTransformer : DocumentableTransformer { private fun <T : Documentable> T.toInheritanceEntries() = (this as? WithSupertypes)?.let { - it.supertypes.map { (k, v) -> k to v.map { it to dri } } + it.supertypes.map { (k, v) -> k to v.map { it.dri to dri } } }.orEmpty() } diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index b0374014..9ca8cdde 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -1,7 +1,11 @@ package org.jetbrains.dokka.base.translators.descriptors import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet -import org.jetbrains.dokka.analysis.* +import org.jetbrains.dokka.analysis.DescriptorDocumentableSource +import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.analysis.KotlinAnalysis +import org.jetbrains.dokka.analysis.from +import org.jetbrains.dokka.base.parsers.MarkdownParser import org.jetbrains.dokka.links.* import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.model.* @@ -9,7 +13,6 @@ import org.jetbrains.dokka.model.Nullable import org.jetbrains.dokka.model.TypeConstructor import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.base.parsers.MarkdownParser import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator import org.jetbrains.dokka.utilities.DokkaLogger @@ -33,7 +36,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.LocalClass import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass -import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny +import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -150,7 +153,7 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.interfaces.toSourceSetDependent()) + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) ) } @@ -177,7 +180,7 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.interfaces.toSourceSetDependent()) + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) ) } @@ -206,7 +209,7 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.interfaces.toSourceSetDependent()) + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) ) } @@ -290,7 +293,7 @@ private class DokkaDescriptorVisitor( extra = PropertyContainer.withAll( descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(), descriptor.getAnnotations().toSourceSetDependent().toAnnotations(), - ImplementedInterfaces(info.interfaces.toSourceSetDependent()) + ImplementedInterfaces(info.allImplementedInterfaces.toSourceSetDependent()) ) ) } @@ -535,11 +538,6 @@ private class DokkaDescriptorVisitor( .filter { it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY } .map { visitClassDescriptor(it as ClassDescriptor, parent) } - private fun MemberScope.packages(parent: DRIWithPlatformInfo): List<DPackage> = - getContributedDescriptors(DescriptorKindFilter.PACKAGES) { true } - .filterIsInstance<PackageFragmentDescriptor>() - .map { visitPackageFragmentDescriptor(it, parent) } - private fun MemberScope.typealiases(parent: DRIWithPlatformInfo, packageLevel: Boolean = false): List<DTypeAlias> = getContributedDescriptors(DescriptorKindFilter.TYPE_ALIASES, packageLevel) .filterIsInstance<TypeAliasDescriptor>() @@ -556,15 +554,30 @@ private class DokkaDescriptorVisitor( getDocumentation()?.toSourceSetDependent() ?: emptyMap() private fun ClassDescriptor.resolveClassDescriptionData(): ClassInfo { - val interfaces = hashSetOf<DRI>() - fun processSuperClasses(supers: List<ClassDescriptor>) { - supers.forEach { - if(it.kind == ClassKind.INTERFACE) interfaces.add(DRI.from(it)) - processSuperClasses(it.getSuperInterfaces() + it.getAllSuperclassesWithoutAny()) - } + tailrec fun processSuperClasses( + inheritorClass: ClassDescriptor?, + interfaces: List<ClassDescriptor>, + level: Int = 0, + inheritanceTree: Set<InheritanceLevel> = emptySet() + ): Set<InheritanceLevel> { + if (inheritorClass == null && interfaces.isEmpty()) return inheritanceTree + + val updatedTree = inheritanceTree + InheritanceLevel( + level, + inheritorClass?.let { DRI.from(it) }, + interfaces.map { DRI.from(it) }) + val superInterfacesFromClass = inheritorClass?.getSuperInterfaces().orEmpty() + return processSuperClasses( + inheritorClass = inheritorClass?.getSuperClassNotAny(), + interfaces = interfaces.flatMap { it.getSuperInterfaces() } + superInterfacesFromClass, + level = level + 1, + inheritanceTree = updatedTree + ) } - processSuperClasses(getSuperInterfaces() + getAllSuperclassesWithoutAny()) - return ClassInfo(getAllSuperclassesWithoutAny().map { DRI.from(it) }, interfaces.toList(), resolveDescriptorData()) + return ClassInfo( + processSuperClasses(getSuperClassNotAny(), getSuperInterfaces()).sortedBy { it.level }, + resolveDescriptorData() + ) } private fun TypeParameterDescriptor.toTypeParameter() = @@ -733,9 +746,16 @@ private class DokkaDescriptorVisitor( private fun ValueArgument.childrenAsText() = this.safeAs<KtValueArgument>()?.children?.map { it.text }.orEmpty() - private data class ClassInfo(val superclasses: List<DRI>, val interfaces: List<DRI>, val docs: SourceSetDependent<DocumentationNode>){ - val supertypes: List<DRI> - get() = (superclasses + interfaces).distinct() + private data class InheritanceLevel(val level: Int, val superclass: DRI?, val interfaces: List<DRI>) + + private data class ClassInfo(val inheritance: List<InheritanceLevel>, val docs: SourceSetDependent<DocumentationNode>){ + val supertypes: List<DriWithKind> + get() = inheritance.firstOrNull { it.level == 0 }?.let { + listOfNotNull(it.superclass?.let { DriWithKind(it, KotlinClassKindTypes.CLASS) }) + it.interfaces.map { DriWithKind(it, KotlinClassKindTypes.INTERFACE) } + }.orEmpty() + + val allImplementedInterfaces: List<DRI> + get() = inheritance.flatMap { it.interfaces }.distinct() } private fun Visibility.toDokkaVisibility(): org.jetbrains.dokka.model.Visibility = when (this) { diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index d426d41b..91b24476 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -12,6 +12,7 @@ import org.jetbrains.dokka.analysis.KotlinAnalysis import org.jetbrains.dokka.analysis.PsiDocumentableSource import org.jetbrains.dokka.analysis.from import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.DriWithKind import org.jetbrains.dokka.links.nextTarget import org.jetbrains.dokka.links.withClass import org.jetbrains.dokka.model.* @@ -127,11 +128,23 @@ class DefaultPsiToDocumentableTranslator( fun parseClasslike(psi: PsiClass, parent: DRI): DClasslike = with(psi) { val dri = parent.withClass(name.toString()) - val ancestorsSet = hashSetOf<Ancestor>() + val inheritanceTree = mutableListOf<AncestorLevel>() val superMethodsKeys = hashSetOf<Int>() val superMethods = mutableListOf<Pair<PsiMethod, DRI>>() methods.forEach { superMethodsKeys.add(it.hash) } - fun parseSupertypes(superTypes: Array<PsiClassType>) { + fun parseSupertypes(superTypes: Array<PsiClassType>, level: Int = 0) { + if(superTypes.isEmpty()) return + val parsedClasses = superTypes.filter { !it.shouldBeIgnored }.mapNotNull { + it.resolve()?.let { + when { + it.isInterface -> DRI.from(it) to JavaClassKindTypes.INTERFACE + else -> DRI.from(it) to JavaClassKindTypes.CLASS + } + } + } + val (classes, interfaces) = parsedClasses.partition { it.second == JavaClassKindTypes.CLASS } + inheritanceTree.add(AncestorLevel(level, classes.firstOrNull()?.first, interfaces.map { it.first })) + superTypes.forEach { type -> (type as? PsiClassType)?.takeUnless { type.shouldBeIgnored }?.resolve()?.let { val definedAt = DRI.from(it) @@ -144,8 +157,7 @@ class DefaultPsiToDocumentableTranslator( superMethods.add(Pair(method, definedAt)) } } - ancestorsSet.add(Ancestor(DRI.from(it), it.isInterface)) - parseSupertypes(it.superTypes) + parseSupertypes(it.superTypes, level + 1) } } } @@ -157,9 +169,16 @@ class DefaultPsiToDocumentableTranslator( val source = PsiDocumentableSource(this).toSourceSetDependent() val classlikes = innerClasses.map { parseClasslike(it, dri) } val visibility = getVisibility().toSourceSetDependent() - val ancestors = ancestorsSet.toList().map { it.dri }.toSourceSetDependent() + val ancestors = inheritanceTree.filter { it.level == 0 }.flatMap { + listOfNotNull(it.superclass?.let { + DriWithKind( + dri = it, + kind = JavaClassKindTypes.CLASS + ) + }) + it.interfaces.map { DriWithKind(dri = it, kind = JavaClassKindTypes.INTERFACE) } + }.toSourceSetDependent() val modifiers = getModifier().toSourceSetDependent() - val implementedInterfacesExtra = ImplementedInterfaces(ancestorsSet.filter { it.isInterface }.map { it.dri }.toList().toSourceSetDependent()) + val implementedInterfacesExtra = ImplementedInterfaces(inheritanceTree.flatMap { it.interfaces }.distinct().toSourceSetDependent()) return when { isAnnotationType -> DAnnotation( @@ -457,5 +476,5 @@ class DefaultPsiToDocumentableTranslator( get() = getChildOfType<PsiJavaCodeReferenceElement>()?.resolve() } - private data class Ancestor(val dri: DRI, val isInterface: Boolean) + private data class AncestorLevel(val level: Int, val superclass: DRI?, val interfaces: List<DRI>) } diff --git a/plugins/base/src/test/kotlin/model/ClassesTest.kt b/plugins/base/src/test/kotlin/model/ClassesTest.kt index 979ea89b..5dc8812e 100644 --- a/plugins/base/src/test/kotlin/model/ClassesTest.kt +++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt @@ -221,7 +221,7 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class with((this / "f").cast<DFunction>()) { modifier.values.forEach { it equals Open } } - D.supertypes.flatMap { it.component2() }.firstOrNull() equals C.dri + D.supertypes.flatMap { it.component2() }.firstOrNull()?.dri equals C.dri } } } @@ -258,8 +258,8 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class modifier.values.forEach { it equals Final } } - D.supers.single() equals C.dri - E.supers.firstOrNull() equals D.dri + D.supers.single().dri equals C.dri + E.supers.single().dri equals D.dri } } @@ -500,4 +500,34 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class } } } + + @Test fun multipleClassInheritance() { + inlineModelTest( + """ + | open class A { } + | open class B: A() { } + | class Tested : B() { } + """.trimIndent() + ) { + with((this / "classes" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames }.single() equals "B" + } + } + } + + @Test fun multipleClassInheritanceWithInterface(){ + inlineModelTest( + """ + | open class A { } + | open class B: A() { } + | interface X { } + | interface Y : X { } + | class Tested : B(), Y { } + """.trimIndent() + ){ + with((this / "classes" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames to it.kind }.sortedBy { it.first } equals listOf("B" to KotlinClassKindTypes.CLASS, "Y" to KotlinClassKindTypes.INTERFACE) + } + } + } }
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/model/JavaTest.kt b/plugins/base/src/test/kotlin/model/JavaTest.kt index 4cad784b..1f042304 100644 --- a/plugins/base/src/test/kotlin/model/JavaTest.kt +++ b/plugins/base/src/test/kotlin/model/JavaTest.kt @@ -54,38 +54,19 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - //@Test fun function() { - // verifyJavaPackageMember("testdata/java/member.java", defaultModelConfig) { cls -> - // assertEquals("Test", cls.name) - // assertEquals(NodeKind.Class, cls.kind) - // with(cls.members(NodeKind.Function).single()) { - // assertEquals("fn", name) - // assertEquals("Summary for Function", content.summary.toTestString().trimEnd()) - // assertEquals(3, content.sections.size) - // with(content.sections[0]) { - // assertEquals("Parameters", tag) - // assertEquals("name", subjectName) - // assertEquals("render(Type:String,SUMMARY): is String parameter", toTestString()) - // } - // with(content.sections[1]) { - // assertEquals("Parameters", tag) - // assertEquals("value", subjectName) - // assertEquals("render(Type:Int,SUMMARY): is int parameter", toTestString()) - // } - // assertEquals("Unit", detail(NodeKind.Type).name) - // assertTrue(members.none()) - // assertTrue(links.none()) - // with(details.first { it.name == "name" }) { - // assertEquals(NodeKind.Parameter, kind) - // assertEquals("String", detail(NodeKind.Type).name) - // } - // with(details.first { it.name == "value" }) { - // assertEquals(NodeKind.Parameter, kind) - // assertEquals("Int", detail(NodeKind.Type).name) - // } - // } - // } - // } + @Test fun multipleClassInheritanceWithInterface() { + inlineModelTest( + """ + |interface Highest { } + |interface Lower extends Highest { } + |class Extendable { } + |class Tested extends Extendable implements Lower { } + """){ + with((this / "java" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames to it.kind }.sortedBy { it.first } equals listOf("Extendable" to JavaClassKindTypes.CLASS, "Lower" to JavaClassKindTypes.INTERFACE) + } + } + } @Test // todo fun memberWithModifiers() { @@ -107,19 +88,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun memberWithModifiers() { - // verifyJavaPackageMember("testdata/java/memberWithModifiers.java", defaultModelConfig) { cls -> - // val modifiers = cls.details(NodeKind.Modifier).map { it.name } - // assertTrue("abstract" in modifiers) - // with(cls.members.single { it.name == "fn" }) { - // assertEquals("protected", details[0].name) - // } - // with(cls.members.single { it.name == "openFn" }) { - // assertEquals("open", details[1].name) - // } - // } - // } - @Test fun superClass() { inlineModelTest( @@ -130,7 +98,7 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { with((this / "java" / "Foo").cast<DClass>()) { val sups = listOf("Exception", "Cloneable") assertTrue( - sups.all { s -> supertypes.values.flatten().any { it.classNames == s } }) + sups.all { s -> supertypes.values.flatten().any { it.dri.classNames == s } }) "Foo must extend ${sups.joinToString(", ")}" } } @@ -178,25 +146,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun typeParameter() { - // verifyJavaPackageMember("testdata/java/typeParameter.java", defaultModelConfig) { cls -> - // val typeParameters = cls.details(NodeKind.TypeParameter) - // with(typeParameters.single()) { - // assertEquals("T", name) - // with(detail(NodeKind.UpperBound)) { - // assertEquals("Comparable", name) - // assertEquals("T", detail(NodeKind.Type).name) - // } - // } - // with(cls.members(NodeKind.Function).single()) { - // val methodTypeParameters = details(NodeKind.TypeParameter) - // with(methodTypeParameters.single()) { - // assertEquals("E", name) - // } - // } - // } - // } - @Test fun constructors() { inlineModelTest( @@ -290,19 +239,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun fields() { - // verifyJavaPackageMember("testdata/java/field.java", defaultModelConfig) { cls -> - // val i = cls.members(NodeKind.Property).single { it.name == "i" } - // assertEquals("Int", i.detail(NodeKind.Type).name) - // assertTrue("var" in i.details(NodeKind.Modifier).map { it.name }) - // - // val s = cls.members(NodeKind.Property).single { it.name == "s" } - // assertEquals("String", s.detail(NodeKind.Type).name) - // assertFalse("var" in s.details(NodeKind.Modifier).map { it.name }) - // assertTrue("static" in s.details(NodeKind.Modifier).map { it.name }) - // } - // } - @Test fun staticMethod() { inlineModelTest( @@ -321,25 +257,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun staticMethod() { todo - // verifyJavaPackageMember("testdata/java/staticMethod.java", defaultModelConfig) { cls -> - // val m = cls.members(NodeKind.Function).single { it.name == "foo" } - // assertTrue("static" in m.details(NodeKind.Modifier).map { it.name }) - // } - // } - // - // /** - // * `@suppress` not supported in Java! - // * - // * [Proposed tags](https://www.oracle.com/technetwork/java/javase/documentation/proposed-tags-142378.html) - // * Proposed tag `@exclude` for it, but not supported yet - // */ - // @Ignore("@suppress not supported in Java!") @Test fun suppressTag() { - // verifyJavaPackageMember("testdata/java/suppressTag.java", defaultModelConfig) { cls -> - // assertEquals(1, cls.members(NodeKind.Function).size) - // } - // } - @Test fun annotatedAnnotation() { inlineModelTest( @@ -367,13 +284,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun deprecation() { - // verifyJavaPackageMember("testdata/java/deprecation.java", defaultModelConfig) { cls -> - // val fn = cls.members(NodeKind.Function).single() - // assertEquals("This should no longer be used", fn.deprecation!!.content.toTestString()) - // } - // } - @Test fun javaLangObject() { inlineModelTest( @@ -389,13 +299,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } - // @Test fun javaLangObject() { - // verifyJavaPackageMember("testdata/java/javaLangObject.java", defaultModelConfig) { cls -> - // val fn = cls.members(NodeKind.Function).single() - // assertEquals("Any", fn.detail(NodeKind.Type).name) - // } - // } - @Test fun enumValues() { inlineModelTest( @@ -440,13 +343,4 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { } } } - - // todo - // @Test fun inheritorLinks() { - // verifyJavaPackageMember("testdata/java/InheritorLinks.java", defaultModelConfig) { cls -> - // val fooClass = cls.members.single { it.name == "Foo" } - // val inheritors = fooClass.references(RefKind.Inheritor) - // assertEquals(1, inheritors.size) - // } - // } } diff --git a/plugins/javadoc/src/main/kotlin/javadoc/signatures/JavadocSignatureProvider.kt b/plugins/javadoc/src/main/kotlin/javadoc/signatures/JavadocSignatureProvider.kt index 11db9fe1..c2483cc2 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/signatures/JavadocSignatureProvider.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/signatures/JavadocSignatureProvider.kt @@ -8,6 +8,7 @@ import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentCon import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.kotlinAsJava.signatures.JavaSignatureUtils import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.sureClassNames import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.pages.ContentKind @@ -68,8 +69,12 @@ class JavadocSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLo supertypes { if (c is WithSupertypes) { c.supertypes.map { (p, dris) -> - list(dris, sourceSets = setOf(p)) { - link(it.fqName(), it, sourceSets = setOf(p)) + val (classes, interfaces) = dris.partition { it.kind == JavaClassKindTypes.CLASS } + list(classes, prefix = " extends ", sourceSets = setOf(p)) { + link(it.dri.sureClassNames, it.dri, sourceSets = setOf(p)) + } + list(interfaces, prefix = " implements ", sourceSets = setOf(p)){ + link(it.dri.sureClassNames, it.dri, sourceSets = setOf(p)) } } } diff --git a/plugins/javadoc/src/main/resources/views/class.korte b/plugins/javadoc/src/main/resources/views/class.korte index 22793d69..62d90f7d 100644 --- a/plugins/javadoc/src/main/resources/views/class.korte +++ b/plugins/javadoc/src/main/resources/views/class.korte @@ -35,7 +35,7 @@ <pre> {% if signature.annotations != null %}{{ signature.annotations|raw }} {% endif %} {{ signature.modifiers }} <span class="typeNameLabel">{{ signature.signatureWithoutModifiers|raw }}</span> -{% if signature.supertypes != null %}extends {{signature.supertypes|raw}} {% endif %} +{% if signature.supertypes != null %}{{signature.supertypes|raw}} {% endif %} </pre> <div class="block">{{ classlikeDocumentation|raw }}</div> </li> diff --git a/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt b/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt index 92620f78..d60e1070 100644 --- a/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt +++ b/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt @@ -39,6 +39,7 @@ class JavadocTest : AbstractCoreTest() { """ |/jvmSrc/javadoc/Test.kt |package javadoc + |import java.io.Serializable |class Test() : Serializable, Cloneable """.trimIndent(), config, @@ -54,7 +55,7 @@ class JavadocTest : AbstractCoreTest() { val testClass = rootPageNode.firstChildOfType<JavadocPackagePageNode>() .firstChildOfType<JavadocClasslikePageNode>() assert( - "<a href=https://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html>java.lang.Cloneable</a>" + " implements <a href=https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html>Serializable</a>, <a href=https://docs.oracle.com/javase/8/docs/api/java/lang/Cloneable.html>Cloneable</a>" == transformer.htmlForContentNode(testClass.signature.supertypes!!, null) ) } diff --git a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt index 693fffac..1ca4ef51 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt @@ -167,7 +167,7 @@ internal fun DClass.asJava(): DClass = copy( properties = properties.map { it.asJava() }, classlikes = classlikes.map { it.asJava() }, generics = generics.map { it.asJava() }, - supertypes = supertypes.mapValues { it.value.map { it.possiblyAsJava() } }, + supertypes = supertypes.mapValues { it.value.map { it.copy(dri = it.dri.possiblyAsJava()) } }, modifier = if (modifier.all { (_, v) -> v is KotlinModifier.Empty }) sourceSets.map { it to JavaModifier.Final } .toMap() else sourceSets.map { it to modifier.values.first() }.toMap() @@ -195,7 +195,7 @@ internal fun DEnum.asJava(): DEnum = copy( }, properties = properties.map { it.asJava() }, classlikes = classlikes.map { it.asJava() }, - supertypes = supertypes.mapValues { it.value.map { it.possiblyAsJava() } } + supertypes = supertypes.mapValues { it.value.map { it.copy(dri = it.dri.possiblyAsJava()) } } // , entries = entries.map { it.asJava() } ) @@ -225,7 +225,7 @@ internal fun DObject.asJava(): DObject = copy( }) ), classlikes = classlikes.map { it.asJava() }, - supertypes = supertypes.mapValues { it.value.map { it.possiblyAsJava() } } + supertypes = supertypes.mapValues { it.value.map { it.copy(dri = it.dri.possiblyAsJava()) } } ) internal fun DInterface.asJava(): DInterface = copy( @@ -235,7 +235,7 @@ internal fun DInterface.asJava(): DInterface = copy( properties = emptyList(), classlikes = classlikes.map { it.asJava() }, // TODO: public static final class DefaultImpls with impls for methods generics = generics.map { it.asJava() }, - supertypes = supertypes.mapValues { it.value.map { it.possiblyAsJava() } } + supertypes = supertypes.mapValues { it.value.map { it.copy(dri = it.dri.possiblyAsJava()) } } ) internal fun DAnnotation.asJava(): DAnnotation = copy( diff --git a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt index ca817219..0e257945 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt @@ -77,8 +77,12 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge } if (c is WithSupertypes) { c.supertypes.map { (p, dris) -> - list(dris, prefix = " extends ", sourceSets = setOf(p)) { - link(it.sureClassNames, it, sourceSets = setOf(p)) + val (classes, interfaces) = dris.partition { it.kind == JavaClassKindTypes.CLASS } + list(classes, prefix = " extends ", sourceSets = setOf(p)) { + link(it.dri.sureClassNames, it.dri, sourceSets = setOf(p)) + } + list(interfaces, prefix = " implements ", sourceSets = setOf(p)){ + link(it.dri.sureClassNames, it.dri, sourceSets = setOf(p)) } } } |