From aa3f05136ca743eac15a9f8deb939f69cff6eb70 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 13 Feb 2015 17:04:58 +0100 Subject: import Java type parameters into documentation model --- src/Java/JavaDocumentationBuilder.kt | 31 +++++++++++-- test/data/java/typeParameter.java | 5 +++ test/src/TestAPI.kt | 7 +++ test/src/model/JavaTest.kt | 84 ++++++++++++++++++++---------------- 4 files changed, 85 insertions(+), 42 deletions(-) create mode 100644 test/data/java/typeParameter.java diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaDocumentationBuilder.kt index 760a9a3a..879c0b2c 100644 --- a/src/Java/JavaDocumentationBuilder.kt +++ b/src/Java/JavaDocumentationBuilder.kt @@ -14,6 +14,7 @@ import com.intellij.psi.PsiPrimitiveType import com.intellij.psi.PsiModifierListOwner import com.intellij.psi.PsiModifier import com.intellij.psi.PsiArrayType +import com.intellij.psi.PsiTypeParameter public class JavaDocumentationBuilder() { fun appendFile(file: PsiJavaFile, module: DocumentationModule) { @@ -48,6 +49,12 @@ public class JavaDocumentationBuilder() { } } + fun DocumentationNode.appendMembers(elements: Array, buildFn: T.() -> DocumentationNode) = + appendChildren(elements, DocumentationReference.Kind.Member, buildFn) + + fun DocumentationNode.appendDetails(elements: Array, buildFn: T.() -> DocumentationNode) = + appendChildren(elements, DocumentationReference.Kind.Detail, buildFn) + fun PsiClass.build(): DocumentationNode { val kind = when { isInterface() -> DocumentationNode.Kind.Interface @@ -58,14 +65,16 @@ public class JavaDocumentationBuilder() { val node = DocumentationNode(this, kind) getExtendsListTypes().forEach { node.appendType(it, Kind.Supertype) } getImplementsListTypes().forEach { node.appendType(it, Kind.Supertype) } - node.appendChildren(getMethods()) { build() } + node.appendDetails(getTypeParameters()) { build() } + node.appendMembers(getMethods()) { build() } return node } fun PsiMethod.build(): DocumentationNode { val node = DocumentationNode(this, Kind.Function) node.appendType(getReturnType()) - node.appendChildren(getParameterList().getParameters(), DocumentationReference.Kind.Detail) { build() } + node.appendDetails(getParameterList().getParameters()) { build() } + node.appendDetails(getTypeParameters()) { build() } return node } @@ -75,6 +84,13 @@ public class JavaDocumentationBuilder() { return node } + fun PsiTypeParameter.build(): DocumentationNode { + val node = DocumentationNode(this, Kind.TypeParameter) + getExtendsListTypes().forEach { node.appendType(it, Kind.UpperBound) } + getImplementsListTypes().forEach { node.appendType(it, Kind.UpperBound) } + return node + } + fun DocumentationNode.appendModifiers(element: PsiModifierListOwner) { val modifierList = element.getModifierList() if (modifierList == null) { @@ -92,9 +108,16 @@ public class JavaDocumentationBuilder() { if (psiType == null) { return } - val name = mapTypeName(psiType) + append(psiType.build(kind), DocumentationReference.Kind.Detail) + } + + fun PsiType.build(kind: DocumentationNode.Kind = DocumentationNode.Kind.Type): DocumentationNode { + val name = mapTypeName(this) val node = DocumentationNode(name, Content.Empty, kind) - append(node, DocumentationReference.Kind.Detail) + if (this is PsiClassType) { + node.appendDetails(getParameters()) { build(Kind.TypeParameter) } + } + return node } private fun mapTypeName(psiType: PsiType): String = when (psiType) { diff --git a/test/data/java/typeParameter.java b/test/data/java/typeParameter.java new file mode 100644 index 00000000..98a6aee9 --- /dev/null +++ b/test/data/java/typeParameter.java @@ -0,0 +1,5 @@ +package test + +class Foo> { + public E foo(); +} diff --git a/test/src/TestAPI.kt b/test/src/TestAPI.kt index 5ba685f6..95fe655e 100644 --- a/test/src/TestAPI.kt +++ b/test/src/TestAPI.kt @@ -37,6 +37,13 @@ public fun verifyModel(vararg files: String, verifier: (DocumentationModule) -> Disposer.dispose(environment) } +public fun verifyPackageMember(vararg files: String, verifier: (DocumentationNode) -> Unit) { + verifyModel(*files) { model -> + val pkg = model.members.single() + verifier(pkg.members.single()) + } +} + public fun verifyOutput(path: String, outputExtension: String, outputGenerator: (DocumentationModule, StringBuilder) -> Unit) { verifyModel(path) { val output = StringBuilder() diff --git a/test/src/model/JavaTest.kt b/test/src/model/JavaTest.kt index d40b3ba3..5c8163a3 100644 --- a/test/src/model/JavaTest.kt +++ b/test/src/model/JavaTest.kt @@ -6,59 +6,49 @@ import org.junit.* public class JavaTest { Test fun function() { - verifyModel("test/data/java/member.java") { model -> - val pkg = model.members.single() - with(pkg.members.single()) { - assertEquals("Test", name) - assertEquals(DocumentationNode.Kind.Class, kind) - with(members.single()) { - assertEquals("fn", name) - assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("Summary for Function", content.summary.toTestString()) - assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) - assertTrue(members.none()) - assertTrue(links.none()) - with(details.first { it.name == "name" }) { - assertEquals(DocumentationNode.Kind.Parameter, kind) - assertEquals("String", detail(DocumentationNode.Kind.Type).name) - } - with(details.first { it.name == "value" }) { - assertEquals(DocumentationNode.Kind.Parameter, kind) - assertEquals("Int", detail(DocumentationNode.Kind.Type).name) - } + verifyPackageMember("test/data/java/member.java") { cls -> + assertEquals("Test", cls.name) + assertEquals(DocumentationNode.Kind.Class, cls.kind) + with(cls.members.single()) { + assertEquals("fn", name) + assertEquals(DocumentationNode.Kind.Function, kind) + assertEquals("Summary for Function", content.summary.toTestString()) + assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) + assertTrue(members.none()) + assertTrue(links.none()) + with(details.first { it.name == "name" }) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals("String", detail(DocumentationNode.Kind.Type).name) + } + with(details.first { it.name == "value" }) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals("Int", detail(DocumentationNode.Kind.Type).name) } } } } Test fun memberWithModifiers() { - verifyModel("test/data/java/memberWithModifiers.java") { model -> - val pkg = model.members.single() - with(pkg.members.single()) { - assertEquals("abstract", details[0].name) - with(members.single()) { - assertEquals("protected", details[0].name) - } + verifyPackageMember("test/data/java/memberWithModifiers.java") { cls -> + assertEquals("abstract", cls.details[0].name) + with(cls.members.single()) { + assertEquals("protected", details[0].name) } } } Test fun superClass() { - verifyModel("test/data/java/superClass.java") { model -> - val pkg = model.members.single() - with(pkg.members.single()) { - val superTypes = details(DocumentationNode.Kind.Supertype) - assertEquals(2, superTypes.size()) - assertEquals("Exception", superTypes[0].name) - assertEquals("Cloneable", superTypes[1].name) - } + verifyPackageMember("test/data/java/superClass.java") { cls -> + val superTypes = cls.details(DocumentationNode.Kind.Supertype) + assertEquals(2, superTypes.size()) + assertEquals("Exception", superTypes[0].name) + assertEquals("Cloneable", superTypes[1].name) } } Test fun arrayType() { - verifyModel("test/data/java/arrayType.java") { model -> - val pkg = model.members.single() - with(pkg.members.single().members.single()) { + verifyPackageMember("test/data/java/arrayType.java") { cls -> + with(cls.members.single()) { assertEquals("Array", detail(DocumentationNode.Kind.Type).name) with(details(DocumentationNode.Kind.Parameter).single()) { assertEquals("Array", detail(DocumentationNode.Kind.Type).name) @@ -67,4 +57,22 @@ public class JavaTest { } } + Test fun typeParameter() { + verifyPackageMember("test/data/java/typeParameter.java") { cls -> + val typeParameters = cls.details(DocumentationNode.Kind.TypeParameter) + with(typeParameters.single()) { + assertEquals("T", name) + with(detail(DocumentationNode.Kind.UpperBound)) { + assertEquals("Comparable", name) + assertEquals("T", detail(DocumentationNode.Kind.TypeParameter).name) + } + } + with(cls.members.single()) { + val methodTypeParameters = details(DocumentationNode.Kind.TypeParameter) + with(methodTypeParameters.single()) { + assertEquals("E", name) + } + } + } + } } -- cgit