From 50e711d24b517bc93c37d89f258c9dafaa038ad1 Mon Sep 17 00:00:00 2001 From: Szymon Świstun Date: Mon, 20 Jan 2020 14:55:42 +0100 Subject: kotlin-as-java plugin --- .../src/main/kotlin/KotlinAsJavaPlugin.kt | 39 ++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt (limited to 'plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt') diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt new file mode 100644 index 00000000..345dc9be --- /dev/null +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt @@ -0,0 +1,39 @@ +package org.jetbrains.dokka.kotlinAsJava + + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.Module +import org.jetbrains.dokka.pages.ModulePageNode +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.plugability.single +import org.jetbrains.dokka.transformers.documentation.DocumentationToPageTranslator +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor + +class KotlinAsJavaPlugin : DokkaPlugin() { + val kotlinAsJavaDescriptorToDocumentableTranslator by extending { CoreExtensions.descriptorToDocumentationTranslator with KotlinAsJavaDescriptorToDocumentationTranslator } + val kotlinAsJavaDocumentableToPageTranslator by extending { CoreExtensions.documentationToPageTranslator with KotlinAsJavaDocumentationToPageTranslator } +} + +object DescriptorCache { + private val cache: HashMap = HashMap() + + fun add(dri: DRI, descriptor: DeclarationDescriptor): Boolean = cache.putIfAbsent(dri, descriptor) == null + operator fun get(dri: DRI): DeclarationDescriptor? = cache[dri] +} + +object KotlinAsJavaDocumentationToPageTranslator : DocumentationToPageTranslator { + override fun invoke(module: Module, context: DokkaContext): ModulePageNode = + KotlinAsJavaPageBuilder { node, kind, operation -> + KotlinAsJavaPageContentBuilder.group( + setOf(node.dri), + node.platformData, + kind, + context.single(CoreExtensions.commentsToContentConverter), + context.logger, + operation + ) + }.pageForModule(module) + +} \ No newline at end of file -- cgit From 848f2e0656e80604cb54932db5b250303aaccca8 Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Wed, 12 Feb 2020 16:01:38 +0100 Subject: Moves DescriptorToDocumentableTransformer to base plugin --- core/src/main/kotlin/CoreExtensions.kt | 1 - core/src/main/kotlin/DokkaGenerator.kt | 2 +- core/src/main/kotlin/model/Documentable.kt | 12 - core/src/main/kotlin/model/classKinds.kt | 25 ++ core/src/main/kotlin/model/typeWrappers.kt | 97 ++++++ .../main/kotlin/plugability/DefaultExtensions.kt | 2 - .../DefaultDescriptorToDocumentationTranslator.kt | 362 --------------------- .../DescriptorToDocumentationTranslator.kt | 3 +- .../psi/DefaultPsiToDocumentationTranslator.kt | 72 ---- plugins/base/build.gradle.kts | 3 +- plugins/base/src/main/kotlin/DokkaBase.kt | 7 + .../DefaultDescriptorToDocumentationTranslator.kt | 338 +++++++++++++++++++ plugins/kotlin-as-java/build.gradle.kts | 4 + ...linAsJavaDescriptorToDocumentationTranslator.kt | 13 +- .../src/main/kotlin/KotlinAsJavaPageBuilder.kt | 1 - .../main/kotlin/KotlinAsJavaPageContentBuilder.kt | 2 +- .../src/main/kotlin/KotlinAsJavaPlugin.kt | 8 +- .../src/main/kotlin/KotlinToJVMResolver.kt | 1 - 18 files changed, 489 insertions(+), 464 deletions(-) create mode 100644 core/src/main/kotlin/model/classKinds.kt create mode 100644 core/src/main/kotlin/model/typeWrappers.kt delete mode 100644 core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt create mode 100644 plugins/base/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt (limited to 'plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt') diff --git a/core/src/main/kotlin/CoreExtensions.kt b/core/src/main/kotlin/CoreExtensions.kt index 18cde210..1364f1c1 100644 --- a/core/src/main/kotlin/CoreExtensions.kt +++ b/core/src/main/kotlin/CoreExtensions.kt @@ -30,7 +30,6 @@ object CoreExtensions { val locationProviderFactory by coreExtension() val outputWriter by coreExtension() val renderer by coreExtension() - val fileExtension by coreExtension() val pageMergerStrategy by coreExtension() private fun coreExtension() = object { diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index a31c04a6..6a21e031 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -130,7 +130,7 @@ class DokkaGenerator( .toList() return context.single(CoreExtensions.descriptorToDocumentationTranslator) - .invoke(platformData.name, packageFragments, platformData, context) + .invoke(platformData.name, packageFragments, platformData) } private fun translatePsi(platformData: PlatformData, context: DokkaContext): Module { diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index e64f82ac..f0820256 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -3,9 +3,6 @@ package org.jetbrains.dokka.model import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.pages.PlatformData -import org.jetbrains.dokka.transformers.descriptors.KotlinClassKindTypes -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility class Module(override val name: String, val packages: List) : Documentable() { @@ -239,15 +236,6 @@ private fun String.shorten(maxLength: Int) = lineSequence().first().let { if (it.length != length || it.length > maxLength) it.take(maxLength - 3) + "..." else it } -interface TypeWrapper { - val constructorFqName: String? - val constructorNamePathSegments: List - val arguments: List - val dri: DRI? -} - -interface ClassKind - fun Documentable.dfs(predicate: (Documentable) -> Boolean): Documentable? = if (predicate(this)) { this diff --git a/core/src/main/kotlin/model/classKinds.kt b/core/src/main/kotlin/model/classKinds.kt new file mode 100644 index 00000000..2548f68d --- /dev/null +++ b/core/src/main/kotlin/model/classKinds.kt @@ -0,0 +1,25 @@ +package org.jetbrains.dokka.model + +import org.jetbrains.dokka.links.DRI +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType + + +interface ClassKind + +enum class KotlinClassKindTypes : ClassKind { + CLASS, + INTERFACE, + ENUM_CLASS, + ENUM_ENTRY, + ANNOTATION_CLASS, + OBJECT; +} + +enum class JavaClassKindTypes : ClassKind { + CLASS, + INTERFACE, + ENUM_CLASS, + ENUM_ENTRY, + ANNOTATION_CLASS; +} diff --git a/core/src/main/kotlin/model/typeWrappers.kt b/core/src/main/kotlin/model/typeWrappers.kt new file mode 100644 index 00000000..5719c6d3 --- /dev/null +++ b/core/src/main/kotlin/model/typeWrappers.kt @@ -0,0 +1,97 @@ +package org.jetbrains.dokka.model + +import com.intellij.psi.PsiArrayType +import com.intellij.psi.PsiEllipsisType +import com.intellij.psi.PsiPrimitiveType +import com.intellij.psi.PsiType +import com.intellij.psi.impl.source.PsiClassReferenceType +import org.jetbrains.dokka.links.DRI +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.types.KotlinType + +interface TypeWrapper { + val constructorFqName: String? + val constructorNamePathSegments: List + val arguments: List + val dri: DRI? +} + +class KotlinTypeWrapper(private val kotlinType: KotlinType) : TypeWrapper { + private val declarationDescriptor = kotlinType.constructor.declarationDescriptor + private val fqNameSafe = declarationDescriptor?.fqNameSafe + override val constructorFqName = fqNameSafe?.asString() + override val constructorNamePathSegments: List = + fqNameSafe?.pathSegments()?.map { it.asString() } ?: emptyList() + override val arguments: List by lazy { + kotlinType.arguments.map { + KotlinTypeWrapper( + it.type + ) + } + } + override val dri: DRI? by lazy { declarationDescriptor?.let { DRI.from(it) } } +} + +class JavaTypeWrapper : TypeWrapper { + + override val constructorFqName: String? + override val constructorNamePathSegments: List + override val arguments: List + override val dri: DRI? + val isPrimitive: Boolean + + constructor( + constructorNamePathSegments: List, + arguments: List, + dri: DRI?, + isPrimitiveType: Boolean + ) { + this.constructorFqName = constructorNamePathSegments.joinToString(".") + this.constructorNamePathSegments = constructorNamePathSegments + this.arguments = arguments + this.dri = dri + this.isPrimitive = isPrimitiveType + } + + constructor(type: PsiType) { + if (type is PsiClassReferenceType) { + val resolved = type.resolve() + constructorFqName = resolved?.qualifiedName + constructorNamePathSegments = resolved?.qualifiedName?.split('.') ?: emptyList() + arguments = type.parameters.mapNotNull { + if (it is PsiClassReferenceType) JavaTypeWrapper(it) else null + } + dri = fromPsi(type) + this.isPrimitive = false + } else if (type is PsiEllipsisType) { + constructorFqName = type.canonicalText + constructorNamePathSegments = listOf(type.canonicalText) // TODO + arguments = emptyList() + dri = DRI("java.lang", "Object") // TODO + this.isPrimitive = false + } else if (type is PsiArrayType) { + constructorFqName = type.canonicalText + constructorNamePathSegments = listOf(type.canonicalText) + arguments = emptyList() + dri = (type as? PsiClassReferenceType)?.let { fromPsi(it) } // TODO + this.isPrimitive = false + } else { + type as PsiPrimitiveType + constructorFqName = type.name + constructorNamePathSegments = type.name.split('.') + arguments = emptyList() + dri = null + this.isPrimitive = true + } + } + + private fun fromPsi(type: PsiClassReferenceType): DRI { + val className = type.className + val pkg = type.canonicalText.removeSuffix(className).removeSuffix(".") + return DRI(packageName = pkg, classNames = className) + } + + override fun toString(): String { + return constructorFqName.orEmpty() + } +} diff --git a/core/src/main/kotlin/plugability/DefaultExtensions.kt b/core/src/main/kotlin/plugability/DefaultExtensions.kt index 1320c282..70a7e4db 100644 --- a/core/src/main/kotlin/plugability/DefaultExtensions.kt +++ b/core/src/main/kotlin/plugability/DefaultExtensions.kt @@ -6,7 +6,6 @@ import org.jetbrains.dokka.renderers.FileWriter import org.jetbrains.dokka.renderers.OutputWriter import org.jetbrains.dokka.renderers.html.HtmlRenderer import org.jetbrains.dokka.resolvers.DefaultLocationProviderFactory -import org.jetbrains.dokka.transformers.descriptors.DefaultDescriptorToDocumentationTranslator import org.jetbrains.dokka.transformers.documentation.DefaultDocumentationNodeMerger import org.jetbrains.dokka.transformers.documentation.DefaultDocumentationToPageTranslator import org.jetbrains.dokka.transformers.pages.DefaultPageMergerStrategy @@ -28,7 +27,6 @@ internal object DefaultExtensions { @Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST") internal fun > get(point: E, fullContext: DokkaContext): List = when (point) { - CoreExtensions.descriptorToDocumentationTranslator -> DefaultDescriptorToDocumentationTranslator CoreExtensions.psiToDocumentationTranslator -> DefaultPsiToDocumentationTranslator CoreExtensions.documentationMerger -> DefaultDocumentationNodeMerger CoreExtensions.commentsToContentConverter -> converter.get(fullContext) diff --git a/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt b/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt deleted file mode 100644 index 173e13ac..00000000 --- a/core/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt +++ /dev/null @@ -1,362 +0,0 @@ -package org.jetbrains.dokka.transformers.descriptors - -import org.jetbrains.dokka.analysis.DokkaResolutionFacade -import org.jetbrains.dokka.links.Callable -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.links.withClass -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.ClassKind -import org.jetbrains.dokka.model.Enum -import org.jetbrains.dokka.model.Function -import org.jetbrains.dokka.model.Property -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.pages.PlatformData -import org.jetbrains.dokka.parsers.MarkdownParser -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies -import org.jetbrains.kotlin.idea.kdoc.findKDoc -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny -import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.KotlinType -import kotlin.reflect.KClass - -object DefaultDescriptorToDocumentationTranslator : DescriptorToDocumentationTranslator { - override fun invoke( - moduleName: String, - packageFragments: Iterable, - platformData: PlatformData, - context: DokkaContext - ) = DokkaDescriptorVisitor(platformData, context.platforms[platformData]?.facade!!).run { - packageFragments.map { - visitPackageFragmentDescriptor( - it, - DRIWithPlatformInfo(DRI.topLevel, null, emptyList()) - ) - } - }.let { Module(moduleName, it) } - -} - - -data class DRIWithPlatformInfo( - val dri: DRI, - val expected: PlatformInfo?, - val actual: List -) - -fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, null, emptyList()) - -open class DokkaDescriptorVisitor( - private val platformData: PlatformData, - private val resolutionFacade: DokkaResolutionFacade -) : DeclarationDescriptorVisitorEmptyBodies() { - override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor, parent: DRIWithPlatformInfo): Nothing { - throw IllegalStateException("${javaClass.simpleName} should never enter ${descriptor.javaClass.simpleName}") - } - - override fun visitPackageFragmentDescriptor( - descriptor: PackageFragmentDescriptor, - parent: DRIWithPlatformInfo - ): Package { - val driWithPlatform = DRI(packageName = descriptor.fqName.asString()).withEmptyInfo() - val scope = descriptor.getMemberScope() - - return Package( - dri = driWithPlatform.dri, - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform) - ) - } - - override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Classlike = - when (descriptor.kind) { - org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) - else -> classDescriptor(descriptor, parent) - } - - fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Enum { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val descriptorData = descriptor.takeUnless { it.isExpect }?.resolveClassDescriptionData() - - return Enum( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - entries = scope.classlikes(driWithPlatform).filter { it.kind == KotlinClassKindTypes.ENUM_ENTRY }.map { - EnumEntry( - it - ) - }, - constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - expected = descriptor.takeIf { it.isExpect }?.resolveClassDescriptionData(), - actual = listOfNotNull(descriptorData), - extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet() - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - fun classDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Class { - val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() - val scope = descriptor.unsubstitutedMemberScope - val descriptorData = descriptor.takeUnless { it.isExpect }?.resolveClassDescriptionData() - val expected = descriptor.takeIf { it.isExpect }?.resolveClassDescriptionData() - val actual = listOfNotNull(descriptorData) - return Class( - dri = driWithPlatform.dri, - name = descriptor.name.asString(), - kind = KotlinClassKindTypes.valueOf(descriptor.kind.toString()), - constructors = descriptor.constructors.map { - visitConstructorDescriptor( - it, - if (it.isPrimary) - DRIWithPlatformInfo( - driWithPlatform.dri, - expected?.info.filterTagWrappers(listOf(Constructor::class)), - actual.filterTagWrappers(listOf(Constructor::class)) - ) - else - DRIWithPlatformInfo(driWithPlatform.dri, null, emptyList()) - ) - }, - functions = scope.functions(driWithPlatform), - properties = scope.properties(driWithPlatform), - classlikes = scope.classlikes(driWithPlatform), - expected = expected, - actual = actual, - extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet() - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): Property { - val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData() - val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) - val dri = parent.dri.copy(callable = Callable.from(descriptor)) - - return Property( - dri = dri, - name = descriptor.name.asString(), - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor( - it, - DRIWithPlatformInfo( - dri, - expected?.filterTagWrappers(listOf(Receiver::class)), - actual.filterTagWrappers(listOf(Receiver::class)) - ) - ) - }, - expected = expected, - actual = actual, - accessors = descriptor.accessors.map { visitPropertyAccessorDescriptor(it, descriptor, dri) }, - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): Function { - val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData() - val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) - val dri = parent.dri.copy(callable = Callable.from(descriptor)) - - return Function( - dri = dri, - name = descriptor.name.asString(), - returnType = descriptor.returnType?.let { KotlinTypeWrapper(it) }, - isConstructor = false, - receiver = descriptor.extensionReceiverParameter?.let { - visitReceiverParameterDescriptor( - it, - DRIWithPlatformInfo( - dri, - expected?.filterTagWrappers(listOf(Receiver::class)), - actual.filterTagWrappers(listOf(Receiver::class)) - ) - ) - }, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter( - index, desc, - DRIWithPlatformInfo( - dri, - expected.filterTagWrappers(listOf(Param::class), desc.name.asString()), - actual.filterTagWrappers(listOf(Param::class), desc.name.asString()) - ) - ) - }, - expected = expected, - actual = actual, - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): Function { - val dri = parent.dri.copy(callable = Callable.from(descriptor)) - return Function( - dri = dri, - name = "", - returnType = KotlinTypeWrapper(descriptor.returnType), - isConstructor = true, - receiver = null, - parameters = descriptor.valueParameters.mapIndexed { index, desc -> - parameter( - index, desc, - DRIWithPlatformInfo( - dri, - parent.expected.filterTagWrappers(listOf(Param::class)), - parent.actual.filterTagWrappers(listOf(Param::class)) - ) - ) - }, - expected = parent.expected ?: descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), - actual = parent.actual, - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - override fun visitReceiverParameterDescriptor( - descriptor: ReceiverParameterDescriptor, - parent: DRIWithPlatformInfo - ) = Parameter( - dri = parent.dri.copy(target = 0), - name = null, - type = KotlinTypeWrapper(descriptor.type), - expected = parent.expected, - actual = parent.actual - ) - - open fun visitPropertyAccessorDescriptor( - descriptor: PropertyAccessorDescriptor, - propertyDescriptor: PropertyDescriptor, - parent: DRI - ): Function { - val dri = parent.copy(callable = Callable.from(descriptor)) - val isGetter = descriptor is PropertyGetterDescriptor - - fun PropertyDescriptor.asParameter(parent: DRI) = - Parameter( - parent.copy(target = 1), - this.name.asString(), - KotlinTypeWrapper(this.type), - descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), - listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) - ) - - val name = run { - val modifier = if (isGetter) "get" else "set" - val rawName = propertyDescriptor.name.asString() - "$modifier${rawName[0].toUpperCase()}${rawName.drop(1)}" - } - - descriptor.visibility - val parameters = - if (isGetter) { - emptyList() - } else { - listOf(propertyDescriptor.asParameter(dri)) - } - - return Function( - dri, - name, - descriptor.returnType?.let { KotlinTypeWrapper(it) }, - false, - null, - parameters, - descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), - listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()), - visibility = mapOf(platformData to descriptor.visibility) - ) - } - - private fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRIWithPlatformInfo) = - Parameter( - dri = parent.dri.copy(target = index + 1), - name = descriptor.name.asString(), - type = KotlinTypeWrapper(descriptor.type), - expected = parent.expected, - actual = parent.actual - ) - - private fun MemberScope.functions(parent: DRIWithPlatformInfo): List = - getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) { true } - .filterIsInstance() - .map { visitFunctionDescriptor(it, parent) } - - private fun MemberScope.properties(parent: DRIWithPlatformInfo): List = - getContributedDescriptors(DescriptorKindFilter.VALUES) { true } - .filterIsInstance() - .map { visitPropertyDescriptor(it, parent) } - - private fun MemberScope.classlikes(parent: DRIWithPlatformInfo): List = - getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { true } - .filterIsInstance() - .map { visitClassDescriptor(it, parent) } - - private fun DeclarationDescriptor.resolveDescriptorData(): PlatformInfo { - val doc = findKDoc() - val parser: MarkdownParser = MarkdownParser(resolutionFacade, this) - val docHeader = parser.parseFromKDocTag(doc) - - return BasePlatformInfo(docHeader, listOf(platformData)) - } - - private fun ClassDescriptor.resolveClassDescriptionData(): ClassPlatformInfo { - return ClassPlatformInfo(resolveDescriptorData(), - (getSuperInterfaces() + getAllSuperclassesWithoutAny()).map { DRI.from(it) }) - } - - private fun PlatformInfo?.filterTagWrappers( - types: List>, - name: String? = null - ): PlatformInfo? { - if (this == null) - return null - return BasePlatformInfo( - DocumentationNode( - this.documentationNode.children.filter { it::class in types && (it as? NamedTagWrapper)?.name == name } - ), - this.platformData - ) - } - - private fun List.filterTagWrappers( - types: List>, - name: String? = null - ): List = - this.map { it.filterTagWrappers(types, name)!! } -} - -data class XMLMega(val key: String, val dri: DRI) : Extra - -enum class KotlinClassKindTypes : ClassKind { - CLASS, - INTERFACE, - ENUM_CLASS, - ENUM_ENTRY, - ANNOTATION_CLASS, - OBJECT; -} - -class KotlinTypeWrapper(private val kotlinType: KotlinType) : TypeWrapper { - private val declarationDescriptor = kotlinType.constructor.declarationDescriptor - private val fqNameSafe = declarationDescriptor?.fqNameSafe - override val constructorFqName = fqNameSafe?.asString() - override val constructorNamePathSegments: List = - fqNameSafe?.pathSegments()?.map { it.asString() } ?: emptyList() - override val arguments: List by lazy { - kotlinType.arguments.map { - KotlinTypeWrapper( - it.type - ) - } - } - override val dri: DRI? by lazy { declarationDescriptor?.let { DRI.from(it) } } -} \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/descriptors/DescriptorToDocumentationTranslator.kt b/core/src/main/kotlin/transformers/descriptors/DescriptorToDocumentationTranslator.kt index 61d636d6..5074833e 100644 --- a/core/src/main/kotlin/transformers/descriptors/DescriptorToDocumentationTranslator.kt +++ b/core/src/main/kotlin/transformers/descriptors/DescriptorToDocumentationTranslator.kt @@ -9,7 +9,6 @@ interface DescriptorToDocumentationTranslator { fun invoke( moduleName: String, packageFragments: Iterable, - platformData: PlatformData, - context: DokkaContext + platformData: PlatformData ): Module } \ No newline at end of file diff --git a/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt b/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt index 144f319f..055df0b2 100644 --- a/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt +++ b/core/src/main/kotlin/transformers/psi/DefaultPsiToDocumentationTranslator.kt @@ -141,75 +141,3 @@ object DefaultPsiToDocumentationTranslator : PsiToDocumentationTranslator { } } } - -enum class JavaClassKindTypes : ClassKind { - CLASS, - INTERFACE, - ENUM_CLASS, - ENUM_ENTRY, - ANNOTATION_CLASS; -} - -class JavaTypeWrapper : TypeWrapper { - - override val constructorFqName: String? - override val constructorNamePathSegments: List - override val arguments: List - override val dri: DRI? - val isPrimitive: Boolean - - constructor( - constructorNamePathSegments: List, - arguments: List, - dri: DRI?, - isPrimitiveType: Boolean - ) { - this.constructorFqName = constructorNamePathSegments.joinToString(".") - this.constructorNamePathSegments = constructorNamePathSegments - this.arguments = arguments - this.dri = dri - this.isPrimitive = isPrimitiveType - } - - constructor(type: PsiType) { - if (type is PsiClassReferenceType) { - val resolved = type.resolve() - constructorFqName = resolved?.qualifiedName - constructorNamePathSegments = resolved?.qualifiedName?.split('.') ?: emptyList() - arguments = type.parameters.mapNotNull { - if (it is PsiClassReferenceType) JavaTypeWrapper(it) else null - } - dri = fromPsi(type) - this.isPrimitive = false - } else if (type is PsiEllipsisType) { - constructorFqName = type.canonicalText - constructorNamePathSegments = listOf(type.canonicalText) // TODO - arguments = emptyList() - dri = DRI("java.lang", "Object") // TODO - this.isPrimitive = false - } else if (type is PsiArrayType) { - constructorFqName = type.canonicalText - constructorNamePathSegments = listOf(type.canonicalText) - arguments = emptyList() - dri = (type as? PsiClassReferenceType)?.let { fromPsi(it) } // TODO - this.isPrimitive = false - } else { - type as PsiPrimitiveType - constructorFqName = type.name - constructorNamePathSegments = type.name.split('.') - arguments = emptyList() - dri = null - this.isPrimitive = true - } - } - - private fun fromPsi(type: PsiClassReferenceType): DRI { - val className = type.className - val pkg = type.canonicalText.removeSuffix(className).removeSuffix(".") - return DRI(packageName = pkg, classNames = className) - } - - override fun toString(): String { - return constructorFqName.orEmpty() - } -} \ No newline at end of file diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts index 386a3288..ba0b5753 100644 --- a/plugins/base/build.gradle.kts +++ b/plugins/base/build.gradle.kts @@ -5,4 +5,5 @@ publishing { from(components["java"]) } } -} \ No newline at end of file +} + diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index e82a59bf..5c579e54 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -1,4 +1,11 @@ +package org.jetbrains.dokka.base + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.base.transformers.descriptors.DefaultDescriptorToDocumentationTranslator import org.jetbrains.dokka.plugability.DokkaPlugin class DokkaBase: DokkaPlugin() { + val defaultDescriptorToDocumentationTranslator by extending { + CoreExtensions.descriptorToDocumentationTranslator providing ::DefaultDescriptorToDocumentationTranslator + } } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt b/plugins/base/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt new file mode 100644 index 00000000..1358cef1 --- /dev/null +++ b/plugins/base/src/main/kotlin/transformers/descriptors/DefaultDescriptorToDocumentationTranslator.kt @@ -0,0 +1,338 @@ +package org.jetbrains.dokka.base.transformers.descriptors + +import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.links.Callable +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.withClass +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.ClassKind +import org.jetbrains.dokka.model.Enum +import org.jetbrains.dokka.model.Function +import org.jetbrains.dokka.model.Property +import org.jetbrains.dokka.model.doc.* +import org.jetbrains.dokka.pages.PlatformData +import org.jetbrains.dokka.parsers.MarkdownParser +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.transformers.descriptors.DescriptorToDocumentationTranslator +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies +import org.jetbrains.kotlin.idea.kdoc.findKDoc +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny +import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.KotlinType +import kotlin.reflect.KClass + +class DefaultDescriptorToDocumentationTranslator( + private val context: DokkaContext +) : DescriptorToDocumentationTranslator { + override fun invoke( + moduleName: String, + packageFragments: Iterable, + platformData: PlatformData + ) = DokkaDescriptorVisitor(platformData, context.platforms[platformData]?.facade!!).run { + packageFragments.map { + visitPackageFragmentDescriptor( + it, + DRIWithPlatformInfo(DRI.topLevel, null, emptyList()) + ) + } + }.let { Module(moduleName, it) } + +} + + +data class DRIWithPlatformInfo( + val dri: DRI, + val expected: PlatformInfo?, + val actual: List +) + +fun DRI.withEmptyInfo() = DRIWithPlatformInfo(this, null, emptyList()) + +open class DokkaDescriptorVisitor( // TODO: close this class and make it private together with DRIWithPlatformInfo + private val platformData: PlatformData, + private val resolutionFacade: DokkaResolutionFacade +) : DeclarationDescriptorVisitorEmptyBodies() { + override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor, parent: DRIWithPlatformInfo): Nothing { + throw IllegalStateException("${javaClass.simpleName} should never enter ${descriptor.javaClass.simpleName}") + } + + override fun visitPackageFragmentDescriptor( + descriptor: PackageFragmentDescriptor, + parent: DRIWithPlatformInfo + ): Package { + val driWithPlatform = DRI(packageName = descriptor.fqName.asString()).withEmptyInfo() + val scope = descriptor.getMemberScope() + + return Package( + dri = driWithPlatform.dri, + functions = scope.functions(driWithPlatform), + properties = scope.properties(driWithPlatform), + classlikes = scope.classlikes(driWithPlatform) + ) + } + + override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Classlike = + when (descriptor.kind) { + org.jetbrains.kotlin.descriptors.ClassKind.ENUM_CLASS -> enumDescriptor(descriptor, parent) + else -> classDescriptor(descriptor, parent) + } + + fun enumDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Enum { + val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() + val scope = descriptor.unsubstitutedMemberScope + val descriptorData = descriptor.takeUnless { it.isExpect }?.resolveClassDescriptionData() + + return Enum( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + entries = scope.classlikes(driWithPlatform).filter { it.kind == KotlinClassKindTypes.ENUM_ENTRY }.map { + EnumEntry( + it + ) + }, + constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) }, + functions = scope.functions(driWithPlatform), + properties = scope.properties(driWithPlatform), + classlikes = scope.classlikes(driWithPlatform), + expected = descriptor.takeIf { it.isExpect }?.resolveClassDescriptionData(), + actual = listOfNotNull(descriptorData), + extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet() + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + fun classDescriptor(descriptor: ClassDescriptor, parent: DRIWithPlatformInfo): Class { + val driWithPlatform = parent.dri.withClass(descriptor.name.asString()).withEmptyInfo() + val scope = descriptor.unsubstitutedMemberScope + val descriptorData = descriptor.takeUnless { it.isExpect }?.resolveClassDescriptionData() + val expected = descriptor.takeIf { it.isExpect }?.resolveClassDescriptionData() + val actual = listOfNotNull(descriptorData) + return Class( + dri = driWithPlatform.dri, + name = descriptor.name.asString(), + kind = KotlinClassKindTypes.valueOf(descriptor.kind.toString()), + constructors = descriptor.constructors.map { + visitConstructorDescriptor( + it, + if (it.isPrimary) + DRIWithPlatformInfo( + driWithPlatform.dri, + expected?.info.filterTagWrappers(listOf(Constructor::class)), + actual.filterTagWrappers(listOf(Constructor::class)) + ) + else + DRIWithPlatformInfo(driWithPlatform.dri, null, emptyList()) + ) + }, + functions = scope.functions(driWithPlatform), + properties = scope.properties(driWithPlatform), + classlikes = scope.classlikes(driWithPlatform), + expected = expected, + actual = actual, + extra = mutableSetOf(), // TODO Implement following method to return proper results getXMLDRIs(descriptor, descriptorData).toMutableSet() + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRIWithPlatformInfo): Property { + val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData() + val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) + val dri = parent.dri.copy(callable = Callable.from(descriptor)) + + return Property( + dri = dri, + name = descriptor.name.asString(), + receiver = descriptor.extensionReceiverParameter?.let { + visitReceiverParameterDescriptor( + it, + DRIWithPlatformInfo( + dri, + expected?.filterTagWrappers(listOf(Receiver::class)), + actual.filterTagWrappers(listOf(Receiver::class)) + ) + ) + }, + expected = expected, + actual = actual, + accessors = descriptor.accessors.map { visitPropertyAccessorDescriptor(it, descriptor, dri) }, + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): Function { + val expected = descriptor.takeIf { it.isExpect }?.resolveDescriptorData() + val actual = listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) + val dri = parent.dri.copy(callable = Callable.from(descriptor)) + + return Function( + dri = dri, + name = descriptor.name.asString(), + returnType = descriptor.returnType?.let { KotlinTypeWrapper(it) }, + isConstructor = false, + receiver = descriptor.extensionReceiverParameter?.let { + visitReceiverParameterDescriptor( + it, + DRIWithPlatformInfo( + dri, + expected?.filterTagWrappers(listOf(Receiver::class)), + actual.filterTagWrappers(listOf(Receiver::class)) + ) + ) + }, + parameters = descriptor.valueParameters.mapIndexed { index, desc -> + parameter( + index, desc, + DRIWithPlatformInfo( + dri, + expected.filterTagWrappers(listOf(Param::class), desc.name.asString()), + actual.filterTagWrappers(listOf(Param::class), desc.name.asString()) + ) + ) + }, + expected = expected, + actual = actual, + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, parent: DRIWithPlatformInfo): Function { + val dri = parent.dri.copy(callable = Callable.from(descriptor)) + return Function( + dri = dri, + name = "", + returnType = KotlinTypeWrapper(descriptor.returnType), + isConstructor = true, + receiver = null, + parameters = descriptor.valueParameters.mapIndexed { index, desc -> + parameter( + index, desc, + DRIWithPlatformInfo( + dri, + parent.expected.filterTagWrappers(listOf(Param::class)), + parent.actual.filterTagWrappers(listOf(Param::class)) + ) + ) + }, + expected = parent.expected ?: descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), + actual = parent.actual, + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + override fun visitReceiverParameterDescriptor( + descriptor: ReceiverParameterDescriptor, + parent: DRIWithPlatformInfo + ) = Parameter( + dri = parent.dri.copy(target = 0), + name = null, + type = KotlinTypeWrapper(descriptor.type), + expected = parent.expected, + actual = parent.actual + ) + + open fun visitPropertyAccessorDescriptor( + descriptor: PropertyAccessorDescriptor, + propertyDescriptor: PropertyDescriptor, + parent: DRI + ): Function { + val dri = parent.copy(callable = Callable.from(descriptor)) + val isGetter = descriptor is PropertyGetterDescriptor + + fun PropertyDescriptor.asParameter(parent: DRI) = + Parameter( + parent.copy(target = 1), + this.name.asString(), + KotlinTypeWrapper(this.type), + descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), + listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()) + ) + + val name = run { + val modifier = if (isGetter) "get" else "set" + val rawName = propertyDescriptor.name.asString() + "$modifier${rawName[0].toUpperCase()}${rawName.drop(1)}" + } + + descriptor.visibility + val parameters = + if (isGetter) { + emptyList() + } else { + listOf(propertyDescriptor.asParameter(dri)) + } + + return Function( + dri, + name, + descriptor.returnType?.let { KotlinTypeWrapper(it) }, + false, + null, + parameters, + descriptor.takeIf { it.isExpect }?.resolveDescriptorData(), + listOfNotNull(descriptor.takeUnless { it.isExpect }?.resolveDescriptorData()), + visibility = mapOf(platformData to descriptor.visibility) + ) + } + + private fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRIWithPlatformInfo) = + Parameter( + dri = parent.dri.copy(target = index + 1), + name = descriptor.name.asString(), + type = KotlinTypeWrapper(descriptor.type), + expected = parent.expected, + actual = parent.actual + ) + + private fun MemberScope.functions(parent: DRIWithPlatformInfo): List = + getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) { true } + .filterIsInstance() + .map { visitFunctionDescriptor(it, parent) } + + private fun MemberScope.properties(parent: DRIWithPlatformInfo): List = + getContributedDescriptors(DescriptorKindFilter.VALUES) { true } + .filterIsInstance() + .map { visitPropertyDescriptor(it, parent) } + + private fun MemberScope.classlikes(parent: DRIWithPlatformInfo): List = + getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { true } + .filterIsInstance() + .map { visitClassDescriptor(it, parent) } + + private fun DeclarationDescriptor.resolveDescriptorData(): PlatformInfo { + val doc = findKDoc() + val parser = MarkdownParser(resolutionFacade, this) + val docHeader = parser.parseFromKDocTag(doc) + + return BasePlatformInfo(docHeader, listOf(platformData)) + } + + private fun ClassDescriptor.resolveClassDescriptionData(): ClassPlatformInfo { + return ClassPlatformInfo(resolveDescriptorData(), + (getSuperInterfaces() + getAllSuperclassesWithoutAny()).map { DRI.from(it) }) + } + + private fun PlatformInfo?.filterTagWrappers( + types: List>, + name: String? = null + ): PlatformInfo? { + if (this == null) + return null + return BasePlatformInfo( + DocumentationNode( + this.documentationNode.children.filter { it::class in types && (it as? NamedTagWrapper)?.name == name } + ), + this.platformData + ) + } + + private fun List.filterTagWrappers( + types: List>, + name: String? = null + ): List = + this.map { it.filterTagWrappers(types, name)!! } +} + diff --git a/plugins/kotlin-as-java/build.gradle.kts b/plugins/kotlin-as-java/build.gradle.kts index 3b281d53..32f9c931 100644 --- a/plugins/kotlin-as-java/build.gradle.kts +++ b/plugins/kotlin-as-java/build.gradle.kts @@ -5,4 +5,8 @@ publishing { from(components["java"]) } } +} + +dependencies { + implementation(project(":plugins:base")) } \ No newline at end of file diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaDescriptorToDocumentationTranslator.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaDescriptorToDocumentationTranslator.kt index 9c4ee9aa..1edf4aa1 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaDescriptorToDocumentationTranslator.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaDescriptorToDocumentationTranslator.kt @@ -1,6 +1,9 @@ package org.jetbrains.dokka.kotlinAsJava import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.base.transformers.descriptors.DRIWithPlatformInfo +import org.jetbrains.dokka.base.transformers.descriptors.DokkaDescriptorVisitor +import org.jetbrains.dokka.base.transformers.descriptors.withEmptyInfo import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.withClass @@ -8,18 +11,16 @@ import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Function import org.jetbrains.dokka.pages.PlatformData import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.transformers.descriptors.DRIWithPlatformInfo import org.jetbrains.dokka.transformers.descriptors.DescriptorToDocumentationTranslator -import org.jetbrains.dokka.transformers.descriptors.DokkaDescriptorVisitor -import org.jetbrains.dokka.transformers.descriptors.withEmptyInfo import org.jetbrains.kotlin.descriptors.* -object KotlinAsJavaDescriptorToDocumentationTranslator : DescriptorToDocumentationTranslator { +class KotlinAsJavaDescriptorToDocumentationTranslator( + private val context: DokkaContext +) : DescriptorToDocumentationTranslator { override fun invoke( moduleName: String, packageFragments: Iterable, - platformData: PlatformData, - context: DokkaContext + platformData: PlatformData ): Module = KotlinAsJavaDokkaDescriptorVisitor(platformData, context.platforms[platformData]?.facade!!).run { packageFragments.map { visitPackageFragmentDescriptor(it, DRI.topLevel.withEmptyInfo()) } diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageBuilder.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageBuilder.kt index 8f026477..6fe10ce1 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageBuilder.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageBuilder.kt @@ -9,7 +9,6 @@ import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Enum import org.jetbrains.dokka.model.Function import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.transformers.descriptors.KotlinClassKindTypes import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageContentBuilder.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageContentBuilder.kt index 05896d11..a5d0bd33 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageContentBuilder.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPageContentBuilder.kt @@ -2,8 +2,8 @@ package org.jetbrains.dokka.kotlinAsJava import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.Function +import org.jetbrains.dokka.model.JavaTypeWrapper import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.transformers.psi.JavaTypeWrapper import org.jetbrains.dokka.utilities.DokkaLogger class KotlinAsJavaPageContentBuilder( diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt index 345dc9be..e99e0843 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt @@ -12,8 +12,12 @@ import org.jetbrains.dokka.transformers.documentation.DocumentationToPageTransla import org.jetbrains.kotlin.descriptors.DeclarationDescriptor class KotlinAsJavaPlugin : DokkaPlugin() { - val kotlinAsJavaDescriptorToDocumentableTranslator by extending { CoreExtensions.descriptorToDocumentationTranslator with KotlinAsJavaDescriptorToDocumentationTranslator } - val kotlinAsJavaDocumentableToPageTranslator by extending { CoreExtensions.documentationToPageTranslator with KotlinAsJavaDocumentationToPageTranslator } + val kotlinAsJavaDescriptorToDocumentableTranslator by extending { + CoreExtensions.descriptorToDocumentationTranslator providing ::KotlinAsJavaDescriptorToDocumentationTranslator + } + val kotlinAsJavaDocumentableToPageTranslator by extending { + CoreExtensions.documentationToPageTranslator with KotlinAsJavaDocumentationToPageTranslator + } } object DescriptorCache { diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinToJVMResolver.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinToJVMResolver.kt index 87a173f3..7b0495e9 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinToJVMResolver.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinToJVMResolver.kt @@ -5,7 +5,6 @@ import org.jetbrains.dokka.links.* import org.jetbrains.dokka.model.* import org.jetbrains.dokka.model.Function import org.jetbrains.dokka.model.Enum -import org.jetbrains.dokka.transformers.psi.JavaTypeWrapper import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor -- cgit From e82beddda7b51f285f0422c6a7078a0a80d54d14 Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Thu, 13 Feb 2020 16:05:04 +0100 Subject: Adds option to mark extension as fallback --- core/src/main/kotlin/DokkaGenerator.kt | 1 - core/src/main/kotlin/plugability/DokkaContext.kt | 32 +++++++++++++--------- core/src/main/kotlin/plugability/DokkaPlugin.kt | 11 ++++++-- core/src/main/kotlin/plugability/extensions.kt | 28 ++++++++++++++----- core/src/main/kotlin/renderers/DefaultRenderer.kt | 1 - core/src/main/kotlin/renderers/OutputWriter.kt | 4 --- .../kotlin/resolvers/DefaultLocationProvider.kt | 2 -- .../DefaultDocumentationToPageTranslator.kt | 1 - plugins/base/src/main/kotlin/DokkaBase.kt | 2 +- .../src/main/kotlin/KotlinAsJavaPlugin.kt | 1 - 10 files changed, 49 insertions(+), 34 deletions(-) (limited to 'plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt') diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index 6a21e031..573ba13e 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -10,7 +10,6 @@ import org.jetbrains.dokka.pages.PlatformData import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.single import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index 6a8ac4a3..b4be5862 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -17,6 +17,8 @@ interface DokkaContext { operator fun get(point: E, askDefault: AskDefault = AskDefault.WhenEmpty): List where T : Any, E : ExtensionPoint + fun single(point: E): T where T : Any, E : ExtensionPoint + val logger: DokkaLogger val configuration: DokkaConfiguration val platforms: Map @@ -41,19 +43,6 @@ interface DokkaContext { } } -fun DokkaContext.single(point: E): T where T : Any, E : ExtensionPoint { - fun throwBadArity(substitution: String): Nothing = throw IllegalStateException( - "$point was expected to have exactly one extension registered, but $substitution found." - ) - - val extensions = get(point, AskDefault.WhenEmpty) - return when (extensions.size) { - 0 -> throwBadArity("none was") - 1 -> extensions.first() - else -> throwBadArity("multiple were") - } -} - interface DokkaContextConfiguration { fun addExtensionDependencies(extension: Extension<*>) } @@ -110,6 +99,23 @@ private class DokkaContextConfigurationImpl( actions(point)?.takeIf { it.isNotEmpty() } ?: DefaultExtensions.get(point, this) } as List + @Suppress("UNCHECKED_CAST") + override fun single(point: E): T where T : Any, E : ExtensionPoint { + fun throwBadArity(substitution: String): Nothing = throw IllegalStateException( + "$point was expected to have exactly one extension registered, but $substitution found." + ) + + val extensions = extensions[point].orEmpty() as List> + return when (extensions.size) { + 0 -> DefaultExtensions.get(point, this).single() ?: throwBadArity("none was") + 1 -> extensions.single().action.get(this) + else -> { + val notFallbacks = extensions.filterNot { it.isFallback } + if (notFallbacks.size == 1) notFallbacks.single().action.get(this) else throwBadArity("many were") + } + } + } + private fun > actions(point: E) = extensions[point]?.map { it.action.get(this) } @Suppress("UNCHECKED_CAST") diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index 1fcbd934..cdc92ca5 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -14,7 +14,7 @@ abstract class DokkaPlugin { internal var context: DokkaContext? = null protected inline fun plugin(): T = context?.plugin(T::class) - ?: throw IllegalStateException("Querying about plugins is only possible with dokka context initialised") + ?: throw IllegalStateException("Querying about plugins is only possible with dokka context initialised") protected fun extensionPoint() = object : ReadOnlyProperty> { @@ -24,7 +24,12 @@ abstract class DokkaPlugin { ) } - protected fun extending(definition: ExtendingDSL.() -> Extension) = ExtensionProvider(definition) + protected fun extending(isFallback: Boolean = false, definition: ExtendingDSL.() -> Extension) = + if (isFallback) { + ExtensionProvider { definition().markedAsFallback() } + } else { + ExtensionProvider(definition) + } protected class ExtensionProvider internal constructor( private val definition: ExtendingDSL.() -> Extension @@ -41,6 +46,6 @@ abstract class DokkaPlugin { extensionDelegates.asSequence() .filterIsInstance>>() // should be always true .map { it.get(this) } - .forEach { if(it.condition.invoke(configuration)) ctx.addExtensionDependencies(it) } + .forEach { if (it.condition.invoke(configuration)) ctx.addExtensionDependencies(it) } } } \ No newline at end of file diff --git a/core/src/main/kotlin/plugability/extensions.kt b/core/src/main/kotlin/plugability/extensions.kt index 4cbb61eb..46c356df 100644 --- a/core/src/main/kotlin/plugability/extensions.kt +++ b/core/src/main/kotlin/plugability/extensions.kt @@ -15,7 +15,8 @@ abstract class Extension internal constructor( internal val extensionName: String, internal val action: LazyEvaluated, internal val ordering: (OrderDsl.() -> Unit)? = null, - internal val condition: DokkaConfiguration.() -> Boolean = { true } + internal val condition: DokkaConfiguration.() -> Boolean = { true }, + internal val isFallback: Boolean ) { override fun toString() = "Extension: $pluginClass/$extensionName" @@ -26,6 +27,8 @@ abstract class Extension internal constructor( override fun hashCode() = listOf(pluginClass, extensionName).hashCode() abstract fun setCondition(condition: (DokkaConfiguration.() -> Boolean)): Extension + + abstract fun markedAsFallback(): Extension } class ExtensionOrdered internal constructor( @@ -34,17 +37,22 @@ class ExtensionOrdered internal constructor( extensionName: String, action: LazyEvaluated, ordering: (OrderDsl.() -> Unit), - condition: DokkaConfiguration.() -> Boolean = { true } + condition: DokkaConfiguration.() -> Boolean = { true }, + isFallback: Boolean = false ) : Extension( extensionPoint, pluginClass, extensionName, action, ordering, - condition + condition, + isFallback ) { override fun setCondition(condition: DokkaConfiguration.() -> Boolean) = ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, ordering!!, condition) + + override fun markedAsFallback() = + ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, ordering!!, condition, true) } class ExtensionUnordered internal constructor( @@ -52,17 +60,22 @@ class ExtensionUnordered internal constructor( pluginClass: String, extensionName: String, action: LazyEvaluated, - condition: DokkaConfiguration.() -> Boolean = { true } + condition: DokkaConfiguration.() -> Boolean = { true }, + isFallback: Boolean = false ) : Extension( extensionPoint, pluginClass, extensionName, action, null, - condition + condition, + isFallback ) { override fun setCondition(condition: DokkaConfiguration.() -> Boolean) = ExtensionUnordered(extensionPoint, pluginClass, extensionName, action, condition) + + override fun markedAsFallback() = + ExtensionUnordered(extensionPoint, pluginClass, extensionName, action, condition, true) } internal data class Ordering(val previous: Set>, val following: Set>) @@ -79,10 +92,11 @@ class ExtendingDSL(private val pluginClass: String, private val extensionName: S infix fun ExtensionPoint.providing(action: (DokkaContext) -> T) = ExtensionUnordered(this, this@ExtendingDSL.pluginClass, extensionName, LazyEvaluated.fromRecipe(action)) - infix fun ExtensionUnordered.order(block: OrderDsl.() -> Unit) = + infix fun ExtensionUnordered.order(block: OrderDsl.() -> Unit) = ExtensionOrdered(extensionPoint, pluginClass, extensionName, action, block) - infix fun Extension.applyIf(condition: DokkaConfiguration.() -> Boolean): Extension = this.setCondition(condition) + infix fun Extension.applyIf(condition: DokkaConfiguration.() -> Boolean): Extension = + this.setCondition(condition) } @ExtensionsDsl diff --git a/core/src/main/kotlin/renderers/DefaultRenderer.kt b/core/src/main/kotlin/renderers/DefaultRenderer.kt index 16cdb4c1..d09d9ded 100644 --- a/core/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/core/src/main/kotlin/renderers/DefaultRenderer.kt @@ -3,7 +3,6 @@ package org.jetbrains.dokka.renderers import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.single import org.jetbrains.dokka.resolvers.LocationProvider import org.jetbrains.dokka.transformers.pages.PageNodeTransformer diff --git a/core/src/main/kotlin/renderers/OutputWriter.kt b/core/src/main/kotlin/renderers/OutputWriter.kt index 30b2b0b6..e317f8ef 100644 --- a/core/src/main/kotlin/renderers/OutputWriter.kt +++ b/core/src/main/kotlin/renderers/OutputWriter.kt @@ -1,9 +1,5 @@ package org.jetbrains.dokka.renderers -import org.jetbrains.dokka.CoreExtensions -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.single - interface OutputWriter { fun write(path: String, text: String, ext: String) diff --git a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt index d30264bb..65d2f794 100644 --- a/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt +++ b/core/src/main/kotlin/resolvers/DefaultLocationProvider.kt @@ -1,10 +1,8 @@ package org.jetbrains.dokka.resolvers -import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.single import org.jetbrains.dokka.utilities.htmlEscape import java.util.* diff --git a/core/src/main/kotlin/transformers/documentation/DefaultDocumentationToPageTranslator.kt b/core/src/main/kotlin/transformers/documentation/DefaultDocumentationToPageTranslator.kt index 81c6dfea..c2a21150 100644 --- a/core/src/main/kotlin/transformers/documentation/DefaultDocumentationToPageTranslator.kt +++ b/core/src/main/kotlin/transformers/documentation/DefaultDocumentationToPageTranslator.kt @@ -6,7 +6,6 @@ import org.jetbrains.dokka.pages.DefaultPageBuilder import org.jetbrains.dokka.pages.DefaultPageContentBuilder import org.jetbrains.dokka.pages.ModulePageNode import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.single object DefaultDocumentationToPageTranslator : DocumentationToPageTranslator { diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 5c579e54..648acfbb 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -5,7 +5,7 @@ import org.jetbrains.dokka.base.transformers.descriptors.DefaultDescriptorToDocu import org.jetbrains.dokka.plugability.DokkaPlugin class DokkaBase: DokkaPlugin() { - val defaultDescriptorToDocumentationTranslator by extending { + val defaultDescriptorToDocumentationTranslator by extending(isFallback = true) { CoreExtensions.descriptorToDocumentationTranslator providing ::DefaultDescriptorToDocumentationTranslator } } \ No newline at end of file diff --git a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt index e99e0843..dd95f00e 100644 --- a/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt +++ b/plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt @@ -7,7 +7,6 @@ import org.jetbrains.dokka.model.Module import org.jetbrains.dokka.pages.ModulePageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.plugability.single import org.jetbrains.dokka.transformers.documentation.DocumentationToPageTranslator import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -- cgit From 3b200cf10e0c50c2eee4b9da3f7039d678fa4aad Mon Sep 17 00:00:00 2001 From: Paweł Marks Date: Sun, 16 Feb 2020 23:20:17 +0100 Subject: Renames DocumentationToPagesTranslatero and moves its implementation to base plugin --- core/src/main/kotlin/CoreExtensions.kt | 4 +- core/src/main/kotlin/DokkaGenerator.kt | 2 +- core/src/main/kotlin/pages/PageBuilder.kt | 158 --------------- core/src/main/kotlin/pages/PageContentBuilder.kt | 215 -------------------- .../main/kotlin/plugability/DefaultExtensions.kt | 2 - .../DefaultDocumentationToPageTranslator.kt | 23 --- .../documentation/DocumentablesToPageTranslator.kt | 9 + .../documentation/DocumentationToPageTranslator.kt | 9 - plugins/base/src/main/kotlin/DokkaBase.kt | 9 +- .../DefaultDocumentablesToPageTranslator.kt | 22 +++ .../transformers/documentables/PageBuilder.kt | 159 +++++++++++++++ .../documentables/PageContentBuilder.kt | 217 +++++++++++++++++++++ .../src/main/kotlin/KotlinAsJavaPageBuilder.kt | 2 + .../main/kotlin/KotlinAsJavaPageContentBuilder.kt | 17 +- .../src/main/kotlin/KotlinAsJavaPlugin.kt | 6 +- 15 files changed, 432 insertions(+), 422 deletions(-) delete mode 100644 core/src/main/kotlin/pages/PageBuilder.kt delete mode 100644 core/src/main/kotlin/pages/PageContentBuilder.kt delete mode 100644 core/src/main/kotlin/transformers/documentation/DefaultDocumentationToPageTranslator.kt create mode 100644 core/src/main/kotlin/transformers/documentation/DocumentablesToPageTranslator.kt delete mode 100644 core/src/main/kotlin/transformers/documentation/DocumentationToPageTranslator.kt create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentablesToPageTranslator.kt create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/PageBuilder.kt create mode 100644 plugins/base/src/main/kotlin/transformers/documentables/PageContentBuilder.kt (limited to 'plugins/kotlin-as-java/src/main/kotlin/KotlinAsJavaPlugin.kt') diff --git a/core/src/main/kotlin/CoreExtensions.kt b/core/src/main/kotlin/CoreExtensions.kt index 47f2e4c1..8ae333ee 100644 --- a/core/src/main/kotlin/CoreExtensions.kt +++ b/core/src/main/kotlin/CoreExtensions.kt @@ -8,7 +8,7 @@ import org.jetbrains.dokka.resolvers.LocationProviderFactory import org.jetbrains.dokka.transformers.descriptors.DescriptorToDocumentationTranslator import org.jetbrains.dokka.transformers.documentation.DocumentableMerger import org.jetbrains.dokka.transformers.documentation.DocumentationNodeTransformer -import org.jetbrains.dokka.transformers.documentation.DocumentationToPageTranslator +import org.jetbrains.dokka.transformers.documentation.DocumentablesToPageTranslator import org.jetbrains.dokka.transformers.pages.PageMergerStrategy import org.jetbrains.dokka.transformers.pages.PageNodeTransformer import org.jetbrains.dokka.transformers.psi.PsiToDocumentationTranslator @@ -25,7 +25,7 @@ object CoreExtensions { val documentableMerger by coreExtension() val documentationTransformer by coreExtension() val commentsToContentConverter by coreExtension() - val documentationToPageTranslator by coreExtension() + val documentablesToPageTranslator by coreExtension() val pageTransformer by coreExtension() val locationProviderFactory by coreExtension() val outputWriter by coreExtension() diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index 1829c9e4..1ad93f4f 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -88,7 +88,7 @@ class DokkaGenerator( fun createPages( transformedDocumentation: Module, context: DokkaContext - ) = context.single(CoreExtensions.documentationToPageTranslator).invoke(transformedDocumentation, context) + ) = context.single(CoreExtensions.documentablesToPageTranslator).invoke(transformedDocumentation, context) fun transformPages( pages: RootPageNode, diff --git a/core/src/main/kotlin/pages/PageBuilder.kt b/core/src/main/kotlin/pages/PageBuilder.kt deleted file mode 100644 index eb6f5e21..00000000 --- a/core/src/main/kotlin/pages/PageBuilder.kt +++ /dev/null @@ -1,158 +0,0 @@ -package org.jetbrains.dokka.pages - -import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.model.Enum -import org.jetbrains.dokka.model.Function -import org.jetbrains.dokka.model.doc.TagWrapper - -open class DefaultPageBuilder( - override val rootContentGroup: RootContentBuilder -) : PageBuilder { - - override fun pageForModule(m: Module): ModulePageNode = - ModulePageNode(m.name.ifEmpty { "root" }, contentForModule(m), m, m.packages.map { pageForPackage(it) }) - - override fun pageForPackage(p: Package) = - PackagePageNode(p.name, contentForPackage(p), setOf(p.dri), p, - p.classlikes.map { pageForClasslike(it) } + - p.functions.map { pageForMember(it) }) - - override fun pageForClasslike(c: Classlike): ClasslikePageNode { - val constructors = when (c) { - is Class -> c.constructors - is Enum -> c.constructors - else -> emptyList() - } - - return ClasslikePageNode(c.name, contentForClasslike(c), setOf(c.dri), c, - constructors.map { pageForMember(it) } + - c.classlikes.map { pageForClasslike(it) } + - c.functions.map { pageForMember(it) }) - } - - override fun pageForMember(m: CallableNode): MemberPageNode = - when (m) { - is Function -> - MemberPageNode(m.name, contentForFunction(m), setOf(m.dri), m) - else -> throw IllegalStateException("$m should not be present here") - } - - protected open fun group(node: Documentable, content: PageContentBuilderFunction) = - rootContentGroup(node, ContentKind.Main, content) - - protected open fun contentForModule(m: Module) = group(m) { - header(1) { text("root") } - block("Packages", 2, ContentKind.Packages, m.packages, m.platformData) { - link(it.name, it.dri) - } - text("Index\n") - text("Link to allpage here") - } - - protected open fun contentForPackage(p: Package) = group(p) { - header(1) { text("Package ${p.name}") } - block("Types", 2, ContentKind.Properties, p.classlikes, p.platformData) { - link(it.name, it.dri) - text(it.briefDocTagString) - } - block("Functions", 2, ContentKind.Functions, p.functions, p.platformData) { - link(it.name, it.dri) - signature(it) - text(it.briefDocTagString) - } - } - - open fun contentForClasslike(c: Classlike): ContentGroup = when (c) { - is Class -> contentForClass(c) - is Enum -> contentForEnum(c) - else -> throw IllegalStateException("$c should not be present here") - } - - protected fun contentForClass(c: Class) = group(c) { - header(1) { text(c.name) } - - c.inherited.takeIf { it.isNotEmpty() }?.let { - header(2) { text("SuperInterfaces") } - linkTable(it) - } - contentForComments(c) - block("Constructors", 2, ContentKind.Functions, c.constructors, c.platformData) { - link(it.name, it.dri) - signature(it) - text(it.briefDocTagString) - } - block("Functions", 2, ContentKind.Functions, c.functions, c.platformData) { - link(it.name, it.dri) - signature(it) - text(it.briefDocTagString) - } - block("Properties", 2, ContentKind.Properties, c.properties, c.platformData) { - link(it.name, it.dri) - text(it.briefDocTagString) - - } - } - - fun contentForEnum(c: Enum): ContentGroup = group(c) { - header(1) { text("enum ${c.name}") } - - block("Entries", 2, ContentKind.Properties, c.entries, c.platformData) { entry -> - link(entry.name, entry.dri) - contentForComments(entry) - } - - c.inherited.takeIf { it.isNotEmpty() }?.let { - header(2) { text("SuperInterfaces") } - linkTable(it) - } - contentForComments(c) - block("Constructors", 2, ContentKind.Functions, c.constructors, c.platformData) { - link(it.name, it.dri) - signature(it) - text(it.briefDocTagString) - } - block("Functions", 2, ContentKind.Functions, c.functions, c.platformData) { - link(it.name, it.dri) - signature(it) - text(it.briefDocTagString) - } - block("Properties", 2, ContentKind.Properties, c.properties, c.platformData) { - link(it.name, it.dri) - text(it.briefDocTagString) - } - } - - private fun PageContentBuilder.contentForComments(d: Documentable) = - d.platformInfo.forEach { platformInfo -> - platformInfo.documentationNode.children.forEach { - header(3) { - text(it.toHeaderString()) - text(" [${platformInfo.platformData.joinToString(", ") { it.platformType.name }}]") - } - comment(it.root) - text("\n") - } - } - - private fun contentForFunction(f: Function) = group(f) { - header(1) { text(f.name) } - signature(f) - contentForComments(f) - block("Parameters", 2, ContentKind.Parameters, f.children, f.platformData) { - text(it.name ?: "") - it.platformInfo.forEach { it.documentationNode.children.forEach { comment(it.root) } } - } - } - - private fun TagWrapper.toHeaderString() = this.javaClass.toGenericString().split('.').last() -} - -typealias RootContentBuilder = (Documentable, Kind, PageContentBuilderFunction) -> ContentGroup - -interface PageBuilder { - val rootContentGroup: RootContentBuilder - fun pageForModule(m: Module): ModulePageNode - fun pageForPackage(p: Package): PackagePageNode - fun pageForMember(m: CallableNode): MemberPageNode - fun pageForClasslike(c: Classlike): ClasslikePageNode -} \ No newline at end of file diff --git a/core/src/main/kotlin/pages/PageContentBuilder.kt b/core/src/main/kotlin/pages/PageContentBuilder.kt deleted file mode 100644 index ed0a0fea..00000000 --- a/core/src/main/kotlin/pages/PageContentBuilder.kt +++ /dev/null @@ -1,215 +0,0 @@ -package org.jetbrains.dokka.pages - -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.model.Documentable -import org.jetbrains.dokka.model.Function -import org.jetbrains.dokka.model.Parameter -import org.jetbrains.dokka.model.TypeWrapper -import org.jetbrains.dokka.model.doc.DocTag -import org.jetbrains.dokka.utilities.DokkaLogger - -open class DefaultPageContentBuilder( - private val dri: Set, - private val platformData: Set, - private val kind: Kind, - private val commentsConverter: CommentsToContentConverter, - open val logger: DokkaLogger, - private val styles: Set