From 7acc52ba723eab08fe796fcfd68755e7f0eb6a66 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sat, 2 Dec 2017 00:50:08 +0300 Subject: WIP: Refactoring, remove LocationService, rework FormatDescriptor --- core/src/main/kotlin/Formats/FormatDescriptor.kt | 38 +++++++++-- core/src/main/kotlin/Formats/GFMFormatService.kt | 46 ++++++------- core/src/main/kotlin/Formats/HtmlFormatService.kt | 13 ++-- .../src/main/kotlin/Formats/HtmlTemplateService.kt | 2 +- .../main/kotlin/Formats/JavaLayoutHtmlFormat.kt | 22 ++++-- .../src/main/kotlin/Formats/JekyllFormatService.kt | 26 +++---- .../kotlin/Formats/KotlinWebsiteFormatService.kt | 67 +++++++++--------- .../Formats/KotlinWebsiteHtmlFormatService.kt | 26 +++---- .../main/kotlin/Formats/MarkdownFormatService.kt | 14 ++-- core/src/main/kotlin/Formats/PackageListService.kt | 9 ++- core/src/main/kotlin/Formats/StandardFormats.kt | 8 +-- .../main/kotlin/Formats/StructuredFormatService.kt | 19 +++--- core/src/main/kotlin/Formats/YamlOutlineService.kt | 8 ++- .../src/main/kotlin/Generation/ConsoleGenerator.kt | 42 ------------ core/src/main/kotlin/Generation/FileGenerator.kt | 17 +++-- core/src/main/kotlin/Generation/Generator.kt | 5 ++ .../kotlin/Locations/FoldersLocationService.kt | 40 ++++------- core/src/main/kotlin/Locations/LocationService.kt | 79 ++++++++++++++-------- .../Locations/SingleFolderLocationService.kt | 30 ++++---- core/src/main/kotlin/Utilities/DokkaModules.kt | 46 ++++++------- 20 files changed, 291 insertions(+), 266 deletions(-) delete mode 100644 core/src/main/kotlin/Generation/ConsoleGenerator.kt (limited to 'core/src/main/kotlin') diff --git a/core/src/main/kotlin/Formats/FormatDescriptor.kt b/core/src/main/kotlin/Formats/FormatDescriptor.kt index da0156a7..fc0c4417 100644 --- a/core/src/main/kotlin/Formats/FormatDescriptor.kt +++ b/core/src/main/kotlin/Formats/FormatDescriptor.kt @@ -1,17 +1,47 @@ package org.jetbrains.dokka.Formats +import com.google.inject.Binder import org.jetbrains.dokka.* import org.jetbrains.dokka.Model.DescriptorSignatureProvider import org.jetbrains.dokka.Samples.SampleProcessingService +import org.jetbrains.dokka.Utilities.bind +import org.jetbrains.dokka.Utilities.toOptional +import org.jetbrains.dokka.Utilities.toType import kotlin.reflect.KClass interface FormatDescriptor { - val formatServiceClass: KClass? - val outlineServiceClass: KClass? - val generatorServiceClass: KClass + fun configureAnalysis(binder: Binder) + fun configureOutput(binder: Binder) +} + +interface FormatDescriptorAnalysisComponentProvider : FormatDescriptor { + val packageDocumentationBuilderClass: KClass val javaDocumentationBuilderClass: KClass val sampleProcessingService: KClass - val packageListServiceClass: KClass? val descriptorSignatureProvider: KClass + + + override fun configureAnalysis(binder: Binder): Unit = with(binder) { + bind() toType descriptorSignatureProvider + bind() toType packageDocumentationBuilderClass + bind() toType javaDocumentationBuilderClass + bind() toType sampleProcessingService + } } + +abstract class FileGeneratorBasedFormatDescriptor : FormatDescriptor, FormatDescriptorAnalysisComponentProvider { + + override fun configureOutput(binder: Binder): Unit = with(binder) { + bind() toOptional (outlineServiceClass) + bind() toOptional formatServiceClass + bind() toType generatorServiceClass + //bind() toType generatorServiceClass + bind() toOptional packageListServiceClass + } + + abstract val formatServiceClass: KClass? + abstract val outlineServiceClass: KClass? + abstract val generatorServiceClass: KClass + abstract val packageListServiceClass: KClass? +} \ No newline at end of file diff --git a/core/src/main/kotlin/Formats/GFMFormatService.kt b/core/src/main/kotlin/Formats/GFMFormatService.kt index f741561c..036ec856 100644 --- a/core/src/main/kotlin/Formats/GFMFormatService.kt +++ b/core/src/main/kotlin/Formats/GFMFormatService.kt @@ -4,14 +4,14 @@ import com.google.inject.Inject import com.google.inject.name.Named import org.jetbrains.dokka.Utilities.impliedPlatformsName -open class GFMOutputBuilder(to: StringBuilder, - location: Location, - locationService: LocationService, - languageService: LanguageService, - extension: String, - impliedPlatforms: List) - : MarkdownOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) -{ +open class GFMOutputBuilder( + to: StringBuilder, + location: Location, + generator: NodeLocationAwareGenerator, + languageService: LanguageService, + extension: String, + impliedPlatforms: List +) : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { override fun appendTable(vararg columns: String, body: () -> Unit) { to.appendln(columns.joinToString(" | ", "| ", " |")) to.appendln("|" + "---|".repeat(columns.size)) @@ -21,8 +21,7 @@ open class GFMOutputBuilder(to: StringBuilder, override fun appendUnorderedList(body: () -> Unit) { if (inTableCell) { wrapInTag("ul", body) - } - else { + } else { super.appendUnorderedList(body) } } @@ -30,8 +29,7 @@ open class GFMOutputBuilder(to: StringBuilder, override fun appendOrderedList(body: () -> Unit) { if (inTableCell) { wrapInTag("ol", body) - } - else { + } else { super.appendOrderedList(body) } } @@ -39,23 +37,25 @@ open class GFMOutputBuilder(to: StringBuilder, override fun appendListItem(body: () -> Unit) { if (inTableCell) { wrapInTag("li", body) - } - else { + } else { super.appendListItem(body) } } } -open class GFMFormatService(locationService: LocationService, - signatureGenerator: LanguageService, - linkExtension: String, - impliedPlatforms: List) -: MarkdownFormatService(locationService, signatureGenerator, linkExtension, impliedPlatforms) { +open class GFMFormatService( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + linkExtension: String, + impliedPlatforms: List +) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) { - @Inject constructor(locationService: LocationService, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List) : this(locationService, signatureGenerator, "md", impliedPlatforms) + @Inject constructor( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + @Named(impliedPlatformsName) impliedPlatforms: List + ) : this(generator, signatureGenerator, "md", impliedPlatforms) override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - GFMOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + GFMOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } diff --git a/core/src/main/kotlin/Formats/HtmlFormatService.kt b/core/src/main/kotlin/Formats/HtmlFormatService.kt index 5e05f51a..560d8597 100644 --- a/core/src/main/kotlin/Formats/HtmlFormatService.kt +++ b/core/src/main/kotlin/Formats/HtmlFormatService.kt @@ -5,16 +5,15 @@ import com.google.inject.name.Named import org.jetbrains.dokka.Utilities.impliedPlatformsName import java.io.File import java.nio.file.Path -import java.nio.file.Paths open class HtmlOutputBuilder(to: StringBuilder, location: Location, - locationService: LocationService, + generator: NodeLocationAwareGenerator, languageService: LanguageService, extension: String, impliedPlatforms: List, val templateService: HtmlTemplateService) - : StructuredOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { override fun appendText(text: String) { to.append(text.htmlEscape()) @@ -95,18 +94,18 @@ open class HtmlOutputBuilder(to: StringBuilder, } } -open class HtmlFormatService @Inject constructor(@Named("folders") locationService: LocationService, +open class HtmlFormatService @Inject constructor(generator: NodeLocationAwareGenerator, signatureGenerator: LanguageService, val templateService: HtmlTemplateService, @Named(impliedPlatformsName) val impliedPlatforms: List) -: StructuredFormatService(locationService, signatureGenerator, "html"), OutlineFormatService { +: StructuredFormatService(generator, signatureGenerator, "html"), OutlineFormatService { override fun enumerateSupportFiles(callback: (String, String) -> Unit) { callback("/dokka/styles/style.css", "style.css") } override fun createOutputBuilder(to: StringBuilder, location: Location) = - HtmlOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms, templateService) + HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) override fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable) { templateService.appendHeader(to, "Module Contents", locationService.calcPathToRoot(location)) @@ -123,7 +122,7 @@ open class HtmlFormatService @Inject constructor(@Named("folders") locationServi link.append(languageService.render(node, LanguageService.RenderMode.FULL)) val tempBuilder = StringBuilder() createOutputBuilder(tempBuilder, location).appendContent(link) - to.appendln("${tempBuilder.toString()}
") + to.appendln("$tempBuilder
") } override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) { diff --git a/core/src/main/kotlin/Formats/HtmlTemplateService.kt b/core/src/main/kotlin/Formats/HtmlTemplateService.kt index 010bc702..22832e34 100644 --- a/core/src/main/kotlin/Formats/HtmlTemplateService.kt +++ b/core/src/main/kotlin/Formats/HtmlTemplateService.kt @@ -16,7 +16,7 @@ interface HtmlTemplateService { to.appendln("") to.appendln("") } - override fun appendHeader(to: StringBuilder, title: String?, basePath: Path) { + override fun appendHeader(to: StringBuilder, title: String?, relativePathToRoot: String) { to.appendln("") to.appendln("") to.appendln("") diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt index 832c466e..9fb72e37 100644 --- a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt +++ b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt @@ -1,16 +1,30 @@ package org.jetbrains.dokka.Formats +import com.google.inject.Binder import com.google.inject.Inject import kotlinx.html.li import kotlinx.html.stream.appendHTML import kotlinx.html.ul import org.jetbrains.dokka.* +import org.jetbrains.dokka.Kotlin.KotlinDescriptorSignatureProvider +import org.jetbrains.dokka.Samples.DefaultSampleProcessingService +import org.jetbrains.dokka.Utilities.bind +import org.jetbrains.dokka.Utilities.toType import java.io.File -class JavaLayoutHtmlFormatDescriptor : KotlinFormatDescriptorBase() { - override val formatServiceClass = JavaLayoutHtmlFormatService::class - override val generatorServiceClass = JavaLayoutHtmlFormatGenerator::class +class JavaLayoutHtmlFormatDescriptor : FormatDescriptor, FormatDescriptorAnalysisComponentProvider { + override val packageDocumentationBuilderClass = KotlinPackageDocumentationBuilder::class + override val javaDocumentationBuilderClass = KotlinJavaDocumentationBuilder::class + override val sampleProcessingService = DefaultSampleProcessingService::class + override val descriptorSignatureProvider = KotlinDescriptorSignatureProvider::class + + override fun configureOutput(binder: Binder): Unit = with(binder) { + bind() toType generatorServiceClass + } + + val formatServiceClass = JavaLayoutHtmlFormatService::class + val generatorServiceClass = JavaLayoutHtmlFormatGenerator::class } @@ -31,7 +45,7 @@ class JavaLayoutHtmlFormatOutputBuilder : FormattedOutputBuilder { } -class JavaLayoutHtmlFormatNavListBuilder @Inject constructor(private val locationService: LocationService) : OutlineFormatService { +class JavaLayoutHtmlFormatNavListBuilder @Inject constructor() : OutlineFormatService { override fun getOutlineFileName(location: Location): File { TODO() } diff --git a/core/src/main/kotlin/Formats/JekyllFormatService.kt b/core/src/main/kotlin/Formats/JekyllFormatService.kt index 6b97bbe0..a948dfa9 100644 --- a/core/src/main/kotlin/Formats/JekyllFormatService.kt +++ b/core/src/main/kotlin/Formats/JekyllFormatService.kt @@ -6,12 +6,11 @@ import org.jetbrains.dokka.Utilities.impliedPlatformsName open class JekyllOutputBuilder(to: StringBuilder, location: Location, - locationService: LocationService, + generator: NodeLocationAwareGenerator, languageService: LanguageService, extension: String, impliedPlatforms: List) - : MarkdownOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) -{ + : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { override fun appendNodes(nodes: Iterable) { to.appendln("---") appendFrontMatter(nodes, to) @@ -26,17 +25,20 @@ open class JekyllOutputBuilder(to: StringBuilder, } -open class JekyllFormatService(locationService: LocationService, - signatureGenerator: LanguageService, - linkExtension: String, - impliedPlatforms: List) -: MarkdownFormatService(locationService, signatureGenerator, linkExtension, impliedPlatforms) { +open class JekyllFormatService( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + linkExtension: String, + impliedPlatforms: List +) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) { - @Inject constructor(locationService: LocationService, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List): this(locationService, signatureGenerator, "html", impliedPlatforms) + @Inject constructor( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + @Named(impliedPlatformsName) impliedPlatforms: List + ) : this(generator, signatureGenerator, "html", impliedPlatforms) override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - JekyllOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + JekyllOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt index 08349980..a98002d4 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteFormatService.kt @@ -6,14 +6,14 @@ import org.jetbrains.dokka.Utilities.impliedPlatformsName import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty -open class KotlinWebsiteOutputBuilder(to: StringBuilder, - location: Location, - locationService: LocationService, - languageService: LanguageService, - extension: String, - impliedPlatforms: List) - : JekyllOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) -{ +open class KotlinWebsiteOutputBuilder( + to: StringBuilder, + location: Location, + generator: NodeLocationAwareGenerator, + languageService: LanguageService, + extension: String, + impliedPlatforms: List +) : JekyllOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { private var needHardLineBreaks = false private var insideDiv = 0 @@ -70,8 +70,7 @@ open class KotlinWebsiteOutputBuilder(to: StringBuilder, override fun appendHeader(level: Int, body: () -> Unit) { if (insideDiv > 0) { wrapInTag("p", body, newlineAfterClose = true) - } - else { + } else { super.appendHeader(level, body) } } @@ -79,8 +78,7 @@ open class KotlinWebsiteOutputBuilder(to: StringBuilder, override fun appendLine() { if (insideDiv > 0) { to.appendln("
") - } - else { + } else { super.appendLine() } } @@ -135,13 +133,14 @@ open class KotlinWebsiteOutputBuilder(to: StringBuilder, to.append("
") } + override fun appendIndentedSoftLineBreak() { if (needHardLineBreaks) { to.append("
    ") } } - private fun identifierClassName(kind: IdentifierKind) = when(kind) { + private fun identifierClassName(kind: IdentifierKind) = when (kind) { IdentifierKind.ParameterName -> "parameterName" IdentifierKind.SummarizedTypeName -> "summarizedTypeName" else -> "identifier" @@ -172,28 +171,29 @@ open class KotlinWebsiteOutputBuilder(to: StringBuilder, } } -class KotlinWebsiteFormatService @Inject constructor(locationService: LocationService, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List, - logger: DokkaLogger) - : JekyllFormatService(locationService, signatureGenerator, "html", impliedPlatforms) -{ +class KotlinWebsiteFormatService @Inject constructor( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + @Named(impliedPlatformsName) impliedPlatforms: List, + logger: DokkaLogger +) : JekyllFormatService(generator, signatureGenerator, "html", impliedPlatforms) { init { logger.warn("Format kotlin-website deprecated and will be removed in next release") } override fun createOutputBuilder(to: StringBuilder, location: Location) = - KotlinWebsiteOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + KotlinWebsiteOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } -class KotlinWebsiteRunnableSamplesOutputBuilder(to: StringBuilder, - location: Location, - locationService: LocationService, - languageService: LanguageService, - extension: String, - impliedPlatforms: List) - : KotlinWebsiteOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) { +class KotlinWebsiteRunnableSamplesOutputBuilder( + to: StringBuilder, + location: Location, + generator: NodeLocationAwareGenerator, + languageService: LanguageService, + extension: String, + impliedPlatforms: List +) : KotlinWebsiteOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { override fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) { div(to, "sample", markdown = true) { @@ -207,17 +207,18 @@ class KotlinWebsiteRunnableSamplesOutputBuilder(to: StringBuilder, } } -class KotlinWebsiteRunnableSamplesFormatService @Inject constructor(locationService: LocationService, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List, - logger: DokkaLogger) - : JekyllFormatService(locationService, signatureGenerator, "html", impliedPlatforms) { +class KotlinWebsiteRunnableSamplesFormatService @Inject constructor( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + @Named(impliedPlatformsName) impliedPlatforms: List, + logger: DokkaLogger +) : JekyllFormatService(generator, signatureGenerator, "html", impliedPlatforms) { init { logger.warn("Format kotlin-website-samples deprecated and will be removed in next release") } override fun createOutputBuilder(to: StringBuilder, location: Location) = - KotlinWebsiteRunnableSamplesOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + KotlinWebsiteRunnableSamplesOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt index 378401f3..8fd53cdd 100644 --- a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt +++ b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt @@ -14,13 +14,14 @@ private object EmptyHtmlTemplateService : HtmlTemplateService { } -open class KotlinWebsiteHtmlOutputBuilder(to: StringBuilder, - location: Location, - locationService: LocationService, - languageService: LanguageService, - extension: String, - impliedPlatforms: List) - : HtmlOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms, EmptyHtmlTemplateService) { +open class KotlinWebsiteHtmlOutputBuilder( + to: StringBuilder, + location: Location, + generator: NodeLocationAwareGenerator, + languageService: LanguageService, + extension: String, + impliedPlatforms: List +) : HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, EmptyHtmlTemplateService) { private var needHardLineBreaks = false private var insideDiv = 0 @@ -169,14 +170,15 @@ open class KotlinWebsiteHtmlOutputBuilder(to: StringBuilder, } } -class KotlinWebsiteHtmlFormatService @Inject constructor(locationService: LocationService, - signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List) - : HtmlFormatService(locationService, signatureGenerator, EmptyHtmlTemplateService, impliedPlatforms) { +class KotlinWebsiteHtmlFormatService @Inject constructor( + generator: NodeLocationAwareGenerator, + signatureGenerator: LanguageService, + @Named(impliedPlatformsName) impliedPlatforms: List +) : HtmlFormatService(generator, signatureGenerator, EmptyHtmlTemplateService, impliedPlatforms) { override fun enumerateSupportFiles(callback: (String, String) -> Unit) {} override fun createOutputBuilder(to: StringBuilder, location: Location) = - KotlinWebsiteHtmlOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + KotlinWebsiteHtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } diff --git a/core/src/main/kotlin/Formats/MarkdownFormatService.kt b/core/src/main/kotlin/Formats/MarkdownFormatService.kt index a7c18a28..4265394f 100644 --- a/core/src/main/kotlin/Formats/MarkdownFormatService.kt +++ b/core/src/main/kotlin/Formats/MarkdownFormatService.kt @@ -21,11 +21,11 @@ private val TWO_LINE_BREAKS = System.lineSeparator() + System.lineSeparator() open class MarkdownOutputBuilder(to: StringBuilder, location: Location, - locationService: LocationService, + generator: NodeLocationAwareGenerator, languageService: LanguageService, extension: String, impliedPlatforms: List) - : StructuredOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) { private val listStack = ArrayDeque() protected var inTableCell = false @@ -225,15 +225,15 @@ open class MarkdownOutputBuilder(to: StringBuilder, } } -open class MarkdownFormatService(locationService: LocationService, +open class MarkdownFormatService(generator: NodeLocationAwareGenerator, signatureGenerator: LanguageService, linkExtension: String, val impliedPlatforms: List) -: StructuredFormatService(locationService, signatureGenerator, "md", linkExtension) { - @Inject constructor(locationService: LocationService, +: StructuredFormatService(generator, signatureGenerator, "md", linkExtension) { + @Inject constructor(generator: NodeLocationAwareGenerator, signatureGenerator: LanguageService, - @Named(impliedPlatformsName) impliedPlatforms: List): this(locationService, signatureGenerator, "md", impliedPlatforms) + @Named(impliedPlatformsName) impliedPlatforms: List): this(generator, signatureGenerator, "md", impliedPlatforms) override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder = - MarkdownOutputBuilder(to, location, locationService, languageService, extension, impliedPlatforms) + MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) } diff --git a/core/src/main/kotlin/Formats/PackageListService.kt b/core/src/main/kotlin/Formats/PackageListService.kt index e7f4e952..be50fac4 100644 --- a/core/src/main/kotlin/Formats/PackageListService.kt +++ b/core/src/main/kotlin/Formats/PackageListService.kt @@ -7,10 +7,9 @@ interface PackageListService { fun formatPackageList(module: DocumentationModule): String } -class DefaultPackageListService @Inject constructor(locationService: FileLocationService, - val formatService: FormatService) : PackageListService { - - val locationService: FileLocationService = locationService.withExtension(formatService.linkExtension) +class DefaultPackageListService @Inject constructor( + val generator: FileGenerator, + val formatService: FormatService) : PackageListService { override fun formatPackageList(module: DocumentationModule): String { val packages = mutableSetOf() @@ -26,7 +25,7 @@ class DefaultPackageListService @Inject constructor(locationService: FileLocatio } NodeKind.Signature -> { if (relocated) - nonStandardLocations[node.name] = locationService.relativePathToLocation(module, node.owner!!) + nonStandardLocations[node.name] = generator.relativePathToLocation(module, node.owner!!) } NodeKind.ExternalClass -> { node.members.forEach { visit(it, relocated = true) } diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt index c0c86f06..54544ebc 100644 --- a/core/src/main/kotlin/Formats/StandardFormats.kt +++ b/core/src/main/kotlin/Formats/StandardFormats.kt @@ -3,17 +3,17 @@ package org.jetbrains.dokka.Formats import org.jetbrains.dokka.* import org.jetbrains.dokka.Kotlin.KotlinAsJavaDescriptorSignatureProvider import org.jetbrains.dokka.Kotlin.KotlinDescriptorSignatureProvider -import org.jetbrains.dokka.Model.DescriptorSignatureProvider import org.jetbrains.dokka.Samples.DefaultSampleProcessingService import org.jetbrains.dokka.Samples.KotlinWebsiteSampleProcessingService import org.jetbrains.dokka.Samples.SampleProcessingService import kotlin.reflect.KClass -abstract class KotlinFormatDescriptorBase : FormatDescriptor { +abstract class KotlinFormatDescriptorBase : FileGeneratorBasedFormatDescriptor() { + override val packageDocumentationBuilderClass = KotlinPackageDocumentationBuilder::class override val javaDocumentationBuilderClass = KotlinJavaDocumentationBuilder::class - override val generatorServiceClass: KClass = FileGenerator::class + override val generatorServiceClass = FileGenerator::class override val outlineServiceClass: KClass? = null override val sampleProcessingService: KClass = DefaultSampleProcessingService::class override val packageListServiceClass: KClass? = DefaultPackageListService::class @@ -25,7 +25,7 @@ class HtmlFormatDescriptor : KotlinFormatDescriptorBase() { override val outlineServiceClass = HtmlFormatService::class } -class HtmlAsJavaFormatDescriptor : FormatDescriptor { +class HtmlAsJavaFormatDescriptor : FileGeneratorBasedFormatDescriptor() { override val formatServiceClass = HtmlFormatService::class override val outlineServiceClass = HtmlFormatService::class override val generatorServiceClass = FileGenerator::class diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt index 5167a102..952e14cf 100644 --- a/core/src/main/kotlin/Formats/StructuredFormatService.kt +++ b/core/src/main/kotlin/Formats/StructuredFormatService.kt @@ -7,11 +7,13 @@ data class FormatLink(val text: String, val href: String) abstract class StructuredOutputBuilder(val to: StringBuilder, val location: Location, - val locationService: LocationService, + val generator: NodeLocationAwareGenerator, val languageService: LanguageService, val extension: String, val impliedPlatforms: List) : FormattedOutputBuilder { + protected fun DocumentationNode.location() = generator.location(this) + protected fun wrap(prefix: String, suffix: String, body: () -> Unit) { to.append(prefix) body() @@ -204,16 +206,16 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, if (from.owner?.kind == NodeKind.GroupNode) return link(from.owner!!, to, extension, name) - return FormatLink(name(to), locationService.relativePathToLocation(from, to)) + return FormatLink(name(to), from.location().relativePathTo(to.location())) } fun locationHref(from: Location, to: DocumentationNode): String { val topLevelPage = to.references(RefKind.TopLevelPage).singleOrNull()?.to if (topLevelPage != null) { val signature = to.detailOrNull(NodeKind.Signature) - return from.relativePathTo(locationService.location(topLevelPage), signature?.name ?: to.name) + return from.relativePathTo(topLevelPage.location(), signature?.name ?: to.name) } - return from.relativePathTo(locationService.location(to)) + return from.relativePathTo(to.location()) } private fun DocumentationNode.isModuleOrPackage(): Boolean = @@ -349,7 +351,8 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, overrides.forEach { appendParagraph { to.append("Overrides ") - val location = locationService.relativePathToLocation(this, it) + val location = location().relativePathTo(it.location()) + appendLink(FormatLink(it.owner!!.name + "." + it.name, location)) } } @@ -383,7 +386,7 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, else platformsToShow - if(platforms.isEmpty()) return + if (platforms.isEmpty()) return appendParagraph { appendStrong { to.append("Platform and version requirements:") } @@ -674,9 +677,9 @@ abstract class StructuredOutputBuilder(val to: StringBuilder, } } -abstract class StructuredFormatService(locationService: LocationService, +abstract class StructuredFormatService(val generator: NodeLocationAwareGenerator, val languageService: LanguageService, override val extension: String, override final val linkExtension: String = extension) : FormatService { - val locationService: LocationService = locationService.withExtension(linkExtension) + } diff --git a/core/src/main/kotlin/Formats/YamlOutlineService.kt b/core/src/main/kotlin/Formats/YamlOutlineService.kt index 7968824c..c36f98eb 100644 --- a/core/src/main/kotlin/Formats/YamlOutlineService.kt +++ b/core/src/main/kotlin/Formats/YamlOutlineService.kt @@ -3,15 +3,17 @@ package org.jetbrains.dokka import com.google.inject.Inject import java.io.File -class YamlOutlineService @Inject constructor(val locationService: LocationService, - val languageService: LanguageService) : OutlineFormatService { +class YamlOutlineService @Inject constructor( + val generator: NodeLocationAwareGenerator, + val languageService: LanguageService +) : OutlineFormatService { override fun getOutlineFileName(location: Location): File = File("${location.path}.yml") var outlineLevel = 0 override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) { val indent = " ".repeat(outlineLevel) to.appendln("$indent- title: ${languageService.renderName(node)}") - to.appendln("$indent url: ${locationService.location(node).path}") + to.appendln("$indent url: ${generator.location(node).path}") } override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) { diff --git a/core/src/main/kotlin/Generation/ConsoleGenerator.kt b/core/src/main/kotlin/Generation/ConsoleGenerator.kt deleted file mode 100644 index 301f86b9..00000000 --- a/core/src/main/kotlin/Generation/ConsoleGenerator.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.jetbrains.dokka - -class ConsoleGenerator(val signatureGenerator: LanguageService, val locationService: LocationService) { - val IndentStep = " " - - fun generate(node: DocumentationNode, indent: String = "") { - println("@${locationService.location(node).path}") - generateHeader(node, indent) - //generateDetails(node, indent) - generateMembers(node, indent) - generateLinks(node, indent) - } - - fun generateHeader(node: DocumentationNode, indent: String = "") { - println(indent + signatureGenerator.render(node)) - val docString = node.content.toString() - if (!docString.isEmpty()) - println("$indent\"${docString.replace("\n", "\n$indent")}\"") - println() - } - - fun generateMembers(node: DocumentationNode, indent: String = "") { - val items = node.members.sortedBy { it.name } - for (child in items) - generate(child, indent + IndentStep) - } - - fun generateDetails(node: DocumentationNode, indent: String = "") { - val items = node.details - for (child in items) - generate(child, indent + " ") - } - - fun generateLinks(node: DocumentationNode, indent: String = "") { - val items = node.links - if (items.isEmpty()) - return - println("$indent Links") - for (child in items) - generate(child, indent + " ") - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/Generation/FileGenerator.kt b/core/src/main/kotlin/Generation/FileGenerator.kt index e055c537..3193a5bc 100644 --- a/core/src/main/kotlin/Generation/FileGenerator.kt +++ b/core/src/main/kotlin/Generation/FileGenerator.kt @@ -1,22 +1,27 @@ package org.jetbrains.dokka import com.google.inject.Inject +import com.google.inject.name.Named import java.io.File import java.io.FileOutputStream import java.io.IOException import java.io.OutputStreamWriter -class FileGenerator @Inject constructor(val locationService: FileLocationService) : Generator { +class FileGenerator @Inject constructor(@Named("outputDir") val rootFile: File) : NodeLocationAwareGenerator { @set:Inject(optional = true) var outlineService: OutlineFormatService? = null @set:Inject(optional = true) lateinit var formatService: FormatService @set:Inject(optional = true) lateinit var options: DocumentationOptions @set:Inject(optional = true) var packageListService: PackageListService? = null + override fun location(node: DocumentationNode): FileLocation { + return FileLocation(File(rootFile, relativePathToNode(node.path.map { it.name }, node.members.any())).appendExtension(formatService.extension)) + } + override fun buildPages(nodes: Iterable) { - val specificLocationService = locationService.withExtension(formatService.extension) + //val specificLocationService = locationService.withExtension(formatService.extension) - for ((location, items) in nodes.groupBy { specificLocationService.location(it) }) { + for ((location, items) in nodes.groupBy { location(it) }) { val file = location.file file.parentFile?.mkdirsOrFail() try { @@ -34,7 +39,7 @@ class FileGenerator @Inject constructor(val locationService: FileLocationService override fun buildOutlines(nodes: Iterable) { val outlineService = this.outlineService ?: return - for ((location, items) in nodes.groupBy { locationService.location(it) }) { + for ((location, items) in nodes.groupBy { location(it) }) { val file = outlineService.getOutlineFileName(location) file.parentFile?.mkdirsOrFail() FileOutputStream(file).use { @@ -47,7 +52,7 @@ class FileGenerator @Inject constructor(val locationService: FileLocationService override fun buildSupportFiles() { formatService.enumerateSupportFiles { resource, targetPath -> - FileOutputStream(locationService.location(listOf(targetPath), false).file).use { + FileOutputStream(relativePathToNode(listOf(targetPath), false)).use { javaClass.getResourceAsStream(resource).copyTo(it) } } @@ -58,7 +63,7 @@ class FileGenerator @Inject constructor(val locationService: FileLocationService for (module in nodes) { - val moduleRoot = locationService.location(module).file.parentFile + val moduleRoot = location(module).file.parentFile val packageListFile = File(moduleRoot, "package-list") packageListFile.writeText("\$dokka.format:${options.outputFormat}\n" + diff --git a/core/src/main/kotlin/Generation/Generator.kt b/core/src/main/kotlin/Generation/Generator.kt index 76a5f350..003386ef 100644 --- a/core/src/main/kotlin/Generation/Generator.kt +++ b/core/src/main/kotlin/Generation/Generator.kt @@ -19,3 +19,8 @@ fun Generator.buildPage(node: DocumentationNode): Unit = buildPages(listOf(node) fun Generator.buildOutline(node: DocumentationNode): Unit = buildOutlines(listOf(node)) fun Generator.buildAll(node: DocumentationNode): Unit = buildAll(listOf(node)) + + +interface NodeLocationAwareGenerator: Generator { + fun location(node: DocumentationNode): Location +} \ No newline at end of file diff --git a/core/src/main/kotlin/Locations/FoldersLocationService.kt b/core/src/main/kotlin/Locations/FoldersLocationService.kt index 83e1cf6a..ae5301e7 100644 --- a/core/src/main/kotlin/Locations/FoldersLocationService.kt +++ b/core/src/main/kotlin/Locations/FoldersLocationService.kt @@ -3,28 +3,18 @@ package org.jetbrains.dokka import com.google.inject.Inject import com.google.inject.name.Named import java.io.File - -class FoldersLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { - constructor(root: String): this(File(root), "") - - override val root: Location - get() = FileLocation(rootFile) - - override fun withExtension(newExtension: String): FileLocationService { - return if (extension.isEmpty()) FoldersLocationService(rootFile, newExtension) else this - } - - override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { - return FileLocation(File(rootFile, relativePathToNode(qualifiedName, hasMembers)).appendExtension(extension)) - } -} - -fun relativePathToNode(qualifiedName: List, hasMembers: Boolean): String { - val parts = qualifiedName.map { identifierToFilename(it) }.filterNot { it.isEmpty() } - return if (!hasMembers) { - // leaf node, use file in owner's folder - parts.joinToString("/") - } else { - parts.joinToString("/") + (if (parts.none()) "" else "/") + "index" - } -} +// +//class FoldersLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { +// constructor(root: String): this(File(root), "") +// +// override val root: Location +// get() = FileLocation(rootFile) +// +// override fun withExtension(newExtension: String): FileLocationService { +// return if (extension.isEmpty()) FoldersLocationService(rootFile, newExtension) else this +// } +// +// override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { +// return FileLocation(File(rootFile, relativePathToNode(qualifiedName, hasMembers)).appendExtension(extension)) +// } +//} diff --git a/core/src/main/kotlin/Locations/LocationService.kt b/core/src/main/kotlin/Locations/LocationService.kt index a51ef8d4..6b7e0511 100644 --- a/core/src/main/kotlin/Locations/LocationService.kt +++ b/core/src/main/kotlin/Locations/LocationService.kt @@ -32,37 +32,51 @@ data class FileLocation(val file: File): Location { } } -/** - * Provides means of retrieving locations for [DocumentationNode](documentation nodes) - * - * `LocationService` determines where documentation for particular node should be generated - * - * * [FoldersLocationService] – represent packages and types as folders, members as files in those folders. - * * [SingleFolderLocationService] – all documentation is generated into single folder using fully qualified names - * for file names. - */ -interface LocationService { - fun withExtension(newExtension: String) = this - fun location(node: DocumentationNode): Location = location(node.path.map { it.name }, node.members.any()) - /** - * Calculates a location corresponding to the specified [qualifiedName]. - * @param hasMembers if true, the node for which the location is calculated has member nodes. - */ - fun location(qualifiedName: List, hasMembers: Boolean): Location - - val root: Location +fun relativePathToNode(qualifiedName: List, hasMembers: Boolean): String { + val parts = qualifiedName.map { identifierToFilename(it) }.filterNot { it.isEmpty() } + return if (!hasMembers) { + // leaf node, use file in owner's folder + parts.joinToString("/") + } else { + parts.joinToString("/") + (if (parts.none()) "" else "/") + "index" + } } -interface FileLocationService: LocationService { - override fun withExtension(newExtension: String): FileLocationService = this - - override fun location(node: DocumentationNode): FileLocation = location(node.path.map { it.name }, node.members.any()) - override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation -} +// +///** +// * Provides means of retrieving locations for [DocumentationNode](documentation nodes) +// * +// * `LocationService` determines where documentation for particular node should be generated +// * +// * * [FoldersLocationService] – represent packages and types as folders, members as files in those folders. +// * * [SingleFolderLocationService] – all documentation is generated into single folder using fully qualified names +// * for file names. +// */ +//interface LocationService { +// fun withExtension(newExtension: String) = this +// +// fun location(node: DocumentationNode): Location = location(node.path.map { it.name }, node.members.any()) +// +// /** +// * Calculates a location corresponding to the specified [qualifiedName]. +// * @param hasMembers if true, the node for which the location is calculated has member nodes. +// */ +// fun location(qualifiedName: List, hasMembers: Boolean): Location +// +// val root: Location +//} +// +// +//interface FileLocationService: LocationService { +// override fun withExtension(newExtension: String): FileLocationService = this +// +// override fun location(node: DocumentationNode): FileLocation = location(node.path.map { it.name }, node.members.any()) +// override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation +//} fun identifierToFilename(path: String): String { val escaped = path.replace('<', '-').replace('>', '-') @@ -70,9 +84,14 @@ fun identifierToFilename(path: String): String { return if (lowercase == "index") "--index--" else lowercase } -/** - * Returns relative location between two nodes. Used for relative links in documentation. - */ -fun LocationService.relativePathToLocation(owner: DocumentationNode, node: DocumentationNode): String { +///** +// * Returns relative location between two nodes. Used for relative links in documentation. +// */ +//fun LocationService.relativePathToLocation(owner: DocumentationNode, node: DocumentationNode): String { +// return location(owner).relativePathTo(location(node), null) +//} + + +fun NodeLocationAwareGenerator.relativePathToLocation(owner: DocumentationNode, node: DocumentationNode): String { return location(owner).relativePathTo(location(node), null) -} +} \ No newline at end of file diff --git a/core/src/main/kotlin/Locations/SingleFolderLocationService.kt b/core/src/main/kotlin/Locations/SingleFolderLocationService.kt index 1b4fdc28..25cf6f8e 100644 --- a/core/src/main/kotlin/Locations/SingleFolderLocationService.kt +++ b/core/src/main/kotlin/Locations/SingleFolderLocationService.kt @@ -3,18 +3,18 @@ package org.jetbrains.dokka import com.google.inject.Inject import com.google.inject.name.Named import java.io.File - -class SingleFolderLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { - constructor(root: String): this(File(root), "") - - override fun withExtension(newExtension: String): FileLocationService = - SingleFolderLocationService(rootFile, newExtension) - - override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { - val filename = qualifiedName.map { identifierToFilename(it) }.joinToString("-") - return FileLocation(File(rootFile, filename).appendExtension(extension)) - } - - override val root: Location - get() = FileLocation(rootFile) -} \ No newline at end of file +// +//class SingleFolderLocationService @Inject constructor(@Named("outputDir") val rootFile: File, val extension: String) : FileLocationService { +// constructor(root: String): this(File(root), "") +// +// override fun withExtension(newExtension: String): FileLocationService = +// SingleFolderLocationService(rootFile, newExtension) +// +// override fun location(qualifiedName: List, hasMembers: Boolean): FileLocation { +// val filename = qualifiedName.map { identifierToFilename(it) }.joinToString("-") +// return FileLocation(File(rootFile, filename).appendExtension(extension)) +// } +// +// override val root: Location +// get() = FileLocation(rootFile) +//} \ No newline at end of file diff --git a/core/src/main/kotlin/Utilities/DokkaModules.kt b/core/src/main/kotlin/Utilities/DokkaModules.kt index dfb114ec..9db08010 100644 --- a/core/src/main/kotlin/Utilities/DokkaModules.kt +++ b/core/src/main/kotlin/Utilities/DokkaModules.kt @@ -4,6 +4,7 @@ import com.google.inject.Binder import com.google.inject.Module import com.google.inject.Provider import com.google.inject.TypeLiteral +import com.google.inject.binder.AnnotatedBindingBuilder import com.google.inject.name.Names import org.jetbrains.dokka.* import org.jetbrains.dokka.Formats.FormatDescriptor @@ -11,6 +12,7 @@ import org.jetbrains.dokka.Model.DescriptorSignatureProvider import org.jetbrains.dokka.Samples.SampleProcessingService import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import java.io.File +import kotlin.reflect.KClass const val impliedPlatformsName = "impliedPlatforms" @@ -22,12 +24,7 @@ class DokkaAnalysisModule(val environment: AnalysisEnvironment, override fun configure(binder: Binder) { binder.bind().toInstance(logger) - val descriptor = ServiceLocator.lookup("format", options.outputFormat) - binder.bind().to(descriptor.descriptorSignatureProvider.java) binder.registerCategory("language") - binder.bind().to(descriptor.packageDocumentationBuilderClass.java) - binder.bind().to(descriptor.javaDocumentationBuilderClass.java) - binder.bind().to(descriptor.sampleProcessingService.java) val coreEnvironment = environment.createCoreEnvironment() binder.bind().toInstance(coreEnvironment) @@ -40,6 +37,9 @@ class DokkaAnalysisModule(val environment: AnalysisEnvironment, binder.bind().toInstance(defaultPlatformsProvider) binder.bind().toInstance(nodeReferenceGraph) + + val descriptor = ServiceLocator.lookup("format", options.outputFormat) + descriptor.configureAnalysis(binder) } } @@ -56,35 +56,26 @@ class DokkaOutputModule(val options: DocumentationOptions, binder.bind(File::class.java).annotatedWith(Names.named("outputDir")).toInstance(File(options.outputDir)) - binder.bindNameAnnotated("singleFolder") - binder.bindNameAnnotated("singleFolder") - binder.bindNameAnnotated("folders") - binder.bindNameAnnotated("folders") +// binder.bindNameAnnotated("singleFolder") +// binder.bindNameAnnotated("singleFolder") +// binder.bindNameAnnotated("folders") +// binder.bindNameAnnotated("folders") // defaults - binder.bind(LocationService::class.java).to(FoldersLocationService::class.java) - binder.bind(FileLocationService::class.java).to(FoldersLocationService::class.java) +// binder.bind(LocationService::class.java).to(FoldersLocationService::class.java) +// binder.bind(FileLocationService::class.java).to(FoldersLocationService::class.java) binder.registerCategory("outline") binder.registerCategory("format") binder.registerCategory("generator") - val descriptor = ServiceLocator.lookup("format", options.outputFormat) - - descriptor.outlineServiceClass?.let { clazz -> - binder.bind(OutlineFormatService::class.java).to(clazz.java) - } - descriptor.formatServiceClass?.let { clazz -> - binder.bind(FormatService::class.java).to(clazz.java) - } - - binder.bind().to(descriptor.generatorServiceClass.java) - - descriptor.packageListServiceClass?.let { binder.bind().to(it.java) } - binder.bind().toInstance(options) binder.bind().toInstance(logger) binder.bind(StringListType).annotatedWith(Names.named(impliedPlatformsName)).toInstance(options.impliedPlatforms) + + val descriptor = ServiceLocator.lookup("format", options.outputFormat) + + descriptor.configureOutput(binder) } } @@ -100,4 +91,9 @@ private inline fun Binder.bindNameAnnotat } -inline fun Binder.bind() = bind(T::class.java) +inline fun Binder.bind(): AnnotatedBindingBuilder = bind(T::class.java) + +inline infix fun > AnnotatedBindingBuilder.toOptional(kClass: TKClass?) = + kClass?.let { to(it.java) } + +inline infix fun > AnnotatedBindingBuilder.toType(kClass: TKClass) = to(kClass.java) -- cgit