diff --git a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt index 3876303c175..d84e9352687 100644 --- a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt +++ b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/JavadocStyleHtmlDoclet.kt @@ -45,11 +45,16 @@ class JavadocStyleHtmlDoclet() : Doclet { fun generateExtensionFunctions(p: KPackage): Unit { val map = inheritedExtensionFunctions(p.functions) - for (e in map.entrySet()) { - val c = e?.getKey() - val functions = e?.getValue() - if (c != null && functions != null) { - run("${p.nameAsPath}/${c.simpleName}-extensions.html", ClassExtensionsTemplate(model, p, c, functions)) + val pmap = inheritedExtensionProperties(p.properties) + val classes = hashSet() + classes.addAll(map.keySet()) + classes.addAll(pmap.keySet()) + for (c in classes) { + if (c != null) { + val functions = map.get(c).notNull() + val properties = pmap.get(c).notNull() + run("${p.nameAsPath}/${c.simpleName}-extensions.html", + ClassExtensionsTemplate(model, p, c, functions, properties)) } } } diff --git a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/templates/ClassExtensionsTemplate.kt b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/templates/ClassExtensionsTemplate.kt index 94a68f71d2d..33fe30a186f 100644 --- a/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/templates/ClassExtensionsTemplate.kt +++ b/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/templates/ClassExtensionsTemplate.kt @@ -10,8 +10,10 @@ import org.jetbrains.kotlin.model.KPackage import org.jetbrains.kotlin.model.KClass import org.jetbrains.kotlin.model.KFunction import org.jetbrains.kotlin.model.KAnnotation +import org.jetbrains.kotlin.model.KProperty -class ClassExtensionsTemplate(m: KModel, p: KPackage, k: KClass, var functions: Collection) : ClassTemplate(m, p, k) { +class ClassExtensionsTemplate(m: KModel, p: KPackage, k: KClass, + val functions: Collection, val properties: Collection) : ClassTemplate(m, p, k) { override fun pageTitle(): String = "${klass.name} Extensions fom ${pkg.name} (${model.title})" @@ -31,6 +33,7 @@ from package ${link(pkg)}

""") + printPropertySummary(properties) printFunctionSummary(functions) printFunctionDetail(functions) println(""" diff --git a/kdoc/src/main/kotlin/org/jetbrains/kotlin/model/KotlinModel.kt b/kdoc/src/main/kotlin/org/jetbrains/kotlin/model/KotlinModel.kt index 2ac6814b9fb..82f75520ab0 100644 --- a/kdoc/src/main/kotlin/org/jetbrains/kotlin/model/KotlinModel.kt +++ b/kdoc/src/main/kotlin/org/jetbrains/kotlin/model/KotlinModel.kt @@ -64,15 +64,55 @@ fun inheritedExtensionFunctions(functions: Collection): Map): Map> { + val map = extensionProperties(properties) + // for each class, lets walk its base classes and add any other extension properties from base classes + val classes = map.keySet().toList() + val answer = TreeMap>() + for (c in map.keySet()) { + val allProperties = map.get(c).notNull().toSortedSet() + answer.put(c, allProperties) + val des = c.descendants() + for (b in des) { + val list = map.get(b) + if (list != null) { + if (allProperties != null) { + for (f in list) { + if (f != null) { + // add the proeprties from the base class if we don't have a matching method + if (!allProperties.any{ it.name == f.name}) { + allProperties.add(f) + } + } + } + } + } + } + } + return answer +} + + // TODO for some reason the SortedMap causes kotlin to freak out a little :) fun extensionFunctions(functions: Collection): Map> { - //fun extensionFunctions(functions: Collection): SortedMap> { val map = TreeMap>() functions.filter{ it.extensionClass != null }.groupBy(map){ it.extensionClass.sure() } return map } -trait KClassOrPackage { +// TODO for some reason the SortedMap causes kotlin to freak out a little :) +fun extensionProperties(properties: Collection): Map> { + val map = TreeMap>() + properties.filter{ it.extensionClass != null }.groupBy(map){ it.extensionClass.sure() } + return map +} + +abstract class KClassOrPackage : KAnnotated() { + + public open val functions: SortedSet = TreeSet() + + public open val properties: SortedSet = TreeSet() } class KModel(var context: BindingContext, var title: String = "Documentation", var version: String = "TODO") { @@ -131,7 +171,7 @@ class KModel(var context: BindingContext, var title: String = "Documentation", v } if (created) { pkg.description = commentsFor(descriptor) - addFunctions(pkg, pkg.functions, descriptor.getMemberScope()) + addFunctions(pkg, descriptor.getMemberScope()) if (pkg.functions.notEmpty()) { pkg.local = true } @@ -139,23 +179,26 @@ class KModel(var context: BindingContext, var title: String = "Documentation", v return pkg; } - protected fun addFunctions(owner: KClassOrPackage, list: Collection, scope: JetScope): Unit { + protected fun addFunctions(owner: KClassOrPackage, scope: JetScope): Unit { try { val descriptors = scope.getAllDescriptors() for (descriptor in descriptors) { if (descriptor is PropertyDescriptor) { - if (owner is KClass) { - val name = descriptor.getName() - val returnType = getClass(descriptor.getReturnType()) - if (returnType != null) { - val property = KProperty(owner, descriptor, name, returnType) - owner.properties.add(property) - } + val name = descriptor.getName() + val returnType = getClass(descriptor.getReturnType()) + if (returnType != null) { + val receiver = descriptor.getReceiverParameter() + val extensionClass = if (receiver is ExtensionReceiver) { + getClass(receiver.getType()) + } else null + + val property = KProperty(owner, descriptor, name, returnType, extensionClass) + owner.properties.add(property) } } else if (descriptor is CallableDescriptor) { val function = createFunction(owner, descriptor) if (function != null) { - list.add(function) + owner.functions.add(function) } } } @@ -271,8 +314,7 @@ abstract class KAnnotated { class KPackage(val model: KModel, val descriptor: NamespaceDescriptor, val name: String, var external: Boolean = false, - var functions: SortedSet = TreeSet(), - var local: Boolean = false) : KAnnotated(), Comparable, KClassOrPackage { + var local: Boolean = false) : KClassOrPackage(), Comparable { override fun compareTo(other: KPackage): Int = name.compareTo(other.name) @@ -296,7 +338,7 @@ class KPackage(val model: KModel, val descriptor: NamespaceDescriptor, klass.baseClasses.add(sc) } } - model.addFunctions(klass, klass.functions, classElement.getDefaultType().getMemberScope()) + model.addFunctions(klass, classElement.getDefaultType().getMemberScope()) } return klass } @@ -364,11 +406,9 @@ class KClass(val pkg: KPackage, val descriptor: ClassDescriptor, var annotations: List = arrayList(), var since: String = "", var authors: List = arrayList(), - var functions: SortedSet = TreeSet(), - var properties: SortedSet = TreeSet(), var baseClasses: List = arrayList(), var nestedClasses: List = arrayList(), - var sourceLine: Int = 2) : KAnnotated(), Comparable, KClassOrPackage { + var sourceLine: Int = 2) : KClassOrPackage(), Comparable { override fun compareTo(other: KClass): Int = name.compareTo(other.name) @@ -444,7 +484,7 @@ class KFunction(val owner: KClassOrPackage, val name: String, } class KProperty(val owner: KClassOrPackage, val descriptor: PropertyDescriptor, val name: String, - val returnType: KClass) : KAnnotated(), Comparable { + val returnType: KClass, val extensionClass: KClass?) : KAnnotated(), Comparable { override fun compareTo(other: KProperty): Int = name.compareTo(other.name)