aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Kotlin/DocumentationBuilder.kt25
-rw-r--r--src/Kotlin/KotlinLanguageService.kt8
-rw-r--r--src/Model/DocumentationNode.kt2
-rw-r--r--test/data/classes/annotatedClassWithAnnotationParameters.kt1
-rw-r--r--test/data/classes/javaAnnotationClass.kt5
-rw-r--r--test/data/format/annotationParams.kt1
-rw-r--r--test/data/format/annotationParams.md12
-rw-r--r--test/data/functions/annotatedFunctionWithAnnotationParameters.kt1
-rw-r--r--test/src/TestAPI.kt3
-rw-r--r--test/src/format/MarkdownFormatTest.kt6
-rw-r--r--test/src/model/ClassTest.kt44
-rw-r--r--test/src/model/FunctionTest.kt23
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)
+ }
+ }
+ }
+ }
+ }
+ }
}
+