Support companion members
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormat.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormat.kt
index ae2af33..5148097 100644
--- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormat.kt
+++ b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormat.kt
@@ -87,23 +87,41 @@
     }
 }
 
+val DocumentationNode.companion get() = members(NodeKind.Object).find { it.details(NodeKind.Modifier).any { it.name == "companion" } }
 
-fun DocumentationNode.signatureForAnchor(logger: DokkaLogger): String = when (kind) {
-    NodeKind.Function, NodeKind.Constructor -> buildString {
+fun DocumentationNode.signatureForAnchor(logger: DokkaLogger): String {
+
+    fun StringBuilder.appendReceiverIfSo() {
         detailOrNull(NodeKind.Receiver)?.let {
             append("(")
             append(it.detail(NodeKind.Type).qualifiedNameFromType())
             append(").")
         }
-        append(name)
-        details(NodeKind.Parameter).joinTo(this, prefix = "(", postfix = ")") { it.detail(NodeKind.Type).qualifiedNameFromType() }
     }
-    NodeKind.Property ->
-        "$name:${detail(NodeKind.Type).qualifiedNameFromType()}"
-    NodeKind.TypeParameter, NodeKind.Parameter -> owner!!.signatureForAnchor(logger) + "/" + name
-    else -> "Not implemented signatureForAnchor $this".also { logger.warn(it) }
-}
 
+    return when (kind) {
+        NodeKind.Function, NodeKind.Constructor, NodeKind.CompanionObjectFunction -> buildString {
+            if (kind == NodeKind.CompanionObjectFunction) {
+                append("Companion.")
+            }
+            appendReceiverIfSo()
+            append(name)
+            details(NodeKind.Parameter).joinTo(this, prefix = "(", postfix = ")") { it.detail(NodeKind.Type).qualifiedNameFromType() }
+        }
+        NodeKind.Property, NodeKind.CompanionObjectProperty -> buildString {
+            if (kind == NodeKind.CompanionObjectProperty) {
+                append("Companion.")
+            }
+            appendReceiverIfSo()
+            append(name)
+            append(":")
+            append(detail(NodeKind.Type).qualifiedNameFromType())
+        }
+        NodeKind.TypeParameter, NodeKind.Parameter -> owner!!.signatureForAnchor(logger) + "/" + name
+        else -> "Not implemented signatureForAnchor $this".also { logger.warn(it) }
+    }
+
+}
 
 fun String.urlEncoded(): String = URLEncoder.encode(this, "UTF-8")
 
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
index 740b278..0c95a41 100644
--- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
+++ b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlFormatOutputBuilder.kt
@@ -202,8 +202,8 @@
                 summaryNodeGroup(node.members(NodeKind.Property), "Top-level properties summary") { propertyLikeSummaryRow(it) }
 
 
-                fullDocs(node.members(NodeKind.Function), { h2 { +"Top-level functions" } }) { memberDocs(it) }
-                fullDocs(node.members(NodeKind.Property), { h2 { +"Top-level properties" } }) { memberDocs(it) }
+                fullDocs(node.members(NodeKind.Function), "Top-level functions") { memberDocs(it) }
+                fullDocs(node.members(NodeKind.Property), "Top-level properties") { memberDocs(it) }
             }
     )
 
@@ -316,42 +316,62 @@
 
                 h2 { +"Summary" }
 
-                fun DocumentationNode.isFunction() = kind == NodeKind.Function || kind == NodeKind.CompanionObjectFunction
-                fun DocumentationNode.isProperty() = kind == NodeKind.Property || kind == NodeKind.CompanionObjectProperty
+                val isCompanion = node.details(NodeKind.Modifier).any { it.name == "companion" }
+                val hasMeaningfulCompanion = !isCompanion && node.companion != null
 
                 fun DocumentationNode.thisTypeExtension() = detail(NodeKind.Receiver).detail(NodeKind.Type).links.any { it == node }
 
