diff options
author | Andrzej Ratajczak <32793002+BarkingBad@users.noreply.github.com> | 2022-01-27 10:39:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-27 12:39:56 +0300 |
commit | 7c44db1ef0075e2b80a4723e0747bbf57c32e775 (patch) | |
tree | d20079f969fbb977603852ef4ea2234e54851f98 /plugins | |
parent | d884fa7ce3088ac9ae0ca1bbad70e698888610fa (diff) | |
download | dokka-7c44db1ef0075e2b80a4723e0747bbf57c32e775.tar.gz dokka-7c44db1ef0075e2b80a4723e0747bbf57c32e775.tar.bz2 dokka-7c44db1ef0075e2b80a4723e0747bbf57c32e775.zip |
Fix resolving DRIs of Enum Entries (#2305)
* Fix resolving DRIs of Enum Entries
* Unify DRIs for Kotlin and Java enums. Add EnumEntry linking tests
* Updates EnumEntry extras in documentable translators
* Fix tests
* Apply requested changes
* Apply requested changes
Diffstat (limited to 'plugins')
13 files changed, 159 insertions, 19 deletions
diff --git a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt index 84445d2a..a1f1542d 100644 --- a/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt +++ b/plugins/base/src/main/kotlin/resolvers/external/javadoc/JavadocExternalLocationProvider.kt @@ -30,13 +30,10 @@ open class JavadocExternalLocationProvider( return "$docWithModule$packageLink/package-summary$extension".htmlEscape() } - // in Kotlin DRI of enum entry is not callable if (DRIExtraContainer(extra)[EnumEntryDRIExtra] != null) { - val (classSplit, enumEntityAnchor) = if (callable == null) { - val lastIndex = classNames?.lastIndexOf(".") ?: 0 + val lastIndex = classNames?.lastIndexOf(".") ?: 0 + val (classSplit, enumEntityAnchor) = classNames?.substring(0, lastIndex) to classNames?.substring(lastIndex + 1) - } else - classNames to callable?.name val classLink = if (packageLink == null) "${classSplit}$extension" else "$packageLink/${classSplit}$extension" diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index e996a865..6078b54d 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -317,7 +317,7 @@ private class DokkaDescriptorVisitor( val classlikes = async { descriptorsWithKind.classlikes.visitClasslikes(driWithPlatform) } DEnumEntry( - dri = driWithPlatform.dri, + dri = driWithPlatform.dri.withEnumEntryExtra(), name = descriptor.name.asString(), documentation = descriptor.resolveDescriptorData(), functions = functions.await(), diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index e7028ef0..79b4798c 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -21,11 +21,11 @@ import org.jetbrains.dokka.base.translators.isDirectlyAnException import org.jetbrains.dokka.base.translators.psi.parsers.JavaDocumentationParser import org.jetbrains.dokka.base.translators.psi.parsers.JavadocParser import org.jetbrains.dokka.base.translators.unquotedValue -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.nextTarget -import org.jetbrains.dokka.links.withClass +import org.jetbrains.dokka.links.* import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.AnnotationTarget +import org.jetbrains.dokka.model.Nullable +import org.jetbrains.dokka.model.TypeConstructor import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.doc.Param import org.jetbrains.dokka.model.properties.PropertyContainer @@ -269,7 +269,7 @@ class DefaultPsiToDocumentableTranslator( name.orEmpty(), fields.filterIsInstance<PsiEnumConstant>().map { entry -> DEnumEntry( - dri.withClass(entry.name), + dri.withClass(entry.name).withEnumEntryExtra(), entry.name, javadocParser.parseDocumentation(entry).toSourceSetDependent(), null, diff --git a/plugins/base/src/main/kotlin/translators/psi/parsers/JavadocParser.kt b/plugins/base/src/main/kotlin/translators/psi/parsers/JavadocParser.kt index f9f591b2..fd8a49c8 100644 --- a/plugins/base/src/main/kotlin/translators/psi/parsers/JavadocParser.kt +++ b/plugins/base/src/main/kotlin/translators/psi/parsers/JavadocParser.kt @@ -326,7 +326,7 @@ class JavadocParser( dri.toString() } ?: UNRESOLVED_PSI_ELEMENT - return """<a data-dri="$dri">${label.ifBlank{ defaultLabel().text }}</a>""" + return """<a data-dri="${dri.htmlEscape()}">${label.ifBlank{ defaultLabel().text }}</a>""" } private fun convertInlineDocTag( diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/EnumsTest.kt index 59a4c6f2..bfdfa73b 100644 --- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/EnumsTest.kt @@ -125,7 +125,7 @@ class EnumsTest : BaseAbstractTest() { pagesGenerationStage = { module -> val entryPage = module.dfs { it.name == "E1" } as ClasslikePageNode val signaturePart = (entryPage.content.dfs { - it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Symbol]" + it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}][Symbol]" } as ContentGroup) assertEquals("(\"e1\", 1, true)", signaturePart.constructorSignature()) } @@ -202,7 +202,7 @@ class EnumsTest : BaseAbstractTest() { ) { pagesTransformationStage = { m -> val entryNode = m.children.first { it.name == "enums" }.children.first { it.name == "Test" }.children.firstIsInstance<ClasslikePageNode>() - val signature = (entryNode.content as ContentGroup).dfs { it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Cover]" } as ContentGroup + val signature = (entryNode.content as ContentGroup).dfs { it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}][Cover]" } as ContentGroup signature.assertNode { header(1) { +"E1" } diff --git a/plugins/base/src/test/kotlin/linking/EnumValuesLinkingTest.kt b/plugins/base/src/test/kotlin/linking/EnumValuesLinkingTest.kt new file mode 100644 index 00000000..29e705fd --- /dev/null +++ b/plugins/base/src/test/kotlin/linking/EnumValuesLinkingTest.kt @@ -0,0 +1,117 @@ +package linking + +import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest +import org.jetbrains.dokka.links.DRIExtraContainer +import org.jetbrains.dokka.links.EnumEntryDRIExtra +import org.jetbrains.dokka.model.dfs +import org.jetbrains.dokka.model.doc.DocumentationLink +import org.jetbrains.dokka.pages.ContentDRILink +import org.jetbrains.dokka.pages.ContentPage +import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.jsoup.Jsoup +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import java.nio.file.Paths +import utils.TestOutputWriterPlugin +import java.lang.AssertionError + +class EnumValuesLinkingTest : BaseAbstractTest() { + + @Test + fun `check if enum values are correctly linked`() { + val writerPlugin = TestOutputWriterPlugin() + val testDataDir = getTestDataDir("linking").toAbsolutePath() + testFromData( + dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf(Paths.get("$testDataDir/jvmMain/kotlin").toString()) + analysisPlatform = "jvm" + name = "jvm" + } + } + }, + pluginOverrides = listOf(writerPlugin) + ) { + documentablesTransformationStage = { + val classlikes = it.packages.single().children + assertEquals(4, classlikes.size) + + val javaLinker = classlikes.single { it.name == "JavaLinker" } + javaLinker.documentation.values.single().children.run { + when (val kotlinLink = this[0].children[1].children[1]) { + is DocumentationLink -> kotlinLink.dri.run { + assertEquals("KotlinEnum.ON_CREATE", this.classNames) + assertEquals(null, this.callable) + assertNotNull(DRIExtraContainer(extra)[EnumEntryDRIExtra]) + } + else -> throw AssertionError("Link node is not DocumentationLink type") + } + + when (val javaLink = this[0].children[2].children[1]) { + is DocumentationLink -> javaLink.dri.run { + assertEquals("JavaEnum.ON_DECEIT", this.classNames) + assertEquals(null, this.callable) + assertNotNull(DRIExtraContainer(extra)[EnumEntryDRIExtra]) + } + else -> throw AssertionError("Link node is not DocumentationLink type") + } + } + + val kotlinLinker = classlikes.single { it.name == "KotlinLinker" } + kotlinLinker.documentation.values.single().children.run { + when (val kotlinLink = this[0].children[0].children[5]) { + is DocumentationLink -> kotlinLink.dri.run { + assertEquals("KotlinEnum.ON_CREATE", this.classNames) + assertEquals(null, this.callable) + assertNotNull(DRIExtraContainer(extra)[EnumEntryDRIExtra]) + } + else -> throw AssertionError("Link node is not DocumentationLink type") + } + + when (val javaLink = this[0].children[0].children[9]) { + is DocumentationLink -> javaLink.dri.run { + assertEquals("JavaEnum.ON_DECEIT", this.classNames) + assertEquals(null, this.callable) + assertNotNull(DRIExtraContainer(extra)[EnumEntryDRIExtra]) + } + else -> throw AssertionError("Link node is not DocumentationLink type") + } + } + + assertEquals( + javaLinker.documentation.values.single().children[0].children[1].children[1].safeAs<DocumentationLink>()?.dri, + kotlinLinker.documentation.values.single().children[0].children[0].children[5].safeAs<DocumentationLink>()?.dri + ) + + assertEquals( + javaLinker.documentation.values.single().children[0].children[2].children[1].safeAs<DocumentationLink>()?.dri, + kotlinLinker.documentation.values.single().children[0].children[0].children[9].safeAs<DocumentationLink>()?.dri + ) + } + + renderingStage = { rootPageNode, _ -> + val classlikes = rootPageNode.children.single().children + assertEquals(4, classlikes.size) + + val javaLinker = classlikes.single { it.name == "JavaLinker" } + (javaLinker as ContentPage).run { + assertNotNull(content.dfs { it is ContentDRILink && it.address.classNames == "KotlinEnum.ON_CREATE" }) + assertNotNull(content.dfs { it is ContentDRILink && it.address.classNames == "JavaEnum.ON_DECEIT" }) + } + + val kotlinLinker = classlikes.single { it.name == "KotlinLinker" } + (kotlinLinker as ContentPage).run { + assertNotNull(content.dfs { it is ContentDRILink && it.address.classNames == "KotlinEnum.ON_CREATE" }) + assertNotNull(content.dfs { it is ContentDRILink && it.address.classNames == "JavaEnum.ON_DECEIT" }) + } + + // single method will throw an exception if there is no single element (0 or 2+) + Jsoup.parse(writerPlugin.writer.contents["root/linking.source/-java-linker/index.html"]).select("a[href=\"../-kotlin-enum/-o-n_-c-r-e-a-t-e/index.html\"]").single() + Jsoup.parse(writerPlugin.writer.contents["root/linking.source/-java-linker/index.html"]).select("a[href=\"../-java-enum/-o-n_-d-e-c-e-i-t/index.html\"]").single() + Jsoup.parse(writerPlugin.writer.contents["root/linking.source/-kotlin-linker/index.html"]).select("a[href=\"../-kotlin-enum/-o-n_-c-r-e-a-t-e/index.html\"]").single() + Jsoup.parse(writerPlugin.writer.contents["root/linking.source/-kotlin-linker/index.html"]).select("a[href=\"../-java-enum/-o-n_-d-e-c-e-i-t/index.html\"]").single() + } + } + } +} diff --git a/plugins/base/src/test/kotlin/locationProvider/JavadocExternalLocationProviderTest.kt b/plugins/base/src/test/kotlin/locationProvider/JavadocExternalLocationProviderTest.kt index cb2b0331..95179e22 100644 --- a/plugins/base/src/test/kotlin/locationProvider/JavadocExternalLocationProviderTest.kt +++ b/plugins/base/src/test/kotlin/locationProvider/JavadocExternalLocationProviderTest.kt @@ -45,8 +45,8 @@ class JavadocExternalLocationProviderTest : BaseAbstractTest() { ) val javaDri = DRI( "java.nio.file", - "StandardOpenOption", - Callable("CREATE", null, emptyList()), + "StandardOpenOption.CREATE", + null, PointingToDeclaration, DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode() ) diff --git a/plugins/base/src/test/kotlin/model/JavaTest.kt b/plugins/base/src/test/kotlin/model/JavaTest.kt index 886aa0be..aa132f6e 100644 --- a/plugins/base/src/test/kotlin/model/JavaTest.kt +++ b/plugins/base/src/test/kotlin/model/JavaTest.kt @@ -391,8 +391,8 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { "RUNTIME", DRI( "java.lang.annotation", - "RetentionPolicy", - DRICallable("RUNTIME", null, emptyList()), + "RetentionPolicy.RUNTIME", + null, PointingToDeclaration, DRIExtraContainer().also { it[EnumEntryDRIExtra] = EnumEntryDRIExtra }.encode() ) diff --git a/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaEnum.java b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaEnum.java new file mode 100644 index 00000000..016365a7 --- /dev/null +++ b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaEnum.java @@ -0,0 +1,5 @@ +package linking.source; + +public enum JavaEnum { + ON_DECEIT, ON_DESTROY; +} diff --git a/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaLinker.java b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaLinker.java new file mode 100644 index 00000000..ac416530 --- /dev/null +++ b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/JavaLinker.java @@ -0,0 +1,8 @@ +package linking.source; + +/** + * Reference link {@link linking.source.KotlinEnum} should resolve <p> + * sjuff sjuff {@link linking.source.KotlinEnum#ON_CREATE} should resolve <p> + * sjujj sjujj {@link linking.source.JavaEnum#ON_DECEIT} should resolve + */ +public class JavaLinker {} diff --git a/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinEnum.kt b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinEnum.kt new file mode 100644 index 00000000..a03316b1 --- /dev/null +++ b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinEnum.kt @@ -0,0 +1,5 @@ +package linking.source + +enum class KotlinEnum { + ON_CREATE, ON_CATASTROPHE +} diff --git a/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinLinker.kt b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinLinker.kt new file mode 100644 index 00000000..45afc3d5 --- /dev/null +++ b/plugins/base/src/test/resources/linking/jvmMain/kotlin/linking/source/KotlinLinker.kt @@ -0,0 +1,8 @@ +package linking.source + +/** + * Reference link [KotlinEnum] should resolve <p> + * stuff stuff [KotlinEnum.ON_CREATE] should resolve <p> + * stuff stuff [JavaEnum.ON_DECEIT] should resolve + */ +class KotlinLinker {} diff --git a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt index 19ef6ae7..10240a3f 100644 --- a/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt +++ b/plugins/javadoc/src/test/kotlin/org/jetbrains/dokka/javadoc/JavadocClasslikeTemplateMapTest.kt @@ -149,13 +149,13 @@ internal class JavadocClasslikeTemplateMapTest : AbstractJavadocTemplateMapTest( val map = allPagesOfType<JavadocClasslikePageNode>().first { it.name == "TestClass" }.templateMap assertEquals("TestClass", map["name"]) val signature = assertIsInstance<Map<String, Any?>>(map["signature"]) - assertEquals("@<a href=Author.html>Author</a>(name = \"Benjamin Franklin\")", signature["annotations"]) + assertEquals("@<a href=Author.html>Author</a>(name = "Benjamin Franklin")", signature["annotations"]) val methods = assertIsInstance<Map<Any, Any?>>(map["methods"]) val ownMethods = assertIsInstance<List<*>>(methods["own"]) val method = assertIsInstance<Map<String, Any?>>(ownMethods.single()) val methodSignature = assertIsInstance<Map<String, Any?>>(method["signature"]) - assertEquals("@<a href=Author.html>Author</a>(name = \"Franklin D. Roosevelt\")", methodSignature["annotations"]) + assertEquals("@<a href=Author.html>Author</a>(name = "Franklin D. Roosevelt")", methodSignature["annotations"]) } } |