diff options
-rw-r--r-- | src/Kotlin/DocumentationBuilder.kt | 25 | ||||
-rw-r--r-- | src/Kotlin/KotlinLanguageService.kt | 8 | ||||
-rw-r--r-- | src/Model/DocumentationNode.kt | 2 | ||||
-rw-r--r-- | test/data/classes/annotatedClassWithAnnotationParameters.kt | 1 | ||||
-rw-r--r-- | test/data/classes/javaAnnotationClass.kt | 5 | ||||
-rw-r--r-- | test/data/format/annotationParams.kt | 1 | ||||
-rw-r--r-- | test/data/format/annotationParams.md | 12 | ||||
-rw-r--r-- | test/data/functions/annotatedFunctionWithAnnotationParameters.kt | 1 | ||||
-rw-r--r-- | test/src/TestAPI.kt | 3 | ||||
-rw-r--r-- | test/src/format/MarkdownFormatTest.kt | 6 | ||||
-rw-r--r-- | test/src/model/ClassTest.kt | 44 | ||||
-rw-r--r-- | test/src/model/FunctionTest.kt | 23 |
12 files changed, 130 insertions, 1 deletions
diff --git a/src/Kotlin/DocumentationBuilder.kt b/src/Kotlin/DocumentationBuilder.kt index 57f8572f..c00580c5 100644 --- a/src/Kotlin/DocumentationBuilder.kt +++ b/src/Kotlin/DocumentationBuilder.kt @@ -9,6 +9,9 @@ import org.jetbrains.jet.lang.resolve.lazy.* import org.jetbrains.jet.lang.descriptors.annotations.Annotated import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant +import com.intellij.openapi.util.text.StringUtil +import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor public data class DocumentationOptions(val includeNonPublic: Boolean = false) @@ -290,10 +293,30 @@ class DocumentationBuilder(val session: ResolveSession, val options: Documentati fun AnnotationDescriptor.build(): DocumentationNode { val annotationClass = getType().getConstructor().getDeclarationDescriptor() val node = DocumentationNode(annotationClass.getName().asString(), Content.Empty, DocumentationNode.Kind.Annotation) - // TODO handle parameters + val arguments = getAllValueArguments().toList().sortBy { it.first.getIndex() } + arguments.forEach { + val valueNode = it.second.build() + if (valueNode != null) { + val paramNode = DocumentationNode(it.first.getName().asString(), Content.Empty, DocumentationNode.Kind.Parameter) + paramNode.append(valueNode, DocumentationReference.Kind.Detail) + node.append(paramNode, DocumentationReference.Kind.Detail) + } + } return node } + fun CompileTimeConstant<out Any?>.build(): DocumentationNode? { + val value = getValue() + val valueString = when(value) { + is String -> + "\"" + StringUtil.escapeStringCharacters(value) + "\"" + is EnumEntrySyntheticClassDescriptor -> + value.getContainingDeclaration().getName().asString() + "." + value.getName() + else -> value?.toString() + } + return if (valueString != null) DocumentationNode(valueString, Content.Empty, DocumentationNode.Kind.Value) else null + } + /** * Generates cross-references for documentation such as extensions for a type, inheritors, etc * diff --git a/src/Kotlin/KotlinLanguageService.kt b/src/Kotlin/KotlinLanguageService.kt index 0538ba74..92d5bf1d 100644 --- a/src/Kotlin/KotlinLanguageService.kt +++ b/src/Kotlin/KotlinLanguageService.kt @@ -172,6 +172,14 @@ class KotlinLanguageService : LanguageService { private fun ContentNode.renderAnnotation(node: DocumentationNode) { identifier(node.name) + val parameters = node.details(DocumentationNode.Kind.Parameter) + if (!parameters.isEmpty()) { + symbol("(") + renderList(parameters) { + text(it.detail(DocumentationNode.Kind.Value).name) + } + symbol(")") + } text(" ") } diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt index 0698a5d0..caae77a8 100644 --- a/src/Model/DocumentationNode.kt +++ b/src/Model/DocumentationNode.kt @@ -90,6 +90,8 @@ public open class DocumentationNode(val name: String, Module Annotation + + Value } } diff --git a/test/data/classes/annotatedClassWithAnnotationParameters.kt b/test/data/classes/annotatedClassWithAnnotationParameters.kt new file mode 100644 index 00000000..1af97e75 --- /dev/null +++ b/test/data/classes/annotatedClassWithAnnotationParameters.kt @@ -0,0 +1 @@ +deprecated("should no longer be used") class Foo() {} diff --git a/test/data/classes/javaAnnotationClass.kt b/test/data/classes/javaAnnotationClass.kt new file mode 100644 index 00000000..c5f5cac4 --- /dev/null +++ b/test/data/classes/javaAnnotationClass.kt @@ -0,0 +1,5 @@ +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy + +Retention(RetentionPolicy.SOURCE) +public annotation class throws() diff --git a/test/data/format/annotationParams.kt b/test/data/format/annotationParams.kt new file mode 100644 index 00000000..ee5b524a --- /dev/null +++ b/test/data/format/annotationParams.kt @@ -0,0 +1 @@ +inlineOptions(InlineOption.LOCAL_CONTINUE_AND_BREAK) fun f() {} diff --git a/test/data/format/annotationParams.md b/test/data/format/annotationParams.md new file mode 100644 index 00000000..6bbdc0e5 --- /dev/null +++ b/test/data/format/annotationParams.md @@ -0,0 +1,12 @@ +[test](out.md) / [](out.md) / [f](out.md) + + +# f + + +``` +inlineOptions([InlineOption.LOCAL_CONTINUE_AND_BREAK]) fun f(): Unit +``` + + + diff --git a/test/data/functions/annotatedFunctionWithAnnotationParameters.kt b/test/data/functions/annotatedFunctionWithAnnotationParameters.kt new file mode 100644 index 00000000..ee5b524a --- /dev/null +++ b/test/data/functions/annotatedFunctionWithAnnotationParameters.kt @@ -0,0 +1 @@ +inlineOptions(InlineOption.LOCAL_CONTINUE_AND_BREAK) fun f() {} diff --git a/test/src/TestAPI.kt b/test/src/TestAPI.kt index cc09f001..af1b8e52 100644 --- a/test/src/TestAPI.kt +++ b/test/src/TestAPI.kt @@ -7,6 +7,7 @@ import org.jetbrains.dokka.* import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor import java.io.File import kotlin.test.assertEquals +import com.intellij.openapi.application.PathManager public fun verifyModel(vararg files: String, verifier: (DocumentationModule) -> Unit) { val messageCollector = object : MessageCollector { @@ -27,6 +28,8 @@ public fun verifyModel(vararg files: String, verifier: (DocumentationModule) -> } val environment = AnalysisEnvironment(messageCollector) { + val stringRoot = PathManager.getResourceRoot(javaClass<String>(), "/java/lang/String.class") + addClasspath(File(stringRoot)) addSources(files.toList()) } diff --git a/test/src/format/MarkdownFormatTest.kt b/test/src/format/MarkdownFormatTest.kt index a1fc7ac1..08267d32 100644 --- a/test/src/format/MarkdownFormatTest.kt +++ b/test/src/format/MarkdownFormatTest.kt @@ -31,4 +31,10 @@ public class MarkdownFormatTest { markdownService.appendNodes(tempLocation, output, model.members.single().members) } } + + Test fun annotationParams() { + verifyOutput("test/data/format/annotationParams.kt", ".md") { model, output -> + markdownService.appendNodes(tempLocation, output, model.members.single().members) + } + } } diff --git a/test/src/model/ClassTest.kt b/test/src/model/ClassTest.kt index 257d73eb..ae82a4f1 100644 --- a/test/src/model/ClassTest.kt +++ b/test/src/model/ClassTest.kt @@ -179,4 +179,48 @@ public class ClassTest { } } } + + Test fun annotatedClassWithAnnotationParameters() { + verifyModel("test/data/classes/annotatedClassWithAnnotationParameters.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("deprecated", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("\"should no longer be used\"", name) + } + } + } + } + } + } + + Test fun javaAnnotationClass() { + verifyModel("test/data/classes/javaAnnotationClass.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("Retention", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("RetentionPolicy.SOURCE", name) + } + } + } + } + } + } } diff --git a/test/src/model/FunctionTest.kt b/test/src/model/FunctionTest.kt index d3d7843a..bf7471ea 100644 --- a/test/src/model/FunctionTest.kt +++ b/test/src/model/FunctionTest.kt @@ -163,4 +163,27 @@ Documentation""", content.description.toTestString()) } } } + + Test fun annotatedFunctionWithAnnotationParameters() { + verifyModel("test/data/functions/annotatedFunctionWithAnnotationParameters.kt") { model -> + with(model.members.single().members.single()) { + assertEquals(1, annotations.count()) + with(annotations[0]) { + assertEquals("inlineOptions", name) + assertEquals(Content.Empty, content) + assertEquals(DocumentationNode.Kind.Annotation, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Parameter, kind) + assertEquals(1, details.count()) + with(details[0]) { + assertEquals(DocumentationNode.Kind.Value, kind) + assertEquals("[InlineOption.LOCAL_CONTINUE_AND_BREAK]", name) + } + } + } + } + } + } } + |