First attempt at @attr and @since parsing.
diff --git a/core/src/main/kotlin/Formats/DacHtmlFormat.kt b/core/src/main/kotlin/Formats/DacHtmlFormat.kt
index d4c6dd8..5de03fa 100644
--- a/core/src/main/kotlin/Formats/DacHtmlFormat.kt
+++ b/core/src/main/kotlin/Formats/DacHtmlFormat.kt
@@ -144,6 +144,13 @@
div {
id = node.signatureForAnchor(logger)
h3(classes = "api-name") { +node.name }
+ div(classes="api-level") {
+ node.apiLevel?.let {
+ +"added in "
+ a(href = "https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels")
+ +"API level ${it.name}"
+ }
+ }
pre(classes = "api-signature no-pretty-print") { renderedSignature(node, LanguageService.RenderMode.FULL) }
contentNodeToMarkup(node.content)
node.constantValue()?.let { value ->
@@ -169,6 +176,102 @@
}
}
}
+
+ override fun FlowContent.classLikeSummaries(page: Page.ClassPage) = with(page) {
+ summaryNodeGroup(
+ nestedClasses,
+ "Nested classes",
+ headerAsRow = true
+ ) {
+ nestedClassSummaryRow(it)
+ }
+
+ summaryNodeGroup(attributes, "XML attributes") { propertyLikeSummaryRow(it) }
+
+ summaryNodeGroup(constants, "Constants") { propertyLikeSummaryRow(it) }
+
+ summaryNodeGroup(
+ constructors,
+ "Constructors",
+ headerAsRow = true
+ ) {
+ functionLikeSummaryRow(it)
+ }
+
+ summaryNodeGroup(functions, "Functions", headerAsRow = true) { functionLikeSummaryRow(it) }
+ summaryNodeGroup(
+ companionFunctions,
+ "Companion functions",
+ headerAsRow = true
+ ) {
+ functionLikeSummaryRow(it)
+ }
+ summaryNodeGroup(
+ inheritedFunctionsByReceiver.entries,
+ "Inherited functions",
+ headerAsRow = true
+ ) {
+ inheritRow(it) {
+ functionLikeSummaryRow(it)
+ }
+ }
+ summaryNodeGroup(
+ extensionFunctions.entries,
+ "Extension functions",
+ headerAsRow = true
+ ) {
+ extensionRow(it) {
+ functionLikeSummaryRow(it)
+ }
+ }
+ summaryNodeGroup(
+ inheritedExtensionFunctions.entries,
+ "Inherited extension functions",
+ headerAsRow = true
+ ) {
+ extensionRow(it) {
+ functionLikeSummaryRow(it)
+ }
+ }
+
+
+ summaryNodeGroup(properties, "Properties", headerAsRow = true) { propertyLikeSummaryRow(it) }
+ summaryNodeGroup(
+ companionProperties,
+ "Companion properties",
+ headerAsRow = true
+ ) {
+ propertyLikeSummaryRow(it)
+ }
+
+ summaryNodeGroup(
+ inheritedPropertiesByReceiver.entries,
+ "Inherited properties",
+ headerAsRow = true
+ ) {
+ inheritRow(it) {
+ propertyLikeSummaryRow(it)
+ }
+ }
+ summaryNodeGroup(
+ extensionProperties.entries,
+ "Extension properties",
+ headerAsRow = true
+ ) {
+ extensionRow(it) {
+ propertyLikeSummaryRow(it)
+ }
+ }
+ summaryNodeGroup(
+ inheritedExtensionProperties.entries,
+ "Inherited extension properties",
+ headerAsRow = true
+ ) {
+ extensionRow(it) {
+ propertyLikeSummaryRow(it)
+ }
+ }
+ }
}
class DacFormatDescriptor : JavaLayoutHtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsKotlin {
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
index 13ba9b1..54cff55 100644
--- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
+++ b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
@@ -314,7 +314,6 @@
propertyLikeSummaryRow(it)
}
-
fullMemberDocs(page.constants, "Top-level constants")
fullMemberDocs(page.functions, "Top-level functions")
fullMemberDocs(page.properties, "Top-level properties")
@@ -758,6 +757,8 @@
val nestedClasses = node.members.filter { it.kind in NodeKind.classLike }
+ val attributes = node.members(NodeKind.Attribute)
+
val constants = node.members.filter { it.constantValue() != null }
val constructors = node.members(NodeKind.Constructor)
diff --git a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
index 12bb04d..5c30840 100644
--- a/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
+++ b/core/src/main/kotlin/Kotlin/DescriptorDocumentationParser.kt
@@ -9,6 +9,7 @@
import org.jetbrains.dokka.Samples.SampleProcessingService
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.kdoc.findKDoc
+import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection
@@ -85,12 +86,18 @@
return content to { node ->
if (kdoc is KDocSection) {
val tags = kdoc.getTags()
- node.addAttributes(tags)
+ node.addExtraTags(tags, descriptor)
}
}
}
- private fun DocumentationNode.addAttributes(tags: Array<KDocTag>) {
+ /**
+ * For now, this only adds @attr tag. There are 3 types of syntax for this:
+ * @attr ref <android.>R.styleable.<attribute_name>
+ * @attr name <attribute_name>
+ * @attr description <attribute_description>
+ */
+ private fun DocumentationNode.addExtraTags(tags: Array<KDocTag>, descriptor: DeclarationDescriptor) {
tags.forEach {
val name = it.name
if (name?.toLowerCase() == "attr") {
@@ -101,25 +108,34 @@
val attribute: DocumentationNode? = when (command) {
REF_COMMAND -> {
val attrRef = more.trim()
- DocumentationNode(attrRef, Content.Empty, NodeKind.XmlAttribute)
+ val qualified = attrRef.split('.', '#')
+ val targetDescriptor = resolveKDocLink(resolutionFacade.resolveSession.bindingContext, resolutionFacade, descriptor, it, qualified)
+ DocumentationNode(attrRef, Content.Empty, NodeKind.Attribute).also {
+ if (targetDescriptor.isNotEmpty()) {
+ refGraph.link(it, targetDescriptor.first().signature(), RefKind.Attribute)
+ }
+ }
}
NAME_COMMAND -> {
val nameMatcher = NAME_TEXT.matcher(more)
if (nameMatcher.matches()) {
val attrName = nameMatcher.group(1)
- DocumentationNode(attrName, Content.Empty, NodeKind.XmlAttribute)
+ DocumentationNode(attrName, Content.Empty, NodeKind.Attribute)
} else {
null
}
}
DESCRIPTION_COMMAND -> {
val attrDescription = more
- DocumentationNode(attrDescription, Content.Empty, NodeKind.XmlAttribute)
+ DocumentationNode(attrDescription, Content.Empty, NodeKind.Attribute)
}
else -> null
}
attribute?.let { append(it, RefKind.Attribute) }
}
+ } else if (name?.toLowerCase() == "since") {
+ val apiLevel = DocumentationNode(it.getContent(), Content.Empty, NodeKind.ApiLevel)
+ append(apiLevel, RefKind.AvailableSince)
}
}
}
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index 919a1c1..145d45d 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -59,7 +59,9 @@
*/
OverloadGroupNote,
- XmlAttribute,
+ Attribute,
+
+ ApiLevel,
GroupNode;
@@ -86,8 +88,6 @@
get() = references(RefKind.Detail).map { it.to }
val members: List<DocumentationNode>
get() = references(RefKind.Member).map { it.to }
- val xmlAttributes: List<DocumentationNode>
- get() = references(RefKind.Attribute).map { it.to }
val inheritedMembers: List<DocumentationNode>
get() = references(RefKind.InheritedMember).map { it.to }
val inheritedCompanionObjectMembers: List<DocumentationNode>
@@ -110,6 +110,10 @@
get() = references(RefKind.Platform).map { it.to.name }
val externalType: DocumentationNode?
get() = references(RefKind.ExternalType).map { it.to }.firstOrNull()
+ val attributes: List<DocumentationNode>
+ get() = references(RefKind.Attribute).map { it.to }
+ val apiLevel: DocumentationNode?
+ get() = references(RefKind.AvailableSince).map { it.to }.firstOrNull()
val supertypes: List<DocumentationNode>
get() = details(NodeKind.Supertype)
diff --git a/core/src/main/kotlin/Model/DocumentationReference.kt b/core/src/main/kotlin/Model/DocumentationReference.kt
index 3f5d9eb..7af072e 100644
--- a/core/src/main/kotlin/Model/DocumentationReference.kt
+++ b/core/src/main/kotlin/Model/DocumentationReference.kt
@@ -20,7 +20,8 @@
TopLevelPage,
Platform,
ExternalType,
- Attribute
+ Attribute,
+ AvailableSince
}
data class DocumentationReference(val from: DocumentationNode, val to: DocumentationNode, val kind: RefKind) {