-                val functionsToDisplay = node.members.filter(DocumentationNode::isFunction)
-                val properties = node.members.filter(DocumentationNode::isProperty)
-                val inheritedFunctionsByReceiver = node.inheritedMembers.filter(DocumentationNode::isFunction).groupBy { it.owner!! }
-                val inheritedPropertiesByReceiver = node.inheritedMembers.filter(DocumentationNode::isProperty).groupBy { it.owner!! }
-                val (extensions, inheritedExtensions) = node.extensions.partition {
-                    it.thisTypeExtension()
-                }
+                val functionKind = if (!isCompanion) NodeKind.Function else NodeKind.CompanionObjectFunction
+                val propertyKind = if (!isCompanion) NodeKind.Property else NodeKind.CompanionObjectProperty
+
+                fun DocumentationNode.isFunction() = kind == functionKind
+                fun DocumentationNode.isProperty() = kind == propertyKind
+
+                val functions = node.members(functionKind)
+                val properties = node.members(propertyKind)
+                val inheritedFunctionsByReceiver = node.inheritedMembers(functionKind).groupBy { it.owner!! }
+                val inheritedPropertiesByReceiver = node.inheritedMembers(propertyKind).groupBy { it.owner!! }
+
+
+                val originalExtensions = if (!isCompanion) node.extensions else node.owner!!.extensions
+                val (extensions, inheritedExtensions) = originalExtensions.partition { it.thisTypeExtension() }
                 val extensionFunctions = extensions.filter(DocumentationNode::isFunction).groupBy { it.owner!! }
                 val extensionProperties = extensions.filter(DocumentationNode::isProperty).groupBy { it.owner!! }
                 val inheritedExtensionFunctions = inheritedExtensions.filter(DocumentationNode::isFunction).groupBy { it.owner!! }
                 val inheritedExtensionProperties = inheritedExtensions.filter(DocumentationNode::isProperty).groupBy { it.owner!! }
 
+                val companionFunctions = node.members(NodeKind.CompanionObjectFunction)
+                val companionProperties = node.members(NodeKind.CompanionObjectProperty)
+
                 summaryNodeGroup(node.members.filter { it.kind in NodeKind.classLike }, "Nested classes", headerAsRow = true) { nestedClassSummaryRow(it) }
 
                 summaryNodeGroup(node.members(NodeKind.Constructor), "Constructors", headerAsRow = true) { functionLikeSummaryRow(it) }
 
-                summaryNodeGroup(functionsToDisplay, "Functions", headerAsRow = true) { functionLikeSummaryRow(it) }
+                summaryNodeGroup(functions, "Functions", headerAsRow = true) { functionLikeSummaryRow(it) }
+                if (!isCompanion) {
+                    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) }
+                if (!isCompanion) {
+                    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) } }
 
 
-                fullDocs(node.members(NodeKind.Constructor), { h2 { +"Constructors" } }) { memberDocs(it) }
-                fullDocs(functionsToDisplay, { h2 { +"Functions" } }) { memberDocs(it) }
-                fullDocs(properties, { h2 { +"Properties" } }) { memberDocs(it) }
+                fullDocs(node.members(NodeKind.Constructor), "Constructors") { memberDocs(it) }
+                fullDocs(functions, "Functions") { memberDocs(it) }
+                fullDocs(properties, "Properties") { memberDocs(it) }
+                if (!isCompanion && !hasMeaningfulCompanion) {
+                    fullDocs(companionFunctions, "Companion functions") { memberDocs(it) }
+                    fullDocs(companionProperties, "Companion properties") { memberDocs(it) }
+                }
             }
     )
 
@@ -431,11 +451,13 @@
 
     private fun FlowContent.fullDocs(
             nodes: List<DocumentationNode>,
-            header: FlowContent.() -> Unit,
+            header: String,
             renderNode: FlowContent.(DocumentationNode) -> Unit
     ) {
         if (nodes.none()) return
-        header()
+        h2 {
+            +header
+        }
         for (node in nodes) {
             renderNode(node)
         }
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlGenerator.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlGenerator.kt
index 6447d9c..f9cbd04 100644
--- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlGenerator.kt
+++ b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlGenerator.kt
@@ -3,6 +3,7 @@
 import com.google.inject.Inject
 import com.google.inject.name.Named
 import org.jetbrains.dokka.*
+import org.jetbrains.dokka.NodeKind.Companion.classLike
 import org.jetbrains.kotlin.preprocessor.mkdirsOrFail
 import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
 import java.io.BufferedWriter
@@ -40,7 +41,16 @@
             in NodeKind.classLike -> tryGetContainerUri(node)?.resolve("#")
             in NodeKind.memberLike -> {
                 val owner = if (node.owner?.kind != NodeKind.ExternalClass) node.owner else node.owner?.owner
-                tryGetMainUri(owner!!)?.resolveInPage(node)
+                if (owner!!.kind in classLike &&
+                        (node.kind == NodeKind.CompanionObjectProperty || node.kind == NodeKind.CompanionObjectFunction) &&
+                        owner.companion != null
+                ) {
+                    val signature = node.detail(NodeKind.Signature)
+                    val originalFunction = owner.companion!!.members.first { it.detailOrNull(NodeKind.Signature)?.name == signature.name }
+                    tryGetMainUri(owner.companion!!)?.resolveInPage(originalFunction)
+                } else {
+                    tryGetMainUri(owner)?.resolveInPage(node)
+                }
             }
             NodeKind.TypeParameter, NodeKind.Parameter -> node.path.asReversed().drop(1).firstNotNullResult(this::tryGetMainUri)?.resolveInPage(node)
             NodeKind.AllTypes -> tryGetContainerUri(node.owner!!)?.resolve("classes.html")