From e99be615ce7c2c2b5c3ee5e3f8941c41c1e7a944 Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Fri, 31 Jan 2020 00:37:29 +0100 Subject: Bump Gradle version, migrate to Kotlin DSL, refactor publishing --- runners/cli/build.gradle.kts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 runners/cli/build.gradle.kts (limited to 'runners/cli/build.gradle.kts') diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts new file mode 100644 index 00000000..4b39d64c --- /dev/null +++ b/runners/cli/build.gradle.kts @@ -0,0 +1,37 @@ +import org.jetbrains.configureBintrayPublication + +plugins { + id("com.github.johnrengelman.shadow") +} + +repositories { + maven(url = "https://dl.bintray.com/orangy/maven") +} + +dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.1.0-dev-3") + implementation(project(":core")) +} + + +tasks { + shadowJar { + val dokka_version: String by project + archiveFileName.set("dokka-cli-$dokka_version.jar") + archiveClassifier.set("") + manifest { + attributes("Main-Class" to "org.jetbrains.dokka.MainKt") + } + } +} + +publishing { + publications { + register("dokkaCli") { + artifactId = "dokka-cli" + project.shadow.component(this) + } + } +} + +configureBintrayPublication("dokkaCli") \ No newline at end of file -- cgit From 9637ec0747815181d56fa53419d4f6c56705752b Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Tue, 12 May 2020 15:19:53 +0200 Subject: Refactor CLI --- core/src/main/kotlin/DokkaBootstrapImpl.kt | 41 +- core/src/main/kotlin/utilities/DokkaLogging.kt | 4 +- runners/cli/build.gradle.kts | 5 +- .../src/main/kotlin/cli/DokkaArgumentsParser.kt | 185 ------- runners/cli/src/main/kotlin/cli/main.kt | 584 +++++++++++---------- 5 files changed, 324 insertions(+), 495 deletions(-) delete mode 100644 runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt (limited to 'runners/cli/build.gradle.kts') diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index d39ee1d5..e0f014c8 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -8,28 +8,25 @@ import org.jetbrains.dokka.utilities.DokkaLogger import java.util.function.BiConsumer -fun parsePerPackageOptions(arg: String): List { - if (arg.isBlank()) return emptyList() - - return arg.split(";").map { it.split(",") }.map { - val prefix = it.first() - if (prefix == "") - throw IllegalArgumentException("Please do not register packageOptions with all match pattern, use global settings instead") - val args = it.subList(1, it.size) - val deprecated = args.find { it.endsWith("deprecated") }?.startsWith("+") ?: true - val reportUndocumented = args.find { it.endsWith("reportUndocumented") }?.startsWith("+") ?: true - val privateApi = args.find { it.endsWith("privateApi") }?.startsWith("+") ?: false - val suppress = args.find { it.endsWith("suppress") }?.startsWith("+") ?: false - PackageOptionsImpl( - prefix, - includeNonPublic = privateApi, - reportUndocumented = reportUndocumented, - skipDeprecated = !deprecated, - suppress = suppress - ) - } +fun parsePerPackageOptions(args: List): List = args.map { it.split(",") }.map { + val prefix = it.first() + if (prefix == "") + throw IllegalArgumentException("Please do not register packageOptions with all match pattern, use global settings instead") + val args = it.subList(1, it.size) + val deprecated = args.find { it.endsWith("deprecated") }?.startsWith("+") ?: true + val reportUndocumented = args.find { it.endsWith("reportUndocumented") }?.startsWith("+") ?: true + val privateApi = args.find { it.endsWith("privateApi") }?.startsWith("+") ?: false + val suppress = args.find { it.endsWith("suppress") }?.startsWith("+") ?: false + PackageOptionsImpl( + prefix, + includeNonPublic = privateApi, + reportUndocumented = reportUndocumented, + skipDeprecated = !deprecated, + suppress = suppress + ) } + class DokkaBootstrapImpl : DokkaBootstrap { class DokkaProxyLogger(val consumer: BiConsumer) : DokkaLogger { @@ -60,9 +57,9 @@ class DokkaBootstrapImpl : DokkaBootstrap { if (warningsCount > 0 || errorsCount > 0) { println( "Generation completed with $warningsCount warning" + - (if (DokkaConsoleLogger.warningsCount == 1) "" else "s") + + (if (warningsCount == 1) "" else "s") + " and $errorsCount error" + - if (DokkaConsoleLogger.errorsCount == 1) "" else "s" + if (errorsCount == 1) "" else "s" ) } else { println("generation completed successfully") diff --git a/core/src/main/kotlin/utilities/DokkaLogging.kt b/core/src/main/kotlin/utilities/DokkaLogging.kt index 1c05c95d..4b671f7b 100644 --- a/core/src/main/kotlin/utilities/DokkaLogging.kt +++ b/core/src/main/kotlin/utilities/DokkaLogging.kt @@ -27,9 +27,9 @@ object DokkaConsoleLogger : DokkaLogger { override fun report() { if (warningsCount > 0 || errorsCount > 0) { - println("Generation completed with warningsCount warning" + + println("Generation completed with $warningsCount warning" + (if(warningsCount == 1) "" else "s") + - " and errorsCount error" + + " and $errorsCount error" + if(errorsCount == 1) "" else "s" ) } else { diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index 4b39d64c..6c3a4d7d 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -5,11 +5,12 @@ plugins { } repositories { - maven(url = "https://dl.bintray.com/orangy/maven") + maven(url = "https://dl.bintray.com/kotlin/kotlinx") } dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.1.0-dev-3") + implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.2.1") + implementation("com.google.code.gson:gson:2.8.5") implementation(project(":core")) } diff --git a/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt b/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt deleted file mode 100644 index 5d795da7..00000000 --- a/runners/cli/src/main/kotlin/cli/DokkaArgumentsParser.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.jetbrains.dokka - -import kotlinx.cli.* -import kotlin.reflect.KProperty - -class ParseContext(val cli: CommandLineInterface = CommandLineInterface("dokka")) { - private val transformActions = mutableMapOf, (String) -> Unit>() - private val flagActions = mutableMapOf, () -> Unit>() - - fun registerFlagAction( - keys: List, - help: String, - property: KProperty<*>, - invoke: () -> Unit - ) { - if (property !in flagActions.keys) { - cli.flagAction(keys, help) { - flagActions[property]!!() - } - } - flagActions[property] = invoke - - } - - fun registerSingleOption( - keys: List, - help: String, - property: KProperty<*>, - invoke: (String) -> Unit - ) { - if (property !in transformActions.keys) { - cli.singleAction(keys, help) { - transformActions[property]!!(it) - } - } - transformActions[property] = invoke - } - - fun registerRepeatableOption( - keys: List, - help: String, - property: KProperty<*>, - invoke: (String) -> Unit - ) { - if (property !in transformActions.keys) { - cli.repeatingAction(keys, help) { - transformActions[property]!!(it) - } - } - transformActions[property] = invoke - } - - fun parse(args: Array) { - cli.parseArgs(*args) - } - -} - -fun CommandLineInterface.singleAction( - keys: List, - help: String, - invoke: (String) -> Unit -) = registerAction( - object : FlagActionBase(keys, help) { - override fun invoke(arguments: ListIterator) { - if (arguments.hasNext()) { - val msg = arguments.next() - invoke(msg) - } - } - - override fun invoke() { - error("should be never called") - } - } -) - -fun CommandLineInterface.repeatingAction( - keys: List, - help: String, - invoke: (String) -> Unit -) = registerAction( - object : FlagActionBase(keys, help) { - override fun invoke(arguments: ListIterator) { - while (arguments.hasNext()) { - val message = arguments.next() - - if (this@repeatingAction.getFlagAction(message) != null) { - arguments.previous() - break - } - invoke(message) - } - } - - override fun invoke() { - error("should be never called") - } - } - -) - - -class DokkaArgumentsParser(val args: Array, val parseContext: ParseContext) { - class OptionDelegate( - var value: T, - private val action: (delegate: OptionDelegate, property: KProperty<*>) -> Unit - ) { - operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value - operator fun provideDelegate(thisRef: Any, property: KProperty<*>): OptionDelegate { - action(this, property) - return this - } - } - - fun parseInto(dest: T): T { - // TODO: constructor: (DokkaArgumentsParser) -> T - parseContext.parse(args) - return dest - } - - fun repeatableOption( - keys: List, - help: String, - transform: (String) -> T - ) = OptionDelegate(mutableListOf()) { delegate, property -> - parseContext.registerRepeatableOption(keys, help, property) { - delegate.value.add(transform(it)) - } - } - - fun repeatableOption( - keys: List, - help: String - ) = repeatableOption(keys, help) { it as T } - - fun repeatableFlag( - keys: List, - help: String, - initElement: (ParseContext) -> T - ) = OptionDelegate(mutableListOf()) { delegate, property -> - parseContext.registerFlagAction(keys, help, property) { - delegate.value.add(initElement(parseContext)) - } - } - - fun singleFlag( - keys: List, - help: String, - initElement: (ParseContext) -> T, - transform: () -> T - ) = OptionDelegate(initElement(parseContext)) { delegate, property -> - parseContext.registerFlagAction(keys, help, property) { - delegate.value = transform() - } - } - - fun singleFlag( - keys: List, - help: String - ) = singleFlag(keys, help, { false }, { true }) - - fun stringOption( - keys: List, - help: String, - defaultValue: T - ) = singleOption(keys, help, { it as T }, { defaultValue }) - - fun singleOption( - keys: List, - help: String, - transform: (String) -> T, - initElement: (ParseContext) -> T - ) = OptionDelegate(initElement(parseContext)) { delegate, property -> - parseContext.registerSingleOption(keys, help, property) { - val toAdd = transform(it) - delegate.value = toAdd - } - } -} - - -//`(-perPackage fqName [-include-non-public] [...other flags])*` (edited) -//`(-sourceLink dir url [-urlSuffix value])*` -//`(-extLink url [packageListUrl])*` \ No newline at end of file diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index 2ef08c2e..515f9bb0 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -1,335 +1,351 @@ package org.jetbrains.dokka +import com.google.gson.Gson +import kotlinx.cli.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import java.io.File -import java.io.FileNotFoundException +import org.jetbrains.kotlin.utils.addToStdlib.cast +import java.io.* import java.net.MalformedURLException import java.net.URL -import java.net.URLClassLoader import java.nio.file.Files import java.nio.file.Paths -open class GlobalArguments(parser: DokkaArgumentsParser) : DokkaConfiguration { - override val outputDir: String by parser.stringOption( - listOf("-output"), - "Output directory path", - "" - ) - - override val format: String by parser.stringOption( - listOf("-format"), - "Output format (text, html, gfm, jekyll, kotlin-website)", - "" - ) - - override val pluginsClasspath: List by parser.repeatableOption( - listOf("-dokkaPlugins"), - "List of jars with dokka plugins" - ) { - File(it) - }.also { - Paths.get("./dokka-base.jar").toAbsolutePath().normalize().run { - if (Files.exists(this)) it.value.add(this.toFile()) - else throw FileNotFoundException("Dokka base plugin is not found! Make sure you placed 'dokka-base.jar' containing base plugin along the cli jar file") - } - } - - override val cacheRoot: String? by parser.stringOption( - listOf("-cacheRoot"), - "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled", - null - ) - - override val offlineMode: Boolean by parser.singleFlag( - listOf("-offlineMode"), - "Offline mode (do not download package lists from the Internet)" - ) +class GlobalArguments(args: Array) : DokkaConfiguration { - override val failOnWarning: Boolean by parser.singleFlag( - listOf("-failOnWarning"), "Fail dokka task if at least one warning was reported" - ) + val parser = ArgParser("globalArguments", prefixStyle = ArgParser.OptionPrefixStyle.JVM) - override val passesConfigurations: List by parser.repeatableFlag( - listOf("-pass"), - "Single dokka pass" - ) { - Arguments(parser).also { if (it.moduleName.isEmpty()) DokkaConsoleLogger.warn("Not specified module name. It can result in unexpected behaviour while including documentation for module") } - } + val json: String? by parser.argument(ArgType.String, description = "Json file name").optional() - override val modules: List = emptyList() + override val outputDir by parser.option(ArgType.String, description = "Output directory path") + .default("./dokka") - override val pluginsConfiguration: Map = mutableMapOf() -} + override val format by parser.option( + ArgType.String, + description = "Output format (html, gfm, jekyll)" + ).default("html") -class Arguments(val parser: DokkaArgumentsParser) : DokkaConfiguration.PassConfiguration { - override val moduleName: String by parser.stringOption( - listOf("-module"), - "Name of the documentation module", - "" + override val cacheRoot by parser.option( + ArgType.String, + description = "Path to cache folder, or 'default' to use ~/.cache/dokka, if not provided caching is disabled" ) - override val displayName: String by parser.stringOption( - listOf("-displayName"), - "Name displayed in the generated documentation", - "" - ) + override val passesConfigurations by parser.option( + ArgTypeArgument, + description = "Single dokka pass", + fullName = "pass" + ).multiple() - override val sourceSetID: String by parser.stringOption( - listOf("-sourceSetID"), - "Source set ID used for declaring dependent source sets", - "main" - ) + override val pluginsConfiguration by parser.option( + ArgTypePlugin, + description = "Configuration for plugins in format fqPluginName=json^^fqPluginName=json..." + ).default(emptyMap()) - override val classpath: List by parser.repeatableOption( - listOf("-classpath"), - "Classpath for symbol resolution" - ) - - override val sourceRoots: List by parser.repeatableOption( - listOf("-src"), - "Source file or directory (allows many paths separated by the system path separator)" - ) { SourceRootImpl(it) } + override val pluginsClasspath by parser.option( + ArgTypeFile, + description = "List of jars with dokka plugins (allows many paths separated by the semicolon `;`)" + ).delimiter(";") - override val dependentSourceSets: List by parser.repeatableOption( - listOf("-dependentSets"), - "Names of dependent source sets" - ) - - override val samples: List by parser.repeatableOption( - listOf("-sample"), - "Source root for samples" - ) - override val includes: List by parser.repeatableOption( - listOf("-include"), - "Markdown files to load (allows many paths separated by the system path separator)" - ) - - override val includeNonPublic: Boolean by parser.singleFlag( - listOf("-includeNonPublic"), - "Include non public" - ) - - override val includeRootPackage: Boolean by parser.singleFlag( - listOf("-includeRootPackage"), - "Include root package" - ) - - override val reportUndocumented: Boolean by parser.singleFlag( - listOf("-reportUndocumented"), - "Report undocumented members" + override val offlineMode by parser.option( + ArgType.Boolean, + "Offline mode (do not download package lists from the Internet)" + ).default(false) + + override val failOnWarning by parser.option( + ArgType.Boolean, + "Throw an exception if the generation exited with warnings" + ).default(false) + + val globalPackageOptions by parser.option( + ArgType.String, + description = "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " + ).delimiter(";") + + val globalLinks by parser.option( + ArgType.String, + description = "External documentation links in format url^packageListUrl^^url2..." + ).delimiter("^^") + + val globalSrcLink by parser.option( + ArgType.String, + description = "Mapping between a source directory and a Web site for browsing the code (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val helpPass by parser.option( + ArgTypeHelpPass, + description = "Prints help for single -pass" ) - override val skipEmptyPackages: Boolean by parser.singleFlag( - listOf("-skipEmptyPackages"), - "Do not create index pages for empty packages" - ) + override val modules: List = emptyList() - override val skipDeprecated: Boolean by parser.singleFlag( - listOf("-skipDeprecated"), - "Do not output deprecated members" - ) + init { + parser.parse(args) - override val jdkVersion: Int by parser.singleOption( - listOf("-jdkVersion"), - "Version of JDK to use for linking to JDK JavaDoc", - { it.toInt() }, - { 8 } - ) + passesConfigurations.all { + it.perPackageOptions.cast>() + .addAll(parsePerPackageOptions(globalPackageOptions)) + } - override val languageVersion: String? by parser.stringOption( - listOf("-languageVersion"), - "Language Version to pass to Kotlin analysis", - null - ) + passesConfigurations.all { + it.externalDocumentationLinks.cast>().addAll(parseLinks(globalLinks)) + } - override val apiVersion: String? by parser.stringOption( - listOf("-apiVersion"), - "Kotlin Api Version to pass to Kotlin analysis", - null - ) + globalSrcLink.forEach { + if (it.isNotEmpty() && it.contains("=")) + passesConfigurations.all { pass -> + pass.sourceLinks.cast>() + .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) + } + else { + DokkaConsoleLogger.warn("Invalid -srcLink syntax. Expected: =[#lineSuffix]. No source links will be generated.") + } + } - override val noStdlibLink: Boolean by parser.singleFlag( - listOf("-noStdlibLink"), - "Disable documentation link to stdlib" - ) + passesConfigurations.forEach { + it.externalDocumentationLinks.cast>().addAll(defaultLinks(it)) + } + } +} - override val noJdkLink: Boolean by parser.singleFlag( - listOf("-noJdkLink"), - "Disable documentation link to JDK" +fun passArguments(args: Array): DokkaConfiguration.PassConfiguration { + + val parser = ArgParser("passConfiguration", prefixStyle = ArgParser.OptionPrefixStyle.JVM) + + val moduleName by parser.option( + ArgType.String, + description = "Name of the documentation module", + fullName = "module" + ).required() + + val displayName by parser.option( + ArgType.String, + description = "Name of the source set" + ).default("JVM") + + val sourceSetID by parser.option( + ArgType.String, + description = "ID of the source set" + ).default("main") + + val classpath by parser.option( + ArgType.String, + description = "Classpath for symbol resolution (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val sourceRoots by parser.option( + ArgType.String, + description = "Source file or directory (allows many paths separated by the semicolon `;`)", + fullName = "src" + ).delimiter(";") + + val dependentSourceRoots by parser.option( + ArgType.String, + description = "Source file or directory (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val dependentSourceSets by parser.option( + ArgType.String, + description = "Names of dependent source sets (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val samples by parser.option( + ArgType.String, + description = "Source root for samples (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val includes by parser.option( + ArgType.String, + description = "Markdown files to load (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val includeNonPublic: Boolean by parser.option(ArgType.Boolean, description = "Include non public") + .default(false) + + val includeRootPackage by parser.option(ArgType.Boolean, description = "Include non public") + .default(false) + + val reportUndocumented by parser.option(ArgType.Boolean, description = "Report undocumented members") + .default(false) + + val skipEmptyPackages by parser.option( + ArgType.Boolean, + description = "Do not create index pages for empty packages" + ).default(false) + + val skipDeprecated by parser.option(ArgType.Boolean, description = "Do not output deprecated members") + .default(false) + + val jdkVersion by parser.option( + ArgType.Int, + description = "Version of JDK to use for linking to JDK JavaDoc" + ).default(8) + + val languageVersion by parser.option( + ArgType.String, + description = "Language Version to pass to Kotlin analysis" ) - override val suppressedFiles: List by parser.repeatableOption( - listOf("-suppressedFile"), - "" + val apiVersion by parser.option( + ArgType.String, + description = "Kotlin Api Version to pass to Kotlin analysis" ) + val noStdlibLink by parser.option(ArgType.Boolean, description = "Disable documentation link to stdlib") + .default(false) + + val noJdkLink by parser.option(ArgType.Boolean, description = "Disable documentation link to JDK") + .default(false) + + val suppressedFiles by parser.option( + ArgType.String, + description = "Paths to files to be suppressed (allows many paths separated by the semicolon `;`)" + ).delimiter(";") + + val analysisPlatform: Platform by parser.option( + ArgTypePlatform, + description = "Platform for analysis" + ).default(Platform.DEFAULT) + + val perPackageOptions by parser.option( + ArgType.String, + description = "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " + ).delimiter(";") + + val externalDocumentationLinks by parser.option( + ArgType.String, + description = "External documentation links in format url^packageListUrl^^url2..." + ).delimiter("^^") + + val sourceLinks by parser.option( + ArgTypeSourceLinkDefinition, + description = "Mapping between a source directory and a Web site for browsing the code (allows many paths separated by the semicolon `;`)", + fullName = "srcLink" + ).delimiter(";") + + parser.parse(args) + + return object : DokkaConfiguration.PassConfiguration { + override val moduleName = moduleName + override val displayName = displayName + override val sourceSetID = sourceSetID + override val classpath = classpath + override val sourceRoots = sourceRoots.map { SourceRootImpl(it.toAbsolutePath()) } + override val dependentSourceSets: List = dependentSourceSets + override val samples = samples.map { it.toAbsolutePath() } + override val includes = includes.map { it.toAbsolutePath() } + override val includeNonPublic = includeNonPublic + override val includeRootPackage = includeRootPackage + override val reportUndocumented = reportUndocumented + override val skipEmptyPackages = skipEmptyPackages + override val skipDeprecated = skipDeprecated + override val jdkVersion = jdkVersion + override val sourceLinks = sourceLinks + override val analysisPlatform = analysisPlatform + override val perPackageOptions = parsePerPackageOptions(perPackageOptions) + override val externalDocumentationLinks = parseLinks(externalDocumentationLinks) + override val languageVersion = languageVersion + override val apiVersion = apiVersion + override val noStdlibLink = noStdlibLink + override val noJdkLink = noJdkLink + override val suppressedFiles = suppressedFiles + } +} - override val analysisPlatform: Platform by parser.singleOption( - listOf("-analysisPlatform"), - "Platform for analysis", - { Platform.fromString(it) }, - { Platform.DEFAULT } - ) +object ArgTypeFile : ArgType(true) { + override fun convert(value: kotlin.String, name: kotlin.String): File = File(value) + override val description: kotlin.String + get() = "{ String that points to file path }" +} +object ArgTypePlatform : ArgType(true) { + override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value) + override val description: kotlin.String + get() = "{ String thar represents paltform }" +} - override val perPackageOptions: MutableList by parser.singleOption( - listOf("-packageOptions"), - "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+reportUndocumented,+suppress;...\" ", - { parsePerPackageOptions(it).toMutableList() }, - { mutableListOf() } - ) +object ArgTypePlugin : ArgType>(true) { + override fun convert(value: kotlin.String, name: kotlin.String): Map = + value.split("^^").map { + it.split("=").let { + it[0] to it[1] + } + }.toMap() - override val externalDocumentationLinks: MutableList by parser.singleOption( - listOf("-links"), - "External documentation links in format url^packageListUrl^^url2...", - { MainKt.parseLinks(it).toMutableList() }, - { mutableListOf() } - ) + override val description: kotlin.String + get() = "{ String fqName=json, remember to escape `\"` inside json }" +} - override val sourceLinks: MutableList by parser.repeatableOption( - listOf("-srcLink"), - "Mapping between a source directory and a Web site for browsing the code" - ) { - if (it.isNotEmpty() && it.contains("=")) - SourceLinkDefinitionImpl.parseSourceLinkDefinition(it) +object ArgTypeSourceLinkDefinition : ArgType(true) { + override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.SourceLinkDefinition = + if (value.isNotEmpty() && value.contains("=")) + SourceLinkDefinitionImpl.parseSourceLinkDefinition(value) else { throw IllegalArgumentException("Warning: Invalid -srcLink syntax. Expected: =[#lineSuffix]. No source links will be generated.") } - } -} -object MainKt { - fun defaultLinks(config: DokkaConfiguration.PassConfiguration): MutableList = - mutableListOf().apply { - if (!config.noJdkLink) - this += DokkaConfiguration.ExternalDocumentationLink - .Builder("https://docs.oracle.com/javase/${config.jdkVersion}/docs/api/") - .build() - - if (!config.noStdlibLink) - this += DokkaConfiguration.ExternalDocumentationLink - .Builder("https://kotlinlang.org/api/latest/jvm/stdlib/") - .build() - } + override val description: kotlin.String + get() = "{ String that represent source links }" +} - fun parseLinks(links: String): List { - val (parsedLinks, parsedOfflineLinks) = links.split("^^") - .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } } - .filter { it.isNotEmpty() } - .partition { it.size == 1 } - - return parsedLinks.map { (root) -> ExternalDocumentationLink.Builder(root).build() } + - parsedOfflineLinks.map { (root, packageList) -> - val rootUrl = URL(root) - val packageListUrl = - try { - URL(packageList) - } catch (ex: MalformedURLException) { - File(packageList).toURI().toURL() - } - ExternalDocumentationLink.Builder(rootUrl, packageListUrl).build() - } - } +object ArgTypeArgument : ArgType(true) { + override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.PassConfiguration = + passArguments(value.split(" ").filter { it.isNotBlank() }.toTypedArray()) - @JvmStatic - fun entry(configuration: DokkaConfiguration) { - val generator = DokkaGenerator(configuration, DokkaConsoleLogger) - generator.generate() - DokkaConsoleLogger.report() - } + override val description: kotlin.String + get() = "" +} - fun findToolsJar(): File { - val javaHome = System.getProperty("java.home") - val default = File(javaHome, "../lib/tools.jar") - val mac = File(javaHome, "../Classes/classes.jar") - return when { - default.exists() -> default - mac.exists() -> mac - else -> { - throw Exception("tools.jar not found, please check it, also you can provide it manually, using -cp") - } - } - } +// Workaround for printing nested parsers help +object ArgTypeHelpPass : ArgType(false) { + override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { passArguments(arrayOf("-h")) } - fun createClassLoaderWithTools(): ClassLoader { - val toolsJar = findToolsJar().canonicalFile.toURI().toURL() - val originalUrls = (javaClass.classLoader as? URLClassLoader)?.urLs - val dokkaJar = javaClass.protectionDomain.codeSource.location - val urls = if (originalUrls != null) arrayOf(toolsJar, *originalUrls) else arrayOf(toolsJar, dokkaJar) - return URLClassLoader(urls, ClassLoader.getSystemClassLoader().parent) - } + override val description: kotlin.String + get() = "" +} - fun startWithToolsJar(configuration: DokkaConfiguration) { - try { - javaClass.classLoader.loadClass("com.sun.tools.doclets.formats.html.HtmlDoclet") - entry(configuration) - } catch (e: ClassNotFoundException) { - val classLoader = createClassLoaderWithTools() - classLoader.loadClass("org.jetbrains.dokka.MainKt") - .methods.find { it.name == "entry" }!! - .invoke(null, configuration) - } +fun defaultLinks(config: DokkaConfiguration.PassConfiguration): MutableList = + mutableListOf().apply { + if (!config.noJdkLink) + this += DokkaConfiguration.ExternalDocumentationLink + .Builder("https://docs.oracle.com/javase/${config.jdkVersion}/docs/api/") + .build() + + if (!config.noStdlibLink) + this += ExternalDocumentationLink + .Builder("https://kotlinlang.org/api/latest/jvm/stdlib/") + .build() } - fun createConfiguration(args: Array): GlobalArguments { - val parseContext = ParseContext() - val parser = DokkaArgumentsParser(args, parseContext) - val configuration = GlobalArguments(parser) - - parseContext.cli.singleAction( - listOf("-globalPackageOptions"), - "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+reportUndocumented,+suppress;...\" " - ) { link -> - configuration.passesConfigurations.all { - it.perPackageOptions.toMutableList().addAll(parsePerPackageOptions(link)) - } - } - - parseContext.cli.singleAction( - listOf("-globalLinks"), - "External documentation links in format url^packageListUrl^^url2..." - ) { link -> - configuration.passesConfigurations.all { - it.externalDocumentationLinks.toMutableList().addAll(parseLinks(link)) - } - } - - parseContext.cli.repeatingAction( - listOf("-globalSrcLink"), - "Mapping between a source directory and a Web site for browsing the code" - ) { - val newSourceLinks = if (it.isNotEmpty() && it.contains("=")) - listOf(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) - else { - if (it.isNotEmpty()) { - DokkaConsoleLogger.warn("Invalid -srcLink syntax. Expected: =[#lineSuffix]. No source links will be generated.") - } - listOf() +private fun String.toAbsolutePath() = Paths.get(this).toAbsolutePath().toString() + +fun parseLinks(links: List): List { + val (parsedLinks, parsedOfflineLinks) = links + .map { it.split("^").map { it.trim() }.filter { it.isNotBlank() } } + .filter { it.isNotEmpty() } + .partition { it.size == 1 } + + return parsedLinks.map { (root) -> ExternalDocumentationLink.Builder(root).build() } + + parsedOfflineLinks.map { (root, packageList) -> + val rootUrl = URL(root) + val packageListUrl = + try { + URL(packageList) + } catch (ex: MalformedURLException) { + File(packageList).toURI().toURL() + } + ExternalDocumentationLink.Builder(rootUrl, packageListUrl).build() } - - configuration.passesConfigurations.all { - it.sourceLinks.toMutableList().addAll(newSourceLinks) - } - } - parser.parseInto(configuration) - configuration.passesConfigurations.forEach { - it.externalDocumentationLinks.addAll(defaultLinks(it)) - } - return configuration - } - - @JvmStatic - fun main(args: Array) { - val configuration = createConfiguration(args) - - if (configuration.format.toLowerCase() == "javadoc") - startWithToolsJar(configuration) - else - entry(configuration) - } } - - +fun main(args: Array) { + val globalArguments = GlobalArguments(args) + val configuration = if (globalArguments.json != null) + Gson().fromJson( + Paths.get(globalArguments.json).toFile().readText(), + DokkaConfigurationImpl::class.java + ) + else + globalArguments + DokkaGenerator(configuration, DokkaConsoleLogger).generate() +} \ No newline at end of file -- cgit From 08f40e2a13006882e8f8425f111b8527e7bbcb0f Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Wed, 24 Jun 2020 09:14:37 +0200 Subject: Remove kotlin source analysis from :core to :kotlin-analysis (thanks to Afzal Najam) --- core/build.gradle.kts | 7 +- core/dependencies/build.gradle.kts | 40 ++ core/src/main/kotlin/DokkaGenerator.kt | 83 +-- .../main/kotlin/analysis/AnalysisEnvironment.kt | 625 -------------------- .../main/kotlin/analysis/CoreKotlinCacheService.kt | 42 -- .../main/kotlin/analysis/CoreProjectFileIndex.kt | 569 ------------------ .../main/kotlin/analysis/JavaResolveExtension.kt | 128 ----- core/src/main/kotlin/links/DRI.kt | 132 +---- core/src/main/kotlin/model/Documentable.kt | 12 +- .../kotlin/model/properties/PropertyContainer.kt | 4 +- core/src/main/kotlin/parsers/HtmlParser.kt | 89 --- core/src/main/kotlin/parsers/MarkdownParser.kt | 418 -------------- core/src/main/kotlin/parsers/Parser.kt | 42 -- .../factories/DocTagsFromIElementFactory.kt | 43 -- .../parsers/factories/DocTagsFromStringFactory.kt | 77 --- core/src/main/kotlin/plugability/DokkaContext.kt | 7 +- core/src/main/kotlin/plugability/DokkaPlugin.kt | 6 +- core/src/main/kotlin/utilities/cast.kt | 5 + coreDependencies/build.gradle.kts | 65 --- .../gradle-integration-tests/build.gradle.kts | 2 +- kotlin-analysis/build.gradle.kts | 27 + kotlin-analysis/dependencies/build.gradle.kts | 67 +++ .../dokka/analysis/AnalysisEnvironment.kt | 636 +++++++++++++++++++++ .../jetbrains/dokka/analysis/CallableFactory.kt | 31 + .../dokka/analysis/CoreKotlinCacheService.kt | 42 ++ .../dokka/analysis/CoreProjectFileIndex.kt | 515 +++++++++++++++++ .../org/jetbrains/dokka/analysis/DRIFactory.kt | 38 ++ .../jetbrains/dokka/analysis/DRITargetFactory.kt | 44 ++ .../org/jetbrains/dokka/analysis/Documentable.kt | 14 + .../dokka/analysis/EnvironmentAndFacade.kt | 59 ++ .../dokka/analysis/JavaResolveExtension.kt | 128 +++++ .../org/jetbrains/dokka/analysis/KotlinAnalysis.kt | 46 ++ .../dokka/analysis/TypeReferenceFactory.kt | 51 ++ plugins/base/build.gradle.kts | 1 + plugins/base/src/main/kotlin/DokkaBase.kt | 21 +- .../kotlin/allModulePage/MultimodulePageCreator.kt | 2 +- plugins/base/src/main/kotlin/parsers/HtmlParser.kt | 89 +++ .../base/src/main/kotlin/parsers/MarkdownParser.kt | 419 ++++++++++++++ plugins/base/src/main/kotlin/parsers/Parser.kt | 42 ++ .../factories/DocTagsFromIElementFactory.kt | 43 ++ .../parsers/factories/DocTagsFromStringFactory.kt | 77 +++ .../ModuleAndPackageDocumentationTransformer.kt | 20 +- .../documentables/ReportUndocumentedTransformer.kt | 1 + .../pages/samples/SamplesTransformer.kt | 41 +- .../pages/sourcelinks/SourceLinksTransformer.kt | 4 +- .../DefaultDescriptorToDocumentableTranslator.kt | 13 +- .../psi/DefaultPsiToDocumentableTranslator.kt | 23 +- .../main/kotlin/translators/psi/JavadocParser.kt | 1 + .../src/test/kotlin/basic/FailOnWarningTest.kt | 6 +- plugins/build.gradle.kts | 3 +- .../main/kotlin/javadoc/pages/JavadocPageNodes.kt | 3 + .../javadoc/src/test/kotlin/javadoc/JavadocTest.kt | 2 +- runners/cli/build.gradle.kts | 1 + runners/cli/src/main/kotlin/cli/main.kt | 2 +- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 6 +- settings.gradle.kts | 6 +- test-tools/build.gradle.kts | 1 + testApi/build.gradle.kts | 2 + .../src/main/kotlin/testApi/context/MockContext.kt | 4 - .../testApi/testRunner/DokkaTestGenerator.kt | 11 +- .../main/kotlin/testApi/testRunner/TestRunner.kt | 3 - 61 files changed, 2545 insertions(+), 2396 deletions(-) create mode 100644 core/dependencies/build.gradle.kts delete mode 100644 core/src/main/kotlin/analysis/AnalysisEnvironment.kt delete mode 100644 core/src/main/kotlin/analysis/CoreKotlinCacheService.kt delete mode 100644 core/src/main/kotlin/analysis/CoreProjectFileIndex.kt delete mode 100644 core/src/main/kotlin/analysis/JavaResolveExtension.kt delete mode 100644 core/src/main/kotlin/parsers/HtmlParser.kt delete mode 100644 core/src/main/kotlin/parsers/MarkdownParser.kt delete mode 100644 core/src/main/kotlin/parsers/Parser.kt delete mode 100644 core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt delete mode 100644 core/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt create mode 100644 core/src/main/kotlin/utilities/cast.kt delete mode 100644 coreDependencies/build.gradle.kts create mode 100644 kotlin-analysis/build.gradle.kts create mode 100644 kotlin-analysis/dependencies/build.gradle.kts create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreProjectFileIndex.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JavaResolveExtension.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt create mode 100644 kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt create mode 100644 plugins/base/src/main/kotlin/parsers/HtmlParser.kt create mode 100644 plugins/base/src/main/kotlin/parsers/MarkdownParser.kt create mode 100644 plugins/base/src/main/kotlin/parsers/Parser.kt create mode 100644 plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt create mode 100644 plugins/base/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt (limited to 'runners/cli/build.gradle.kts') diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1d61e410..fc62b73d 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,12 +6,9 @@ plugins { } dependencies { - api(project(":coreDependencies", configuration = "shadow")) + api(project("dependencies", configuration = "shadow")) - val kotlin_version: String by project - api("org.jetbrains.kotlin:kotlin-compiler:$kotlin_version") - implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version") - implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version") + implementation(kotlin("reflect")) implementation("com.google.code.gson:gson:2.8.5") implementation("org.jsoup:jsoup:1.12.1") diff --git a/core/dependencies/build.gradle.kts b/core/dependencies/build.gradle.kts new file mode 100644 index 00000000..a26d109e --- /dev/null +++ b/core/dependencies/build.gradle.kts @@ -0,0 +1,40 @@ +import org.jetbrains.configureBintrayPublication + +plugins { + id("com.github.johnrengelman.shadow") + `maven-publish` + id("com.jfrog.bintray") +} + +repositories { + maven(url = "https://kotlin.bintray.com/kotlin-plugin") +} + +dependencies { + // TODO (see https://github.com/Kotlin/dokka/issues/1009) + implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) + + implementation("org.jetbrains:markdown:0.1.41") { + because("it's published only on bintray") + } +} + +tasks { + shadowJar { + val dokka_version: String by project + archiveFileName.set("dokka-dependencies-$dokka_version.jar") + archiveClassifier.set("") + } +} + +publishing { + publications { + register("dokkaCoreDependencies") { + artifactId = "dokka-core-dependencies" + project.shadow.component(this) + } + } +} + +configureBintrayPublication("dokkaCoreDependencies") diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index b2e572d4..b88c6223 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -1,7 +1,5 @@ package org.jetbrains.dokka -import org.jetbrains.dokka.analysis.AnalysisEnvironment -import org.jetbrains.dokka.analysis.DokkaResolutionFacade import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.SourceSetCache import org.jetbrains.dokka.model.SourceSetData @@ -9,13 +7,7 @@ import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.messages.MessageRenderer -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.utils.PathUtil -import java.io.File + /** * DokkaGenerator is the main entry point for generating documentation @@ -26,15 +18,13 @@ class DokkaGenerator( private val logger: DokkaLogger ) { fun generate() = timed { - report("Setting up analysis environments") val sourceSetsCache = SourceSetCache() - val sourceSets: Map = setUpAnalysis(configuration, sourceSetsCache) report("Initializing plugins") - val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache) + val context = initializePlugins(configuration, logger, sourceSetsCache) report("Creating documentation models") - val modulesFromPlatforms = createDocumentationModels(sourceSets, context) + val modulesFromPlatforms = createDocumentationModels(context, sourceSetsCache) report("Transforming documentation model before merging") val transformedDocumentationBeforeMerge = transformDocumentationModelBeforeMerge(modulesFromPlatforms, context) @@ -59,9 +49,8 @@ class DokkaGenerator( fun generateAllModulesPage() = timed { val sourceSetsCache = SourceSetCache() - val sourceSets = emptyMap() report("Initializing plugins") - val context = initializePlugins(configuration, logger, sourceSets, sourceSetsCache) + val context = initializePlugins(configuration, logger, sourceSetsCache) report("Creating all modules page") val pages = createAllModulePage(context) @@ -73,26 +62,20 @@ class DokkaGenerator( render(transformedPages, context) }.dump("\n\n === TIME MEASUREMENT ===\n") - fun setUpAnalysis( - configuration: DokkaConfiguration, - sourceSetsCache: SourceSetCache - ): Map = - configuration.passesConfigurations.map { - sourceSetsCache.getSourceSet(it) to createEnvironmentAndFacade(configuration, it) - }.toMap() fun initializePlugins( configuration: DokkaConfiguration, logger: DokkaLogger, - sourceSets: Map, sourceSetsCache: SourceSetCache, pluginOverrides: List = emptyList() - ) = DokkaContext.create(configuration, logger, sourceSets, sourceSetsCache, pluginOverrides) + ) = DokkaContext.create(configuration, logger, sourceSetsCache, pluginOverrides) fun createDocumentationModels( - platforms: Map, - context: DokkaContext - ) = platforms.flatMap { (pdata, _) -> translateSources(pdata, context) } + context: DokkaContext, + sourceSetsCache: SourceSetCache + ) = context.configuration.passesConfigurations + .map { passConfiguration -> sourceSetsCache.getSourceSet(passConfiguration) } + .flatMap { passConfiguration -> translateSources(passConfiguration, context) } fun transformDocumentationModelBeforeMerge( modulesFromPlatforms: List, @@ -150,56 +133,10 @@ class DokkaGenerator( } } - private fun createEnvironmentAndFacade( - configuration: DokkaConfiguration, - pass: DokkaConfiguration.PassConfiguration - ): EnvironmentAndFacade = - AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run { - if (analysisPlatform == Platform.jvm) { - addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) - } - pass.classpath.forEach { addClasspath(File(it)) } - - addSources( - (pass.sourceRoots + configuration.passesConfigurations.filter { it.sourceSetID in pass.dependentSourceSets } - .flatMap { it.sourceRoots }) - .map { it.path } - ) - - loadLanguageVersionSettings(pass.languageVersion, pass.apiVersion) - - val environment = createCoreEnvironment() - val (facade, _) = createResolutionFacade(environment) - EnvironmentAndFacade(environment, facade) - } - private fun translateSources(platformData: SourceSetData, context: DokkaContext) = context[CoreExtensions.sourceToDocumentableTranslator].map { it.invoke(platformData, context) } - - class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { - override fun clear() { - seenErrors = false - } - - private var seenErrors = false - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { - if (severity == CompilerMessageSeverity.ERROR) { - seenErrors = true - } - logger.info(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) - } - - override fun hasErrors() = seenErrors - } -} - -// It is not data class due to ill-defined equals -class EnvironmentAndFacade(val environment: KotlinCoreEnvironment, val facade: DokkaResolutionFacade) { - operator fun component1() = environment - operator fun component2() = facade } private class Timer(startTime: Long, private val logger: DokkaLogger?) { diff --git a/core/src/main/kotlin/analysis/AnalysisEnvironment.kt b/core/src/main/kotlin/analysis/AnalysisEnvironment.kt deleted file mode 100644 index 33451dd6..00000000 --- a/core/src/main/kotlin/analysis/AnalysisEnvironment.kt +++ /dev/null @@ -1,625 +0,0 @@ -package org.jetbrains.dokka.analysis - -import com.google.common.collect.ImmutableMap -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.core.CoreModuleManager -import com.intellij.mock.MockComponentManager -import com.intellij.openapi.Disposable -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.OrderEnumerationHandler -import com.intellij.openapi.roots.ProjectFileIndex -import com.intellij.openapi.roots.ProjectRootManager -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.vfs.StandardFileSystems -import com.intellij.psi.PsiElement -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.dokka.Platform -import org.jetbrains.kotlin.analyzer.* -import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters -import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices -import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns -import org.jetbrains.kotlin.caches.resolve.* -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.config.ContentRoot -import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot -import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM -import org.jetbrains.kotlin.cli.jvm.config.* -import org.jetbrains.kotlin.cli.jvm.index.JavaRoot -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.container.getService -import org.jetbrains.kotlin.container.tryGetService -import org.jetbrains.kotlin.context.ProjectContext -import org.jetbrains.kotlin.context.withModule -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory -import org.jetbrains.kotlin.js.config.JSConfigurationKeys -import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices -import org.jetbrains.kotlin.library.impl.createKotlinLibrary -import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.CommonPlatforms -import org.jetbrains.kotlin.platform.TargetPlatform -import org.jetbrains.kotlin.platform.js.JsPlatforms -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms.unspecifiedJvmPlatform -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.CompilerEnvironment -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices -import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics -import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters -import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory -import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices -import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices -import org.jetbrains.kotlin.resolve.lazy.ResolveSession -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice -import org.jetbrains.kotlin.util.slicedMap.WritableSlice -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin -import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor -import org.jetbrains.kotlin.ide.konan.NativePlatformKindResolution -import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass -import org.jetbrains.kotlin.platform.IdePlatformKind -import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind -import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind -import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind -import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind -import org.jetbrains.kotlin.platform.konan.NativePlatforms -import java.io.File - -const val JAR_SEPARATOR = "!/" -const val KLIB_EXTENSION = "klib" - -/** - * Kotlin as a service entry point - * - * Configures environment, analyses files and provides facilities to perform code processing without emitting bytecode - * - * $messageCollector: required by compiler infrastructure and will receive all compiler messages - * $body: optional and can be used to configure environment without creating local variable - */ -class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPlatform: Platform) : Disposable { - val configuration = CompilerConfiguration() - - init { - configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) - } - - fun createCoreEnvironment(): KotlinCoreEnvironment { - System.setProperty("idea.io.use.nio2", "true") - - val configFiles = when (analysisPlatform) { - Platform.jvm, Platform.common -> EnvironmentConfigFiles.JVM_CONFIG_FILES - Platform.native -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES - Platform.js -> EnvironmentConfigFiles.JS_CONFIG_FILES - } - - val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles) - val projectComponentManager = environment.project as MockComponentManager - - val projectFileIndex = CoreProjectFileIndex( - environment.project, - environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS) - ) - - val moduleManager = object : CoreModuleManager(environment.project, this) { - override fun getModules(): Array = arrayOf(projectFileIndex.module) - } - - CoreApplicationEnvironment.registerComponentInstance( - projectComponentManager.picoContainer, - ModuleManager::class.java, moduleManager - ) - - CoreApplicationEnvironment.registerExtensionPoint( - Extensions.getRootArea(), - OrderEnumerationHandler.EP_NAME, OrderEnumerationHandler.Factory::class.java - ) - - projectComponentManager.registerService( - ProjectFileIndex::class.java, - projectFileIndex - ) - - projectComponentManager.registerService( - ProjectRootManager::class.java, - CoreProjectRootManager(projectFileIndex) - ) - - registerExtensionPoint( - ApplicationExtensionDescriptor("org.jetbrains.kotlin.idePlatformKind", IdePlatformKind::class.java), - listOf( - CommonIdePlatformKind, - JvmIdePlatformKind, - JsIdePlatformKind, - NativeIdePlatformKind - ) - ) - - registerExtensionPoint( - IdePlatformKindResolution.Companion, - listOf( - CommonPlatformKindResolution(), - JvmPlatformKindResolution(), - JsPlatformKindResolution(), - NativePlatformKindResolution() - ) - ) - - return environment - } - - private fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = - when (analysisPlatform) { - Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) - Platform.js, Platform.common, Platform.native -> GlobalSearchScope.filesScope( - project, - sourceFiles.map { it.virtualFile }.toSet() - ) - } - - fun createResolutionFacade(environment: KotlinCoreEnvironment): Pair { - val projectContext = ProjectContext(environment.project, "Dokka") - val sourceFiles = environment.getSourceFiles() - - - val targetPlatform = when (analysisPlatform) { - Platform.js -> JsPlatforms.defaultJsPlatform - Platform.common -> CommonPlatforms.defaultCommonPlatform - Platform.native -> NativePlatforms.unspecifiedNativePlatform - Platform.jvm -> JvmPlatforms.defaultJvmPlatform - } - - val nativeLibraries = classpath.filter { it.extension == KLIB_EXTENSION } - .map { createNativeLibraryModuleInfo(it) } - - val library = object : LibraryModuleInfo { - override val analyzerServices: PlatformDependentAnalyzerServices = - analysisPlatform.analyzerServices() - override val name: Name = Name.special("") - override val platform: TargetPlatform = targetPlatform - override fun dependencies(): List = listOf(this) - override fun getLibraryRoots(): Collection = - classpath.filterNot { it.extension == KLIB_EXTENSION }.map { it.absolutePath } - } - - val module = object : ModuleInfo { - override val analyzerServices: PlatformDependentAnalyzerServices = - analysisPlatform.analyzerServices() - override val name: Name = Name.special("") - override val platform: TargetPlatform = targetPlatform - override fun dependencies(): List = listOf(this, library) + nativeLibraries - } - - val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) - val modulesContent: (ModuleInfo) -> ModuleContent = { - when (it) { - library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) - in nativeLibraries -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - else -> throw IllegalArgumentException("Unexpected module info") - } - } - - var builtIns: JvmBuiltIns? = null - - val resolverForProject = when (analysisPlatform) { - Platform.jvm -> { - builtIns = JvmBuiltIns( - projectContext.storageManager, - JvmBuiltIns.Kind.FROM_CLASS_LOADER - ) // TODO we should use FROM_DEPENDENCIES - createJvmResolverForProject( - projectContext, - module, - library, - modulesContent, - sourcesScope, - builtIns - ) - } - Platform.common -> createCommonResolverForProject( - projectContext, - module, - library, - modulesContent, - environment - ) - Platform.js -> createJsResolverForProject(projectContext, module, library, modulesContent) - Platform.native -> createNativeResolverForProject(projectContext, module, library, modulesContent) - - } - val libraryModuleDescriptor = resolverForProject.descriptorForModule(library) - val moduleDescriptor = resolverForProject.descriptorForModule(module) - builtIns?.initialize(moduleDescriptor, true) - - val resolverForLibrary = - resolverForProject.resolverForModule(library) // Required before module to initialize library properly - val resolverForModule = resolverForProject.resolverForModule(module) - val libraryResolutionFacade = - DokkaResolutionFacade(environment.project, libraryModuleDescriptor, resolverForLibrary) - val created = DokkaResolutionFacade(environment.project, moduleDescriptor, resolverForModule) - val projectComponentManager = environment.project as MockComponentManager - projectComponentManager.registerService(KotlinCacheService::class.java, CoreKotlinCacheService(created)) - - return created to libraryResolutionFacade - } - - private fun Platform.analyzerServices() = when (this) { - Platform.js -> JsPlatformAnalyzerServices - Platform.common -> CommonPlatformAnalyzerServices - Platform.native -> NativePlatformAnalyzerServices - Platform.jvm -> JvmPlatformAnalyzerServices - } - - private fun createNativeLibraryModuleInfo(libraryFile: File): LibraryModuleInfo { - val kotlinLibrary = createKotlinLibrary(org.jetbrains.kotlin.konan.file.File(libraryFile.absolutePath), "",false) - return object : LibraryModuleInfo { - override val analyzerServices: PlatformDependentAnalyzerServices = - analysisPlatform.analyzerServices() - override val name: Name = Name.special("") - override val platform: TargetPlatform = NativePlatforms.unspecifiedNativePlatform - override fun dependencies(): List = listOf(this) - override fun getLibraryRoots(): Collection = listOf(libraryFile.absolutePath) - override val capabilities: Map, Any?> - get() = super.capabilities + (KlibModuleOrigin.CAPABILITY to kotlinLibrary) - } - } - - private fun createCommonResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - library: LibraryModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent, - environment: KotlinCoreEnvironment - ): ResolverForProject { - return object : AbstractResolverForProject( - "Dokka", - projectContext, - modules = listOf(module, library) - ) { - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - - override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = - CommonResolverForModuleFactory( - CommonAnalysisParameters { content -> - environment.createPackagePartProvider(content.moduleContentScope) - }, - CompilerEnvironment, - unspecifiedJvmPlatform, - true - ).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT - ) - } - } - - private fun createJsResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - library: LibraryModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent - ): ResolverForProject { - return object : AbstractResolverForProject( - "Dokka", - projectContext, - modules = listOf(module, library) - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = JsResolverForModuleFactory( - CompilerEnvironment - ).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT - ) - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - private fun createNativeResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - library: LibraryModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent - ): ResolverForProject { - return object : AbstractResolverForProject( - "Dokka", - projectContext, - modules = module.dependencies() - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule { - - return NativeResolverForModuleFactory( - PlatformAnalysisParameters.Empty, - CompilerEnvironment, - NativePlatforms.unspecifiedNativePlatform - ).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT - ) - } - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - private fun createJvmResolverForProject( - projectContext: ProjectContext, - module: ModuleInfo, - library: LibraryModuleInfo, - modulesContent: (ModuleInfo) -> ModuleContent, - sourcesScope: GlobalSearchScope, - builtIns: KotlinBuiltIns - ): ResolverForProject { - val javaRoots = classpath - .mapNotNull { - val rootFile = when (it.extension) { - "jar" -> StandardFileSystems.jar().findFileByPath("${it.absolutePath}${JAR_SEPARATOR}") - else -> StandardFileSystems.local().findFileByPath(it.absolutePath) - } - rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) } - } - - return object : AbstractResolverForProject( - "Dokka", - projectContext, - modules = listOf(module, library) - ) { - override fun modulesContent(module: ModuleInfo): ModuleContent = - when (module) { - library -> ModuleContent(module, emptyList(), GlobalSearchScope.notScope(sourcesScope)) - module -> ModuleContent(module, emptyList(), sourcesScope) - else -> throw IllegalArgumentException("Unexpected module info") - } - - override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = builtIns - - override fun createResolverForModule( - descriptor: ModuleDescriptor, - moduleInfo: ModuleInfo - ): ResolverForModule = JvmResolverForModuleFactory( - JvmPlatformParameters({ content -> - JvmPackagePartProvider( - configuration.languageVersionSettings, - content.moduleContentScope - ) - .apply { - addRoots(javaRoots, messageCollector) - } - }, { - val file = (it as? BinaryJavaClass)?.virtualFile ?: (it as JavaClassImpl).psi.containingFile.virtualFile - if (file in sourcesScope) - module - else - library - }), - CompilerEnvironment, - unspecifiedJvmPlatform - ).createResolverForModule( - descriptor as ModuleDescriptorImpl, - projectContext.withModule(descriptor), - modulesContent(moduleInfo), - this, - LanguageVersionSettingsImpl.DEFAULT - ) - - override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null - } - } - - fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) { - val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE - val apiVersion = - apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion) - configuration.languageVersionSettings = LanguageVersionSettingsImpl(languageVersion, apiVersion) - } - - /** - * Classpath for this environment. - */ - val classpath: List - get() = configuration.jvmClasspathRoots - - /** - * Adds list of paths to classpath. - * $paths: collection of files to add - */ - fun addClasspath(paths: List) { - if (analysisPlatform == Platform.js) { - configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) - } - configuration.addJvmClasspathRoots(paths) - } - - /** - * Adds path to classpath. - * $path: path to add - */ - fun addClasspath(path: File) { - if (analysisPlatform == Platform.js) { - configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) - } - configuration.addJvmClasspathRoot(path) - } - - /** - * List of source roots for this environment. - */ - val sources: List - get() = configuration.get(CLIConfigurationKeys.CONTENT_ROOTS) - ?.filterIsInstance() - ?.map { it.path } ?: emptyList() - - /** - * Adds list of paths to source roots. - * $list: collection of files to add - */ - fun addSources(list: List) { - list.forEach { - configuration.addKotlinSourceRoot(it) - val file = File(it) - if (file.isDirectory || file.extension == ".java") { - configuration.addJavaSourceRoot(file) - } - } - } - - fun addRoots(list: List) { - configuration.addAll(CLIConfigurationKeys.CONTENT_ROOTS, list) - } - - /** - * Disposes the environment and frees all associated resources. - */ - override fun dispose() { - Disposer.dispose(this) - } - - companion object { - private fun registerExtensionPoint( - appExtension: ApplicationExtensionDescriptor, - instances: List - ) { - if (Extensions.getRootArea().hasExtensionPoint(appExtension.extensionPointName)) - return - - appExtension.registerExtensionPoint() - instances.forEach(appExtension::registerExtension) - } - } -} - -fun contentRootFromPath(path: String): ContentRoot { - val file = File(path) - return if (file.extension == "java") JavaSourceRoot(file, null) else KotlinSourceRoot(path, false) -} - - -class DokkaResolutionFacade( - override val project: Project, - override val moduleDescriptor: ModuleDescriptor, - val resolverForModule: ResolverForModule -) : ResolutionFacade { - override fun analyzeWithAllCompilerChecks(elements: Collection): AnalysisResult { - throw UnsupportedOperationException() - } - - override fun tryGetFrontendService(element: PsiElement, serviceClass: Class): T? { - return resolverForModule.componentProvider.tryGetService(serviceClass) - } - - override fun resolveToDescriptor( - declaration: KtDeclaration, - bodyResolveMode: BodyResolveMode - ): DeclarationDescriptor { - return resolveSession.resolveToDescriptor(declaration) - } - - override fun analyze(elements: Collection, bodyResolveMode: BodyResolveMode): BindingContext { - throw UnsupportedOperationException() - } - - val resolveSession: ResolveSession get() = getFrontendService(ResolveSession::class.java) - - override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext { - if (element is KtDeclaration) { - val descriptor = resolveToDescriptor(element) - return object : BindingContext { - override fun getKeys(p0: WritableSlice?): Collection { - throw UnsupportedOperationException() - } - - override fun getType(p0: KtExpression): KotlinType? { - throw UnsupportedOperationException() - } - - override fun get(slice: ReadOnlySlice?, key: K): V? { - if (key != element) { - throw UnsupportedOperationException() - } - return when { - slice == BindingContext.DECLARATION_TO_DESCRIPTOR -> descriptor as V - slice == BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER && (element as KtParameter).hasValOrVar() -> descriptor as V - else -> null - } - } - - override fun getDiagnostics(): Diagnostics { - throw UnsupportedOperationException() - } - - override fun addOwnDataTo(p0: BindingTrace, p1: Boolean) { - throw UnsupportedOperationException() - } - - override fun getSliceContents(p0: ReadOnlySlice): ImmutableMap { - throw UnsupportedOperationException() - } - - } - } - throw UnsupportedOperationException() - } - - override fun getFrontendService(element: PsiElement, serviceClass: Class): T { - throw UnsupportedOperationException() - } - - override fun getFrontendService(serviceClass: Class): T { - return resolverForModule.componentProvider.getService(serviceClass) - } - - override fun getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class): T { - return resolverForModule.componentProvider.getService(serviceClass) - } - - override fun getIdeService(serviceClass: Class): T { - throw UnsupportedOperationException() - } - -} diff --git a/core/src/main/kotlin/analysis/CoreKotlinCacheService.kt b/core/src/main/kotlin/analysis/CoreKotlinCacheService.kt deleted file mode 100644 index bcf91225..00000000 --- a/core/src/main/kotlin/analysis/CoreKotlinCacheService.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.jetbrains.dokka.analysis - -import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.analyzer.ModuleInfo -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache - - -class CoreKotlinCacheService(private val resolutionFacade: DokkaResolutionFacade) : KotlinCacheService { - override fun getResolutionFacade(elements: List): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacade( - elements: List, - platform: org.jetbrains.kotlin.platform.TargetPlatform - ): ResolutionFacade { - return resolutionFacade - } - - override fun getResolutionFacadeByFile( - file: PsiFile, - platform: org.jetbrains.kotlin.platform.TargetPlatform - ): ResolutionFacade? { - return resolutionFacade - } - - override fun getResolutionFacadeByModuleInfo( - moduleInfo: ModuleInfo, - platform: org.jetbrains.kotlin.platform.TargetPlatform - ): ResolutionFacade? { - return resolutionFacade - } - - override fun getSuppressionCache(): KotlinSuppressCache { - throw UnsupportedOperationException() - } - -} - diff --git a/core/src/main/kotlin/analysis/CoreProjectFileIndex.kt b/core/src/main/kotlin/analysis/CoreProjectFileIndex.kt deleted file mode 100644 index 45138e39..00000000 --- a/core/src/main/kotlin/analysis/CoreProjectFileIndex.kt +++ /dev/null @@ -1,569 +0,0 @@ -package org.jetbrains.dokka.analysis - -import com.intellij.openapi.Disposable -import com.intellij.openapi.components.BaseComponent -import com.intellij.openapi.extensions.ExtensionPointName -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.openapi.projectRoots.SdkAdditionalData -import com.intellij.openapi.projectRoots.SdkModificator -import com.intellij.openapi.projectRoots.SdkTypeId -import com.intellij.openapi.roots.* -import com.intellij.openapi.roots.impl.ProjectOrderEnumerator -import com.intellij.openapi.util.Condition -import com.intellij.openapi.util.Key -import com.intellij.openapi.util.UserDataHolderBase -import com.intellij.openapi.vfs.StandardFileSystems -import com.intellij.openapi.vfs.VfsUtilCore.getVirtualFileForJar -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.VirtualFileFilter -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.util.messages.MessageBus -import org.jetbrains.jps.model.module.JpsModuleSourceRootType -import org.jetbrains.kotlin.cli.common.config.ContentRoot -import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot -import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot -import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot -import org.picocontainer.PicoContainer -import java.io.File - -/** - * Workaround for the lack of ability to create a ProjectFileIndex implementation using only - * classes from projectModel-{api,impl}. - */ -class CoreProjectFileIndex(private val project: Project, contentRoots: List) : ProjectFileIndex, ModuleFileIndex { - override fun iterateContent(p0: ContentIterator, p1: VirtualFileFilter?): Boolean { - throw UnsupportedOperationException() - } - - override fun iterateContentUnderDirectory(p0: VirtualFile, p1: ContentIterator, p2: VirtualFileFilter?): Boolean { - throw UnsupportedOperationException() - } - - override fun isInLibrary(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - val sourceRoots = contentRoots.filter { it !is JvmClasspathRoot } - val classpathRoots = contentRoots.filterIsInstance() - - val module: Module = object : UserDataHolderBase(), Module { - override fun isDisposed(): Boolean { - throw UnsupportedOperationException() - } - - override fun getOptionValue(p0: String): String? { - throw UnsupportedOperationException() - } - - override fun clearOption(p0: String) { - throw UnsupportedOperationException() - } - - override fun getName(): String = "" - - override fun getModuleWithLibrariesScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleWithDependentsScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleContentScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun isLoaded(): Boolean { - throw UnsupportedOperationException() - } - - override fun setOption(p0: String, p1: String?) { - throw UnsupportedOperationException() - } - - override fun getModuleWithDependenciesScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleWithDependenciesAndLibrariesScope(p0: Boolean): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getProject(): Project = this@CoreProjectFileIndex.project - - override fun getModuleContentWithDependenciesScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleFilePath(): String { - throw UnsupportedOperationException() - } - - override fun getModuleTestsWithDependentsScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleScope(): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleScope(p0: Boolean): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleRuntimeScope(p0: Boolean): GlobalSearchScope { - throw UnsupportedOperationException() - } - - override fun getModuleFile(): VirtualFile? { - throw UnsupportedOperationException() - } - - override fun getExtensions(p0: ExtensionPointName): Array { - throw UnsupportedOperationException() - } - - override fun getComponent(p0: String): BaseComponent? { - throw UnsupportedOperationException() - } - - override fun getComponent(p0: Class, p1: T): T { - throw UnsupportedOperationException() - } - - override fun getComponent(interfaceClass: Class): T? { - if (interfaceClass == ModuleRootManager::class.java) { - return moduleRootManager as T - } - throw UnsupportedOperationException() - } - - override fun getDisposed(): Condition<*> { - throw UnsupportedOperationException() - } - - override fun getComponents(p0: Class): Array { - throw UnsupportedOperationException() - } - - override fun getPicoContainer(): PicoContainer { - throw UnsupportedOperationException() - } - - override fun hasComponent(p0: Class<*>): Boolean { - throw UnsupportedOperationException() - } - - override fun getMessageBus(): MessageBus { - throw UnsupportedOperationException() - } - - override fun dispose() { - throw UnsupportedOperationException() - } - } - - private val sdk: Sdk = object : Sdk, RootProvider { - override fun getFiles(rootType: OrderRootType): Array = classpathRoots - .mapNotNull { StandardFileSystems.local().findFileByPath(it.file.path) } - .toTypedArray() - - override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { - throw UnsupportedOperationException() - } - - override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener, p1: Disposable) { - throw UnsupportedOperationException() - } - - override fun getUrls(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun removeRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { - throw UnsupportedOperationException() - } - - override fun getSdkModificator(): SdkModificator { - throw UnsupportedOperationException() - } - - override fun getName(): String = "" - - override fun getRootProvider(): RootProvider = this - - override fun getHomePath(): String? { - throw UnsupportedOperationException() - } - - override fun getVersionString(): String? { - throw UnsupportedOperationException() - } - - override fun getSdkAdditionalData(): SdkAdditionalData? { - throw UnsupportedOperationException() - } - - override fun clone(): Any { - throw UnsupportedOperationException() - } - - override fun getSdkType(): SdkTypeId { - throw UnsupportedOperationException() - } - - override fun getHomeDirectory(): VirtualFile? { - throw UnsupportedOperationException() - } - - override fun getUserData(p0: Key): T? { - throw UnsupportedOperationException() - } - - override fun putUserData(p0: Key, p1: T?) { - throw UnsupportedOperationException() - } - } - - private val moduleSourceOrderEntry = object : ModuleSourceOrderEntry { - override fun getFiles(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun getUrls(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun accept(p0: RootPolicy, p1: R?): R { - throw UnsupportedOperationException() - } - - - override fun getPresentableName(): String { - throw UnsupportedOperationException() - } - - override fun getOwnerModule(): Module = module - - - override fun isValid(): Boolean { - throw UnsupportedOperationException() - } - - override fun compareTo(other: OrderEntry?): Int { - throw UnsupportedOperationException() - } - - override fun getRootModel(): ModuleRootModel = moduleRootManager - - override fun isSynthetic(): Boolean { - throw UnsupportedOperationException() - } - } - - private val sdkOrderEntry = object : JdkOrderEntry { - override fun getFiles(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun getUrls(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun accept(p0: RootPolicy, p1: R?): R { - throw UnsupportedOperationException() - } - - override fun getJdkName(): String? { - throw UnsupportedOperationException() - } - - override fun getJdk(): Sdk = sdk - - override fun getPresentableName(): String { - throw UnsupportedOperationException() - } - - override fun getOwnerModule(): Module { - throw UnsupportedOperationException() - } - - override fun isValid(): Boolean { - throw UnsupportedOperationException() - } - - override fun getRootFiles(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun getRootUrls(p0: OrderRootType): Array { - throw UnsupportedOperationException() - } - - override fun compareTo(other: OrderEntry?): Int { - throw UnsupportedOperationException() - } - - override fun isSynthetic(): Boolean { - throw UnsupportedOperationException() - } - - } - - inner class MyModuleRootManager : ModuleRootManager() { - override fun getExternalSource(): ProjectModelExternalSource? { - throw UnsupportedOperationException() - } - - override fun getExcludeRoots(): Array { - throw UnsupportedOperationException() - } - - override fun getContentEntries(): Array { - throw UnsupportedOperationException() - } - - override fun getExcludeRootUrls(): Array { - throw UnsupportedOperationException() - } - - override fun processOrder(p0: RootPolicy, p1: R): R { - throw UnsupportedOperationException() - } - - override fun getSourceRoots(p0: Boolean): Array { - throw UnsupportedOperationException() - } - - override fun getSourceRoots(): Array { - throw UnsupportedOperationException() - } - - override fun getSourceRoots(p0: JpsModuleSourceRootType<*>): MutableList { - throw UnsupportedOperationException() - } - - override fun getSourceRoots(p0: MutableSet>): MutableList { - throw UnsupportedOperationException() - } - - override fun getContentRoots(): Array { - throw UnsupportedOperationException() - } - - override fun orderEntries(): OrderEnumerator = - ProjectOrderEnumerator(project, null).using(object : RootModelProvider { - override fun getModules(): Array = arrayOf(module) - - override fun getRootModel(p0: Module): ModuleRootModel = this@MyModuleRootManager - }) - - override fun getModuleExtension(p0: Class): T { - throw UnsupportedOperationException() - } - - override fun getDependencyModuleNames(): Array { - throw UnsupportedOperationException() - } - - override fun getModule(): Module = this@CoreProjectFileIndex.module - - override fun isSdkInherited(): Boolean { - throw UnsupportedOperationException() - } - - override fun getOrderEntries(): Array = arrayOf(moduleSourceOrderEntry, sdkOrderEntry) - - override fun getSourceRootUrls(): Array { - throw UnsupportedOperationException() - } - - override fun getSourceRootUrls(p0: Boolean): Array { - throw UnsupportedOperationException() - } - - override fun getSdk(): Sdk? { - throw UnsupportedOperationException() - } - - override fun getContentRootUrls(): Array { - throw UnsupportedOperationException() - } - - override fun getModuleDependencies(): Array { - throw UnsupportedOperationException() - } - - override fun getModuleDependencies(p0: Boolean): Array { - throw UnsupportedOperationException() - } - - override fun getModifiableModel(): ModifiableRootModel { - throw UnsupportedOperationException() - } - - override fun isDependsOn(p0: Module): Boolean { - throw UnsupportedOperationException() - } - - override fun getFileIndex(): ModuleFileIndex { - return this@CoreProjectFileIndex - } - - override fun getDependencies(): Array { - throw UnsupportedOperationException() - } - - override fun getDependencies(p0: Boolean): Array { - throw UnsupportedOperationException() - } - } - - val moduleRootManager = MyModuleRootManager() - - override fun getContentRootForFile(p0: VirtualFile): VirtualFile? { - throw UnsupportedOperationException() - } - - override fun getContentRootForFile(p0: VirtualFile, p1: Boolean): VirtualFile? { - throw UnsupportedOperationException() - } - - override fun getPackageNameByDirectory(p0: VirtualFile): String? { - throw UnsupportedOperationException() - } - - override fun isInLibrarySource(file: VirtualFile): Boolean = false - - override fun getClassRootForFile(file: VirtualFile): VirtualFile? = - classpathRoots.firstOrNull { it.contains(file) }?.let { StandardFileSystems.local().findFileByPath(it.file.path) } - - override fun getOrderEntriesForFile(file: VirtualFile): List = - if (classpathRoots.contains(file)) listOf(sdkOrderEntry) else emptyList() - - override fun isInLibraryClasses(file: VirtualFile): Boolean = classpathRoots.contains(file) - - override fun isExcluded(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun getSourceRootForFile(p0: VirtualFile): VirtualFile? { - throw UnsupportedOperationException() - } - - override fun isUnderIgnored(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun isLibraryClassFile(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun getModuleForFile(file: VirtualFile): Module? = - if (sourceRoots.contains(file)) module else null - - private fun List.contains(file: VirtualFile): Boolean = any { it.contains(file) } - - override fun getModuleForFile(p0: VirtualFile, p1: Boolean): Module? { - throw UnsupportedOperationException() - } - - override fun isInSource(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun isIgnored(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun isContentSourceFile(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun isInSourceContent(file: VirtualFile): Boolean = sourceRoots.contains(file) - - override fun iterateContent(p0: ContentIterator): Boolean { - throw UnsupportedOperationException() - } - - override fun isInContent(p0: VirtualFile): Boolean { - throw UnsupportedOperationException() - } - - override fun iterateContentUnderDirectory(p0: VirtualFile, p1: ContentIterator): Boolean { - throw UnsupportedOperationException() - } - - override fun isInTestSourceContent(file: VirtualFile): Boolean = false - - override fun isUnderSourceRootOfType(p0: VirtualFile, p1: MutableSet>): Boolean { - throw UnsupportedOperationException() - } - - override fun getOrderEntryForFile(p0: VirtualFile): OrderEntry? { - throw UnsupportedOperationException() - } -} - -class CoreProjectRootManager(val projectFileIndex: CoreProjectFileIndex) : ProjectRootManager() { - override fun orderEntries(): OrderEnumerator { - throw UnsupportedOperationException() - } - - override fun orderEntries(p0: MutableCollection): OrderEnumerator { - throw UnsupportedOperationException() - } - - override fun getContentRootsFromAllModules(): Array { - throw UnsupportedOperationException() - } - - override fun setProjectSdk(p0: Sdk?) { - throw UnsupportedOperationException() - } - - override fun setProjectSdkName(p0: String) { - throw UnsupportedOperationException() - } - - override fun getModuleSourceRoots(p0: MutableSet>): MutableList { - throw UnsupportedOperationException() - } - - override fun getContentSourceRoots(): Array { - throw UnsupportedOperationException() - } - - override fun getFileIndex(): ProjectFileIndex = projectFileIndex - - override fun getProjectSdkName(): String? { - throw UnsupportedOperationException() - } - - override fun getProjectSdk(): Sdk? { - throw UnsupportedOperationException() - } - - override fun getContentRoots(): Array { - throw UnsupportedOperationException() - } - - override fun getContentRootUrls(): MutableList { - throw UnsupportedOperationException() - } - -} - -fun ContentRoot.contains(file: VirtualFile) = when (this) { - is JvmContentRoot -> { - val path = if (file.fileSystem.protocol == StandardFileSystems.JAR_PROTOCOL) - getVirtualFileForJar(file)?.path ?: file.path - else - file.path - File(path).startsWith(this.file.absoluteFile) - } - is KotlinSourceRoot -> File(file.path).startsWith(File(this.path).absoluteFile) - else -> false -} diff --git a/core/src/main/kotlin/analysis/JavaResolveExtension.kt b/core/src/main/kotlin/analysis/JavaResolveExtension.kt deleted file mode 100644 index ab6bec9c..00000000 --- a/core/src/main/kotlin/analysis/JavaResolveExtension.kt +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:JvmName("JavaResolutionUtils") - -package org.jetbrains.dokka.analysis - -import com.intellij.psi.* -import org.jetbrains.kotlin.asJava.unwrapped -import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.load.java.sources.JavaSourceElement -import org.jetbrains.kotlin.load.java.structure.* -import org.jetbrains.kotlin.load.java.structure.impl.* -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver -import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter -import org.jetbrains.kotlin.resolve.scopes.MemberScope - -// TODO: Remove that file - -@JvmOverloads -fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { - val method = originalElement as? PsiMethod ?: return null - if (method.containingClass == null || !Name.isValidIdentifier(method.name)) return null - val resolver = method.getJavaDescriptorResolver(resolutionFacade) - return when { - method.isConstructor -> resolver?.resolveConstructor(JavaConstructorImpl(method)) - else -> resolver?.resolveMethod(JavaMethodImpl(method)) - } -} - -@JvmOverloads -fun PsiClass.getJavaClassDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): ClassDescriptor? { - val psiClass = originalElement as? PsiClass ?: return null - return psiClass.getJavaDescriptorResolver(resolutionFacade)?.resolveClass(JavaClassImpl(psiClass)) -} - -@JvmOverloads -fun PsiField.getJavaFieldDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): PropertyDescriptor? { - val field = originalElement as? PsiField ?: return null - return field.getJavaDescriptorResolver(resolutionFacade)?.resolveField(JavaFieldImpl(field)) -} - -@JvmOverloads -fun PsiMember.getJavaMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { - return when (this) { - is PsiEnumConstant -> containingClass?.getJavaClassDescriptor(resolutionFacade) - is PsiClass -> getJavaClassDescriptor(resolutionFacade) - is PsiMethod -> getJavaMethodDescriptor(resolutionFacade) - is PsiField -> getJavaFieldDescriptor(resolutionFacade) - else -> null - } -} - -@JvmOverloads -fun PsiMember.getJavaOrKotlinMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { - val callable = unwrapped - return when (callable) { - is PsiMember -> getJavaMemberDescriptor(resolutionFacade) - is KtDeclaration -> { - val descriptor = resolutionFacade.resolveToDescriptor(callable) - if (descriptor is ClassDescriptor && this is PsiMethod) descriptor.unsubstitutedPrimaryConstructor else descriptor - } - else -> null - } -} - -private fun PsiElement.getJavaDescriptorResolver(resolutionFacade: ResolutionFacade): JavaDescriptorResolver? { - return resolutionFacade.tryGetFrontendService(this, JavaDescriptorResolver::class.java) -} - -private fun JavaDescriptorResolver.resolveMethod(method: JavaMethod): DeclarationDescriptor? { - return getContainingScope(method) - ?.getContributedDescriptors(nameFilter = { true }, kindFilter = DescriptorKindFilter.CALLABLES) - ?.filterIsInstance() - ?.findByJavaElement(method) -} - -private fun JavaDescriptorResolver.resolveConstructor(constructor: JavaConstructor): ConstructorDescriptor? { - return resolveClass(constructor.containingClass)?.constructors?.findByJavaElement(constructor) -} - -private fun JavaDescriptorResolver.resolveField(field: JavaField): PropertyDescriptor? { - return getContainingScope(field)?.getContributedVariables(field.name, NoLookupLocation.FROM_IDE)?.findByJavaElement(field) -} - -private fun JavaDescriptorResolver.getContainingScope(member: JavaMember): MemberScope? { - val containingClass = resolveClass(member.containingClass) - return if (member.isStatic) - containingClass?.staticScope - else - containingClass?.defaultType?.memberScope -} - -private fun Collection.findByJavaElement(javaElement: JavaElement): T? { - return firstOrNull { member -> - val memberJavaElement = (member.original.source as? JavaSourceElement)?.javaElement - when { - memberJavaElement == javaElement -> - true - memberJavaElement is JavaElementImpl<*> && javaElement is JavaElementImpl<*> -> - memberJavaElement.psi.isEquivalentTo(javaElement.psi) - else -> - false - } - } -} - -fun PsiElement.javaResolutionFacade() = - KotlinCacheService.getInstance(project).getResolutionFacadeByFile(this.originalElement.containingFile, JvmPlatforms.defaultJvmPlatform)!! diff --git a/core/src/main/kotlin/links/DRI.kt b/core/src/main/kotlin/links/DRI.kt index 9cc51fb7..3f6d886f 100644 --- a/core/src/main/kotlin/links/DRI.kt +++ b/core/src/main/kotlin/links/DRI.kt @@ -1,15 +1,5 @@ package org.jetbrains.dokka.links -import com.intellij.psi.* -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf -import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeProjection -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - /** * [DRI] stands for DokkaResourceIdentifier */ @@ -21,33 +11,10 @@ data class DRI( val extra: String? = null ) { override fun toString(): String = - "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature().orEmpty()}/$target/${extra.orEmpty()}" + "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature() + .orEmpty()}/$target/${extra.orEmpty()}" companion object { - fun from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run { - val callable = firstIsInstanceOrNull() - DRI( - firstIsInstanceOrNull()?.fqName?.asString(), - (filterIsInstance() + filterIsInstance()).toList() - .takeIf { it.isNotEmpty() } - ?.asReversed() - ?.joinToString(separator = ".") { it.name.asString() }, - callable?.let { Callable.from(it) }, - DriTarget.from(descriptor) - ) - } - - fun from(psi: PsiElement) = psi.parentsWithSelf.run { - val psiMethod = firstIsInstanceOrNull() - val psiField = firstIsInstanceOrNull() - val classes = filterIsInstance().toList() - DRI( - classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', ""), - classes.toList().takeIf { it.isNotEmpty() }?.asReversed()?.mapNotNull { it.name }?.joinToString("."), - psiMethod?.let { Callable.from(it) } ?: psiField?.let { Callable.from(it) } , - DriTarget.from(psi) - ) - } val topLevel = DRI() } } @@ -78,71 +45,11 @@ data class Callable( ) { fun signature() = "${receiver?.toString().orEmpty()}#${params.joinToString("#")}" - companion object { - fun from(descriptor: CallableDescriptor) = with(descriptor) { - Callable( - name.asString(), - extensionReceiverParameter?.let { TypeReference.from(it) }, - valueParameters.mapNotNull { TypeReference.from(it) } - ) - } - - fun from(psi: PsiMethod) = with(psi) { - Callable( - name, - null, - parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) }) - } - - fun from(psi: PsiField): Callable { - return Callable( - name = psi.name, - receiver = null, - params = emptyList() - ) - } - } + companion object } sealed class TypeReference { - companion object { - fun from(d: ReceiverParameterDescriptor): TypeReference? = - when (d.value) { - is ExtensionReceiver -> fromPossiblyNullable(d.type) - else -> run { - println("Unknown value type for $d") - null - } - } - - fun from(d: ValueParameterDescriptor): TypeReference? = - fromPossiblyNullable(d.type) - - fun from(p: PsiClass) = TypeReference - - private fun fromPossiblyNullable(t: KotlinType, self: KotlinType? = null): TypeReference = - from(t, self).let { if (t.isMarkedNullable) Nullable(it) else it } - - private fun from(t: KotlinType, self: KotlinType? = null): TypeReference = - if (self is KotlinType && self.constructor == t.constructor && self.arguments == t.arguments) - SelfType - else when (val d = t.constructor.declarationDescriptor) { - is TypeParameterDescriptor -> TypeParam( - d.upperBounds.map { fromPossiblyNullable(it, self ?: t) } - ) - else -> TypeConstructor( - t.constructorName.orEmpty(), - t.arguments.map { fromProjection(it, self) } - ) - } - - private fun fromProjection(t: TypeProjection, r: KotlinType? = null): TypeReference = - if (t.isStarProjection) { - StarProjection - } else { - fromPossiblyNullable(t.type, r) - } - } + companion object } data class JavaClassReference(val name: String) : TypeReference() { @@ -171,39 +78,10 @@ object StarProjection : TypeReference() { override fun toString() = "*" } -private val KotlinType.constructorName - get() = constructor.declarationDescriptor?.fqNameSafe?.asString() - sealed class DriTarget { override fun toString(): String = this.javaClass.simpleName - companion object { - fun from(descriptor: DeclarationDescriptor): DriTarget = descriptor.parentsWithSelf.run { - return when (descriptor) { - is TypeParameterDescriptor -> PointingToGenericParameters(descriptor.index) - else -> { - val callable = firstIsInstanceOrNull() - val params = - callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty() - val parameterDescriptor = firstIsInstanceOrNull() - - parameterDescriptor?.let { PointingToCallableParameters(params.indexOf(it)) } - ?: PointingToDeclaration - } - } - } - - fun from(psi: PsiElement): DriTarget = psi.parentsWithSelf.run { - return when (psi) { - is PsiTypeParameter -> PointingToGenericParameters(psi.index) - else -> firstIsInstanceOrNull()?.let { - val callable = firstIsInstanceOrNull() - val params = (callable?.parameterList?.parameters).orEmpty() - PointingToCallableParameters(params.indexOf(it)) - } ?: PointingToDeclaration - } - } - } + companion object } data class PointingToGenericParameters(val parameterIndex: Int) : DriTarget() { diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt index 90958210..768bddc5 100644 --- a/core/src/main/kotlin/model/Documentable.kt +++ b/core/src/main/kotlin/model/Documentable.kt @@ -1,12 +1,10 @@ package org.jetbrains.dokka.model -import com.intellij.psi.PsiNamedElement import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.properties.WithExtraProperties -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.load.kotlin.toSourceElement + abstract class Documentable { abstract val name: String? @@ -406,11 +404,3 @@ fun SourceSetDependent?.orEmpty(): SourceSetDependent = this ?: emptyM interface DocumentableSource { val path: String } - -class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : DocumentableSource { - override val path = descriptor.toSourceElement.containingFile.toString() -} - -class PsiDocumentableSource(val psi: PsiNamedElement) : DocumentableSource { - override val path = psi.containingFile.virtualFile.path -} \ No newline at end of file diff --git a/core/src/main/kotlin/model/properties/PropertyContainer.kt b/core/src/main/kotlin/model/properties/PropertyContainer.kt index 107bede5..e1e0250e 100644 --- a/core/src/main/kotlin/model/properties/PropertyContainer.kt +++ b/core/src/main/kotlin/model/properties/PropertyContainer.kt @@ -1,7 +1,5 @@ package org.jetbrains.dokka.model.properties -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull - class PropertyContainer internal constructor( @PublishedApi internal val map: Map, ExtraProperty> ) { @@ -45,7 +43,7 @@ fun C.mergeExtras(left: C, right: C): C where C : Any, C : WithExtraProperti (l.key as ExtraProperty.Key>).mergeStrategyFor(l, r) } - strategies.firstIsInstanceOrNull()?.error?.invoke() + strategies.filterIsInstance().firstOrNull()?.error?.invoke() val replaces: List> = strategies.filterIsInstance>().map { it.newProperty } diff --git a/core/src/main/kotlin/parsers/HtmlParser.kt b/core/src/main/kotlin/parsers/HtmlParser.kt deleted file mode 100644 index a0652b95..00000000 --- a/core/src/main/kotlin/parsers/HtmlParser.kt +++ /dev/null @@ -1,89 +0,0 @@ -package org.jetbrains.dokka.parsers - -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.parsers.factories.DocTagsFromStringFactory -import org.jsoup.Jsoup -import org.jsoup.nodes.Node -import org.jsoup.select.NodeFilter -import org.jsoup.select.NodeTraversor - -class HtmlParser : Parser() { - - inner class NodeFilterImpl : NodeFilter { - - private val nodesCache: MutableMap> = mutableMapOf() - private var currentDepth = 0 - - fun collect(): DocTag = nodesCache[currentDepth]!![0] - - override fun tail(node: Node?, depth: Int): NodeFilter.FilterResult { - val nodeName = node!!.nodeName() - val nodeAttributes = node.attributes() - - if(nodeName in listOf("#document", "html", "head")) - return NodeFilter.FilterResult.CONTINUE - - val body: String - val params: Map - - - if(nodeName != "#text") { - body = "" - params = nodeAttributes.map { it.key to it.value }.toMap() - } else { - body = nodeAttributes["#text"] - params = emptyMap() - } - - val docNode = if(depth < currentDepth) { - DocTagsFromStringFactory.getInstance(nodeName, nodesCache.getOrDefault(currentDepth, mutableListOf()).toList(), params, body).also { - nodesCache[currentDepth] = mutableListOf() - currentDepth = depth - } - } else { - DocTagsFromStringFactory.getInstance(nodeName, emptyList(), params, body) - } - - nodesCache.getOrDefault(depth, mutableListOf()) += docNode - return NodeFilter.FilterResult.CONTINUE - } - - override fun head(node: Node?, depth: Int): NodeFilter.FilterResult { - - val nodeName = node!!.nodeName() - - if(currentDepth < depth) { - currentDepth = depth - nodesCache[currentDepth] = mutableListOf() - } - - if(nodeName in listOf("#document", "html", "head")) - return NodeFilter.FilterResult.CONTINUE - - return NodeFilter.FilterResult.CONTINUE - } - } - - - private fun htmlToDocNode(string: String): DocTag { - val document = Jsoup.parse(string) - val nodeFilterImpl = NodeFilterImpl() - NodeTraversor.filter(nodeFilterImpl, document.root()) - return nodeFilterImpl.collect() - } - - private fun replaceLinksWithHrefs(javadoc: String): String = Regex("\\{@link .*?}").replace(javadoc) { - val split = it.value.dropLast(1).split(" ") - if(split.size !in listOf(2, 3)) - return@replace it.value - if(split.size == 3) - return@replace "${split[2]}" - else - return@replace "${split[1]}" - } - - override fun parseStringToDocNode(extractedString: String) = htmlToDocNode(extractedString) - override fun preparse(text: String) = replaceLinksWithHrefs(text) -} - - diff --git a/core/src/main/kotlin/parsers/MarkdownParser.kt b/core/src/main/kotlin/parsers/MarkdownParser.kt deleted file mode 100644 index 07e1fcc3..00000000 --- a/core/src/main/kotlin/parsers/MarkdownParser.kt +++ /dev/null @@ -1,418 +0,0 @@ -package org.jetbrains.dokka.parsers - -import com.intellij.psi.PsiElement -import org.jetbrains.dokka.model.doc.* -import org.intellij.markdown.MarkdownElementTypes -import org.intellij.markdown.MarkdownTokenTypes -import org.intellij.markdown.ast.ASTNode -import org.intellij.markdown.ast.CompositeASTNode -import org.intellij.markdown.ast.LeafASTNode -import org.intellij.markdown.ast.impl.ListItemCompositeNode -import org.intellij.markdown.flavours.gfm.GFMElementTypes -import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor -import org.intellij.markdown.flavours.gfm.GFMTokenTypes -import org.jetbrains.dokka.analysis.DokkaResolutionFacade -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.parsers.factories.DocTagsFromIElementFactory -import org.jetbrains.dokka.utilities.DokkaLogger -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink -import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag -import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection -import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import java.net.MalformedURLException -import org.intellij.markdown.parser.MarkdownParser as IntellijMarkdownParser - -class MarkdownParser( - private val resolutionFacade: DokkaResolutionFacade? = null, - private val declarationDescriptor: DeclarationDescriptor? = null, - private val logger: DokkaLogger -) : Parser() { - - inner class MarkdownVisitor(val text: String, val destinationLinksMap: Map) { - - private fun headersHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - node.type, - visitNode(node.children.find { it.type == MarkdownTokenTypes.ATX_CONTENT } - ?: throw IllegalStateException("Wrong AST Tree. ATX Header does not contain expected content")).children - ) - - private fun horizontalRulesHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance(MarkdownTokenTypes.HORIZONTAL_RULE) - - private fun emphasisHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - node.type, - children = listOf(visitNode(node.children[node.children.size / 2])) - ) - - private fun blockquotesHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - node.type, children = node.children - .filterIsInstance() - .evaluateChildren() - ) - - private fun listsHandler(node: ASTNode): DocTag { - - val children = node.children.filterIsInstance().flatMap { - if (it.children.last().type in listOf( - MarkdownElementTypes.ORDERED_LIST, - MarkdownElementTypes.UNORDERED_LIST - ) - ) { - val nestedList = it.children.last() - (it.children as MutableList).removeAt(it.children.lastIndex) - listOf(it, nestedList) - } else - listOf(it) - } - - return DocTagsFromIElementFactory.getInstance( - node.type, - children = - children - .map { - if (it.type == MarkdownElementTypes.LIST_ITEM) - DocTagsFromIElementFactory.getInstance( - it.type, - children = it - .children - .filterIsInstance() - .evaluateChildren() - ) - else - visitNode(it) - }, - params = - if (node.type == MarkdownElementTypes.ORDERED_LIST) { - val listNumberNode = node.children.first().children.first() - mapOf( - "start" to text.substring( - listNumberNode.startOffset, - listNumberNode.endOffset - ).trim().dropLast(1) - ) - } else - emptyMap() - ) - } - - private fun resolveDRI(mdLink: String): DRI? = - mdLink - .removePrefix("[") - .removeSuffix("]") - .let { link -> - try { - java.net.URL(link) - null - } catch (e: MalformedURLException) { - try { - if (resolutionFacade != null && declarationDescriptor != null) { - resolveKDocLink( - resolutionFacade.resolveSession.bindingContext, - resolutionFacade, - declarationDescriptor, - null, - link.split('.') - ).minBy { it is ClassDescriptor }?.let { DRI.from(it) } - } else null - } catch (e1: IllegalArgumentException) { - null - } - } - } - - private fun referenceLinksHandler(node: ASTNode): DocTag { - val linkLabel = node.children.find { it.type == MarkdownElementTypes.LINK_LABEL } - ?: throw IllegalStateException("Wrong AST Tree. Reference link does not contain expected content") - val linkText = node.children.findLast { it.type == MarkdownElementTypes.LINK_TEXT } ?: linkLabel - - val linkKey = text.substring(linkLabel.startOffset, linkLabel.endOffset) - - val link = destinationLinksMap[linkKey.toLowerCase()] ?: linkKey - - return linksHandler(linkText, link) - } - - private fun inlineLinksHandler(node: ASTNode): DocTag { - val linkText = node.children.find { it.type == MarkdownElementTypes.LINK_TEXT } - ?: throw IllegalStateException("Wrong AST Tree. Inline link does not contain expected content") - val linkDestination = node.children.find { it.type == MarkdownElementTypes.LINK_DESTINATION } - ?: throw IllegalStateException("Wrong AST Tree. Inline link does not contain expected content") - val linkTitle = node.children.find { it.type == MarkdownElementTypes.LINK_TITLE } - - val link = text.substring(linkDestination.startOffset, linkDestination.endOffset) - - return linksHandler(linkText, link, linkTitle) - } - - private fun autoLinksHandler(node: ASTNode): DocTag { - val link = text.substring(node.startOffset + 1, node.endOffset - 1) - - return linksHandler(node, link) - } - - private fun linksHandler(linkText: ASTNode, link: String, linkTitle: ASTNode? = null): DocTag { - val dri: DRI? = resolveDRI(link) - val params = if (linkTitle == null) - mapOf("href" to link) - else - mapOf("href" to link, "title" to text.substring(linkTitle.startOffset + 1, linkTitle.endOffset - 1)) - - return DocTagsFromIElementFactory.getInstance( - MarkdownElementTypes.INLINE_LINK, - params = params, - children = linkText.children.drop(1).dropLast(1).evaluateChildren(), - dri = dri - ) - } - - private fun imagesHandler(node: ASTNode): DocTag { - val linkNode = - node.children.last().children.find { it.type == MarkdownElementTypes.LINK_LABEL }!!.children[1] - val link = text.substring(linkNode.startOffset, linkNode.endOffset) - val src = mapOf("src" to link) - return DocTagsFromIElementFactory.getInstance( - node.type, - params = src, - children = listOf(visitNode(node.children.last().children.find { it.type == MarkdownElementTypes.LINK_TEXT }!!)) - ) - } - - private fun codeSpansHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - node.type, - children = listOf( - DocTagsFromIElementFactory.getInstance( - MarkdownTokenTypes.TEXT, - body = text.substring(node.startOffset + 1, node.endOffset - 1).replace('\n', ' ').trimIndent() - ) - - ) - ) - - private fun codeFencesHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - node.type, - children = node - .children - .dropWhile { it.type != MarkdownTokenTypes.CODE_FENCE_CONTENT } - .dropLastWhile { it.type != MarkdownTokenTypes.CODE_FENCE_CONTENT } - .map { - if (it.type == MarkdownTokenTypes.EOL) - LeafASTNode(MarkdownTokenTypes.HARD_LINE_BREAK, 0, 0) - else - it - }.evaluateChildren(), - params = node - .children - .find { it.type == MarkdownTokenTypes.FENCE_LANG } - ?.let { mapOf("lang" to text.substring(it.startOffset, it.endOffset)) } - ?: emptyMap() - ) - - private fun codeBlocksHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance(node.type, children = node.children.evaluateChildren()) - - private fun defaultHandler(node: ASTNode): DocTag = - DocTagsFromIElementFactory.getInstance( - MarkdownElementTypes.PARAGRAPH, - children = node.children.evaluateChildren() - ) - - fun visitNode(node: ASTNode): DocTag = - when (node.type) { - MarkdownElementTypes.ATX_1, - MarkdownElementTypes.ATX_2, - MarkdownElementTypes.ATX_3, - MarkdownElementTypes.ATX_4, - MarkdownElementTypes.ATX_5, - MarkdownElementTypes.ATX_6 -> headersHandler(node) - MarkdownTokenTypes.HORIZONTAL_RULE -> horizontalRulesHandler(node) - MarkdownElementTypes.STRONG, - MarkdownElementTypes.EMPH -> emphasisHandler(node) - MarkdownElementTypes.FULL_REFERENCE_LINK, - MarkdownElementTypes.SHORT_REFERENCE_LINK -> referenceLinksHandler(node) - MarkdownElementTypes.INLINE_LINK -> inlineLinksHandler(node) - MarkdownElementTypes.AUTOLINK -> autoLinksHandler(node) - MarkdownElementTypes.BLOCK_QUOTE -> blockquotesHandler(node) - MarkdownElementTypes.UNORDERED_LIST, - MarkdownElementTypes.ORDERED_LIST -> listsHandler(node) - MarkdownElementTypes.CODE_BLOCK -> codeBlocksHandler(node) - MarkdownElementTypes.CODE_FENCE -> codeFencesHandler(node) - MarkdownElementTypes.CODE_SPAN -> codeSpansHandler(node) - MarkdownElementTypes.IMAGE -> imagesHandler(node) - MarkdownTokenTypes.HARD_LINE_BREAK -> DocTagsFromIElementFactory.getInstance(node.type) - MarkdownTokenTypes.CODE_FENCE_CONTENT, - MarkdownTokenTypes.CODE_LINE, - MarkdownTokenTypes.TEXT -> DocTagsFromIElementFactory.getInstance( - MarkdownTokenTypes.TEXT, - body = text - .substring(node.startOffset, node.endOffset).transform() - ) - MarkdownElementTypes.MARKDOWN_FILE -> if (node.children.size == 1) visitNode(node.children.first()) else defaultHandler( - node - ) - GFMElementTypes.STRIKETHROUGH -> DocTagsFromIElementFactory.getInstance( - GFMElementTypes.STRIKETHROUGH, - body = text - .substring(node.startOffset, node.endOffset).transform() - ) - GFMElementTypes.TABLE -> DocTagsFromIElementFactory.getInstance( - GFMElementTypes.TABLE, - children = node.children.filterTabSeparators().evaluateChildren() - ) - GFMElementTypes.HEADER -> DocTagsFromIElementFactory.getInstance( - GFMElementTypes.HEADER, - children = node.children.filterTabSeparators().evaluateChildren() - ) - GFMElementTypes.ROW -> DocTagsFromIElementFactory.getInstance( - GFMElementTypes.ROW, - children = node.children.filterTabSeparators().evaluateChildren() - ) - else -> defaultHandler(node) - } - - private fun List.filterTabSeparators() = - this.filterNot { it.type == GFMTokenTypes.TABLE_SEPARATOR } - - private fun List.evaluateChildren(): List = - this.removeUselessTokens().mergeLeafASTNodes().map { visitNode(it) } - - private fun List.removeUselessTokens(): List = - this.filterIndexed { index, node -> - !(node.type == MarkdownElementTypes.LINK_DEFINITION || ( - node.type == MarkdownTokenTypes.EOL && - this.getOrNull(index - 1)?.type == MarkdownTokenTypes.HARD_LINE_BREAK - )) - } - - private val notLeafNodes = listOf(MarkdownTokenTypes.HORIZONTAL_RULE, MarkdownTokenTypes.HARD_LINE_BREAK) - - private fun List.isNotLeaf(index: Int): Boolean = - if (index in 0..this.lastIndex) - (this[index] is CompositeASTNode) || this[index].type in notLeafNodes - else - false - - private fun List.mergeLeafASTNodes(): List { - val children: MutableList = mutableListOf() - var index = 0 - while (index <= this.lastIndex) { - if (this.isNotLeaf(index)) { - children += this[index] - } else { - val startOffset = this[index].startOffset - while (index < this.lastIndex) { - if (this.isNotLeaf(index + 1) || this[index + 1].startOffset != this[index].endOffset) { - val endOffset = this[index].endOffset - if (text.substring(startOffset, endOffset).transform().trim().isNotEmpty()) - children += LeafASTNode(MarkdownTokenTypes.TEXT, startOffset, endOffset) - break - } - index++ - } - if (index == this.lastIndex) { - val endOffset = this[index].endOffset - if (text.substring(startOffset, endOffset).transform().trim().isNotEmpty()) - children += LeafASTNode(MarkdownTokenTypes.TEXT, startOffset, endOffset) - } - } - index++ - } - return children - } - - private fun String.transform() = this - .replace(Regex("\n\n+"), "") // Squashing new lines between paragraphs - .replace(Regex("\n"), " ") - .replace(Regex(" >+ +"), " ") // Replacement used in blockquotes, get rid of garbage - } - - - private fun getAllDestinationLinks(text: String, node: ASTNode): List> = - node.children - .filter { it.type == MarkdownElementTypes.LINK_DEFINITION } - .map { - text.substring(it.children[0].startOffset, it.children[0].endOffset).toLowerCase() to - text.substring(it.children[2].startOffset, it.children[2].endOffset) - } + - node.children.filterIsInstance().flatMap { getAllDestinationLinks(text, it) } - - - private fun markdownToDocNode(text: String): DocTag { - - val flavourDescriptor = GFMFlavourDescriptor() - val markdownAstRoot: ASTNode = IntellijMarkdownParser(flavourDescriptor).buildMarkdownTreeFromString(text) - - return MarkdownVisitor(text, getAllDestinationLinks(text, markdownAstRoot).toMap()).visitNode(markdownAstRoot) - } - - override fun parseStringToDocNode(extractedString: String) = markdownToDocNode(extractedString) - override fun preparse(text: String) = text - - private fun findParent(kDoc: PsiElement): PsiElement = - if (kDoc is KDocSection) findParent(kDoc.parent) else kDoc - - private fun getAllKDocTags(kDocImpl: PsiElement): List = - kDocImpl.children.filterIsInstance().filterNot { it is KDocSection } + kDocImpl.children.flatMap { - getAllKDocTags( - it - ) - } - - fun parseFromKDocTag(kDocTag: KDocTag?): DocumentationNode { - return if (kDocTag == null) - DocumentationNode(emptyList()) - else - DocumentationNode( - (listOf(kDocTag) + getAllKDocTags(findParent(kDocTag))).map { - when (it.knownTag) { - null -> if (it.name == null) Description(parseStringToDocNode(it.getContent())) else CustomTagWrapper( - parseStringToDocNode(it.getContent()), - it.name!! - ) - KDocKnownTag.AUTHOR -> Author(parseStringToDocNode(it.getContent())) - KDocKnownTag.THROWS -> Throws( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.EXCEPTION -> Throws( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.PARAM -> Param( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.RECEIVER -> Receiver(parseStringToDocNode(it.getContent())) - KDocKnownTag.RETURN -> Return(parseStringToDocNode(it.getContent())) - KDocKnownTag.SEE -> See( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty(), - parseStringToDocNode("[${it.getSubjectName()}]") - .let { - val link = it.children[0] - if (link is DocumentationLink) link.dri - else null - } - ) - KDocKnownTag.SINCE -> Since(parseStringToDocNode(it.getContent())) - KDocKnownTag.CONSTRUCTOR -> Constructor(parseStringToDocNode(it.getContent())) - KDocKnownTag.PROPERTY -> Property( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.SAMPLE -> Sample( - parseStringToDocNode(it.getContent()), - it.getSubjectName().orEmpty() - ) - KDocKnownTag.SUPPRESS -> Suppress(parseStringToDocNode(it.getContent())) - } - } - ) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/parsers/Parser.kt b/core/src/main/kotlin/parsers/Parser.kt deleted file mode 100644 index 05adc4d5..00000000 --- a/core/src/main/kotlin/parsers/Parser.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.jetbrains.dokka.parsers - -import org.jetbrains.dokka.model.doc.* - -abstract class Parser { - - abstract fun parseStringToDocNode(extractedString: String): DocTag - abstract fun preparse(text: String): String - - fun parse(text: String): DocumentationNode { - - val list = jkdocToListOfPairs(preparse(text)) - - val mappedList: List = list.map { - when(it.first) { - "description" -> Description(parseStringToDocNode(it.second)) - "author" -> Author(parseStringToDocNode(it.second)) - "version" -> Version(parseStringToDocNode(it.second)) - "since" -> Since(parseStringToDocNode(it.second)) - "see" -> See(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '), null) - "param" -> Param(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) - "property" -> Property(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) - "return" -> Return(parseStringToDocNode(it.second)) - "constructor" -> Constructor(parseStringToDocNode(it.second)) - "receiver" -> Receiver(parseStringToDocNode(it.second)) - "throws", "exception" -> Throws(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) - "deprecated" -> Deprecated(parseStringToDocNode(it.second)) - "sample" -> Sample(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) - "suppress" -> Suppress(parseStringToDocNode(it.second)) - else -> CustomTagWrapper(parseStringToDocNode(it.second), it.first) - } - } - return DocumentationNode(mappedList) - } - - private fun jkdocToListOfPairs(javadoc: String): List> = - "description $javadoc" - .split("\n@") - .map { - it.substringBefore(' ') to it.substringAfter(' ') - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt b/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt deleted file mode 100644 index dda6c627..00000000 --- a/core/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.jetbrains.dokka.parsers.factories - -import org.jetbrains.dokka.model.doc.* -import org.intellij.markdown.IElementType -import org.intellij.markdown.MarkdownElementTypes -import org.intellij.markdown.MarkdownTokenTypes -import org.intellij.markdown.flavours.gfm.GFMElementTypes -import org.jetbrains.dokka.links.DRI -import java.lang.NullPointerException - -object DocTagsFromIElementFactory { - fun getInstance(type: IElementType, children: List = emptyList(), params: Map = emptyMap(), body: String? = null, dri: DRI? = null) = - when(type) { - MarkdownElementTypes.SHORT_REFERENCE_LINK, - MarkdownElementTypes.FULL_REFERENCE_LINK, - MarkdownElementTypes.INLINE_LINK -> if(dri == null) A(children, params) else DocumentationLink(dri, children, params) - MarkdownElementTypes.STRONG -> B(children, params) - MarkdownElementTypes.BLOCK_QUOTE -> BlockQuote(children, params) - MarkdownElementTypes.CODE_SPAN, - MarkdownElementTypes.CODE_BLOCK, - MarkdownElementTypes.CODE_FENCE -> Code(children, params) - MarkdownElementTypes.ATX_1 -> H1(children, params) - MarkdownElementTypes.ATX_2 -> H2(children, params) - MarkdownElementTypes.ATX_3 -> H3(children, params) - MarkdownElementTypes.ATX_4 -> H4(children, params) - MarkdownElementTypes.ATX_5 -> H5(children, params) - MarkdownElementTypes.ATX_6 -> H6(children, params) - MarkdownElementTypes.EMPH -> I(children, params) - MarkdownElementTypes.IMAGE -> Img(children, params) - MarkdownElementTypes.LIST_ITEM -> Li(children, params) - MarkdownElementTypes.ORDERED_LIST -> Ol(children, params) - MarkdownElementTypes.UNORDERED_LIST -> Ul(children, params) - MarkdownElementTypes.PARAGRAPH -> P(children, params) - MarkdownTokenTypes.TEXT -> Text(body ?: throw NullPointerException("Text body should be at least empty string passed to DocNodes factory!"), children, params ) - MarkdownTokenTypes.HORIZONTAL_RULE -> HorizontalRule - MarkdownTokenTypes.HARD_LINE_BREAK -> Br - GFMElementTypes.STRIKETHROUGH -> Strikethrough(children, params) - GFMElementTypes.TABLE -> Table(children, params) - GFMElementTypes.HEADER -> Th(children, params) - GFMElementTypes.ROW -> Tr(children, params) - else -> CustomDocTag(children, params) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt b/core/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt deleted file mode 100644 index 3425f52e..00000000 --- a/core/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.jetbrains.dokka.parsers.factories - -import org.jetbrains.dokka.model.doc.* -import org.jetbrains.dokka.links.DRI -import java.lang.NullPointerException - -object DocTagsFromStringFactory { - fun getInstance(name: String, children: List = emptyList(), params: Map = emptyMap(), body: String? = null, dri: DRI? = null) = - when(name) { - "a" -> A(children, params) - "big" -> Big(children, params) - "b" -> B(children, params) - "blockquote" -> BlockQuote(children, params) - "br" -> Br - "cite" -> Cite(children, params) - "code" -> Code(children, params) - "dd" -> Dd(children, params) - "dfn" -> Dfn(children, params) - "dir" -> Dir(children, params) - "div" -> Div(children, params) - "dl" -> Dl(children, params) - "dt" -> Dt(children, params) - "Em" -> Em(children, params) - "font" -> Font(children, params) - "footer" -> Footer(children, params) - "frame" -> Frame(children, params) - "frameset" -> FrameSet(children, params) - "h1" -> H1(children, params) - "h2" -> H2(children, params) - "h3" -> H3(children, params) - "h4" -> H4(children, params) - "h5" -> H5(children, params) - "h6" -> H6(children, params) - "head" -> Head(children, params) - "header" -> Header(children, params) - "html" -> Html(children, params) - "i" -> I(children, params) - "iframe" -> IFrame(children, params) - "img" -> Img(children, params) - "input" -> Input(children, params) - "li" -> Li(children, params) - "link" -> Link(children, params) - "listing" -> Listing(children, params) - "main" -> Main(children, params) - "menu" -> Menu(children, params) - "meta" -> Meta(children, params) - "nav" -> Nav(children, params) - "noframes" -> NoFrames(children, params) - "noscript" -> NoScript(children, params) - "ol" -> Ol(children, params) - "p" -> P(children, params) - "pre" -> Pre(children, params) - "script" -> Script(children, params) - "section" -> Section(children, params) - "small" -> Small(children, params) - "span" -> Span(children, params) - "strong" -> Strong(children, params) - "sub" -> Sub(children, params) - "sup" -> Sup(children, params) - "table" -> Table(children, params) - "#text" -> Text(body ?: throw NullPointerException("Text body should be at least empty string passed to DocNodes factory!"), children, params) - "tBody" -> TBody(children, params) - "td" -> Td(children, params) - "tFoot" -> TFoot(children, params) - "th" -> Th(children, params) - "tHead" -> THead(children, params) - "title" -> Title(children, params) - "tr" -> Tr(children, params) - "tt" -> Tt(children, params) - "u" -> U(children, params) - "ul" -> Ul(children, params) - "var" -> Var(children, params) - "documentationlink" -> DocumentationLink(dri ?: throw NullPointerException("DRI cannot be passed null while constructing documentation link!"), children, params) - "hr" -> HorizontalRule - else -> CustomDocTag(children, params) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/plugability/DokkaContext.kt b/core/src/main/kotlin/plugability/DokkaContext.kt index 692803dd..a2ff26c7 100644 --- a/core/src/main/kotlin/plugability/DokkaContext.kt +++ b/core/src/main/kotlin/plugability/DokkaContext.kt @@ -1,9 +1,7 @@ package org.jetbrains.dokka.plugability import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.model.SourceSetCache -import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.utilities.DokkaLogger import java.io.File import java.net.URLClassLoader @@ -23,7 +21,6 @@ interface DokkaContext { val sourceSetCache: SourceSetCache val logger: DokkaLogger val configuration: DokkaConfiguration - val platforms: Map val unusedPoints: Collection> @@ -31,11 +28,10 @@ interface DokkaContext { fun create( configuration: DokkaConfiguration, logger: DokkaLogger, - sourceSets: Map, sourceSetsCache: SourceSetCache, pluginOverrides: List ): DokkaContext = - DokkaContextConfigurationImpl(logger, configuration, sourceSets, sourceSetsCache).apply { + DokkaContextConfigurationImpl(logger, configuration, sourceSetsCache).apply { // File(it.path) is a workaround for an incorrect filesystem in a File instance returned by Gradle. configuration.pluginsClasspath.map { File(it.path).toURI().toURL() } .toTypedArray() @@ -59,7 +55,6 @@ interface DokkaContextConfiguration { private class DokkaContextConfigurationImpl( override val logger: DokkaLogger, override val configuration: DokkaConfiguration, - override val platforms: Map, override val sourceSetCache: SourceSetCache ) : DokkaContext, DokkaContextConfiguration { private val plugins = mutableMapOf, DokkaPlugin>() diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index 24f417d8..fe472b12 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -2,7 +2,6 @@ package org.jetbrains.dokka.plugability import com.google.gson.Gson import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.kotlin.utils.addToStdlib.cast import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty import kotlin.reflect.KProperty1 @@ -60,8 +59,9 @@ interface ConfigurableBlock inline fun Configurable.pluginConfiguration(block: T.() -> Unit) { val instance = T::class.createInstance().apply(block) - pluginsConfiguration.cast>()[P::class.qualifiedName!!] = - Gson().toJson(instance, T::class.java) + + val mutablePluginsConfiguration = pluginsConfiguration as MutableMap + mutablePluginsConfiguration[P::class.qualifiedName!!] = Gson().toJson(instance, T::class.java) } inline fun P.query(extension: P.() -> ExtensionPoint): List = diff --git a/core/src/main/kotlin/utilities/cast.kt b/core/src/main/kotlin/utilities/cast.kt new file mode 100644 index 00000000..d4a8d73d --- /dev/null +++ b/core/src/main/kotlin/utilities/cast.kt @@ -0,0 +1,5 @@ +package org.jetbrains.dokka.utilities + +inline fun Any.cast(): T { + return this as T +} diff --git a/coreDependencies/build.gradle.kts b/coreDependencies/build.gradle.kts deleted file mode 100644 index 9af82d9f..00000000 --- a/coreDependencies/build.gradle.kts +++ /dev/null @@ -1,65 +0,0 @@ -import org.jetbrains.configureBintrayPublication - -plugins { - id("com.github.johnrengelman.shadow") - `maven-publish` - id("com.jfrog.bintray") -} - -val intellijCore: Configuration by configurations.creating - -repositories { - maven(url = "https://www.jetbrains.com/intellij-repository/snapshots") - maven(url = "https://www.jetbrains.com/intellij-repository/releases") - maven(url = "https://kotlin.bintray.com/kotlin-plugin") -} - -fun intellijCoreAnalysis() = zipTree(intellijCore.singleFile).matching { - include("intellij-core-analysis.jar") -} - -dependencies { - val idea_version: String by project - intellijCore("com.jetbrains.intellij.idea:intellij-core:$idea_version") - val kotlin_plugin_version: String by project - implementation(intellijCoreAnalysis()) - implementation("org.jetbrains.kotlin:kotlin-plugin-ij193:$kotlin_plugin_version") { - //TODO: parametrize ij version after 1.3.70 - isTransitive = false - } - implementation("org.jetbrains:markdown:0.1.41") { - because("it's published only on bintray") - } - implementation("org.jetbrains.kotlin:ide-common-ij193:$kotlin_plugin_version") - implementation(kotlin("stdlib-jdk8")) - implementation(kotlin("reflect")) -} - -tasks { - shadowJar { - val dokka_version: String by project - archiveFileName.set("dokka-dependencies-$dokka_version.jar") - archiveClassifier.set("") - - exclude("colorScheme/**") - exclude("fileTemplates/**") - exclude("inspectionDescriptions/**") - exclude("intentionDescriptions/**") - exclude("tips/**") - exclude("messages/**") - exclude("src/**") - exclude("**/*.kotlin_metadata") - exclude("**/*.kotlin_builtins") - } -} - -publishing { - publications { - register("dokkaCoreDependencies") { - artifactId = "dokka-core-dependencies" - project.shadow.component(this) - } - } -} - -configureBintrayPublication("dokkaCoreDependencies") diff --git a/integration-tests/gradle-integration-tests/build.gradle.kts b/integration-tests/gradle-integration-tests/build.gradle.kts index 7fc945b5..7cb96738 100644 --- a/integration-tests/gradle-integration-tests/build.gradle.kts +++ b/integration-tests/gradle-integration-tests/build.gradle.kts @@ -14,7 +14,7 @@ dependencies { testImplementation(gradleTestKit()) dokkaPlugin(project(path = ":runners:gradle-plugin")) - dokkaCore(project(path = ":coreDependencies", configuration = "shadow")) + dokkaCore(project(path = ":core:dependencies", configuration = "shadow")) dokkaCore(project(path = ":core")) kotlinGradle("org.jetbrains.kotlin:kotlin-gradle-plugin") } diff --git a/kotlin-analysis/build.gradle.kts b/kotlin-analysis/build.gradle.kts new file mode 100644 index 00000000..67480f82 --- /dev/null +++ b/kotlin-analysis/build.gradle.kts @@ -0,0 +1,27 @@ +import org.jetbrains.configureBintrayPublication + +plugins { + id("com.github.johnrengelman.shadow") + `maven-publish` + id("com.jfrog.bintray") +} + +dependencies { + compileOnly(project(":core")) + + val kotlin_version: String by project + api("org.jetbrains.kotlin:kotlin-compiler:$kotlin_version") + + api(project(":kotlin-analysis:dependencies", configuration = "shadow")) +} + +publishing { + publications { + register("analysis") { + artifactId = "dokka-analysis" + from(components["java"]) + } + } +} + +configureBintrayPublication("analysis") diff --git a/kotlin-analysis/dependencies/build.gradle.kts b/kotlin-analysis/dependencies/build.gradle.kts new file mode 100644 index 00000000..5bba6422 --- /dev/null +++ b/kotlin-analysis/dependencies/build.gradle.kts @@ -0,0 +1,67 @@ +import org.jetbrains.configureBintrayPublication + + +plugins { + id("com.github.johnrengelman.shadow") + `maven-publish` + id("com.jfrog.bintray") +} + +repositories { + maven(url = "https://www.jetbrains.com/intellij-repository/snapshots") + maven(url = "https://www.jetbrains.com/intellij-repository/releases") + maven(url = "https://kotlin.bintray.com/kotlin-plugin") +} + +val intellijCore: Configuration by configurations.creating + +fun intellijCoreAnalysis() = zipTree(intellijCore.singleFile).matching { + include("intellij-core-analysis.jar") +} + +dependencies { + val kotlin_plugin_version: String by project + api("org.jetbrains.kotlin:ide-common-ij193:$kotlin_plugin_version") + api("org.jetbrains.kotlin:kotlin-plugin-ij193:$kotlin_plugin_version") { + //TODO: parametrize ij version after 1.3.70 + isTransitive = false + } + + val idea_version: String by project + intellijCore("com.jetbrains.intellij.idea:intellij-core:$idea_version") + implementation(intellijCoreAnalysis()) + + implementation("org.jetbrains:markdown:0.1.41") { + because("it's published only on bintray") + } +} + +tasks { + shadowJar { + val dokka_version: String by project + archiveFileName.set("dokka-kotlin-analysis-dependencies-$dokka_version.jar") + archiveClassifier.set("") + + exclude("colorScheme/**") + exclude("fileTemplates/**") + exclude("inspectionDescriptions/**") + exclude("intentionDescriptions/**") + exclude("tips/**") + exclude("messages/**") + exclude("src/**") + exclude("**/*.kotlin_metadata") + exclude("**/*.kotlin_builtins") + } +} + + +publishing { + publications { + register("kotlin-analysis-dependencies") { + artifactId = "kotlin-analysis-dependencies" + project.shadow.component(this) + } + } +} + +configureBintrayPublication("kotlin-analysis-dependencies") diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt new file mode 100644 index 00000000..7836bde9 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/AnalysisEnvironment.kt @@ -0,0 +1,636 @@ +package org.jetbrains.dokka.analysis + +import com.google.common.collect.ImmutableMap +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.core.CoreModuleManager +import com.intellij.mock.MockComponentManager +import com.intellij.openapi.Disposable +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.module.Module +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.OrderEnumerationHandler +import com.intellij.openapi.roots.ProjectFileIndex +import com.intellij.openapi.roots.ProjectRootManager +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.psi.PsiElement +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.dokka.Platform +import org.jetbrains.kotlin.analyzer.* +import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters +import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices +import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns +import org.jetbrains.kotlin.caches.resolve.* +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.config.ContentRoot +import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot +import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM +import org.jetbrains.kotlin.cli.jvm.config.* +import org.jetbrains.kotlin.cli.jvm.index.JavaRoot +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.container.getService +import org.jetbrains.kotlin.container.tryGetService +import org.jetbrains.kotlin.context.ProjectContext +import org.jetbrains.kotlin.context.withModule +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices +import org.jetbrains.kotlin.library.impl.createKotlinLibrary +import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.js.JsPlatforms +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms.unspecifiedJvmPlatform +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.CompilerEnvironment +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices +import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics +import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters +import org.jetbrains.kotlin.resolve.jvm.JvmResolverForModuleFactory +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices +import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices +import org.jetbrains.kotlin.resolve.lazy.ResolveSession +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice +import org.jetbrains.kotlin.util.slicedMap.WritableSlice +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin +import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor +import org.jetbrains.kotlin.ide.konan.NativePlatformKindResolution +import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass +import org.jetbrains.kotlin.platform.IdePlatformKind +import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind +import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind +import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind +import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind +import org.jetbrains.kotlin.platform.konan.NativePlatforms +import java.io.File + +const val JAR_SEPARATOR = "!/" +const val KLIB_EXTENSION = "klib" + +/** + * Kotlin as a service entry point + * + * Configures environment, analyses files and provides facilities to perform code processing without emitting bytecode + * + * $messageCollector: required by compiler infrastructure and will receive all compiler messages + * $body: optional and can be used to configure environment without creating local variable + */ +class AnalysisEnvironment(val messageCollector: MessageCollector, val analysisPlatform: Platform) : Disposable { + val configuration = CompilerConfiguration() + + init { + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) + } + + fun createCoreEnvironment(): KotlinCoreEnvironment { + System.setProperty("idea.io.use.nio2", "true") + + val configFiles = when (analysisPlatform) { + Platform.jvm, Platform.common -> EnvironmentConfigFiles.JVM_CONFIG_FILES + Platform.native -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES + Platform.js -> EnvironmentConfigFiles.JS_CONFIG_FILES + } + + val environment = KotlinCoreEnvironment.createForProduction(this, configuration, configFiles) + val projectComponentManager = environment.project as MockComponentManager + + val projectFileIndex = CoreProjectFileIndex( + environment.project, + environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS) + ) + + val moduleManager = object : CoreModuleManager(environment.project, this) { + override fun getModules(): Array = arrayOf(projectFileIndex.module) + } + + CoreApplicationEnvironment.registerComponentInstance( + projectComponentManager.picoContainer, + ModuleManager::class.java, moduleManager + ) + + CoreApplicationEnvironment.registerExtensionPoint( + Extensions.getRootArea(), + OrderEnumerationHandler.EP_NAME, OrderEnumerationHandler.Factory::class.java + ) + + projectComponentManager.registerService( + ProjectFileIndex::class.java, + projectFileIndex + ) + + projectComponentManager.registerService( + ProjectRootManager::class.java, + CoreProjectRootManager(projectFileIndex) + ) + + registerExtensionPoint( + ApplicationExtensionDescriptor("org.jetbrains.kotlin.idePlatformKind", IdePlatformKind::class.java), + listOf( + CommonIdePlatformKind, + JvmIdePlatformKind, + JsIdePlatformKind, + NativeIdePlatformKind + ) + ) + + registerExtensionPoint( + IdePlatformKindResolution, + listOf( + CommonPlatformKindResolution(), + JvmPlatformKindResolution(), + JsPlatformKindResolution(), + NativePlatformKindResolution() + ) + ) + + return environment + } + + private fun createSourceModuleSearchScope(project: Project, sourceFiles: List): GlobalSearchScope = + when (analysisPlatform) { + Platform.jvm -> TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles) + Platform.js, Platform.common, Platform.native -> GlobalSearchScope.filesScope( + project, + sourceFiles.map { it.virtualFile }.toSet() + ) + } + + fun createResolutionFacade(environment: KotlinCoreEnvironment): Pair { + val projectContext = ProjectContext(environment.project, "Dokka") + val sourceFiles = environment.getSourceFiles() + + + val targetPlatform = when (analysisPlatform) { + Platform.js -> JsPlatforms.defaultJsPlatform + Platform.common -> CommonPlatforms.defaultCommonPlatform + Platform.native -> NativePlatforms.unspecifiedNativePlatform + Platform.jvm -> JvmPlatforms.defaultJvmPlatform + } + + val nativeLibraries = classpath.filter { it.extension == KLIB_EXTENSION } + .map { createNativeLibraryModuleInfo(it) } + + val library = object : LibraryModuleInfo { + override val analyzerServices: PlatformDependentAnalyzerServices = + analysisPlatform.analyzerServices() + override val name: Name = Name.special("") + override val platform: TargetPlatform = targetPlatform + override fun dependencies(): List = listOf(this) + override fun getLibraryRoots(): Collection = + classpath.filterNot { it.extension == KLIB_EXTENSION }.map { it.absolutePath } + } + + val module = object : ModuleInfo { + override val analyzerServices: PlatformDependentAnalyzerServices = + analysisPlatform.analyzerServices() + override val name: Name = Name.special("") + override val platform: TargetPlatform = targetPlatform + override fun dependencies(): List = listOf(this, library) + nativeLibraries + } + + val sourcesScope = createSourceModuleSearchScope(environment.project, sourceFiles) + val modulesContent: (ModuleInfo) -> ModuleContent = { + when (it) { + library -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + module -> ModuleContent(it, emptyList(), GlobalSearchScope.allScope(environment.project)) + in nativeLibraries -> ModuleContent(it, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + else -> throw IllegalArgumentException("Unexpected module info") + } + } + + var builtIns: JvmBuiltIns? = null + + val resolverForProject = when (analysisPlatform) { + Platform.jvm -> { + builtIns = JvmBuiltIns( + projectContext.storageManager, + JvmBuiltIns.Kind.FROM_CLASS_LOADER + ) // TODO we should use FROM_DEPENDENCIES + createJvmResolverForProject( + projectContext, + module, + library, + modulesContent, + sourcesScope, + builtIns + ) + } + Platform.common -> createCommonResolverForProject( + projectContext, + module, + library, + modulesContent, + environment + ) + Platform.js -> createJsResolverForProject(projectContext, module, library, modulesContent) + Platform.native -> createNativeResolverForProject(projectContext, module, library, modulesContent) + + } + val libraryModuleDescriptor = resolverForProject.descriptorForModule(library) + val moduleDescriptor = resolverForProject.descriptorForModule(module) + builtIns?.initialize(moduleDescriptor, true) + + val resolverForLibrary = + resolverForProject.resolverForModule(library) // Required before module to initialize library properly + val resolverForModule = resolverForProject.resolverForModule(module) + val libraryResolutionFacade = + DokkaResolutionFacade( + environment.project, + libraryModuleDescriptor, + resolverForLibrary + ) + val created = + DokkaResolutionFacade( + environment.project, + moduleDescriptor, + resolverForModule + ) + val projectComponentManager = environment.project as MockComponentManager + projectComponentManager.registerService(KotlinCacheService::class.java, + CoreKotlinCacheService(created) + ) + + return created to libraryResolutionFacade + } + + private fun Platform.analyzerServices() = when (this) { + Platform.js -> JsPlatformAnalyzerServices + Platform.common -> CommonPlatformAnalyzerServices + Platform.native -> NativePlatformAnalyzerServices + Platform.jvm -> JvmPlatformAnalyzerServices + } + + private fun createNativeLibraryModuleInfo(libraryFile: File): LibraryModuleInfo { + val kotlinLibrary = createKotlinLibrary(org.jetbrains.kotlin.konan.file.File(libraryFile.absolutePath), "",false) + return object : LibraryModuleInfo { + override val analyzerServices: PlatformDependentAnalyzerServices = + analysisPlatform.analyzerServices() + override val name: Name = Name.special("") + override val platform: TargetPlatform = NativePlatforms.unspecifiedNativePlatform + override fun dependencies(): List = listOf(this) + override fun getLibraryRoots(): Collection = listOf(libraryFile.absolutePath) + override val capabilities: Map, Any?> + get() = super.capabilities + (KlibModuleOrigin.CAPABILITY to kotlinLibrary) + } + } + + private fun createCommonResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent, + environment: KotlinCoreEnvironment + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = listOf(module, library) + ) { + override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null + + override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) + + override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance + + override fun createResolverForModule( + descriptor: ModuleDescriptor, + moduleInfo: ModuleInfo + ): ResolverForModule = + CommonResolverForModuleFactory( + CommonAnalysisParameters { content -> + environment.createPackagePartProvider(content.moduleContentScope) + }, + CompilerEnvironment, + unspecifiedJvmPlatform, + true + ).createResolverForModule( + descriptor as ModuleDescriptorImpl, + projectContext.withModule(descriptor), + modulesContent(moduleInfo), + this, + LanguageVersionSettingsImpl.DEFAULT + ) + } + } + + private fun createJsResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = listOf(module, library) + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) + override fun createResolverForModule( + descriptor: ModuleDescriptor, + moduleInfo: ModuleInfo + ): ResolverForModule = JsResolverForModuleFactory( + CompilerEnvironment + ).createResolverForModule( + descriptor as ModuleDescriptorImpl, + projectContext.withModule(descriptor), + modulesContent(moduleInfo), + this, + LanguageVersionSettingsImpl.DEFAULT + ) + + override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance + + override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null + } + } + + private fun createNativeResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent + ): ResolverForProject { + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = module.dependencies() + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = modulesContent(module) + override fun createResolverForModule( + descriptor: ModuleDescriptor, + moduleInfo: ModuleInfo + ): ResolverForModule { + + return NativeResolverForModuleFactory( + PlatformAnalysisParameters.Empty, + CompilerEnvironment, + NativePlatforms.unspecifiedNativePlatform + ).createResolverForModule( + descriptor as ModuleDescriptorImpl, + projectContext.withModule(descriptor), + modulesContent(moduleInfo), + this, + LanguageVersionSettingsImpl.DEFAULT + ) + } + + override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = DefaultBuiltIns.Instance + + override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null + } + } + + private fun createJvmResolverForProject( + projectContext: ProjectContext, + module: ModuleInfo, + library: LibraryModuleInfo, + modulesContent: (ModuleInfo) -> ModuleContent, + sourcesScope: GlobalSearchScope, + builtIns: KotlinBuiltIns + ): ResolverForProject { + val javaRoots = classpath + .mapNotNull { + val rootFile = when (it.extension) { + "jar" -> StandardFileSystems.jar().findFileByPath("${it.absolutePath}$JAR_SEPARATOR") + else -> StandardFileSystems.local().findFileByPath(it.absolutePath) + } + rootFile?.let { JavaRoot(it, JavaRoot.RootType.BINARY) } + } + + return object : AbstractResolverForProject( + "Dokka", + projectContext, + modules = listOf(module, library) + ) { + override fun modulesContent(module: ModuleInfo): ModuleContent = + when (module) { + library -> ModuleContent(module, emptyList(), GlobalSearchScope.notScope(sourcesScope)) + module -> ModuleContent(module, emptyList(), sourcesScope) + else -> throw IllegalArgumentException("Unexpected module info") + } + + override fun builtInsForModule(module: ModuleInfo): KotlinBuiltIns = builtIns + + override fun createResolverForModule( + descriptor: ModuleDescriptor, + moduleInfo: ModuleInfo + ): ResolverForModule = JvmResolverForModuleFactory( + JvmPlatformParameters({ content -> + JvmPackagePartProvider( + configuration.languageVersionSettings, + content.moduleContentScope + ) + .apply { + addRoots(javaRoots, messageCollector) + } + }, { + val file = (it as? BinaryJavaClass)?.virtualFile ?: (it as JavaClassImpl).psi.containingFile.virtualFile + if (file in sourcesScope) + module + else + library + }), + CompilerEnvironment, + unspecifiedJvmPlatform + ).createResolverForModule( + descriptor as ModuleDescriptorImpl, + projectContext.withModule(descriptor), + modulesContent(moduleInfo), + this, + LanguageVersionSettingsImpl.DEFAULT + ) + + override fun sdkDependency(module: ModuleInfo): ModuleInfo? = null + } + } + + fun loadLanguageVersionSettings(languageVersionString: String?, apiVersionString: String?) { + val languageVersion = LanguageVersion.fromVersionString(languageVersionString) ?: LanguageVersion.LATEST_STABLE + val apiVersion = + apiVersionString?.let { ApiVersion.parse(it) } ?: ApiVersion.createByLanguageVersion(languageVersion) + configuration.languageVersionSettings = LanguageVersionSettingsImpl(languageVersion, apiVersion) + } + + /** + * Classpath for this environment. + */ + val classpath: List + get() = configuration.jvmClasspathRoots + + /** + * Adds list of paths to classpath. + * $paths: collection of files to add + */ + fun addClasspath(paths: List) { + if (analysisPlatform == Platform.js) { + configuration.addAll(JSConfigurationKeys.LIBRARIES, paths.map { it.absolutePath }) + } + configuration.addJvmClasspathRoots(paths) + } + + /** + * Adds path to classpath. + * $path: path to add + */ + fun addClasspath(path: File) { + if (analysisPlatform == Platform.js) { + configuration.add(JSConfigurationKeys.LIBRARIES, path.absolutePath) + } + configuration.addJvmClasspathRoot(path) + } + + /** + * List of source roots for this environment. + */ + val sources: List + get() = configuration.get(CLIConfigurationKeys.CONTENT_ROOTS) + ?.filterIsInstance() + ?.map { it.path } ?: emptyList() + + /** + * Adds list of paths to source roots. + * $list: collection of files to add + */ + fun addSources(list: List) { + list.forEach { + configuration.addKotlinSourceRoot(it) + val file = File(it) + if (file.isDirectory || file.extension == ".java") { + configuration.addJavaSourceRoot(file) + } + } + } + + fun addRoots(list: List) { + configuration.addAll(CLIConfigurationKeys.CONTENT_ROOTS, list) + } + + /** + * Disposes the environment and frees all associated resources. + */ + override fun dispose() { + Disposer.dispose(this) + } + + companion object { + private fun registerExtensionPoint( + appExtension: ApplicationExtensionDescriptor, + instances: List + ) { + if (Extensions.getRootArea().hasExtensionPoint(appExtension.extensionPointName)) + return + + appExtension.registerExtensionPoint() + instances.forEach(appExtension::registerExtension) + } + } +} + +fun contentRootFromPath(path: String): ContentRoot { + val file = File(path) + return if (file.extension == "java") JavaSourceRoot(file, null) else KotlinSourceRoot(path, false) +} + + +class DokkaResolutionFacade( + override val project: Project, + override val moduleDescriptor: ModuleDescriptor, + val resolverForModule: ResolverForModule +) : ResolutionFacade { + override fun analyzeWithAllCompilerChecks(elements: Collection): AnalysisResult { + throw UnsupportedOperationException() + } + + override fun tryGetFrontendService(element: PsiElement, serviceClass: Class): T? { + return resolverForModule.componentProvider.tryGetService(serviceClass) + } + + override fun resolveToDescriptor( + declaration: KtDeclaration, + bodyResolveMode: BodyResolveMode + ): DeclarationDescriptor { + return resolveSession.resolveToDescriptor(declaration) + } + + override fun analyze(elements: Collection, bodyResolveMode: BodyResolveMode): BindingContext { + throw UnsupportedOperationException() + } + + val resolveSession: ResolveSession get() = getFrontendService(ResolveSession::class.java) + + override fun analyze(element: KtElement, bodyResolveMode: BodyResolveMode): BindingContext { + if (element is KtDeclaration) { + val descriptor = resolveToDescriptor(element) + return object : BindingContext { + override fun getKeys(p0: WritableSlice?): Collection { + throw UnsupportedOperationException() + } + + override fun getType(p0: KtExpression): KotlinType? { + throw UnsupportedOperationException() + } + + override fun get(slice: ReadOnlySlice?, key: K): V? { + if (key != element) { + throw UnsupportedOperationException() + } + return when { + slice == BindingContext.DECLARATION_TO_DESCRIPTOR -> descriptor as V + slice == BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER && (element as KtParameter).hasValOrVar() -> descriptor as V + else -> null + } + } + + override fun getDiagnostics(): Diagnostics { + throw UnsupportedOperationException() + } + + override fun addOwnDataTo(p0: BindingTrace, p1: Boolean) { + throw UnsupportedOperationException() + } + + override fun getSliceContents(p0: ReadOnlySlice): ImmutableMap { + throw UnsupportedOperationException() + } + + } + } + throw UnsupportedOperationException() + } + + override fun getFrontendService(element: PsiElement, serviceClass: Class): T { + throw UnsupportedOperationException() + } + + override fun getFrontendService(serviceClass: Class): T { + return resolverForModule.componentProvider.getService(serviceClass) + } + + override fun getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class): T { + return resolverForModule.componentProvider.getService(serviceClass) + } + + override fun getIdeService(serviceClass: Class): T { + throw UnsupportedOperationException() + } + +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt new file mode 100644 index 00000000..ebfe20a5 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CallableFactory.kt @@ -0,0 +1,31 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMethod +import org.jetbrains.dokka.links.Callable +import org.jetbrains.dokka.links.JavaClassReference +import org.jetbrains.dokka.links.TypeReference +import org.jetbrains.kotlin.descriptors.CallableDescriptor + +fun Callable.Companion.from(descriptor: CallableDescriptor) = with(descriptor) { + Callable( + name.asString(), + extensionReceiverParameter?.let { TypeReference.from(it) }, + valueParameters.mapNotNull { TypeReference.from(it) } + ) +} + +fun Callable.Companion.from(psi: PsiMethod) = with(psi) { + Callable( + name, + null, + parameterList.parameters.map { param -> JavaClassReference(param.type.canonicalText) }) +} + +fun Callable.Companion.from(psi: PsiField): Callable { + return Callable( + name = psi.name, + receiver = null, + params = emptyList() + ) +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt new file mode 100644 index 00000000..68415875 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreKotlinCacheService.kt @@ -0,0 +1,42 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiFile +import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache + + +class CoreKotlinCacheService(private val resolutionFacade: DokkaResolutionFacade) : KotlinCacheService { + override fun getResolutionFacade(elements: List): ResolutionFacade { + return resolutionFacade + } + + override fun getResolutionFacade( + elements: List, + platform: org.jetbrains.kotlin.platform.TargetPlatform + ): ResolutionFacade { + return resolutionFacade + } + + override fun getResolutionFacadeByFile( + file: PsiFile, + platform: org.jetbrains.kotlin.platform.TargetPlatform + ): ResolutionFacade? { + return resolutionFacade + } + + override fun getResolutionFacadeByModuleInfo( + moduleInfo: ModuleInfo, + platform: org.jetbrains.kotlin.platform.TargetPlatform + ): ResolutionFacade? { + return resolutionFacade + } + + override fun getSuppressionCache(): KotlinSuppressCache { + throw UnsupportedOperationException() + } + +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreProjectFileIndex.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreProjectFileIndex.kt new file mode 100644 index 00000000..d0e0bb4f --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/CoreProjectFileIndex.kt @@ -0,0 +1,515 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.BaseComponent +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.projectRoots.Sdk +import com.intellij.openapi.projectRoots.SdkAdditionalData +import com.intellij.openapi.projectRoots.SdkModificator +import com.intellij.openapi.projectRoots.SdkTypeId +import com.intellij.openapi.roots.* +import com.intellij.openapi.roots.impl.ProjectOrderEnumerator +import com.intellij.openapi.util.Condition +import com.intellij.openapi.util.Key +import com.intellij.openapi.util.UserDataHolderBase +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VfsUtilCore.getVirtualFileForJar +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileFilter +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.util.messages.MessageBus +import org.jetbrains.jps.model.module.JpsModuleSourceRootType +import org.jetbrains.kotlin.cli.common.config.ContentRoot +import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot +import org.picocontainer.PicoContainer +import java.io.File + +/** + * Workaround for the lack of ability to create a ProjectFileIndex implementation using only + * classes from projectModel-{api,impl}. + */ +class CoreProjectFileIndex(private val project: Project, contentRoots: List) : ProjectFileIndex, ModuleFileIndex { + override fun iterateContent(p0: ContentIterator, p1: VirtualFileFilter?): Boolean { + throw UnsupportedOperationException() + } + + override fun iterateContentUnderDirectory(p0: VirtualFile, p1: ContentIterator, p2: VirtualFileFilter?): Boolean { + throw UnsupportedOperationException() + } + + override fun isInLibrary(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + val sourceRoots = contentRoots.filter { it !is JvmClasspathRoot } + val classpathRoots = contentRoots.filterIsInstance() + + val module: Module = object : UserDataHolderBase(), Module { + override fun isDisposed(): Boolean { + throw UnsupportedOperationException() + } + + override fun getName(): String = "" + + override fun getModuleWithLibrariesScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependentsScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependenciesScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleWithDependenciesAndLibrariesScope(p0: Boolean): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleTestsWithDependentsScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleScope(): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getModuleRuntimeScope(p0: Boolean): GlobalSearchScope { + throw UnsupportedOperationException() + } + + override fun getExtensions(p0: ExtensionPointName): Array { + throw UnsupportedOperationException() + } + + override fun getComponent(interfaceClass: Class): T? { + if (interfaceClass == ModuleRootManager::class.java) { + return moduleRootManager as T + } + throw UnsupportedOperationException() + } + + override fun getDisposed(): Condition<*> { + throw UnsupportedOperationException() + } + + override fun getPicoContainer(): PicoContainer { + throw UnsupportedOperationException() + } + + override fun getMessageBus(): MessageBus { + throw UnsupportedOperationException() + } + + override fun dispose() { + throw UnsupportedOperationException() + } + } + + private val sdk: Sdk = object : Sdk, RootProvider { + override fun getFiles(rootType: OrderRootType): Array = classpathRoots + .mapNotNull { StandardFileSystems.local().findFileByPath(it.file.path) } + .toTypedArray() + + override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { + throw UnsupportedOperationException() + } + + override fun addRootSetChangedListener(p0: RootProvider.RootSetChangedListener, p1: Disposable) { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun removeRootSetChangedListener(p0: RootProvider.RootSetChangedListener) { + throw UnsupportedOperationException() + } + + override fun getSdkModificator(): SdkModificator { + throw UnsupportedOperationException() + } + + override fun getName(): String = "" + + override fun getRootProvider(): RootProvider = this + + override fun getHomePath(): String? { + throw UnsupportedOperationException() + } + + override fun getVersionString(): String? { + throw UnsupportedOperationException() + } + + override fun getSdkAdditionalData(): SdkAdditionalData? { + throw UnsupportedOperationException() + } + + override fun clone(): Any { + throw UnsupportedOperationException() + } + + override fun getSdkType(): SdkTypeId { + throw UnsupportedOperationException() + } + + override fun getHomeDirectory(): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun getUserData(p0: Key): T? { + throw UnsupportedOperationException() + } + + override fun putUserData(p0: Key, p1: T?) { + throw UnsupportedOperationException() + } + } + + private val moduleSourceOrderEntry = object : ModuleSourceOrderEntry { + override fun getFiles(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun accept(p0: RootPolicy, p1: R?): R { + throw UnsupportedOperationException() + } + + + override fun getPresentableName(): String { + throw UnsupportedOperationException() + } + + override fun getOwnerModule(): Module = module + + + override fun isValid(): Boolean { + throw UnsupportedOperationException() + } + + override fun compareTo(other: OrderEntry?): Int { + throw UnsupportedOperationException() + } + + override fun getRootModel(): ModuleRootModel = moduleRootManager + + override fun isSynthetic(): Boolean { + throw UnsupportedOperationException() + } + } + + private val sdkOrderEntry = object : JdkOrderEntry { + override fun getFiles(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun getUrls(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun accept(p0: RootPolicy, p1: R?): R { + throw UnsupportedOperationException() + } + + override fun getJdkName(): String? { + throw UnsupportedOperationException() + } + + override fun getJdk(): Sdk = sdk + + override fun getPresentableName(): String { + throw UnsupportedOperationException() + } + + override fun getOwnerModule(): Module { + throw UnsupportedOperationException() + } + + override fun isValid(): Boolean { + throw UnsupportedOperationException() + } + + override fun getRootFiles(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun getRootUrls(p0: OrderRootType): Array { + throw UnsupportedOperationException() + } + + override fun compareTo(other: OrderEntry?): Int { + throw UnsupportedOperationException() + } + + override fun isSynthetic(): Boolean { + throw UnsupportedOperationException() + } + + } + + inner class MyModuleRootManager : ModuleRootManager() { + override fun getExternalSource(): ProjectModelExternalSource? { + throw UnsupportedOperationException() + } + + override fun getExcludeRoots(): Array { + throw UnsupportedOperationException() + } + + override fun getContentEntries(): Array { + throw UnsupportedOperationException() + } + + override fun getExcludeRootUrls(): Array { + throw UnsupportedOperationException() + } + + override fun processOrder(p0: RootPolicy, p1: R): R { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: Boolean): Array { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(): Array { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: JpsModuleSourceRootType<*>): MutableList { + throw UnsupportedOperationException() + } + + override fun getSourceRoots(p0: MutableSet>): MutableList { + throw UnsupportedOperationException() + } + + override fun getContentRoots(): Array { + throw UnsupportedOperationException() + } + + override fun orderEntries(): OrderEnumerator = + ProjectOrderEnumerator(project, null).using(object : RootModelProvider { + override fun getModules(): Array = arrayOf(module) + + override fun getRootModel(p0: Module): ModuleRootModel = this@MyModuleRootManager + }) + + override fun getModuleExtension(p0: Class): T { + throw UnsupportedOperationException() + } + + override fun getDependencyModuleNames(): Array { + throw UnsupportedOperationException() + } + + override fun getModule(): Module = this@CoreProjectFileIndex.module + + override fun isSdkInherited(): Boolean { + throw UnsupportedOperationException() + } + + override fun getOrderEntries(): Array = arrayOf(moduleSourceOrderEntry, sdkOrderEntry) + + override fun getSourceRootUrls(): Array { + throw UnsupportedOperationException() + } + + override fun getSourceRootUrls(p0: Boolean): Array { + throw UnsupportedOperationException() + } + + override fun getSdk(): Sdk? { + throw UnsupportedOperationException() + } + + override fun getContentRootUrls(): Array { + throw UnsupportedOperationException() + } + + override fun getModuleDependencies(): Array { + throw UnsupportedOperationException() + } + + override fun getModuleDependencies(p0: Boolean): Array { + throw UnsupportedOperationException() + } + + override fun getModifiableModel(): ModifiableRootModel { + throw UnsupportedOperationException() + } + + override fun isDependsOn(p0: Module): Boolean { + throw UnsupportedOperationException() + } + + override fun getFileIndex(): ModuleFileIndex { + return this@CoreProjectFileIndex + } + + override fun getDependencies(): Array { + throw UnsupportedOperationException() + } + + override fun getDependencies(p0: Boolean): Array { + throw UnsupportedOperationException() + } + } + + val moduleRootManager = MyModuleRootManager() + + override fun getContentRootForFile(p0: VirtualFile): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun getContentRootForFile(p0: VirtualFile, p1: Boolean): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun getPackageNameByDirectory(p0: VirtualFile): String? { + throw UnsupportedOperationException() + } + + override fun isInLibrarySource(file: VirtualFile): Boolean = false + + override fun getClassRootForFile(file: VirtualFile): VirtualFile? = + classpathRoots.firstOrNull { it.contains(file) }?.let { StandardFileSystems.local().findFileByPath(it.file.path) } + + override fun getOrderEntriesForFile(file: VirtualFile): List = + if (classpathRoots.contains(file)) listOf(sdkOrderEntry) else emptyList() + + override fun isInLibraryClasses(file: VirtualFile): Boolean = classpathRoots.contains(file) + + override fun isExcluded(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun getSourceRootForFile(p0: VirtualFile): VirtualFile? { + throw UnsupportedOperationException() + } + + override fun isUnderIgnored(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun isLibraryClassFile(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun getModuleForFile(file: VirtualFile): Module? = + if (sourceRoots.contains(file)) module else null + + private fun List.contains(file: VirtualFile): Boolean = any { it.contains(file) } + + override fun getModuleForFile(p0: VirtualFile, p1: Boolean): Module? { + throw UnsupportedOperationException() + } + + override fun isInSource(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun isIgnored(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun isContentSourceFile(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun isInSourceContent(file: VirtualFile): Boolean = sourceRoots.contains(file) + + override fun iterateContent(p0: ContentIterator): Boolean { + throw UnsupportedOperationException() + } + + override fun isInContent(p0: VirtualFile): Boolean { + throw UnsupportedOperationException() + } + + override fun iterateContentUnderDirectory(p0: VirtualFile, p1: ContentIterator): Boolean { + throw UnsupportedOperationException() + } + + override fun isInTestSourceContent(file: VirtualFile): Boolean = false + + override fun isUnderSourceRootOfType(p0: VirtualFile, p1: MutableSet>): Boolean { + throw UnsupportedOperationException() + } + + override fun getOrderEntryForFile(p0: VirtualFile): OrderEntry? { + throw UnsupportedOperationException() + } +} + +class CoreProjectRootManager(val projectFileIndex: CoreProjectFileIndex) : ProjectRootManager() { + override fun orderEntries(): OrderEnumerator { + throw UnsupportedOperationException() + } + + override fun orderEntries(p0: MutableCollection): OrderEnumerator { + throw UnsupportedOperationException() + } + + override fun getContentRootsFromAllModules(): Array { + throw UnsupportedOperationException() + } + + override fun setProjectSdk(p0: Sdk?) { + throw UnsupportedOperationException() + } + + override fun setProjectSdkName(p0: String) { + throw UnsupportedOperationException() + } + + override fun getModuleSourceRoots(p0: MutableSet>): MutableList { + throw UnsupportedOperationException() + } + + override fun getContentSourceRoots(): Array { + throw UnsupportedOperationException() + } + + override fun getFileIndex(): ProjectFileIndex = projectFileIndex + + override fun getProjectSdkName(): String? { + throw UnsupportedOperationException() + } + + override fun getProjectSdk(): Sdk? { + throw UnsupportedOperationException() + } + + override fun getContentRoots(): Array { + throw UnsupportedOperationException() + } + + override fun getContentRootUrls(): MutableList { + throw UnsupportedOperationException() + } + +} + +fun ContentRoot.contains(file: VirtualFile) = when (this) { + is JvmContentRoot -> { + val path = if (file.fileSystem.protocol == StandardFileSystems.JAR_PROTOCOL) + getVirtualFileForJar(file)?.path ?: file.path + else + file.path + File(path).startsWith(this.file.absoluteFile) + } + is KotlinSourceRoot -> File(file.path).startsWith(File(this.path).absoluteFile) + else -> false +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt new file mode 100644 index 00000000..513817f3 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRIFactory.kt @@ -0,0 +1,38 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiField +import com.intellij.psi.PsiMethod +import org.jetbrains.dokka.links.Callable +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.DriTarget +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +fun DRI.Companion.from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run { + val callable = firstIsInstanceOrNull() + DRI( + firstIsInstanceOrNull()?.fqName?.asString(), + (filterIsInstance() + filterIsInstance()).toList() + .takeIf { it.isNotEmpty() } + ?.asReversed() + ?.joinToString(separator = ".") { it.name.asString() }, + callable?.let { Callable.from(it) }, + DriTarget.from(descriptor) + ) +} + +fun DRI.Companion.from(psi: PsiElement) = psi.parentsWithSelf.run { + val psiMethod = firstIsInstanceOrNull() + val psiField = firstIsInstanceOrNull() + val classes = filterIsInstance().toList() + DRI( + classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', ""), + classes.toList().takeIf { it.isNotEmpty() }?.asReversed()?.mapNotNull { it.name }?.joinToString("."), + psiMethod?.let { Callable.from(it) } ?: psiField?.let { Callable.from(it) }, + DriTarget.from(psi) + ) +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt new file mode 100644 index 00000000..031a5a32 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/DRITargetFactory.kt @@ -0,0 +1,44 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiParameter +import com.intellij.psi.PsiTypeParameter +import org.jetbrains.dokka.links.DriTarget +import org.jetbrains.dokka.links.PointingToCallableParameters +import org.jetbrains.dokka.links.PointingToDeclaration +import org.jetbrains.dokka.links.PointingToGenericParameters +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.ParameterDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +fun DriTarget.Companion.from(descriptor: DeclarationDescriptor): DriTarget = descriptor.parentsWithSelf.run { + return when (descriptor) { + is TypeParameterDescriptor -> PointingToGenericParameters(descriptor.index) + else -> { + val callable = firstIsInstanceOrNull() + val params = + callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty() + val parameterDescriptor = firstIsInstanceOrNull() + + parameterDescriptor?.let { PointingToCallableParameters(params.indexOf(it)) } + ?: PointingToDeclaration + } + } +} + + +fun DriTarget.Companion.from(psi: PsiElement): DriTarget = psi.parentsWithSelf.run { + return when (psi) { + is PsiTypeParameter -> PointingToGenericParameters(psi.index) + else -> firstIsInstanceOrNull()?.let { + val callable = firstIsInstanceOrNull() + val params = (callable?.parameterList?.parameters).orEmpty() + PointingToCallableParameters(params.indexOf(it)) + } ?: PointingToDeclaration + } +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt new file mode 100644 index 00000000..0c55fed4 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/Documentable.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiNamedElement +import org.jetbrains.dokka.model.DocumentableSource +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.load.kotlin.toSourceElement + +class DescriptorDocumentableSource(val descriptor: DeclarationDescriptor) : DocumentableSource { + override val path = descriptor.toSourceElement.containingFile.toString() +} + +class PsiDocumentableSource(val psi: PsiNamedElement) : DocumentableSource { + override val path = psi.containingFile.virtualFile.path +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt new file mode 100644 index 00000000..9d15123a --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/EnvironmentAndFacade.kt @@ -0,0 +1,59 @@ +package org.jetbrains.dokka.analysis + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageRenderer +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.utils.PathUtil +import java.io.File + +internal fun createEnvironmentAndFacade( + logger: DokkaLogger, + configuration: DokkaConfiguration, + pass: DokkaConfiguration.PassConfiguration +): EnvironmentAndFacade = + AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run { + if (analysisPlatform == Platform.jvm) { + addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) + } + pass.classpath.forEach { addClasspath(File(it)) } + + addSources( + (pass.sourceRoots + configuration.passesConfigurations.filter { it.sourceSetID in pass.dependentSourceSets } + .flatMap { it.sourceRoots }) + .map { it.path } + ) + + loadLanguageVersionSettings(pass.languageVersion, pass.apiVersion) + + val environment = createCoreEnvironment() + val (facade, _) = createResolutionFacade(environment) + EnvironmentAndFacade(environment, facade) + } + +class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector { + override fun clear() { + seenErrors = false + } + + private var seenErrors = false + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { + if (severity == CompilerMessageSeverity.ERROR) { + seenErrors = true + } + logger.info(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location)) + } + + override fun hasErrors() = seenErrors +} + +// It is not data class due to ill-defined equals +class EnvironmentAndFacade(val environment: KotlinCoreEnvironment, val facade: DokkaResolutionFacade) { + operator fun component1() = environment + operator fun component2() = facade +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JavaResolveExtension.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JavaResolveExtension.kt new file mode 100644 index 00000000..ab6bec9c --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/JavaResolveExtension.kt @@ -0,0 +1,128 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:JvmName("JavaResolutionUtils") + +package org.jetbrains.dokka.analysis + +import com.intellij.psi.* +import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.java.sources.JavaSourceElement +import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.load.java.structure.impl.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter +import org.jetbrains.kotlin.resolve.scopes.MemberScope + +// TODO: Remove that file + +@JvmOverloads +fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { + val method = originalElement as? PsiMethod ?: return null + if (method.containingClass == null || !Name.isValidIdentifier(method.name)) return null + val resolver = method.getJavaDescriptorResolver(resolutionFacade) + return when { + method.isConstructor -> resolver?.resolveConstructor(JavaConstructorImpl(method)) + else -> resolver?.resolveMethod(JavaMethodImpl(method)) + } +} + +@JvmOverloads +fun PsiClass.getJavaClassDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): ClassDescriptor? { + val psiClass = originalElement as? PsiClass ?: return null + return psiClass.getJavaDescriptorResolver(resolutionFacade)?.resolveClass(JavaClassImpl(psiClass)) +} + +@JvmOverloads +fun PsiField.getJavaFieldDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): PropertyDescriptor? { + val field = originalElement as? PsiField ?: return null + return field.getJavaDescriptorResolver(resolutionFacade)?.resolveField(JavaFieldImpl(field)) +} + +@JvmOverloads +fun PsiMember.getJavaMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { + return when (this) { + is PsiEnumConstant -> containingClass?.getJavaClassDescriptor(resolutionFacade) + is PsiClass -> getJavaClassDescriptor(resolutionFacade) + is PsiMethod -> getJavaMethodDescriptor(resolutionFacade) + is PsiField -> getJavaFieldDescriptor(resolutionFacade) + else -> null + } +} + +@JvmOverloads +fun PsiMember.getJavaOrKotlinMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? { + val callable = unwrapped + return when (callable) { + is PsiMember -> getJavaMemberDescriptor(resolutionFacade) + is KtDeclaration -> { + val descriptor = resolutionFacade.resolveToDescriptor(callable) + if (descriptor is ClassDescriptor && this is PsiMethod) descriptor.unsubstitutedPrimaryConstructor else descriptor + } + else -> null + } +} + +private fun PsiElement.getJavaDescriptorResolver(resolutionFacade: ResolutionFacade): JavaDescriptorResolver? { + return resolutionFacade.tryGetFrontendService(this, JavaDescriptorResolver::class.java) +} + +private fun JavaDescriptorResolver.resolveMethod(method: JavaMethod): DeclarationDescriptor? { + return getContainingScope(method) + ?.getContributedDescriptors(nameFilter = { true }, kindFilter = DescriptorKindFilter.CALLABLES) + ?.filterIsInstance() + ?.findByJavaElement(method) +} + +private fun JavaDescriptorResolver.resolveConstructor(constructor: JavaConstructor): ConstructorDescriptor? { + return resolveClass(constructor.containingClass)?.constructors?.findByJavaElement(constructor) +} + +private fun JavaDescriptorResolver.resolveField(field: JavaField): PropertyDescriptor? { + return getContainingScope(field)?.getContributedVariables(field.name, NoLookupLocation.FROM_IDE)?.findByJavaElement(field) +} + +private fun JavaDescriptorResolver.getContainingScope(member: JavaMember): MemberScope? { + val containingClass = resolveClass(member.containingClass) + return if (member.isStatic) + containingClass?.staticScope + else + containingClass?.defaultType?.memberScope +} + +private fun Collection.findByJavaElement(javaElement: JavaElement): T? { + return firstOrNull { member -> + val memberJavaElement = (member.original.source as? JavaSourceElement)?.javaElement + when { + memberJavaElement == javaElement -> + true + memberJavaElement is JavaElementImpl<*> && javaElement is JavaElementImpl<*> -> + memberJavaElement.psi.isEquivalentTo(javaElement.psi) + else -> + false + } + } +} + +fun PsiElement.javaResolutionFacade() = + KotlinCacheService.getInstance(project).getResolutionFacadeByFile(this.originalElement.containingFile, JvmPlatforms.defaultJvmPlatform)!! diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt new file mode 100644 index 00000000..cd07b2a3 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt @@ -0,0 +1,46 @@ +@file:Suppress("FunctionName") + +package org.jetbrains.dokka.analysis + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.model.SourceSetCache +import org.jetbrains.dokka.model.SourceSetData +import org.jetbrains.dokka.model.SourceSetDependent +import org.jetbrains.dokka.plugability.DokkaContext + +fun KotlinAnalysis(context: DokkaContext): KotlinAnalysis { + val environments = context.configuration.passesConfigurations + .associate { passConfiguration -> + context.sourceSetCache.getSourceSet(passConfiguration) to createEnvironmentAndFacade( + logger = context.logger, + configuration = context.configuration, + pass = passConfiguration + ) + } + + return KotlinAnalysisImpl(context.sourceSetCache, environments) +} + +interface KotlinAnalysis : SourceSetDependent { + override fun get(key: SourceSetData): EnvironmentAndFacade + operator fun get(sourceSetID: String): EnvironmentAndFacade + operator fun get(passConfiguration: DokkaConfiguration.PassConfiguration): EnvironmentAndFacade +} + +internal class KotlinAnalysisImpl( + private val sourceSetCache: SourceSetCache, + private val environments: SourceSetDependent +) : KotlinAnalysis, SourceSetDependent by environments { + + override fun get(key: SourceSetData): EnvironmentAndFacade { + return environments[key] ?: throw IllegalStateException("Missing EnvironmentAndFacade for sourceSet $key") + } + + override fun get(sourceSetID: String): EnvironmentAndFacade { + return environments.entries.first { (sourceSet, _) -> sourceSet.sourceSetID == sourceSetID }.value + } + + override fun get(passConfiguration: DokkaConfiguration.PassConfiguration): EnvironmentAndFacade { + return get(sourceSetCache.getSourceSet(passConfiguration)) + } +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt new file mode 100644 index 00000000..e07672d4 --- /dev/null +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/TypeReferenceFactory.kt @@ -0,0 +1,51 @@ +package org.jetbrains.dokka.analysis + +import com.intellij.psi.PsiClass +import org.jetbrains.dokka.links.* +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe +import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeProjection + +fun TypeReference.Companion.from(d: ReceiverParameterDescriptor): TypeReference? = + when (d.value) { + is ExtensionReceiver -> fromPossiblyNullable(d.type) + else -> run { + println("Unknown value type for $d") + null + } + } + +fun TypeReference.Companion.from(d: ValueParameterDescriptor): TypeReference? = + fromPossiblyNullable(d.type) + +fun TypeReference.Companion.from(p: PsiClass) = TypeReference + +private fun TypeReference.Companion.fromPossiblyNullable(t: KotlinType, self: KotlinType? = null): TypeReference = + from(t, self).let { if (t.isMarkedNullable) Nullable(it) else it } + +private fun TypeReference.Companion.from(t: KotlinType, self: KotlinType? = null): TypeReference = + if (self is KotlinType && self.constructor == t.constructor && self.arguments == t.arguments) + SelfType + else when (val d = t.constructor.declarationDescriptor) { + is TypeParameterDescriptor -> TypeParam( + d.upperBounds.map { fromPossiblyNullable(it, self ?: t) } + ) + else -> TypeConstructor( + t.constructorName.orEmpty(), + t.arguments.map { fromProjection(it, self) } + ) + } + +private fun TypeReference.Companion.fromProjection(t: TypeProjection, r: KotlinType? = null): TypeReference = + if (t.isStarProjection) { + StarProjection + } else { + fromPossiblyNullable(t.type, r) + } + +private val KotlinType.constructorName + get() = constructor.declarationDescriptor?.fqNameSafe?.asString() diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts index 24a7f593..97d6a646 100644 --- a/plugins/base/build.gradle.kts +++ b/plugins/base/build.gradle.kts @@ -5,6 +5,7 @@ plugins { } dependencies { + api(project(":kotlin-analysis")) implementation("org.jsoup:jsoup:1.12.1") implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.6.10") testImplementation(project(":test-tools")) diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index cf4ad88f..f1b0d969 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -1,6 +1,9 @@ +@file:Suppress("unused") + package org.jetbrains.dokka.base import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.analysis.KotlinAnalysis import org.jetbrains.dokka.base.allModulePage.MultimodulePageCreator import org.jetbrains.dokka.base.renderers.* import org.jetbrains.dokka.base.renderers.html.* @@ -37,13 +40,19 @@ class DokkaBase : DokkaPlugin() { val externalLocationProviderFactory by extensionPoint() val outputWriter by extensionPoint() val htmlPreprocessors by extensionPoint() + val kotlinAnalysis by extensionPoint() + val descriptorToDocumentableTranslator by extending { - CoreExtensions.sourceToDocumentableTranslator with DefaultDescriptorToDocumentableTranslator + CoreExtensions.sourceToDocumentableTranslator providing { ctx -> + DefaultDescriptorToDocumentableTranslator(ctx.single(kotlinAnalysis)) + } } val psiToDocumentableTranslator by extending { - CoreExtensions.sourceToDocumentableTranslator with DefaultPsiToDocumentableTranslator + CoreExtensions.sourceToDocumentableTranslator providing { ctx -> + DefaultPsiToDocumentableTranslator(ctx.single(kotlinAnalysis)) + } } val documentableMerger by extending(isFallback = true) { @@ -69,7 +78,9 @@ class DokkaBase : DokkaPlugin() { } val modulesAndPackagesDocumentation by extending(isFallback = true) { - CoreExtensions.preMergeDocumentableTransformer providing ::ModuleAndPackageDocumentationTransformer + CoreExtensions.preMergeDocumentableTransformer providing { ctx -> + ModuleAndPackageDocumentationTransformer(ctx, ctx.single(kotlinAnalysis)) + } } val kotlinSignatureProvider by extending(isFallback = true) { @@ -124,6 +135,10 @@ class DokkaBase : DokkaPlugin() { CoreExtensions.renderer providing ::HtmlRenderer applyIf { format == "html" } } + val defaultKotlinAnalysis by extending(isFallback = true) { + kotlinAnalysis providing { ctx -> KotlinAnalysis(ctx) } + } + val locationProvider by extending(isFallback = true) { locationProviderFactory providing ::DefaultLocationProviderFactory } diff --git a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt index ea1d8510..cdaa0274 100644 --- a/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt +++ b/plugins/base/src/main/kotlin/allModulePage/MultimodulePageCreator.kt @@ -9,7 +9,7 @@ import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.doc.P import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.parsers.MarkdownParser +import org.jetbrains.dokka.base.parsers.MarkdownParser import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.transformers.pages.PageCreator diff --git a/plugins/base/src/main/kotlin/parsers/HtmlParser.kt b/plugins/base/src/main/kotlin/parsers/HtmlParser.kt new file mode 100644 index 00000000..ece3cf24 --- /dev/null +++ b/plugins/base/src/main/kotlin/parsers/HtmlParser.kt @@ -0,0 +1,89 @@ +package org.jetbrains.dokka.base.parsers + +import org.jetbrains.dokka.model.doc.* +import org.jetbrains.dokka.base.parsers.factories.DocTagsFromStringFactory +import org.jsoup.Jsoup +import org.jsoup.nodes.Node +import org.jsoup.select.NodeFilter +import org.jsoup.select.NodeTraversor + +class HtmlParser : Parser() { + + inner class NodeFilterImpl : NodeFilter { + + private val nodesCache: MutableMap> = mutableMapOf() + private var currentDepth = 0 + + fun collect(): DocTag = nodesCache[currentDepth]!![0] + + override fun tail(node: Node?, depth: Int): NodeFilter.FilterResult { + val nodeName = node!!.nodeName() + val nodeAttributes = node.attributes() + + if(nodeName in listOf("#document", "html", "head")) + return NodeFilter.FilterResult.CONTINUE + + val body: String + val params: Map + + + if(nodeName != "#text") { + body = "" + params = nodeAttributes.map { it.key to it.value }.toMap() + } else { + body = nodeAttributes["#text"] + params = emptyMap() + } + + val docNode = if(depth < currentDepth) { + DocTagsFromStringFactory.getInstance(nodeName, nodesCache.getOrDefault(currentDepth, mutableListOf()).toList(), params, body).also { + nodesCache[currentDepth] = mutableListOf() + currentDepth = depth + } + } else { + DocTagsFromStringFactory.getInstance(nodeName, emptyList(), params, body) + } + + nodesCache.getOrDefault(depth, mutableListOf()) += docNode + return NodeFilter.FilterResult.CONTINUE + } + + override fun head(node: Node?, depth: Int): NodeFilter.FilterResult { + + val nodeName = node!!.nodeName() + + if(currentDepth < depth) { + currentDepth = depth + nodesCache[currentDepth] = mutableListOf() + } + + if(nodeName in listOf("#document", "html", "head")) + return NodeFilter.FilterResult.CONTINUE + + return NodeFilter.FilterResult.CONTINUE + } + } + + + private fun htmlToDocNode(string: String): DocTag { + val document = Jsoup.parse(string) + val nodeFilterImpl = NodeFilterImpl() + NodeTraversor.filter(nodeFilterImpl, document.root()) + return nodeFilterImpl.collect() + } + + private fun replaceLinksWithHrefs(javadoc: String): String = Regex("\\{@link .*?}").replace(javadoc) { + val split = it.value.dropLast(1).split(" ") + if(split.size !in listOf(2, 3)) + return@replace it.value + if(split.size == 3) + return@replace "${split[2]}" + else + return@replace "${split[1]}" + } + + override fun parseStringToDocNode(extractedString: String) = htmlToDocNode(extractedString) + override fun preparse(text: String) = replaceLinksWithHrefs(text) +} + + diff --git a/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt new file mode 100644 index 00000000..6075ef73 --- /dev/null +++ b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt @@ -0,0 +1,419 @@ +package org.jetbrains.dokka.base.parsers + +import com.intellij.psi.PsiElement +import org.jetbrains.dokka.model.doc.* +import org.intellij.markdown.MarkdownElementTypes +import org.intellij.markdown.MarkdownTokenTypes +import org.intellij.markdown.ast.ASTNode +import org.intellij.markdown.ast.CompositeASTNode +import org.intellij.markdown.ast.LeafASTNode +import org.intellij.markdown.ast.impl.ListItemCompositeNode +import org.intellij.markdown.flavours.gfm.GFMElementTypes +import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor +import org.intellij.markdown.flavours.gfm.GFMTokenTypes +import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.analysis.from +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.base.parsers.factories.DocTagsFromIElementFactory +import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink +import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag +import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection +import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag +import java.net.MalformedURLException +import org.intellij.markdown.parser.MarkdownParser as IntellijMarkdownParser + +class MarkdownParser( + private val resolutionFacade: DokkaResolutionFacade? = null, + private val declarationDescriptor: DeclarationDescriptor? = null, + private val logger: DokkaLogger +) : Parser() { + + inner class MarkdownVisitor(val text: String, val destinationLinksMap: Map) { + + private fun headersHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + node.type, + visitNode(node.children.find { it.type == MarkdownTokenTypes.ATX_CONTENT } + ?: throw IllegalStateException("Wrong AST Tree. ATX Header does not contain expected content")).children + ) + + private fun horizontalRulesHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance(MarkdownTokenTypes.HORIZONTAL_RULE) + + private fun emphasisHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + node.type, + children = listOf(visitNode(node.children[node.children.size / 2])) + ) + + private fun blockquotesHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + node.type, children = node.children + .filterIsInstance() + .evaluateChildren() + ) + + private fun listsHandler(node: ASTNode): DocTag { + + val children = node.children.filterIsInstance().flatMap { + if (it.children.last().type in listOf( + MarkdownElementTypes.ORDERED_LIST, + MarkdownElementTypes.UNORDERED_LIST + ) + ) { + val nestedList = it.children.last() + (it.children as MutableList).removeAt(it.children.lastIndex) + listOf(it, nestedList) + } else + listOf(it) + } + + return DocTagsFromIElementFactory.getInstance( + node.type, + children = + children + .map { + if (it.type == MarkdownElementTypes.LIST_ITEM) + DocTagsFromIElementFactory.getInstance( + it.type, + children = it + .children + .filterIsInstance() + .evaluateChildren() + ) + else + visitNode(it) + }, + params = + if (node.type == MarkdownElementTypes.ORDERED_LIST) { + val listNumberNode = node.children.first().children.first() + mapOf( + "start" to text.substring( + listNumberNode.startOffset, + listNumberNode.endOffset + ).trim().dropLast(1) + ) + } else + emptyMap() + ) + } + + private fun resolveDRI(mdLink: String): DRI? = + mdLink + .removePrefix("[") + .removeSuffix("]") + .let { link -> + try { + java.net.URL(link) + null + } catch (e: MalformedURLException) { + try { + if (resolutionFacade != null && declarationDescriptor != null) { + resolveKDocLink( + resolutionFacade.resolveSession.bindingContext, + resolutionFacade, + declarationDescriptor, + null, + link.split('.') + ).minBy { it is ClassDescriptor }?.let { DRI.from(it) } + } else null + } catch (e1: IllegalArgumentException) { + null + } + } + } + + private fun referenceLinksHandler(node: ASTNode): DocTag { + val linkLabel = node.children.find { it.type == MarkdownElementTypes.LINK_LABEL } + ?: throw IllegalStateException("Wrong AST Tree. Reference link does not contain expected content") + val linkText = node.children.findLast { it.type == MarkdownElementTypes.LINK_TEXT } ?: linkLabel + + val linkKey = text.substring(linkLabel.startOffset, linkLabel.endOffset) + + val link = destinationLinksMap[linkKey.toLowerCase()] ?: linkKey + + return linksHandler(linkText, link) + } + + private fun inlineLinksHandler(node: ASTNode): DocTag { + val linkText = node.children.find { it.type == MarkdownElementTypes.LINK_TEXT } + ?: throw IllegalStateException("Wrong AST Tree. Inline link does not contain expected content") + val linkDestination = node.children.find { it.type == MarkdownElementTypes.LINK_DESTINATION } + ?: throw IllegalStateException("Wrong AST Tree. Inline link does not contain expected content") + val linkTitle = node.children.find { it.type == MarkdownElementTypes.LINK_TITLE } + + val link = text.substring(linkDestination.startOffset, linkDestination.endOffset) + + return linksHandler(linkText, link, linkTitle) + } + + private fun autoLinksHandler(node: ASTNode): DocTag { + val link = text.substring(node.startOffset + 1, node.endOffset - 1) + + return linksHandler(node, link) + } + + private fun linksHandler(linkText: ASTNode, link: String, linkTitle: ASTNode? = null): DocTag { + val dri: DRI? = resolveDRI(link) + val params = if (linkTitle == null) + mapOf("href" to link) + else + mapOf("href" to link, "title" to text.substring(linkTitle.startOffset + 1, linkTitle.endOffset - 1)) + + return DocTagsFromIElementFactory.getInstance( + MarkdownElementTypes.INLINE_LINK, + params = params, + children = linkText.children.drop(1).dropLast(1).evaluateChildren(), + dri = dri + ) + } + + private fun imagesHandler(node: ASTNode): DocTag { + val linkNode = + node.children.last().children.find { it.type == MarkdownElementTypes.LINK_LABEL }!!.children[1] + val link = text.substring(linkNode.startOffset, linkNode.endOffset) + val src = mapOf("src" to link) + return DocTagsFromIElementFactory.getInstance( + node.type, + params = src, + children = listOf(visitNode(node.children.last().children.find { it.type == MarkdownElementTypes.LINK_TEXT }!!)) + ) + } + + private fun codeSpansHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + node.type, + children = listOf( + DocTagsFromIElementFactory.getInstance( + MarkdownTokenTypes.TEXT, + body = text.substring(node.startOffset + 1, node.endOffset - 1).replace('\n', ' ').trimIndent() + ) + + ) + ) + + private fun codeFencesHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + node.type, + children = node + .children + .dropWhile { it.type != MarkdownTokenTypes.CODE_FENCE_CONTENT } + .dropLastWhile { it.type != MarkdownTokenTypes.CODE_FENCE_CONTENT } + .map { + if (it.type == MarkdownTokenTypes.EOL) + LeafASTNode(MarkdownTokenTypes.HARD_LINE_BREAK, 0, 0) + else + it + }.evaluateChildren(), + params = node + .children + .find { it.type == MarkdownTokenTypes.FENCE_LANG } + ?.let { mapOf("lang" to text.substring(it.startOffset, it.endOffset)) } + ?: emptyMap() + ) + + private fun codeBlocksHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance(node.type, children = node.children.evaluateChildren()) + + private fun defaultHandler(node: ASTNode): DocTag = + DocTagsFromIElementFactory.getInstance( + MarkdownElementTypes.PARAGRAPH, + children = node.children.evaluateChildren() + ) + + fun visitNode(node: ASTNode): DocTag = + when (node.type) { + MarkdownElementTypes.ATX_1, + MarkdownElementTypes.ATX_2, + MarkdownElementTypes.ATX_3, + MarkdownElementTypes.ATX_4, + MarkdownElementTypes.ATX_5, + MarkdownElementTypes.ATX_6 -> headersHandler(node) + MarkdownTokenTypes.HORIZONTAL_RULE -> horizontalRulesHandler(node) + MarkdownElementTypes.STRONG, + MarkdownElementTypes.EMPH -> emphasisHandler(node) + MarkdownElementTypes.FULL_REFERENCE_LINK, + MarkdownElementTypes.SHORT_REFERENCE_LINK -> referenceLinksHandler(node) + MarkdownElementTypes.INLINE_LINK -> inlineLinksHandler(node) + MarkdownElementTypes.AUTOLINK -> autoLinksHandler(node) + MarkdownElementTypes.BLOCK_QUOTE -> blockquotesHandler(node) + MarkdownElementTypes.UNORDERED_LIST, + MarkdownElementTypes.ORDERED_LIST -> listsHandler(node) + MarkdownElementTypes.CODE_BLOCK -> codeBlocksHandler(node) + MarkdownElementTypes.CODE_FENCE -> codeFencesHandler(node) + MarkdownElementTypes.CODE_SPAN -> codeSpansHandler(node) + MarkdownElementTypes.IMAGE -> imagesHandler(node) + MarkdownTokenTypes.HARD_LINE_BREAK -> DocTagsFromIElementFactory.getInstance(node.type) + MarkdownTokenTypes.CODE_FENCE_CONTENT, + MarkdownTokenTypes.CODE_LINE, + MarkdownTokenTypes.TEXT -> DocTagsFromIElementFactory.getInstance( + MarkdownTokenTypes.TEXT, + body = text + .substring(node.startOffset, node.endOffset).transform() + ) + MarkdownElementTypes.MARKDOWN_FILE -> if (node.children.size == 1) visitNode(node.children.first()) else defaultHandler( + node + ) + GFMElementTypes.STRIKETHROUGH -> DocTagsFromIElementFactory.getInstance( + GFMElementTypes.STRIKETHROUGH, + body = text + .substring(node.startOffset, node.endOffset).transform() + ) + GFMElementTypes.TABLE -> DocTagsFromIElementFactory.getInstance( + GFMElementTypes.TABLE, + children = node.children.filterTabSeparators().evaluateChildren() + ) + GFMElementTypes.HEADER -> DocTagsFromIElementFactory.getInstance( + GFMElementTypes.HEADER, + children = node.children.filterTabSeparators().evaluateChildren() + ) + GFMElementTypes.ROW -> DocTagsFromIElementFactory.getInstance( + GFMElementTypes.ROW, + children = node.children.filterTabSeparators().evaluateChildren() + ) + else -> defaultHandler(node) + } + + private fun List.filterTabSeparators() = + this.filterNot { it.type == GFMTokenTypes.TABLE_SEPARATOR } + + private fun List.evaluateChildren(): List = + this.removeUselessTokens().mergeLeafASTNodes().map { visitNode(it) } + + private fun List.removeUselessTokens(): List = + this.filterIndexed { index, node -> + !(node.type == MarkdownElementTypes.LINK_DEFINITION || ( + node.type == MarkdownTokenTypes.EOL && + this.getOrNull(index - 1)?.type == MarkdownTokenTypes.HARD_LINE_BREAK + )) + } + + private val notLeafNodes = listOf(MarkdownTokenTypes.HORIZONTAL_RULE, MarkdownTokenTypes.HARD_LINE_BREAK) + + private fun List.isNotLeaf(index: Int): Boolean = + if (index in 0..this.lastIndex) + (this[index] is CompositeASTNode) || this[index].type in notLeafNodes + else + false + + private fun List.mergeLeafASTNodes(): List { + val children: MutableList = mutableListOf() + var index = 0 + while (index <= this.lastIndex) { + if (this.isNotLeaf(index)) { + children += this[index] + } else { + val startOffset = this[index].startOffset + while (index < this.lastIndex) { + if (this.isNotLeaf(index + 1) || this[index + 1].startOffset != this[index].endOffset) { + val endOffset = this[index].endOffset + if (text.substring(startOffset, endOffset).transform().trim().isNotEmpty()) + children += LeafASTNode(MarkdownTokenTypes.TEXT, startOffset, endOffset) + break + } + index++ + } + if (index == this.lastIndex) { + val endOffset = this[index].endOffset + if (text.substring(startOffset, endOffset).transform().trim().isNotEmpty()) + children += LeafASTNode(MarkdownTokenTypes.TEXT, startOffset, endOffset) + } + } + index++ + } + return children + } + + private fun String.transform() = this + .replace(Regex("\n\n+"), "") // Squashing new lines between paragraphs + .replace(Regex("\n"), " ") + .replace(Regex(" >+ +"), " ") // Replacement used in blockquotes, get rid of garbage + } + + + private fun getAllDestinationLinks(text: String, node: ASTNode): List> = + node.children + .filter { it.type == MarkdownElementTypes.LINK_DEFINITION } + .map { + text.substring(it.children[0].startOffset, it.children[0].endOffset).toLowerCase() to + text.substring(it.children[2].startOffset, it.children[2].endOffset) + } + + node.children.filterIsInstance().flatMap { getAllDestinationLinks(text, it) } + + + private fun markdownToDocNode(text: String): DocTag { + + val flavourDescriptor = GFMFlavourDescriptor() + val markdownAstRoot: ASTNode = IntellijMarkdownParser(flavourDescriptor).buildMarkdownTreeFromString(text) + + return MarkdownVisitor(text, getAllDestinationLinks(text, markdownAstRoot).toMap()).visitNode(markdownAstRoot) + } + + override fun parseStringToDocNode(extractedString: String) = markdownToDocNode(extractedString) + override fun preparse(text: String) = text + + private fun findParent(kDoc: PsiElement): PsiElement = + if (kDoc is KDocSection) findParent(kDoc.parent) else kDoc + + private fun getAllKDocTags(kDocImpl: PsiElement): List = + kDocImpl.children.filterIsInstance().filterNot { it is KDocSection } + kDocImpl.children.flatMap { + getAllKDocTags( + it + ) + } + + fun parseFromKDocTag(kDocTag: KDocTag?): DocumentationNode { + return if (kDocTag == null) + DocumentationNode(emptyList()) + else + DocumentationNode( + (listOf(kDocTag) + getAllKDocTags(findParent(kDocTag))).map { + when (it.knownTag) { + null -> if (it.name == null) Description(parseStringToDocNode(it.getContent())) else CustomTagWrapper( + parseStringToDocNode(it.getContent()), + it.name!! + ) + KDocKnownTag.AUTHOR -> Author(parseStringToDocNode(it.getContent())) + KDocKnownTag.THROWS -> Throws( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty() + ) + KDocKnownTag.EXCEPTION -> Throws( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty() + ) + KDocKnownTag.PARAM -> Param( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty() + ) + KDocKnownTag.RECEIVER -> Receiver(parseStringToDocNode(it.getContent())) + KDocKnownTag.RETURN -> Return(parseStringToDocNode(it.getContent())) + KDocKnownTag.SEE -> See( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty(), + parseStringToDocNode("[${it.getSubjectName()}]") + .let { + val link = it.children[0] + if (link is DocumentationLink) link.dri + else null + } + ) + KDocKnownTag.SINCE -> Since(parseStringToDocNode(it.getContent())) + KDocKnownTag.CONSTRUCTOR -> Constructor(parseStringToDocNode(it.getContent())) + KDocKnownTag.PROPERTY -> Property( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty() + ) + KDocKnownTag.SAMPLE -> Sample( + parseStringToDocNode(it.getContent()), + it.getSubjectName().orEmpty() + ) + KDocKnownTag.SUPPRESS -> Suppress(parseStringToDocNode(it.getContent())) + } + } + ) + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/parsers/Parser.kt b/plugins/base/src/main/kotlin/parsers/Parser.kt new file mode 100644 index 00000000..1dd0c34a --- /dev/null +++ b/plugins/base/src/main/kotlin/parsers/Parser.kt @@ -0,0 +1,42 @@ +package org.jetbrains.dokka.base.parsers + +import org.jetbrains.dokka.model.doc.* + +abstract class Parser { + + abstract fun parseStringToDocNode(extractedString: String): DocTag + abstract fun preparse(text: String): String + + fun parse(text: String): DocumentationNode { + + val list = jkdocToListOfPairs(preparse(text)) + + val mappedList: List = list.map { + when(it.first) { + "description" -> Description(parseStringToDocNode(it.second)) + "author" -> Author(parseStringToDocNode(it.second)) + "version" -> Version(parseStringToDocNode(it.second)) + "since" -> Since(parseStringToDocNode(it.second)) + "see" -> See(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '), null) + "param" -> Param(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) + "property" -> Property(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) + "return" -> Return(parseStringToDocNode(it.second)) + "constructor" -> Constructor(parseStringToDocNode(it.second)) + "receiver" -> Receiver(parseStringToDocNode(it.second)) + "throws", "exception" -> Throws(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) + "deprecated" -> Deprecated(parseStringToDocNode(it.second)) + "sample" -> Sample(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' ')) + "suppress" -> Suppress(parseStringToDocNode(it.second)) + else -> CustomTagWrapper(parseStringToDocNode(it.second), it.first) + } + } + return DocumentationNode(mappedList) + } + + private fun jkdocToListOfPairs(javadoc: String): List> = + "description $javadoc" + .split("\n@") + .map { + it.substringBefore(' ') to it.substringAfter(' ') + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt new file mode 100644 index 00000000..e81eb513 --- /dev/null +++ b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromIElementFactory.kt @@ -0,0 +1,43 @@ +package org.jetbrains.dokka.base.parsers.factories + +import org.jetbrains.dokka.model.doc.* +import org.intellij.markdown.IElementType +import org.intellij.markdown.MarkdownElementTypes +import org.intellij.markdown.MarkdownTokenTypes +import org.intellij.markdown.flavours.gfm.GFMElementTypes +import org.jetbrains.dokka.links.DRI +import java.lang.NullPointerException + +object DocTagsFromIElementFactory { + fun getInstance(type: IElementType, children: List = emptyList(), params: Map = emptyMap(), body: String? = null, dri: DRI? = null) = + when(type) { + MarkdownElementTypes.SHORT_REFERENCE_LINK, + MarkdownElementTypes.FULL_REFERENCE_LINK, + MarkdownElementTypes.INLINE_LINK -> if(dri == null) A(children, params) else DocumentationLink(dri, children, params) + MarkdownElementTypes.STRONG -> B(children, params) + MarkdownElementTypes.BLOCK_QUOTE -> BlockQuote(children, params) + MarkdownElementTypes.CODE_SPAN, + MarkdownElementTypes.CODE_BLOCK, + MarkdownElementTypes.CODE_FENCE -> Code(children, params) + MarkdownElementTypes.ATX_1 -> H1(children, params) + MarkdownElementTypes.ATX_2 -> H2(children, params) + MarkdownElementTypes.ATX_3 -> H3(children, params) + MarkdownElementTypes.ATX_4 -> H4(children, params) + MarkdownElementTypes.ATX_5 -> H5(children, params) + MarkdownElementTypes.ATX_6 -> H6(children, params) + MarkdownElementTypes.EMPH -> I(children, params) + MarkdownElementTypes.IMAGE -> Img(children, params) + MarkdownElementTypes.LIST_ITEM -> Li(children, params) + MarkdownElementTypes.ORDERED_LIST -> Ol(children, params) + MarkdownElementTypes.UNORDERED_LIST -> Ul(children, params) + MarkdownElementTypes.PARAGRAPH -> P(children, params) + MarkdownTokenTypes.TEXT -> Text(body ?: throw NullPointerException("Text body should be at least empty string passed to DocNodes factory!"), children, params ) + MarkdownTokenTypes.HORIZONTAL_RULE -> HorizontalRule + MarkdownTokenTypes.HARD_LINE_BREAK -> Br + GFMElementTypes.STRIKETHROUGH -> Strikethrough(children, params) + GFMElementTypes.TABLE -> Table(children, params) + GFMElementTypes.HEADER -> Th(children, params) + GFMElementTypes.ROW -> Tr(children, params) + else -> CustomDocTag(children, params) + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt new file mode 100644 index 00000000..de7c3cad --- /dev/null +++ b/plugins/base/src/main/kotlin/parsers/factories/DocTagsFromStringFactory.kt @@ -0,0 +1,77 @@ +package org.jetbrains.dokka.base.parsers.factories + +import org.jetbrains.dokka.model.doc.* +import org.jetbrains.dokka.links.DRI +import java.lang.NullPointerException + +object DocTagsFromStringFactory { + fun getInstance(name: String, children: List = emptyList(), params: Map = emptyMap(), body: String? = null, dri: DRI? = null) = + when(name) { + "a" -> A(children, params) + "big" -> Big(children, params) + "b" -> B(children, params) + "blockquote" -> BlockQuote(children, params) + "br" -> Br + "cite" -> Cite(children, params) + "code" -> Code(children, params) + "dd" -> Dd(children, params) + "dfn" -> Dfn(children, params) + "dir" -> Dir(children, params) + "div" -> Div(children, params) + "dl" -> Dl(children, params) + "dt" -> Dt(children, params) + "Em" -> Em(children, params) + "font" -> Font(children, params) + "footer" -> Footer(children, params) + "frame" -> Frame(children, params) + "frameset" -> FrameSet(children, params) + "h1" -> H1(children, params) + "h2" -> H2(children, params) + "h3" -> H3(children, params) + "h4" -> H4(children, params) + "h5" -> H5(children, params) + "h6" -> H6(children, params) + "head" -> Head(children, params) + "header" -> Header(children, params) + "html" -> Html(children, params) + "i" -> I(children, params) + "iframe" -> IFrame(children, params) + "img" -> Img(children, params) + "input" -> Input(children, params) + "li" -> Li(children, params) + "link" -> Link(children, params) + "listing" -> Listing(children, params) + "main" -> Main(children, params) + "menu" -> Menu(children, params) + "meta" -> Meta(children, params) + "nav" -> Nav(children, params) + "noframes" -> NoFrames(children, params) + "noscript" -> NoScript(children, params) + "ol" -> Ol(children, params) + "p" -> P(children, params) + "pre" -> Pre(children, params) + "script" -> Script(children, params) + "section" -> Section(children, params) + "small" -> Small(children, params) + "span" -> Span(children, params) + "strong" -> Strong(children, params) + "sub" -> Sub(children, params) + "sup" -> Sup(children, params) + "table" -> Table(children, params) + "#text" -> Text(body ?: throw NullPointerException("Text body should be at least empty string passed to DocNodes factory!"), children, params) + "tBody" -> TBody(children, params) + "td" -> Td(children, params) + "tFoot" -> TFoot(children, params) + "th" -> Th(children, params) + "tHead" -> THead(children, params) + "title" -> Title(children, params) + "tr" -> Tr(children, params) + "tt" -> Tt(children, params) + "u" -> U(children, params) + "ul" -> Ul(children, params) + "var" -> Var(children, params) + "documentationlink" -> DocumentationLink(dri ?: throw NullPointerException("DRI cannot be passed null while constructing documentation link!"), children, params) + "hr" -> HorizontalRule + else -> CustomDocTag(children, params) + } +} \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index 2aab6018..63232793 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -1,10 +1,13 @@ package org.jetbrains.dokka.base.transformers.documentables +import org.jetbrains.dokka.analysis.EnvironmentAndFacade +import org.jetbrains.dokka.analysis.KotlinAnalysis import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.model.sourceSet -import org.jetbrains.dokka.parsers.MarkdownParser +import org.jetbrains.dokka.base.parsers.MarkdownParser +import org.jetbrains.dokka.model.SourceSetDependent import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.kotlin.name.FqName @@ -12,9 +15,12 @@ import java.nio.file.Files import java.nio.file.Paths -internal class ModuleAndPackageDocumentationTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { +internal class ModuleAndPackageDocumentationTransformer( + private val context: DokkaContext, + private val kotlinAnalysis: KotlinAnalysis +) : PreMergeDocumentableTransformer { - override fun invoke(original: List): List { + override fun invoke(modules: List): List { val modulesAndPackagesDocumentation = context.configuration.passesConfigurations @@ -47,13 +53,12 @@ internal class ModuleAndPackageDocumentationTransformer(val context: DokkaContex } }.toMap() - return original.map { module -> + return modules.map { module -> val moduleDocumentation = module.sourceSets.mapNotNull { pd -> val doc = modulesAndPackagesDocumentation[Pair(module.name, pd)] - val facade = context.platforms[pd]?.facade - ?: return@mapNotNull null.also { context.logger.warn("Could not find platform data for ${pd.moduleName}/${pd.sourceSetID}") } + val facade = kotlinAnalysis[pd].facade try { doc?.get("Module")?.get(module.name)?.run { pd to MarkdownParser( @@ -71,8 +76,7 @@ internal class ModuleAndPackageDocumentationTransformer(val context: DokkaContex val packagesDocumentation = module.packages.map { it.name to it.sourceSets.mapNotNull { pd -> val doc = modulesAndPackagesDocumentation[Pair(module.name, pd)] - val facade = context.platforms[pd]?.facade - ?: return@mapNotNull null.also { context.logger.warn("Could not find platform data for ${pd.moduleName}/${pd.sourceSetID}") } + val facade = kotlinAnalysis[pd].facade val descriptor = facade.moduleDescriptor.getPackage(FqName(it.name.let { if(it == "[JS root]") "" else it })) doc?.get("Package")?.get(it.name)?.run { pd to MarkdownParser( diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt index 7d475571..0b47345d 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ReportUndocumentedTransformer.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka.base.transformers.documentables import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.PassConfiguration +import org.jetbrains.dokka.analysis.DescriptorDocumentableSource import org.jetbrains.dokka.model.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.DocumentableTransformer diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt index 57655a9d..0d133a65 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt @@ -1,11 +1,11 @@ package org.jetbrains.dokka.base.transformers.pages.samples import com.intellij.psi.PsiElement -import org.jetbrains.dokka.DokkaGenerator -import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.Platform import org.jetbrains.dokka.analysis.AnalysisEnvironment +import org.jetbrains.dokka.analysis.DokkaMessageCollector import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.analysis.EnvironmentAndFacade import org.jetbrains.dokka.base.renderers.platforms import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.SourceSetData @@ -41,7 +41,7 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { } private fun setUpAnalysis(context: DokkaContext) = context.configuration.passesConfigurations.map { - context.sourceSet(it) to AnalysisEnvironment(DokkaGenerator.DokkaMessageCollector(context.logger), it.analysisPlatform).run { + context.sourceSet(it) to AnalysisEnvironment(DokkaMessageCollector(context.logger), it.analysisPlatform).run { if (analysisPlatform == Platform.jvm) { addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre()) } @@ -57,11 +57,16 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { } }.toMap() - private fun ContentNode.addSample(contentPage: ContentPage, platform: SourceSetData, fqName: String, analysis: Map): ContentNode { - val facade = analysis[platform]?.facade ?: - return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.moduleName}")} - val psiElement = fqNameToPsiElement(facade, fqName) ?: - return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } + private fun ContentNode.addSample( + contentPage: ContentPage, + platform: SourceSetData, + fqName: String, + analysis: Map + ): ContentNode { + val facade = analysis[platform]?.facade + ?: return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.moduleName}") } + val psiElement = fqNameToPsiElement(facade, fqName) + ?: return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } val imports = processImports(psiElement) // TODO: Process somehow imports. Maybe just attach them at the top of each body val body = processBody(psiElement) val node = contentCode(contentPage.platforms(), contentPage.dri, body, "kotlin") @@ -70,10 +75,14 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { } private fun ContentNode.dfs(fqName: String, node: ContentCode): ContentNode { - return when(this) { + return when (this) { is ContentHeader -> copy(children.map { it.dfs(fqName, node) }) is ContentDivergentGroup -> copy(children.map { it.dfs(fqName, node) } as List) - is ContentDivergentInstance -> copy(before.let { it?.dfs(fqName, node) }, divergent.let { it.dfs(fqName, node) }, after.let { it?.dfs(fqName, node) }) + is ContentDivergentInstance -> copy( + before.let { it?.dfs(fqName, node) }, + divergent.dfs(fqName, node), + after.let { it?.dfs(fqName, node) } + ) is ContentCode -> copy(children.map { it.dfs(fqName, node) }) is ContentDRILink -> copy(children.map { it.dfs(fqName, node) }) is ContentResolvedLink -> copy(children.map { it.dfs(fqName, node) }) @@ -90,10 +99,14 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { private fun fqNameToPsiElement(resolutionFacade: DokkaResolutionFacade, functionName: String): PsiElement? { val packageName = functionName.takeWhile { it != '.' } - val descriptor = resolutionFacade.resolveSession.getPackageFragment(FqName(packageName)) ?: - return null.also { context.logger.warn("Cannot find descriptor for package $packageName") } - val symbol = resolveKDocSampleLink(BindingContext.EMPTY, resolutionFacade, descriptor, functionName.split(".")).firstOrNull() ?: - return null.also { context.logger.warn("Unresolved function $functionName in @sample") } + val descriptor = resolutionFacade.resolveSession.getPackageFragment(FqName(packageName)) + ?: return null.also { context.logger.warn("Cannot find descriptor for package $packageName") } + val symbol = resolveKDocSampleLink( + BindingContext.EMPTY, + resolutionFacade, + descriptor, + functionName.split(".") + ).firstOrNull() ?: return null.also { context.logger.warn("Unresolved function $functionName in @sample") } return DescriptorToSourceUtils.descriptorToDeclaration(symbol) } diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 8113d277..7603c80b 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -3,11 +3,11 @@ package org.jetbrains.dokka.base.transformers.pages.sourcelinks import com.intellij.psi.PsiElement import com.intellij.psi.PsiDocumentManager import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.analysis.DescriptorDocumentableSource +import org.jetbrains.dokka.analysis.PsiDocumentableSource import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder -import org.jetbrains.dokka.model.DescriptorDocumentableSource import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.model.DocumentableSource -import org.jetbrains.dokka.model.PsiDocumentableSource import org.jetbrains.dokka.model.WithExpectActual import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 49d8ae0f..cefea4ec 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -1,6 +1,6 @@ package org.jetbrains.dokka.base.translators.descriptors -import org.jetbrains.dokka.analysis.DokkaResolutionFacade +import org.jetbrains.dokka.analysis.* import org.jetbrains.dokka.links.* import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.model.* @@ -8,7 +8,7 @@ import org.jetbrains.dokka.model.Nullable import org.jetbrains.dokka.model.TypeConstructor import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.properties.PropertyContainer -import org.jetbrains.dokka.parsers.MarkdownParser +import org.jetbrains.dokka.base.parsers.MarkdownParser import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator import org.jetbrains.dokka.utilities.DokkaLogger @@ -52,18 +52,19 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue as ConstantsEnumValue import org.jetbrains.kotlin.resolve.constants.KClassValue as ConstantsKtClassValue import kotlin.IllegalArgumentException -object DefaultDescriptorToDocumentableTranslator : SourceToDocumentableTranslator { +class DefaultDescriptorToDocumentableTranslator( + private val kotlinAnalysis: KotlinAnalysis +) : SourceToDocumentableTranslator { override fun invoke(sourceSet: SourceSetData, context: DokkaContext): DModule { - - val (environment, facade) = context.platforms.getValue(sourceSet) + val (environment, facade) = kotlinAnalysis[sourceSet] val packageFragments = environment.getSourceFiles().asSequence() .map { it.packageFqName } .distinct() .mapNotNull { facade.resolveSession.getPackageFragment(it) } .toList() - return DokkaDescriptorVisitor(sourceSet, context.platforms.getValue(sourceSet).facade, context.logger).run { + return DokkaDescriptorVisitor(sourceSet, kotlinAnalysis[sourceSet].facade, context.logger).run { packageFragments.mapNotNull { it.safeAs() }.map { visitPackageFragmentDescriptor( it, diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index a5117b09..e71d936a 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -7,6 +7,10 @@ import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.* import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.psi.impl.source.PsiImmediateClassType +import org.jetbrains.dokka.analysis.KotlinAnalysis +import org.jetbrains.dokka.analysis.PsiDocumentableSource +import org.jetbrains.dokka.analysis.from +import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.links.nextTarget import org.jetbrains.dokka.links.withClass @@ -17,6 +21,7 @@ import org.jetbrains.dokka.model.doc.Param import org.jetbrains.dokka.model.doc.Text import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation @@ -33,15 +38,17 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.io.File -object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { +class DefaultPsiToDocumentableTranslator( + private val kotlinAnalysis: KotlinAnalysis +) : SourceToDocumentableTranslator { - override fun invoke(sourceSetData: SourceSetData, context: DokkaContext): DModule { + override fun invoke(sourceSet: SourceSetData, context: DokkaContext): DModule { fun isFileInSourceRoots(file: File): Boolean { - return sourceSetData.sourceRoots.any { root -> file.path.startsWith(File(root.path).absolutePath) } + return sourceSet.sourceRoots.any { root -> file.path.startsWith(File(root.path).absolutePath) } } - val (environment, _) = context.platforms.getValue(sourceSetData) + val (environment, _) = kotlinAnalysis[sourceSet] val sourceRoots = environment.configuration.get(CLIConfigurationKeys.CONTENT_ROOTS) ?.filterIsInstance() @@ -59,11 +66,11 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { val docParser = DokkaPsiParser( - sourceSetData, + sourceSet, context.logger ) return DModule( - sourceSetData.moduleName, + sourceSet.moduleName, psiFiles.mapNotNull { it.safeAs() }.groupBy { it.packageName }.map { (packageName, psiFiles) -> val dri = DRI(packageName = packageName) DPackage( @@ -76,12 +83,12 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator { emptyList(), emptyMap(), null, - setOf(sourceSetData) + setOf(sourceSet) ) }, emptyMap(), null, - setOf(sourceSetData) + setOf(sourceSet) ) } diff --git a/plugins/base/src/main/kotlin/translators/psi/JavadocParser.kt b/plugins/base/src/main/kotlin/translators/psi/JavadocParser.kt index d8130974..7119ba68 100644 --- a/plugins/base/src/main/kotlin/translators/psi/JavadocParser.kt +++ b/plugins/base/src/main/kotlin/translators/psi/JavadocParser.kt @@ -6,6 +6,7 @@ import com.intellij.psi.impl.source.tree.JavaDocElementType import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.javadoc.* import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.dokka.analysis.from import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.doc.* import org.jetbrains.dokka.model.doc.Deprecated diff --git a/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt b/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt index 2c805110..d548b75b 100644 --- a/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt +++ b/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt @@ -28,7 +28,7 @@ class FailOnWarningTest : AbstractCoreTest() { |package sample """.trimIndent(), configuration ) { - analysisSetupStage = { + pluginsSetupStage = { logger.warn("Warning!") } } @@ -53,7 +53,7 @@ class FailOnWarningTest : AbstractCoreTest() { |package sample """.trimIndent(), configuration ) { - analysisSetupStage = { + pluginsSetupStage = { logger.error("Error!") } } @@ -102,7 +102,7 @@ class FailOnWarningTest : AbstractCoreTest() { |package sample """.trimIndent(), configuration ) { - analysisSetupStage = { + pluginsSetupStage = { logger.warn("Error!") logger.error("Error!") } diff --git a/plugins/build.gradle.kts b/plugins/build.gradle.kts index d681cf2a..bb3b1a3d 100644 --- a/plugins/build.gradle.kts +++ b/plugins/build.gradle.kts @@ -6,8 +6,9 @@ subprojects { dependencies { compileOnly(project(":core")) -// compileOnly(project(":coreDependencies", configuration = "shadow")) // uncomment if IntelliJ does not recognize pacakges from IntelliJ implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) testImplementation(project(":testApi")) testImplementation("org.junit.jupiter:junit-jupiter:5.6.0") diff --git a/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt b/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt index c148a440..becacd26 100644 --- a/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt +++ b/plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt @@ -2,6 +2,9 @@ package javadoc.pages import com.intellij.psi.PsiClass import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.analysis.DescriptorDocumentableSource +import org.jetbrains.dokka.analysis.PsiDocumentableSource +import org.jetbrains.dokka.analysis.from import org.jetbrains.dokka.base.renderers.platforms import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.* diff --git a/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt b/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt index 45e97945..905cb61b 100644 --- a/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt +++ b/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt @@ -66,4 +66,4 @@ class JavadocTest : AbstractCoreTest() { // } // } // } -} \ No newline at end of file +} diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index 6c3a4d7d..8c4955ca 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.2.1") implementation("com.google.code.gson:gson:2.8.5") implementation(project(":core")) + implementation(kotlin("stdlib")) } diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index f0df08e0..80971ae2 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -5,7 +5,7 @@ import kotlinx.cli.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import org.jetbrains.dokka.DokkaConfiguration.PassConfiguration.* import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.dokka.utilities.cast import java.io.* import java.net.MalformedURLException import java.net.URL diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt index b7961b6e..41d6e67a 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.gradle import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Usage import org.gradle.util.GradleVersion import java.io.File import java.io.InputStream @@ -20,9 +21,8 @@ open class DokkaPlugin : Plugin { val pluginsConfiguration = project.configurations.create("dokkaPlugins").apply { dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-base:${DokkaVersion.version}")) attributes.attribute( - org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE, - project.objects.named(org.gradle.api.attributes.Usage::class.java, "java-runtime") - ) + Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, "java-runtime") + ) isCanBeConsumed = false } addDokkaTasks(project, dokkaRuntimeConfiguration, pluginsConfiguration, DokkaTask::class.java) diff --git a/settings.gradle.kts b/settings.gradle.kts index c813518d..bb91edc6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,15 @@ rootProject.name = "dokka" include("core") +include("core:dependencies") include("plugins:base:search-component") -include("coreDependencies") include("testApi") include("test-tools") include("runners:gradle-plugin") include("runners:cli") include("runners:maven-plugin") +include("kotlin-analysis") +include("kotlin-analysis:dependencies") include("plugins:base") include("plugins:base:frontend") include("plugins:mathjax") @@ -27,7 +29,7 @@ pluginManagement { } repositories { - maven(url="https://dl.bintray.com/kotlin/kotlin-dev/") + maven(url = "https://dl.bintray.com/kotlin/kotlin-dev/") mavenLocal() mavenCentral() jcenter() diff --git a/test-tools/build.gradle.kts b/test-tools/build.gradle.kts index 7fd8a879..a61787a8 100644 --- a/test-tools/build.gradle.kts +++ b/test-tools/build.gradle.kts @@ -1,5 +1,6 @@ dependencies { implementation(project(":testApi")) implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) implementation("com.willowtreeapps.assertk:assertk-jvm:0.22") } \ No newline at end of file diff --git a/testApi/build.gradle.kts b/testApi/build.gradle.kts index 43c984b5..c8b510a1 100644 --- a/testApi/build.gradle.kts +++ b/testApi/build.gradle.kts @@ -7,8 +7,10 @@ plugins { dependencies { api(project(":core")) + implementation(project(":kotlin-analysis")) implementation("junit:junit:4.13") // TODO: remove dependency to junit implementation(kotlin("stdlib")) + implementation(kotlin("reflect")) } val sourceJar by tasks.registering(Jar::class) { diff --git a/testApi/src/main/kotlin/testApi/context/MockContext.kt b/testApi/src/main/kotlin/testApi/context/MockContext.kt index 11520280..e3da5f68 100644 --- a/testApi/src/main/kotlin/testApi/context/MockContext.kt +++ b/testApi/src/main/kotlin/testApi/context/MockContext.kt @@ -1,7 +1,6 @@ package org.jetbrains.dokka.testApi.context import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.model.SourceSetCache import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.plugability.DokkaContext @@ -16,7 +15,6 @@ import kotlin.reflect.full.memberProperties class MockContext( vararg extensions: Pair, (DokkaContext) -> Any>, private val testConfiguration: DokkaConfiguration? = null, - private val testSourceSets: Map? = null, private val unusedExtensionPoints: List>? = null, override val sourceSetCache: SourceSetCache ) : DokkaContext { @@ -41,8 +39,6 @@ class MockContext( override val configuration: DokkaConfiguration get() = testConfiguration ?: throw IllegalStateException("This mock context doesn't provide configuration") - override val platforms: Map - get() = testSourceSets ?: throw IllegalStateException("This mock context doesn't provide platforms data") override val unusedPoints: Collection> get() = unusedExtensionPoints ?: throw IllegalStateException("This mock context doesn't provide unused extension points") diff --git a/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt b/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt index 2ca8523b..7248a4cb 100644 --- a/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt +++ b/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt @@ -2,7 +2,6 @@ package org.jetbrains.dokka.testApi.testRunner import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaGenerator -import org.jetbrains.dokka.EnvironmentAndFacade import org.jetbrains.dokka.model.SourceSetCache import org.jetbrains.dokka.model.SourceSetData import org.jetbrains.dokka.plugability.DokkaPlugin @@ -19,17 +18,11 @@ internal class DokkaTestGenerator( val dokkaGenerator = DokkaGenerator(configuration, logger) val sourceSetsCache = SourceSetCache() - val platforms: Map = dokkaGenerator.setUpAnalysis( - configuration, - sourceSetsCache - ) - analysisSetupStage(platforms) - val context = - dokkaGenerator.initializePlugins(configuration, logger, platforms, sourceSetsCache, pluginOverrides) + dokkaGenerator.initializePlugins(configuration, logger, sourceSetsCache, pluginOverrides) pluginsSetupStage(context) - val modulesFromPlatforms = dokkaGenerator.createDocumentationModels(platforms, context) + val modulesFromPlatforms = dokkaGenerator.createDocumentationModels(context, sourceSetsCache) documentablesCreationStage(modulesFromPlatforms) val filteredModules = dokkaGenerator.transformDocumentationModelBeforeMerge(modulesFromPlatforms, context) diff --git a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt index 9df20138..88595f85 100644 --- a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt +++ b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt @@ -106,7 +106,6 @@ abstract class AbstractCoreTest { } protected class TestBuilder { - var analysisSetupStage: (Map) -> Unit = {} var pluginsSetupStage: (DokkaContext) -> Unit = {} var documentablesCreationStage: (List) -> Unit = {} var documentablesFirstTransformationStep: (List) -> Unit = {} @@ -118,7 +117,6 @@ abstract class AbstractCoreTest { @PublishedApi internal fun build() = TestMethods( - analysisSetupStage, pluginsSetupStage, documentablesCreationStage, documentablesFirstTransformationStep, @@ -240,7 +238,6 @@ abstract class AbstractCoreTest { } data class TestMethods( - val analysisSetupStage: (Map) -> Unit, val pluginsSetupStage: (DokkaContext) -> Unit, val documentablesCreationStage: (List) -> Unit, val documentablesFirstTransformationStep: (List) -> Unit, -- cgit From b0e8622f374f6499058b0f083367b4a54512b702 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 30 Jun 2020 23:06:03 +0200 Subject: Enforce workspace unique SourceSetID --- build.gradle.kts | 4 +- core/src/main/kotlin/DokkaBootstrapImpl.kt | 5 +- core/src/main/kotlin/DokkaGenerator.kt | 2 +- .../main/kotlin/DokkaMultimoduleBootstrapImpl.kt | 5 +- core/src/main/kotlin/configuration.kt | 27 ++- core/src/main/kotlin/defaultConfiguration.kt | 22 ++- core/src/main/kotlin/plugability/DokkaPlugin.kt | 2 +- .../org/jetbrains/dokka/analysis/KotlinAnalysis.kt | 5 +- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 22 +-- .../main/kotlin/signatures/JvmSignatureUtils.kt | 3 +- .../DocumentableVisibilityFilterTransformer.kt | 12 +- .../EmptyPackagesFilterTransformer.kt | 6 +- .../ModuleAndPackageDocumentationTransformer.kt | 4 +- .../pages/samples/SamplesTransformer.kt | 4 +- .../DefaultDescriptorToDocumentableTranslator.kt | 4 +- .../psi/DefaultPsiToDocumentableTranslator.kt | 2 +- plugins/base/src/test/kotlin/basic/DRITest.kt | 40 ++-- .../base/src/test/kotlin/basic/DokkaBasicTests.kt | 6 +- .../src/test/kotlin/basic/FailOnWarningTest.kt | 18 +- .../annotations/ContentForAnnotationsTest.kt | 6 +- .../annotations/DepredatedAndSinceKotlinTest.kt | 8 +- .../kotlin/content/params/ContentForParamsTest.kt | 4 +- .../content/seealso/ContentForSeeAlsoTest.kt | 6 +- .../content/signatures/ContentForSignaturesTest.kt | 4 +- .../SkippingParenthesisForConstructorsTest.kt | 6 +- plugins/base/src/test/kotlin/enums/EnumsTest.kt | 20 +- .../src/test/kotlin/expect/AbstractExpectTest.kt | 6 +- .../test/kotlin/filter/DeprecationFilterTest.kt | 22 +-- .../test/kotlin/filter/EmptyPackagesFilterTest.kt | 11 +- .../src/test/kotlin/filter/VisibilityFilterTest.kt | 22 +-- plugins/base/src/test/kotlin/issues/IssuesTest.kt | 6 +- .../kotlin/linkableContent/LinkableContentTest.kt | 38 ++-- .../DefaultLocationProviderTest.kt | 6 +- plugins/base/src/test/kotlin/markdown/KDocTest.kt | 6 +- plugins/base/src/test/kotlin/markdown/LinkTest.kt | 10 +- .../base/src/test/kotlin/model/InheritorsTest.kt | 8 +- plugins/base/src/test/kotlin/model/PropertyTest.kt | 6 +- .../kotlin/multiplatform/BasicMultiplatformTest.kt | 10 +- .../test/kotlin/pageMerger/PageNodeMergerTest.kt | 10 +- .../test/kotlin/renderers/html/DivergentTest.kt | 8 +- .../renderers/html/SourceSetDependentHintTest.kt | 8 +- .../test/kotlin/renderers/html/defaultSourceSet.kt | 9 +- .../test/kotlin/resourceLinks/ResourceLinksTest.kt | 6 +- .../PageTransformerBuilderTest.kt | 12 +- .../ReportUndocumentedTransformerTest.kt | 136 ++++++------- .../DefaultPsiToDocumentableTranslatorTest.kt | 14 +- plugins/base/src/test/kotlin/utils/ModelUtils.kt | 4 +- plugins/gfm/src/main/kotlin/GfmPlugin.kt | 6 +- .../javadoc/AbstractJavadocTemplateMapTest.kt | 5 +- .../javadoc/src/test/kotlin/javadoc/JavadocTest.kt | 4 +- .../kotlin/javadoc/location/JavadocLocationTest.kt | 6 +- .../src/test/kotlin/KotlinAsJavaPluginTest.kt | 13 +- runners/ant/build.gradle | 18 -- runners/ant/src/main/kotlin/ant/dokka.kt | 210 --------------------- runners/ant/src/main/resources/dokka-antlib.xml | 3 - runners/cli/build.gradle.kts | 3 +- runners/cli/src/main/kotlin/cli/main.kt | 57 +++--- runners/gradle-plugin/build.gradle.kts | 2 + .../dokka/gradle/ConfigurationExtractor.kt | 2 +- .../jetbrains/dokka/gradle/DokkaCollectorTask.kt | 8 +- .../dokka/gradle/DokkaSourceSetIDFactory.kt | 10 + .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 36 ++-- .../dokka/gradle/configurationImplementations.kt | 93 +++++++-- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 4 +- .../gradle/KotlinDslDokkaTaskConfigurationTest.kt | 77 ++++++++ runners/maven-plugin/src/main/kotlin/DokkaMojo.kt | 14 +- .../src/main/kotlin/testApi/context/MockContext.kt | 3 +- .../testApi/testRunner/DokkaTestGenerator.kt | 3 +- .../main/kotlin/testApi/testRunner/TestRunner.kt | 19 +- 69 files changed, 567 insertions(+), 634 deletions(-) delete mode 100644 runners/ant/build.gradle delete mode 100644 runners/ant/src/main/kotlin/ant/dokka.kt delete mode 100644 runners/ant/src/main/resources/dokka-antlib.xml create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt (limited to 'runners/cli/build.gradle.kts') diff --git a/build.gradle.kts b/build.gradle.kts index c94faa77..04f4afd4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ allprojects { val language_version: String by project tasks.withType(KotlinCompile::class).all { kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict -Xskip-metadata-version-check" + freeCompilerArgs += "-Xjsr305=strict -Xskip-metadata-version-check -Xopt-in=kotlin.RequiresOptIn." languageVersion = language_version apiVersion = language_version jvmTarget = "1.8" @@ -49,4 +49,4 @@ subprojects { } } -println("Publication version: $dokka_version") \ No newline at end of file +println("Publication version: $dokka_version") diff --git a/core/src/main/kotlin/DokkaBootstrapImpl.kt b/core/src/main/kotlin/DokkaBootstrapImpl.kt index bd632546..be3d6c9b 100644 --- a/core/src/main/kotlin/DokkaBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaBootstrapImpl.kt @@ -1,8 +1,6 @@ package org.jetbrains.dokka -import com.google.gson.Gson import org.jetbrains.dokka.DokkaConfiguration.PackageOptions -import org.jetbrains.dokka.utilities.DokkaConsoleLogger import org.jetbrains.dokka.utilities.DokkaLogger import java.util.function.BiConsumer @@ -80,7 +78,6 @@ class DokkaBootstrapImpl : DokkaBootstrap { } private lateinit var generator: DokkaGenerator - val gson = Gson() fun configure(logger: DokkaLogger, configuration: DokkaConfigurationImpl) = with(configuration) { @@ -113,7 +110,7 @@ class DokkaBootstrapImpl : DokkaBootstrap { override fun configure(logger: BiConsumer, serializedConfigurationJSON: String) = configure( DokkaProxyLogger(logger), - gson.fromJson(serializedConfigurationJSON, DokkaConfigurationImpl::class.java) + DokkaConfigurationImpl(serializedConfigurationJSON) ) override fun generate() = generator.generate() diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt index ce8d229a..ee1adf0b 100644 --- a/core/src/main/kotlin/DokkaGenerator.kt +++ b/core/src/main/kotlin/DokkaGenerator.kt @@ -68,7 +68,7 @@ class DokkaGenerator( fun createDocumentationModels( context: DokkaContext ) = context.configuration.sourceSets - .flatMap { passConfiguration -> translateSources(passConfiguration, context) } + .flatMap { sourceSet -> translateSources(sourceSet, context) } fun transformDocumentationModelBeforeMerge( modulesFromPlatforms: List, diff --git a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt index 6825ce64..70b99f8d 100644 --- a/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt +++ b/core/src/main/kotlin/DokkaMultimoduleBootstrapImpl.kt @@ -1,6 +1,5 @@ package org.jetbrains.dokka -import com.google.gson.Gson import org.jetbrains.dokka.DokkaBootstrapImpl.DokkaProxyLogger import org.jetbrains.dokka.utilities.DokkaLogger import java.util.function.BiConsumer @@ -15,11 +14,11 @@ class DokkaMultimoduleBootstrapImpl : DokkaBootstrap { override fun configure(logger: BiConsumer, serializedConfigurationJSON: String) = configure( DokkaProxyLogger(logger), - Gson().fromJson(serializedConfigurationJSON, DokkaConfigurationImpl::class.java) + DokkaConfigurationImpl(serializedConfigurationJSON) ) override fun generate() { generator.generateAllModulesPage() } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt index 463d2342..c531ab9a 100644 --- a/core/src/main/kotlin/configuration.kt +++ b/core/src/main/kotlin/configuration.kt @@ -1,6 +1,10 @@ +@file:Suppress("FunctionName") + package org.jetbrains.dokka +import com.google.gson.Gson import java.io.File +import java.io.Serializable import java.net.URL object DokkaDefaults { @@ -43,6 +47,23 @@ enum class Platform(val key: String) { } } +data class DokkaSourceSetID( + val moduleName: String, + val sourceSetName: String +) : Serializable { + override fun toString(): String { + return "$moduleName/$sourceSetName" + } +} + +fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl { + return Gson().fromJson(json, DokkaConfigurationImpl::class.java) +} + +fun DokkaConfiguration.toJson(): String { + return Gson().toJson(this) +} + interface DokkaConfiguration { val outputDir: String val format: String @@ -55,12 +76,12 @@ interface DokkaConfiguration { val pluginsConfiguration: Map interface DokkaSourceSet { - val moduleName: String + val sourceSetID: DokkaSourceSetID val displayName: String - val sourceSetID: String + val moduleDisplayName: String val classpath: List val sourceRoots: List - val dependentSourceSets: List + val dependentSourceSets: Set val samples: List val includes: List val includeNonPublic: Boolean diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index d3ac9df2..47bd7fe2 100644 --- a/core/src/main/kotlin/defaultConfiguration.kt +++ b/core/src/main/kotlin/defaultConfiguration.kt @@ -1,5 +1,6 @@ package org.jetbrains.dokka +import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import java.io.File import java.net.URL @@ -16,12 +17,12 @@ data class DokkaConfigurationImpl( ) : DokkaConfiguration data class DokkaSourceSetImpl( - override val moduleName: String, + override val moduleDisplayName: String, override val displayName: String, - override val sourceSetID: String, + override val sourceSetID: DokkaSourceSetID, override val classpath: List, override val sourceRoots: List, - override val dependentSourceSets: List, + override val dependentSourceSets: Set, override val samples: List, override val includes: List, override val includeNonPublic: Boolean, @@ -39,23 +40,23 @@ data class DokkaSourceSetImpl( override val noJdkLink: Boolean, override val suppressedFiles: List, override val analysisPlatform: Platform -) : DokkaConfiguration.DokkaSourceSet +) : DokkaSourceSet data class DokkaModuleDescriptionImpl( override val name: String, override val path: String, override val docFile: String -): DokkaConfiguration.DokkaModuleDescription +) : DokkaConfiguration.DokkaModuleDescription data class SourceRootImpl( override val path: String -): DokkaConfiguration.SourceRoot +) : DokkaConfiguration.SourceRoot data class SourceLinkDefinitionImpl( override val path: String, override val url: String, override val lineSuffix: String? -): DokkaConfiguration.SourceLinkDefinition { +) : DokkaConfiguration.SourceLinkDefinition { companion object { fun parseSourceLinkDefinition(srcLink: String): SourceLinkDefinitionImpl { val (path, urlAndLine) = srcLink.split('=') @@ -73,9 +74,10 @@ data class PackageOptionsImpl( override val reportUndocumented: Boolean?, override val skipDeprecated: Boolean, override val suppress: Boolean -): DokkaConfiguration.PackageOptions +) : DokkaConfiguration.PackageOptions -data class ExternalDocumentationLinkImpl(override val url: URL, - override val packageListUrl: URL +data class ExternalDocumentationLinkImpl( + override val url: URL, + override val packageListUrl: URL ) : DokkaConfiguration.ExternalDocumentationLink diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index fe472b12..7ead43b8 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -82,4 +82,4 @@ inline fun configuratio } } } -} \ No newline at end of file +} diff --git a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt index 426ffdde..e723768c 100644 --- a/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt +++ b/kotlin-analysis/src/main/kotlin/org/jetbrains/dokka/analysis/KotlinAnalysis.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.analysis import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet +import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.model.SourceSetDependent import org.jetbrains.dokka.plugability.DokkaContext @@ -21,7 +22,7 @@ fun KotlinAnalysis(context: DokkaContext): KotlinAnalysis { interface KotlinAnalysis : SourceSetDependent { override fun get(key: DokkaSourceSet): EnvironmentAndFacade - operator fun get(sourceSetID: String): EnvironmentAndFacade + operator fun get(sourceSetID: DokkaSourceSetID): EnvironmentAndFacade } internal class KotlinAnalysisImpl( @@ -32,7 +33,7 @@ internal class KotlinAnalysisImpl( return environments[key] ?: throw IllegalStateException("Missing EnvironmentAndFacade for sourceSet $key") } - override fun get(sourceSetID: String): EnvironmentAndFacade { + override fun get(sourceSetID: DokkaSourceSetID): EnvironmentAndFacade { return environments.entries.first { (sourceSet, _) -> sourceSet.sourceSetID == sourceSetID }.value } } diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index de892bb1..f8fa3b2e 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -94,7 +94,7 @@ open class HtmlRenderer( group.sourceSets.forEach { button(classes = "platform-tag platform-selector") { attributes["data-active"] = "" - attributes["data-filter"] = it.sourceSetID + attributes["data-filter"] = it.sourceSetID.toString() when (it.analysisPlatform.key) { "common" -> classes = classes + "common-like" "native" -> classes = classes + "native-like" @@ -168,10 +168,10 @@ open class HtmlRenderer( attributes["data-toggle-list"] = "data-toggle-list" contents.forEachIndexed { index, pair -> button(classes = "platform-bookmark") { - attributes["data-filterable-current"] = pair.first.sourceSetID - attributes["data-filterable-set"] = pair.first.sourceSetID + attributes["data-filterable-current"] = pair.first.sourceSetID.toString() + attributes["data-filterable-set"] = pair.first.sourceSetID.toString() if (index == 0) attributes["data-active"] = "" - attributes["data-toggle"] = pair.first.sourceSetID + attributes["data-toggle"] = pair.first.sourceSetID.toString() when ( pair.first.analysisPlatform.key ) { @@ -180,7 +180,7 @@ open class HtmlRenderer( "jvm" -> classes = classes + "jvm-like" "js" -> classes = classes + "js-like" } - attributes["data-toggle"] = pair.first.sourceSetID + attributes["data-toggle"] = pair.first.sourceSetID.toString() text(pair.first.displayName) } } @@ -212,7 +212,7 @@ open class HtmlRenderer( }.map { it to createHTML(prettyPrint = false).div(classes = "content sourceset-depenent-content") { if (counter++ == 0) attributes["data-active"] = "" - attributes["data-togglable"] = it.sourceSetID + attributes["data-togglable"] = it.sourceSetID.toString() unsafe { +html } @@ -249,10 +249,10 @@ open class HtmlRenderer( consumer.onTagContentUnsafe { +createHTML().div("divergent-group") { attributes["data-filterable-current"] = groupedDivergent.keys.joinToString(" ") { - it.sourceSetID + it.sourceSetID.toString() } attributes["data-filterable-set"] = groupedDivergent.keys.joinToString(" ") { - it.sourceSetID + it.sourceSetID.toString() } val divergentForPlatformDependent = groupedDivergent.map { (sourceSet, elements) -> @@ -353,10 +353,10 @@ open class HtmlRenderer( div(classes = "table-row") { if (!style.contains(MultimoduleTable)) { attributes["data-filterable-current"] = node.sourceSets.joinToString(" ") { - it.sourceSetID + it.sourceSetID.toString() } attributes["data-filterable-set"] = node.sourceSets.joinToString(" ") { - it.sourceSetID + it.sourceSetID.toString() } } @@ -728,4 +728,4 @@ private fun String.stripDiv() = drop(5).dropLast(6) // TODO: Find a way to do it private val PageNode.isNavigable: Boolean get() = this !is RendererSpecificPage || strategy != RenderingStrategy.DoNothing -fun PropertyContainer.extraHtmlAttributes() = allOfType() \ No newline at end of file +fun PropertyContainer.extraHtmlAttributes() = allOfType() diff --git a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt index f042eae3..2a242948 100644 --- a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt +++ b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt @@ -1,6 +1,5 @@ package org.jetbrains.dokka.base.signatures -import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.* @@ -142,4 +141,4 @@ interface JvmSignatureUtils { sealed class AtStrategy object All : AtStrategy() object OnlyOnce : AtStrategy() -object Never : AtStrategy() \ No newline at end of file +object Never : AtStrategy() diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt index c3cc4d38..ff05beed 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilterTransformer.kt @@ -9,11 +9,9 @@ import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMergeDocumentableTransformer { override fun invoke(modules: List) = modules.map { original -> - val passOptions = original.sourceSets.single() - val packageOptions = passOptions.perPackageOptions - original.let { - DocumentableVisibilityFilter(packageOptions, passOptions).processModule(it) - } + val sourceSet = original.sourceSets.single() + val packageOptions = sourceSet.perPackageOptions + DocumentableVisibilityFilter(packageOptions, sourceSet).processModule(original) } private class DocumentableVisibilityFilter( @@ -45,7 +43,7 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe private fun filterPackages(packages: List): Pair> { var packagesListChanged = false - val filteredPackages = packages.mapNotNull { + val filteredPackages = packages.map { var modified = false val functions = filterFunctions(it.functions).let { (listModified, list) -> modified = modified || listModified @@ -326,4 +324,4 @@ class DocumentableVisibilityFilterTransformer(val context: DokkaContext) : PreMe return Pair(classlikesListChanged, filteredClasslikes) } } -} \ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/EmptyPackagesFilterTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/EmptyPackagesFilterTransformer.kt index 3fd0081a..61abfbd7 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/EmptyPackagesFilterTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/EmptyPackagesFilterTransformer.kt @@ -14,9 +14,9 @@ class EmptyPackagesFilterTransformer(val context: DokkaContext) : PreMergeDocume } private class EmptyPackagesFilter( - val passOptions: DokkaConfiguration.DokkaSourceSet + val sourceSet: DokkaConfiguration.DokkaSourceSet ) { - fun DPackage.shouldBeSkipped() = passOptions.skipEmptyPackages && + fun DPackage.shouldBeSkipped() = sourceSet.skipEmptyPackages && functions.isEmpty() && properties.isEmpty() && classlikes.isEmpty() @@ -25,4 +25,4 @@ class EmptyPackagesFilterTransformer(val context: DokkaContext) : PreMergeDocume packages = module.packages.filter { !it.shouldBeSkipped() } ) } -} \ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt index 1f718a7c..a0800da8 100644 --- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt @@ -1,12 +1,10 @@ package org.jetbrains.dokka.base.transformers.documentables -import org.jetbrains.dokka.analysis.EnvironmentAndFacade import org.jetbrains.dokka.analysis.KotlinAnalysis import org.jetbrains.dokka.model.DModule import org.jetbrains.dokka.model.doc.DocumentationNode import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.parsers.MarkdownParser -import org.jetbrains.dokka.model.SourceSetDependent import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.kotlin.name.FqName @@ -24,7 +22,7 @@ internal class ModuleAndPackageDocumentationTransformer( val modulesAndPackagesDocumentation = context.configuration.sourceSets .map { - Pair(it.moduleName, it) to + Pair(it.moduleDisplayName, it) to it.includes.map { Paths.get(it) } .also { it.forEach { diff --git a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt index b39715a7..41dea1a2 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/samples/SamplesTransformer.kt @@ -67,7 +67,7 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { analysis: Map ): ContentNode { val facade = analysis[platform]?.facade - ?: return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.moduleName}") } + ?: return this.also { context.logger.warn("Cannot resolve facade for platform ${platform.moduleDisplayName}") } val psiElement = fqNameToPsiElement(facade, fqName) ?: return this.also { context.logger.warn("Cannot find PsiElement corresponding to $fqName") } val imports = @@ -147,4 +147,4 @@ abstract class SamplesTransformer(val context: DokkaContext) : PageTransformer { style = styles + ContentStyle.RunnableSample + TextStyle.Monospace, extra = extra ) -} \ No newline at end of file +} diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 9cdd251c..b0374014 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.idea.kdoc.findKDoc -import org.jetbrains.kotlin.idea.kdoc.isBoringBuiltinClass import org.jetbrains.kotlin.load.kotlin.toSourceElement import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* @@ -36,7 +35,6 @@ import org.jetbrains.kotlin.resolve.constants.KClassValue.Value.NormalClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces -import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.source.KotlinSourceElement @@ -71,7 +69,7 @@ class DefaultDescriptorToDocumentableTranslator( DRIWithPlatformInfo(DRI.topLevel, emptyMap()) ) } - }.let { DModule(sourceSet.moduleName, it, emptyMap(), null, setOf(sourceSet)) } + }.let { DModule(sourceSet.moduleDisplayName, it, emptyMap(), null, setOf(sourceSet)) } } } diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt index 76f8319d..5a55e3ec 100644 --- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt @@ -68,7 +68,7 @@ class DefaultPsiToDocumentableTranslator( context.logger ) return DModule( - sourceSet.moduleName, + sourceSet.moduleDisplayName, psiFiles.mapNotNull { it.safeAs() }.groupBy { it.packageName }.map { (packageName, psiFiles) -> val dri = DRI(packageName = packageName) DPackage( diff --git a/plugins/base/src/test/kotlin/basic/DRITest.kt b/plugins/base/src/test/kotlin/basic/DRITest.kt index 1f4c7d93..559a2dbf 100644 --- a/plugins/base/src/test/kotlin/basic/DRITest.kt +++ b/plugins/base/src/test/kotlin/basic/DRITest.kt @@ -5,19 +5,19 @@ import org.jetbrains.dokka.links.Callable import org.jetbrains.dokka.links.Nullable import org.jetbrains.dokka.links.TypeConstructor import org.jetbrains.dokka.model.* -import org.jetbrains.dokka.pages.* -import org.jetbrains.dokka.pages.dfs -import org.junit.jupiter.api.Assertions.assertEquals +import org.jetbrains.dokka.pages.ClasslikePageNode +import org.jetbrains.dokka.pages.ContentPage +import org.jetbrains.dokka.pages.MemberPageNode import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest - +import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test class DRITest : AbstractCoreTest() { @Test fun issue634() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -52,8 +52,8 @@ class DRITest : AbstractCoreTest() { @Test fun issue634WithImmediateNullableSelf() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -82,8 +82,8 @@ class DRITest : AbstractCoreTest() { @Test fun issue634WithGenericNullableReceiver() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -112,8 +112,8 @@ class DRITest : AbstractCoreTest() { @Test fun issue642WithStarAndAny() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { analysisPlatform = "js" sourceRoots = listOf("src/") } @@ -171,8 +171,8 @@ class DRITest : AbstractCoreTest() { @Test fun driForGenericClass(){ val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -201,8 +201,8 @@ class DRITest : AbstractCoreTest() { @Test fun driForGenericFunction(){ val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") classpath = listOfNotNull(jvmStdlibPath) } @@ -243,8 +243,8 @@ class DRITest : AbstractCoreTest() { @Test fun driForFunctionNestedInsideInnerClass() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") classpath = listOfNotNull(jvmStdlibPath) } @@ -280,8 +280,8 @@ class DRITest : AbstractCoreTest() { @Test fun driForGenericExtensionFunction(){ val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } diff --git a/plugins/base/src/test/kotlin/basic/DokkaBasicTests.kt b/plugins/base/src/test/kotlin/basic/DokkaBasicTests.kt index 5cc17bf3..bceb79ae 100644 --- a/plugins/base/src/test/kotlin/basic/DokkaBasicTests.kt +++ b/plugins/base/src/test/kotlin/basic/DokkaBasicTests.kt @@ -11,8 +11,8 @@ class DokkaBasicTests : AbstractCoreTest() { @Test fun basic1() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } } @@ -39,4 +39,4 @@ class DokkaBasicTests : AbstractCoreTest() { private fun ModulePageNode.getClasslikeToMemberMap() = this.parentMap.filterValues { it is ClasslikePageNode }.entries.groupBy({ it.value }) { it.key } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt b/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt index d548b75b..9d2c5825 100644 --- a/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt +++ b/plugins/base/src/test/kotlin/basic/FailOnWarningTest.kt @@ -14,8 +14,8 @@ class FailOnWarningTest : AbstractCoreTest() { fun `throws exception if one or more warnings were emitted`() { val configuration = dokkaConfiguration { failOnWarning = true - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin") } } @@ -39,8 +39,8 @@ class FailOnWarningTest : AbstractCoreTest() { fun `throws exception if one or more error were emitted`() { val configuration = dokkaConfiguration { failOnWarning = true - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin") } } @@ -66,8 +66,8 @@ class FailOnWarningTest : AbstractCoreTest() { val configuration = dokkaConfiguration { failOnWarning = true - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin") } } @@ -88,8 +88,8 @@ class FailOnWarningTest : AbstractCoreTest() { fun `does not throw if disabled`() { val configuration = dokkaConfiguration { failOnWarning = false - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin") } } @@ -115,4 +115,4 @@ private class ZeroErrorOrWarningCountDokkaLogger( ) : DokkaLogger by logger { override var warningsCount: Int = 0 override var errorsCount: Int = 0 -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/content/annotations/ContentForAnnotationsTest.kt b/plugins/base/src/test/kotlin/content/annotations/ContentForAnnotationsTest.kt index 7add4119..bf78b847 100644 --- a/plugins/base/src/test/kotlin/content/annotations/ContentForAnnotationsTest.kt +++ b/plugins/base/src/test/kotlin/content/annotations/ContentForAnnotationsTest.kt @@ -14,8 +14,8 @@ class ContentForAnnotationsTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" } @@ -218,4 +218,4 @@ class ContentForAnnotationsTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/content/annotations/DepredatedAndSinceKotlinTest.kt b/plugins/base/src/test/kotlin/content/annotations/DepredatedAndSinceKotlinTest.kt index 99ec25c5..69de1bcd 100644 --- a/plugins/base/src/test/kotlin/content/annotations/DepredatedAndSinceKotlinTest.kt +++ b/plugins/base/src/test/kotlin/content/annotations/DepredatedAndSinceKotlinTest.kt @@ -3,19 +3,17 @@ package content.annotations import matchers.content.* import org.jetbrains.dokka.pages.ContentPage -import org.jetbrains.dokka.pages.PackagePageNode import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest import org.junit.jupiter.api.Test import utils.ParamAttributes import utils.bareSignature -import utils.propertySignature class DepredatedAndSinceKotlinTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" } @@ -102,4 +100,4 @@ class DepredatedAndSinceKotlinTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt b/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt index f6e80891..a9689bc5 100644 --- a/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt +++ b/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt @@ -17,8 +17,8 @@ import utils.* class ContentForParamsTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" } diff --git a/plugins/base/src/test/kotlin/content/seealso/ContentForSeeAlsoTest.kt b/plugins/base/src/test/kotlin/content/seealso/ContentForSeeAlsoTest.kt index 696c3032..24970660 100644 --- a/plugins/base/src/test/kotlin/content/seealso/ContentForSeeAlsoTest.kt +++ b/plugins/base/src/test/kotlin/content/seealso/ContentForSeeAlsoTest.kt @@ -11,8 +11,8 @@ import utils.unnamedTag class ContentForSeeAlsoTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" } @@ -456,4 +456,4 @@ class ContentForSeeAlsoTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt b/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt index 6cb8b0f4..cabe822d 100644 --- a/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt +++ b/plugins/base/src/test/kotlin/content/signatures/ContentForSignaturesTest.kt @@ -14,8 +14,8 @@ import utils.typealiasSignature class ContentForSignaturesTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" includeNonPublic = true diff --git a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt index d203025b..c2fbd26f 100644 --- a/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt +++ b/plugins/base/src/test/kotlin/content/signatures/SkippingParenthesisForConstructorsTest.kt @@ -8,8 +8,8 @@ import utils.functionSignature class ConstructorsSignaturesTest : AbstractCoreTest() { private val testConfiguration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" } @@ -190,4 +190,4 @@ class ConstructorsSignaturesTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/EnumsTest.kt index be910b5c..6a973f8e 100644 --- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/EnumsTest.kt @@ -14,8 +14,8 @@ class EnumsTest : AbstractCoreTest() { @Test fun basicEnum() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -45,8 +45,8 @@ class EnumsTest : AbstractCoreTest() { @Test fun enumWithCompanion() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -90,8 +90,8 @@ class EnumsTest : AbstractCoreTest() { @Test fun enumWithConstructor() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -136,8 +136,8 @@ class EnumsTest : AbstractCoreTest() { @Test fun enumWithMethods() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -179,8 +179,8 @@ class EnumsTest : AbstractCoreTest() { @Test fun enumWithAnnotationsOnEntries(){ val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } diff --git a/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt b/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt index 3b69a54e..4dfdc410 100644 --- a/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt +++ b/plugins/base/src/test/kotlin/expect/AbstractExpectTest.kt @@ -15,8 +15,8 @@ abstract class AbstractExpectTest( protected fun generateOutput(path: Path, outFormat: String): Path? { val config = dokkaConfiguration { format = outFormat - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf(path.toAbsolutePath().asString()) } } @@ -101,4 +101,4 @@ abstract class AbstractExpectTest( ret?.let { Files.list(it).forEach { f -> f.copyRecursively(out.resolve(f.fileName)) } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt index c15e53e8..c8b9f2d4 100644 --- a/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt +++ b/plugins/base/src/test/kotlin/filter/DeprecationFilterTest.kt @@ -9,8 +9,8 @@ class DeprecationFilterTest : AbstractCoreTest() { @Test fun `function with false global skipDeprecated`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { skipDeprecated = false sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -39,8 +39,8 @@ class DeprecationFilterTest : AbstractCoreTest() { @Test fun `deprecated function with false global skipDeprecated`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { skipDeprecated = false sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -69,8 +69,8 @@ class DeprecationFilterTest : AbstractCoreTest() { @Test fun `deprecated function with true global skipDeprecated`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") skipDeprecated = true } @@ -99,8 +99,8 @@ class DeprecationFilterTest : AbstractCoreTest() { @Test fun `deprecated function with false global true package skipDeprecated`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") skipDeprecated = false perPackageOptions = mutableListOf( @@ -136,8 +136,8 @@ class DeprecationFilterTest : AbstractCoreTest() { @Test fun `deprecated function with true global false package skipDeprecated`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") skipDeprecated = true perPackageOptions = mutableListOf( @@ -170,4 +170,4 @@ class DeprecationFilterTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt b/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt index 7d96541b..e5b9e9c2 100644 --- a/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt +++ b/plugins/base/src/test/kotlin/filter/EmptyPackagesFilterTest.kt @@ -1,6 +1,5 @@ package filter -import org.jetbrains.dokka.PackageOptionsImpl import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -9,8 +8,8 @@ class EmptyPackagesFilterTest : AbstractCoreTest() { @Test fun `empty package with false skipEmptyPackages`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { skipEmptyPackages = false sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -37,8 +36,8 @@ class EmptyPackagesFilterTest : AbstractCoreTest() { @Test fun `empty package with true skipEmptyPackages`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { skipEmptyPackages = true sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -61,4 +60,4 @@ class EmptyPackagesFilterTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt b/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt index 5e8e33dc..192de449 100644 --- a/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt +++ b/plugins/base/src/test/kotlin/filter/VisibilityFilterTest.kt @@ -9,8 +9,8 @@ class VisibilityFilterTest : AbstractCoreTest() { @Test fun `public function with false global includeNonPublic`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { includeNonPublic = false sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -39,8 +39,8 @@ class VisibilityFilterTest : AbstractCoreTest() { @Test fun `private function with false global includeNonPublic`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { includeNonPublic = false sourceRoots = listOf("src/main/kotlin/basic/Test.kt") } @@ -69,8 +69,8 @@ class VisibilityFilterTest : AbstractCoreTest() { @Test fun `private function with true global includeNonPublic`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") includeNonPublic = true } @@ -99,8 +99,8 @@ class VisibilityFilterTest : AbstractCoreTest() { @Test fun `private function with false global true package includeNonPublic`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") includeNonPublic = false perPackageOptions = mutableListOf( @@ -136,8 +136,8 @@ class VisibilityFilterTest : AbstractCoreTest() { @Test fun `private function with true global false package includeNonPublic`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/basic/Test.kt") includeNonPublic = true perPackageOptions = mutableListOf( @@ -170,4 +170,4 @@ class VisibilityFilterTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/issues/IssuesTest.kt b/plugins/base/src/test/kotlin/issues/IssuesTest.kt index f67229b7..7b065349 100644 --- a/plugins/base/src/test/kotlin/issues/IssuesTest.kt +++ b/plugins/base/src/test/kotlin/issues/IssuesTest.kt @@ -34,8 +34,8 @@ class IssuesTest : AbstractModelTest("/src/main/kotlin/issues/Test.kt", "issues" |} """, configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") classpath = listOfNotNull(jvmStdlibPath) } @@ -70,4 +70,4 @@ class IssuesTest : AbstractModelTest("/src/main/kotlin/issues/Test.kt", "issues" // } // } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/linkableContent/LinkableContentTest.kt b/plugins/base/src/test/kotlin/linkableContent/LinkableContentTest.kt index 191df066..2775fcf4 100644 --- a/plugins/base/src/test/kotlin/linkableContent/LinkableContentTest.kt +++ b/plugins/base/src/test/kotlin/linkableContent/LinkableContentTest.kt @@ -23,23 +23,23 @@ class LinkableContentTest : AbstractCoreTest() { val includesDir = getTestDataDir("linkable/includes").toAbsolutePath() val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { moduleName = "example" analysisPlatform = "js" sourceRoots = listOf("jsMain", "commonMain", "jvmAndJsSecondCommonMain").map { Paths.get("$testDataDir/$it/kotlin").toString() } - sourceSetID = "js" + name = "js" includes = listOf(Paths.get("$includesDir/include2.md").toString()) } - pass { + sourceSet { moduleName = "example" analysisPlatform = "jvm" sourceRoots = listOf("jvmMain", "commonMain", "jvmAndJsSecondCommonMain").map { Paths.get("$testDataDir/$it/kotlin").toString() } - sourceSetID = "jvm" + name = "jvm" includes = listOf(Paths.get("$includesDir/include1.md").toString()) } } @@ -62,8 +62,8 @@ class LinkableContentTest : AbstractCoreTest() { val testDataDir = getTestDataDir("linkable/sources").toAbsolutePath() val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { moduleName = "example" analysisPlatform = "js" sourceRoots = listOf("$testDataDir/jsMain/kotlin") @@ -74,9 +74,9 @@ class LinkableContentTest : AbstractCoreTest() { lineSuffix = "#L" ) ) - sourceSetID = "js" + name = "js" } - pass { + sourceSet { moduleName = "example" analysisPlatform = "jvm" sourceRoots = listOf("$testDataDir/jvmMain/kotlin") @@ -87,7 +87,7 @@ class LinkableContentTest : AbstractCoreTest() { lineSuffix = "#L" ) ) - sourceSetID = "jvm" + name = "jvm" } } } @@ -127,19 +127,19 @@ class LinkableContentTest : AbstractCoreTest() { val testDataDir = getTestDataDir("linkable/samples").toAbsolutePath() val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { moduleName = "example" analysisPlatform = "js" sourceRoots = listOf("$testDataDir/jsMain/kotlin") - sourceSetID = "js" + name = "js" samples = listOf("$testDataDir/jsMain/resources/Samples.kt") } - pass { + sourceSet { moduleName = "example" analysisPlatform = "jvm" sourceRoots = listOf("$testDataDir/jvmMain/kotlin") - sourceSetID = "jvm" + name = "jvm" samples = listOf("$testDataDir/jvmMain/resources/Samples.kt") } } @@ -196,11 +196,11 @@ class LinkableContentTest : AbstractCoreTest() { | """.trimIndent(), dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = "jvm" - sourceSetID = "js" + name = "js" } } } @@ -222,4 +222,4 @@ class LinkableContentTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt b/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt index 1bc3ea29..a219fb04 100644 --- a/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt +++ b/plugins/base/src/test/kotlin/locationProvider/DefaultLocationProviderTest.kt @@ -10,8 +10,8 @@ class DefaultLocationProviderTest: AbstractCoreTest() { @Test fun `#644 same directory for module and package`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -38,4 +38,4 @@ class DefaultLocationProviderTest: AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/markdown/KDocTest.kt b/plugins/base/src/test/kotlin/markdown/KDocTest.kt index 218f7244..f5b29322 100644 --- a/plugins/base/src/test/kotlin/markdown/KDocTest.kt +++ b/plugins/base/src/test/kotlin/markdown/KDocTest.kt @@ -9,8 +9,8 @@ import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest abstract class KDocTest : AbstractCoreTest() { private val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/example/Test.kt") } } @@ -44,4 +44,4 @@ abstract class KDocTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/markdown/LinkTest.kt b/plugins/base/src/test/kotlin/markdown/LinkTest.kt index ddcef5db..8e4e588e 100644 --- a/plugins/base/src/test/kotlin/markdown/LinkTest.kt +++ b/plugins/base/src/test/kotlin/markdown/LinkTest.kt @@ -13,8 +13,8 @@ class LinkTest : AbstractCoreTest() { @Test fun linkToClassLoader() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/parser") } } @@ -46,8 +46,8 @@ class LinkTest : AbstractCoreTest() { @Test fun returnTypeShouldHaveLinkToOuterClassFromInner() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin") } } @@ -75,4 +75,4 @@ class LinkTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/model/InheritorsTest.kt b/plugins/base/src/test/kotlin/model/InheritorsTest.kt index f5517abb..503cf50c 100644 --- a/plugins/base/src/test/kotlin/model/InheritorsTest.kt +++ b/plugins/base/src/test/kotlin/model/InheritorsTest.kt @@ -44,12 +44,12 @@ class InheritorsTest : AbstractModelTest("/src/main/kotlin/inheritors/Test.kt", @Test fun multiplatform() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("common/src/", "jvm/src/") analysisPlatform = "jvm" } - pass { + sourceSet { sourceRoots = listOf("common/src/", "js/src/") analysisPlatform = "js" } @@ -92,4 +92,4 @@ class InheritorsTest : AbstractModelTest("/src/main/kotlin/inheritors/Test.kt", } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/model/PropertyTest.kt b/plugins/base/src/test/kotlin/model/PropertyTest.kt index e384b920..af952b43 100644 --- a/plugins/base/src/test/kotlin/model/PropertyTest.kt +++ b/plugins/base/src/test/kotlin/model/PropertyTest.kt @@ -169,8 +169,8 @@ class PropertyTest : AbstractModelTest("/src/main/kotlin/property/Test.kt", "pro |@Strictfp var property = "test" """, configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") classpath = listOfNotNull(jvmStdlibPath) } @@ -262,4 +262,4 @@ class PropertyTest : AbstractModelTest("/src/main/kotlin/property/Test.kt", "pro // } // //} -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt b/plugins/base/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt index 5facd194..b3ac7b07 100644 --- a/plugins/base/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt +++ b/plugins/base/src/test/kotlin/multiplatform/BasicMultiplatformTest.kt @@ -11,8 +11,8 @@ class BasicMultiplatformTest : AbstractCoreTest() { val testDataDir = getTestDataDir("multiplatform/basicMultiplatformTest").toAbsolutePath() val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("$testDataDir/jvmMain/") } } @@ -28,8 +28,8 @@ class BasicMultiplatformTest : AbstractCoreTest() { @Test fun inlineTestExample() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/multiplatform/Test.kt") } } @@ -51,4 +51,4 @@ class BasicMultiplatformTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt index 6ef38aa9..935b9377 100644 --- a/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt +++ b/plugins/base/src/test/kotlin/pageMerger/PageNodeMergerTest.kt @@ -39,8 +39,8 @@ class PageNodeMergerTest : AbstractCoreTest() { fun sameNameStrategyTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/pageMerger/Test.kt") } } @@ -82,8 +82,8 @@ class PageNodeMergerTest : AbstractCoreTest() { val strList: MutableList = mutableListOf() val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/pageMerger/Test.kt") } } @@ -123,4 +123,4 @@ class PageNodeMergerTest : AbstractCoreTest() { fun PageNode.childrenRec(): List = listOf(this) + children.flatMap { it.childrenRec() } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt index 6ceb805b..d4778a8e 100644 --- a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt +++ b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt @@ -12,14 +12,14 @@ class DivergentTest : RenderingOnlyTestBase() { private val js = defaultSourceSet.copy( "root", "JS", - "js", + defaultSourceSet.sourceSetID.copy(sourceSetName = "js"), analysisPlatform = Platform.js, sourceRoots = listOf(SourceRootImpl("pl1")) ) private val jvm = defaultSourceSet.copy( "root", "JVM", - "jvm", + defaultSourceSet.sourceSetID.copy(sourceSetName = "jvm"), analysisPlatform = Platform.jvm, sourceRoots = listOf(SourceRootImpl("pl1")) @@ -27,7 +27,7 @@ class DivergentTest : RenderingOnlyTestBase() { private val native = defaultSourceSet.copy( "root", "NATIVE", - "native", + defaultSourceSet.sourceSetID.copy(sourceSetName = "native"), analysisPlatform = Platform.native, sourceRoots = listOf(SourceRootImpl("pl1")) ) @@ -344,4 +344,4 @@ class DivergentTest : RenderingOnlyTestBase() { Div(Div("b-", Span()), Div(Div(Div(("b")))), "ab+") ) } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt b/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt index c868cfd5..ea1ea9ae 100644 --- a/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt +++ b/plugins/base/src/test/kotlin/renderers/html/SourceSetDependentHintTest.kt @@ -15,21 +15,21 @@ class SourceSetDependentHintTest : RenderingOnlyTestBase() { private val pl1 = defaultSourceSet.copy( "root", "pl1", - "pl1", + defaultSourceSet.sourceSetID.copy(sourceSetName = "pl1"), analysisPlatform = Platform.js, sourceRoots = listOf(SourceRootImpl("pl1")) ) private val pl2 = defaultSourceSet.copy( "root", "pl2", - "pl2", + defaultSourceSet.sourceSetID.copy(sourceSetName = "pl2"), analysisPlatform = Platform.jvm, sourceRoots = listOf(SourceRootImpl("pl1")) ) private val pl3 = defaultSourceSet.copy( "root", "pl3", - "pl3", + defaultSourceSet.sourceSetID.copy(sourceSetName = "pl3"), analysisPlatform = Platform.native, sourceRoots = listOf(SourceRootImpl("pl1")) ) @@ -135,4 +135,4 @@ class SourceSetDependentHintTest : RenderingOnlyTestBase() { HtmlRenderer(context).render(page) renderedContent.match(Div(Div(Div("a")), Div(Div("b")))) } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt b/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt index 771cabaa..a9be1cfd 100644 --- a/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt +++ b/plugins/base/src/test/kotlin/renderers/html/defaultSourceSet.kt @@ -1,15 +1,16 @@ package renderers.html +import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.DokkaSourceSetImpl import org.jetbrains.dokka.Platform internal val defaultSourceSet = DokkaSourceSetImpl( - moduleName = "DEFAULT", + moduleDisplayName = "DEFAULT", displayName = "DEFAULT", - sourceSetID = "DEFAULT", + sourceSetID = DokkaSourceSetID("DEFAULT", "DEFAULT"), classpath = emptyList(), sourceRoots = emptyList(), - dependentSourceSets = emptyList(), + dependentSourceSets = emptySet(), samples = emptyList(), includes = emptyList(), includeNonPublic = false, @@ -27,4 +28,4 @@ internal val defaultSourceSet = DokkaSourceSetImpl( noJdkLink = false, suppressedFiles = emptyList(), analysisPlatform = Platform.DEFAULT -) \ No newline at end of file +) diff --git a/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt b/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt index be87813b..4f8a834b 100644 --- a/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt +++ b/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt @@ -26,8 +26,8 @@ class ResourceLinksTest : AbstractCoreTest() { @Test fun resourceLinksTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/test/Test.kt") } } @@ -68,4 +68,4 @@ class ResourceLinksTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/transformerBuilders/PageTransformerBuilderTest.kt b/plugins/base/src/test/kotlin/transformerBuilders/PageTransformerBuilderTest.kt index e66490c1..d8e057da 100644 --- a/plugins/base/src/test/kotlin/transformerBuilders/PageTransformerBuilderTest.kt +++ b/plugins/base/src/test/kotlin/transformerBuilders/PageTransformerBuilderTest.kt @@ -21,8 +21,8 @@ class PageTransformerBuilderTest : AbstractCoreTest() { @Test fun scannerTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/transformerBuilder/Test.kt") } } @@ -58,8 +58,8 @@ class PageTransformerBuilderTest : AbstractCoreTest() { @Test fun mapperTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/transformerBuilder/Test.kt") } } @@ -98,8 +98,8 @@ class PageTransformerBuilderTest : AbstractCoreTest() { @Test fun structureTransformerTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/kotlin/transformerBuilder/Test.kt") } } diff --git a/plugins/base/src/test/kotlin/transformers/ReportUndocumentedTransformerTest.kt b/plugins/base/src/test/kotlin/transformers/ReportUndocumentedTransformerTest.kt index 523813fc..72948372 100644 --- a/plugins/base/src/test/kotlin/transformers/ReportUndocumentedTransformerTest.kt +++ b/plugins/base/src/test/kotlin/transformers/ReportUndocumentedTransformerTest.kt @@ -12,8 +12,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented class gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -39,8 +39,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented non-public class does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -65,8 +65,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented function gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -95,8 +95,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented property gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -125,8 +125,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented primary constructor does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -153,8 +153,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `data class component functions do not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin") } @@ -183,8 +183,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented secondary constructor gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -213,8 +213,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented inherited function does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -246,8 +246,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `undocumented inherited property does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -279,8 +279,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `overridden function does not get reported when super is documented`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -315,8 +315,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `overridden property does not get reported when super is documented`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -349,10 +349,10 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { } @Test - fun `report disabled by pass configuration`() { + fun `report disabled by source set`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = false sourceRoots = listOf("src/main/kotlin/Test.kt") } @@ -377,8 +377,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `report enabled by package configuration`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { perPackageOptions += packageOptions( prefix = "sample", reportUndocumented = true, @@ -407,8 +407,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `report enabled by more specific package configuration`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { perPackageOptions += packageOptions( prefix = "sample", reportUndocumented = false, @@ -445,8 +445,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `report disabled by more specific package configuration`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { perPackageOptions += packageOptions( prefix = "sample", reportUndocumented = true, @@ -483,22 +483,22 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `multiplatform undocumented class gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + val commonMain = sourceSet { reportUndocumented = true analysisPlatform = Platform.common.toString() - sourceSetID = "commonMain" + name = "commonMain" displayName = "commonMain" sourceRoots = listOf("src/commonMain/kotlin") } - pass { + sourceSet { reportUndocumented = true analysisPlatform = Platform.jvm.toString() - sourceSetID = "jvmMain" + name = "jvmMain" displayName = "jvmMain" sourceRoots = listOf("src/jvmMain/kotlin") - dependentSourceSets = listOf("commonMain") + dependentSourceSets = setOf(commonMain.sourceSetID) } } } @@ -526,22 +526,22 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `multiplatform undocumented class does not get reported if expect is documented`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + val commonMain = sourceSet { reportUndocumented = true analysisPlatform = Platform.common.toString() - sourceSetID = "commonMain" + name = "commonMain" displayName = "commonMain" sourceRoots = listOf("src/commonMain/kotlin") } - pass { + sourceSet { reportUndocumented = true analysisPlatform = Platform.jvm.toString() - sourceSetID = "jvmMain" + name = "jvmMain" displayName = "jvmMain" sourceRoots = listOf("src/jvmMain/kotlin") - dependentSourceSets = listOf("commonMain") + dependentSourceSets = setOf(commonMain.sourceSetID) } } } @@ -568,31 +568,31 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `multiplatform undocumented function gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + val commonMain = sourceSet { reportUndocumented = true analysisPlatform = Platform.common.toString() - sourceSetID = "commonMain" + name = "commonMain" displayName = "commonMain" sourceRoots = listOf("src/commonMain/kotlin") } - pass { + sourceSet { reportUndocumented = true analysisPlatform = Platform.jvm.toString() - sourceSetID = "jvmMain" + name = "jvmMain" displayName = "jvmMain" sourceRoots = listOf("src/jvmMain/kotlin") - dependentSourceSets = listOf("commonMain") + dependentSourceSets = setOf(commonMain.sourceSetID) } - pass { + sourceSet { reportUndocumented = true analysisPlatform = Platform.native.toString() - sourceSetID = "macosMain" + name = "macosMain" displayName = "macosMain" sourceRoots = listOf("src/macosMain/kotlin") - dependentSourceSets = listOf("commonMain") + dependentSourceSets = setOf(commonMain.sourceSetID) } } } @@ -625,8 +625,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented class gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -652,8 +652,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented non-public class does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -677,8 +677,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented constructor does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -706,8 +706,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented method gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -736,8 +736,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented property gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -766,8 +766,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java undocumented inherited method gets reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -805,8 +805,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java documented inherited method does not get reported`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } @@ -842,8 +842,8 @@ class ReportUndocumentedTransformerTest : AbstractCoreTest() { @Test fun `java overridden function does not get reported when super is documented`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { reportUndocumented = true sourceRoots = listOf("src/main/java") } diff --git a/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt b/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt index 5f8a7864..95fbb3c6 100644 --- a/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt +++ b/plugins/base/src/test/kotlin/translators/DefaultPsiToDocumentableTranslatorTest.kt @@ -12,8 +12,8 @@ class DefaultPsiToDocumentableTranslatorTest : AbstractCoreTest() { @Test fun `method overriding two documented classes picks closest class documentation`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/java") } } @@ -57,8 +57,8 @@ class DefaultPsiToDocumentableTranslatorTest : AbstractCoreTest() { @Test fun `method overriding class and interface picks class documentation`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/java") } } @@ -102,8 +102,8 @@ class DefaultPsiToDocumentableTranslatorTest : AbstractCoreTest() { @Test fun `method overriding two classes picks closest documented class documentation`() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/main/java") } } @@ -153,4 +153,4 @@ class DefaultPsiToDocumentableTranslatorTest : AbstractCoreTest() { ?.body.orEmpty() } -} \ No newline at end of file +} diff --git a/plugins/base/src/test/kotlin/utils/ModelUtils.kt b/plugins/base/src/test/kotlin/utils/ModelUtils.kt index 9697a843..87a9c802 100644 --- a/plugins/base/src/test/kotlin/utils/ModelUtils.kt +++ b/plugins/base/src/test/kotlin/utils/ModelUtils.kt @@ -16,8 +16,8 @@ abstract class AbstractModelTest(val path: String? = null, val pkg: String) : Mo block: DModule.() -> Unit ) { val testConfiguration = configuration ?: dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") analysisPlatform = platform } diff --git a/plugins/gfm/src/main/kotlin/GfmPlugin.kt b/plugins/gfm/src/main/kotlin/GfmPlugin.kt index b955d403..287ef74f 100644 --- a/plugins/gfm/src/main/kotlin/GfmPlugin.kt +++ b/plugins/gfm/src/main/kotlin/GfmPlugin.kt @@ -140,7 +140,7 @@ open class CommonmarkRenderer( platforms.joinToString( prefix = " [", postfix = "] $text " - ) { "${it.moduleName}/${it.sourceSetID}" }) + ) { "${it.moduleDisplayName}/${it.sourceSetID}" }) buildNewLine() } } @@ -157,7 +157,7 @@ open class CommonmarkRenderer( ) { if(node.dci.kind == ContentKind.Sample || node.dci.kind == ContentKind.Parameters){ node.sourceSets.forEach {sourcesetData -> - append("${sourcesetData.moduleName}/${sourcesetData.sourceSetID}") + append("${sourcesetData.moduleDisplayName}/${sourcesetData.sourceSetID}") buildNewLine() buildTable(node.copy(children = node.children.filter { it.sourceSets.contains(sourcesetData) }, dci = node.dci.copy(kind = ContentKind.Main)), pageContext, sourceSetRestriction) buildNewLine() @@ -286,4 +286,4 @@ class MarkdownLocationProvider( dokkaContext ) { override val extension = ".md" -} \ No newline at end of file +} diff --git a/plugins/javadoc/src/test/kotlin/javadoc/AbstractJavadocTemplateMapTest.kt b/plugins/javadoc/src/test/kotlin/javadoc/AbstractJavadocTemplateMapTest.kt index 138208ae..4fa65c58 100644 --- a/plugins/javadoc/src/test/kotlin/javadoc/AbstractJavadocTemplateMapTest.kt +++ b/plugins/javadoc/src/test/kotlin/javadoc/AbstractJavadocTemplateMapTest.kt @@ -15,8 +15,8 @@ import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest internal abstract class AbstractJavadocTemplateMapTest : AbstractCoreTest() { protected var config: DokkaConfigurationImpl = dokkaConfiguration { format = "javadoc" - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src") analysisPlatform = "jvm" } @@ -62,7 +62,6 @@ internal abstract class AbstractJavadocTemplateMapTest : AbstractCoreTest() { ) { testInline(query, configuration) { renderingStage = { rootPageNode, dokkaContext -> - // TODO NOW: Clarify preprocessors! val transformedRootPageNode = preprocessors.fold(rootPageNode) { acc, pageTransformer -> pageTransformer(acc) } diff --git a/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt b/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt index 905cb61b..31a33ad5 100644 --- a/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt +++ b/plugins/javadoc/src/test/kotlin/javadoc/JavadocTest.kt @@ -10,8 +10,8 @@ class JavadocTest : AbstractCoreTest() { fun test() { val config = dokkaConfiguration { format = "javadoc" - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("jvmSrc/") analysisPlatform = "jvm" } diff --git a/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt b/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt index cbaa3dd6..a47f0142 100644 --- a/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt +++ b/plugins/javadoc/src/test/kotlin/javadoc/location/JavadocLocationTest.kt @@ -23,8 +23,8 @@ class JavadocTest : AbstractCoreTest() { val config = dokkaConfiguration { format = "javadoc" - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("jvmSrc/") externalDocumentationLinks = listOf( externalLink("https://docs.oracle.com/javase/8/docs/api/"), @@ -60,4 +60,4 @@ class JavadocTest : AbstractCoreTest() { } } } -} \ No newline at end of file +} diff --git a/plugins/kotlin-as-java/src/test/kotlin/KotlinAsJavaPluginTest.kt b/plugins/kotlin-as-java/src/test/kotlin/KotlinAsJavaPluginTest.kt index db87051b..96446201 100644 --- a/plugins/kotlin-as-java/src/test/kotlin/KotlinAsJavaPluginTest.kt +++ b/plugins/kotlin-as-java/src/test/kotlin/KotlinAsJavaPluginTest.kt @@ -3,7 +3,6 @@ package kotlinAsJavaPlugin import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest import org.jetbrains.kotlin.utils.addToStdlib.cast -import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.junit.jupiter.api.Test class KotlinAsJavaPluginTest : AbstractCoreTest() { @@ -11,8 +10,8 @@ class KotlinAsJavaPluginTest : AbstractCoreTest() { @Test fun topLevelTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -49,8 +48,8 @@ class KotlinAsJavaPluginTest : AbstractCoreTest() { @Test fun topLevelWithClassTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } @@ -90,8 +89,8 @@ class KotlinAsJavaPluginTest : AbstractCoreTest() { @Test fun kotlinAndJavaTest() { val configuration = dokkaConfiguration { - passes { - pass { + sourceSets { + sourceSet { sourceRoots = listOf("src/") } } diff --git a/runners/ant/build.gradle b/runners/ant/build.gradle deleted file mode 100644 index 216420c6..00000000 --- a/runners/ant/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -apply plugin: 'kotlin' - -sourceCompatibility = 1.8 - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" - languageVersion = language_version - apiVersion = language_version - jvmTarget = "1.8" - } -} - -dependencies { - compile project(":core") - compileOnly group: 'org.apache.ant', name: 'ant', version: ant_version -} - diff --git a/runners/ant/src/main/kotlin/ant/dokka.kt b/runners/ant/src/main/kotlin/ant/dokka.kt deleted file mode 100644 index d275ed82..00000000 --- a/runners/ant/src/main/kotlin/ant/dokka.kt +++ /dev/null @@ -1,210 +0,0 @@ -package org.jetbrains.dokka.ant - -import org.apache.tools.ant.BuildException -import org.apache.tools.ant.Project -import org.apache.tools.ant.Task -import org.apache.tools.ant.types.Path -import org.apache.tools.ant.types.Reference -import org.jetbrains.dokka.* -import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink -import org.jetbrains.dokka.utilities.DokkaConsoleLogger -import org.jetbrains.dokka.utilities.DokkaLogger -import java.io.File - -class AntLogger(val task: Task): DokkaLogger { - override var warningsCount: Int = 0 - override var errorsCount: Int = 0 - override fun debug(message: String) = task.log(message, Project.MSG_DEBUG) - override fun info(message: String) = task.log(message, Project.MSG_VERBOSE) - override fun progress(message: String) = task.log(message, Project.MSG_INFO) - override fun warn(message: String) = task.log(message, Project.MSG_WARN).also { warningsCount++ } - override fun error(message: String) = task.log(message, Project.MSG_ERR).also { errorsCount++ } - override fun report() { - if (warningsCount > 0 || errorsCount > 0) { - task.log("Generation completed with $warningsCount warning" + - (if(warningsCount == 1) "" else "s") + - " and $errorsCount error" + - if(errorsCount == 1) "" else "s" - ) - } else { - task.log("generation completed successfully") - } - } -} - -class AntSourceLinkDefinition(var path: String? = null, var url: String? = null, var lineSuffix: String? = null) - -class AntSourceRoot(var path: String? = null) { - fun toSourceRoot(): SourceRootImpl? = path?.let { path -> - SourceRootImpl(path) - } -} - -class TextProperty(var value: String = "") - -class AntPassConfig(task: Task) : DokkaConfiguration.PassConfiguration { - override var moduleName: String = "" - override val classpath: List - get() = buildClassPath.list().toList() - - override val sourceRoots: List - get() = sourcePath.list().map { SourceRootImpl(it) } + antSourceRoots.mapNotNull { it.toSourceRoot() } - - override val samples: List - get() = samplesPath.list().toList() - override val includes: List - get() = includesPath.list().toList() - override var includeNonPublic: Boolean = false - override var includeRootPackage: Boolean = true - override var reportUndocumented: Boolean = false - override var skipEmptyPackages: Boolean = true - override var skipDeprecated: Boolean = false - override var jdkVersion: Int = 8 - override val sourceLinks: List - get() = antSourceLinkDefinition.map { - val path = it.path!! - val url = it.url!! - SourceLinkDefinitionImpl(File(path).canonicalFile.absolutePath, url, it.lineSuffix) - } - override val perPackageOptions: MutableList = mutableListOf() - override val externalDocumentationLinks: List - get() = buildExternalLinksBuilders.map { it.build() } + defaultExternalDocumentationLinks - - override var languageVersion: String? = null - override var apiVersion: String? = null - override var noStdlibLink: Boolean = false - override var noJdkLink: Boolean = false - override var suppressedFiles: MutableList = mutableListOf() - override var collectInheritedExtensionsFromLibraries: Boolean = false - override var analysisPlatform: Platform = Platform.DEFAULT - override var targets: List = listOf() - get() = buildTargets.filter { it.value != "" } - .map { it.value } - - override var sinceKotlin: String? = null - - private val samplesPath: Path by lazy { Path(task.project) } - private val includesPath: Path by lazy { Path(task.project) } - private val buildClassPath: Path by lazy { Path(task.project) } - val sourcePath: Path by lazy { Path(task.project) } - val antSourceRoots: MutableList = mutableListOf() - - private val buildTargets: MutableList = mutableListOf() - private val buildExternalLinksBuilders: MutableList = mutableListOf() - val antSourceLinkDefinition: MutableList = mutableListOf() - - private val defaultExternalDocumentationLinks: List - get() { - val links = mutableListOf() - if (!noJdkLink) - links += DokkaConfiguration.ExternalDocumentationLink.Builder("https://docs.oracle.com/javase/$jdkVersion/docs/api/").build() - - if (!noStdlibLink) - links += DokkaConfiguration.ExternalDocumentationLink.Builder("https://kotlinlang.org/api/latest/jvm/stdlib/").build() - return links - } - - - fun setSamples(ref: Path) { - samplesPath.append(ref) - } - - fun setSamplesRef(ref: Reference) { - samplesPath.createPath().refid = ref - } - - fun setInclude(ref: Path) { - includesPath.append(ref) - } - - fun setClasspath(classpath: Path) { - buildClassPath.append(classpath) - } - - fun createPackageOptions(): AntPackageOptions = AntPackageOptions().apply { perPackageOptions.add(this) } - - fun createSourceRoot(): AntSourceRoot = AntSourceRoot().apply { antSourceRoots.add(this) } - - fun createTarget(): TextProperty = TextProperty().apply { - buildTargets.add(this) - } - - fun setClasspathRef(ref: Reference) { - buildClassPath.createPath().refid = ref - } - - fun setSrc(src: Path) { - sourcePath.append(src) - } - - fun setSrcRef(ref: Reference) { - sourcePath.createPath().refid = ref - } - - fun createSourceLink(): AntSourceLinkDefinition { - val def = AntSourceLinkDefinition() - antSourceLinkDefinition.add(def) - return def - } - - fun createExternalDocumentationLink() = - ExternalDocumentationLink.Builder().apply { buildExternalLinksBuilders.add(this) } - -} - -class AntPackageOptions( - override var prefix: String = "", - override var includeNonPublic: Boolean = false, - override var reportUndocumented: Boolean = true, - override var skipDeprecated: Boolean = false, - override var suppress: Boolean = false) : DokkaConfiguration.PackageOptions - -class DokkaAntTask: Task(), DokkaConfiguration { - - override var format: String = "html" - override var generateIndexPages: Boolean = false - override var outputDir: String = "" - override var impliedPlatforms: List = listOf() - get() = buildImpliedPlatforms.map { it.value }.toList() - private val buildImpliedPlatforms: MutableList = mutableListOf() - - override var cacheRoot: String? = null - override val passesConfigurations: MutableList = mutableListOf() - override var pluginsClasspath: List = mutableListOf() - - fun createPassConfig() = AntPassConfig(this).apply { passesConfigurations.add(this) } - fun createImpliedPlatform(): TextProperty = TextProperty().apply { buildImpliedPlatforms.add(this) } - - - override fun execute() { - for (passConfig in passesConfigurations) { - if (passConfig.sourcePath.list().isEmpty() && passConfig.antSourceRoots.isEmpty()) { - throw BuildException("At least one source path needs to be specified") - } - - if (passConfig.moduleName == "") { - throw BuildException("Module name needs to be specified and not empty") - } - - for (sourceLink in passConfig.antSourceLinkDefinition) { - if (sourceLink.path == null) { - throw BuildException("'path' attribute of a element is required") - } - if (sourceLink.path!!.contains("\\")) { - throw BuildException("'dir' attribute of a - incorrect value, only Unix based path allowed") - } - - if (sourceLink.url == null) { - throw BuildException("'url' attribute of a element is required") - } - } - } - - if (outputDir == "") { - throw BuildException("Output directory needs to be specified and not empty") - } - - val generator = DokkaGenerator(this, AntLogger(this)) - generator.generate() - } -} \ No newline at end of file diff --git a/runners/ant/src/main/resources/dokka-antlib.xml b/runners/ant/src/main/resources/dokka-antlib.xml deleted file mode 100644 index 9c3373d5..00000000 --- a/runners/ant/src/main/resources/dokka-antlib.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index 8c4955ca..bc09f2cd 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -10,7 +10,6 @@ repositories { dependencies { implementation("org.jetbrains.kotlinx:kotlinx-cli-jvm:0.2.1") - implementation("com.google.code.gson:gson:2.8.5") implementation(project(":core")) implementation(kotlin("stdlib")) } @@ -36,4 +35,4 @@ publishing { } } -configureBintrayPublication("dokkaCli") \ No newline at end of file +configureBintrayPublication("dokkaCli") diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index b0fb45b2..5e5cd6b2 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -1,6 +1,5 @@ package org.jetbrains.dokka -import com.google.gson.Gson import kotlinx.cli.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet.* @@ -34,7 +33,7 @@ class GlobalArguments(args: Array) : DokkaConfiguration { override val sourceSets by parser.option( ArgTypeArgument, description = "Single dokka source set", - fullName = "pass" + fullName = "sourceSet" ).multiple() override val pluginsConfiguration by parser.option( @@ -60,7 +59,7 @@ class GlobalArguments(args: Array) : DokkaConfiguration { val globalPackageOptions by parser.option( ArgType.String, - description = "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " + description = "List of package source sets in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " ).delimiter(";") val globalLinks by parser.option( @@ -73,9 +72,9 @@ class GlobalArguments(args: Array) : DokkaConfiguration { description = "Mapping between a source directory and a Web site for browsing the code (allows many paths separated by the semicolon `;`)" ).delimiter(";") - val helpPass by parser.option( - ArgTypeHelpPass, - description = "Prints help for single -pass" + val helpSourceSet by parser.option( + ArgTypeHelpSourceSet, + description = "Prints help for single -sourceSet" ) override val modules: List = emptyList() @@ -94,8 +93,8 @@ class GlobalArguments(args: Array) : DokkaConfiguration { globalSrcLink.forEach { if (it.isNotEmpty() && it.contains("=")) - sourceSets.all { pass -> - pass.sourceLinks.cast>() + sourceSets.all { sourceSet -> + sourceSet.sourceLinks.cast>() .add(SourceLinkDefinitionImpl.parseSourceLinkDefinition(it)) } else { @@ -112,9 +111,9 @@ class GlobalArguments(args: Array) : DokkaConfiguration { } } -fun passArguments(args: Array): DokkaConfiguration.DokkaSourceSet { +private fun parseSourceSet(args: Array): DokkaConfiguration.DokkaSourceSet { - val parser = ArgParser("passConfiguration", prefixStyle = ArgParser.OptionPrefixStyle.JVM) + val parser = ArgParser("sourceSet", prefixStyle = ArgParser.OptionPrefixStyle.JVM) val moduleName by parser.option( ArgType.String, @@ -122,16 +121,21 @@ fun passArguments(args: Array): DokkaConfiguration.DokkaSourceSet { fullName = "module" ).required() - val displayName by parser.option( + val moduleDisplayName by parser.option( ArgType.String, - description = "Name of the source set" - ).default("JVM") + description = "Name of the documentation module" + ) - val sourceSetID by parser.option( + val name by parser.option( ArgType.String, - description = "ID of the source set" + description = "Name of the source set" ).default("main") + val displayName by parser.option( + ArgType.String, + description = "Displayed name of the source set" + ).default("JVM") + val classpath by parser.option( ArgType.String, description = "Classpath for symbol resolution (allows many paths separated by the semicolon `;`)" @@ -213,7 +217,7 @@ fun passArguments(args: Array): DokkaConfiguration.DokkaSourceSet { val perPackageOptions by parser.option( ArgType.String, - description = "List of package passConfiguration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " + description = "List of package source set configuration in format \"prefix,-deprecated,-privateApi,+warnUndocumented,+suppress;...\" " ).delimiter(";") val externalDocumentationLinks by parser.option( @@ -230,12 +234,14 @@ fun passArguments(args: Array): DokkaConfiguration.DokkaSourceSet { parser.parse(args) return object : DokkaConfiguration.DokkaSourceSet { - override val moduleName = moduleName + override val moduleDisplayName = moduleDisplayName ?: moduleName override val displayName = displayName - override val sourceSetID = sourceSetID + override val sourceSetID = DokkaSourceSetID(moduleName, name) override val classpath = classpath override val sourceRoots = sourceRoots.map { SourceRootImpl(it.toAbsolutePath()) } - override val dependentSourceSets: List = dependentSourceSets + override val dependentSourceSets: Set = dependentSourceSets + .map { dependentSourceSetName -> DokkaSourceSetID(moduleName, dependentSourceSetName) } + .toSet() override val samples = samples.map { it.toAbsolutePath() } override val includes = includes.map { it.toAbsolutePath() } override val includeNonPublic = includeNonPublic @@ -294,15 +300,15 @@ object ArgTypeSourceLinkDefinition : ArgType(true) { override fun convert(value: kotlin.String, name: kotlin.String): DokkaConfiguration.DokkaSourceSet = - passArguments(value.split(" ").filter { it.isNotBlank() }.toTypedArray()) + parseSourceSet(value.split(" ").filter { it.isNotBlank() }.toTypedArray()) override val description: kotlin.String get() = "" } // Workaround for printing nested parsers help -object ArgTypeHelpPass : ArgType(false) { - override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { passArguments(arrayOf("-h")) } +object ArgTypeHelpSourceSet : ArgType(false) { + override fun convert(value: kotlin.String, name: kotlin.String): Any = Any().also { parseSourceSet(arrayOf("-h")) } override val description: kotlin.String get() = "" @@ -345,11 +351,10 @@ fun parseLinks(links: List): List { fun main(args: Array) { val globalArguments = GlobalArguments(args) val configuration = if (globalArguments.json != null) - Gson().fromJson( - Paths.get(globalArguments.json).toFile().readText(), - DokkaConfigurationImpl::class.java + DokkaConfigurationImpl( + Paths.get(checkNotNull(globalArguments.json)).toFile().readText() ) else globalArguments DokkaGenerator(configuration, DokkaConsoleLogger).generate() -} \ No newline at end of file +} diff --git a/runners/gradle-plugin/build.gradle.kts b/runners/gradle-plugin/build.gradle.kts index 71d7e72f..2c25a707 100644 --- a/runners/gradle-plugin/build.gradle.kts +++ b/runners/gradle-plugin/build.gradle.kts @@ -19,6 +19,8 @@ dependencies { compileOnly(gradleKotlinDsl()) testImplementation(gradleApi()) testImplementation(kotlin("test-junit")) + testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin") + constraints { val kotlin_version: String by project compileOnly("org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}") { diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt index 3bd0b6ab..c9693467 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt @@ -169,4 +169,4 @@ class ConfigurationExtractor(private val project: Project) { val dependentSourceSets: List, val platform: String ) : Serializable -} \ No newline at end of file +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt index ead0f90a..823206e3 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt @@ -19,7 +19,7 @@ open class DokkaCollectorTask : DefaultTask() { @TaskAction fun collect() { - val passesConfigurations = getProjects(project).filter { it.name in modules }.flatMap { + val sourceSets = getProjects(project).filter { it.name in modules }.flatMap { val tasks = try { it.tasks.withType(DokkaTask::class.java) } catch (e: UnknownTaskException) { @@ -30,11 +30,11 @@ open class DokkaCollectorTask : DefaultTask() { val initial = GradleDokkaConfigurationImpl().apply { outputDir = outputDirectory - cacheRoot = passesConfigurations.first().cacheRoot - format = passesConfigurations.first().format + cacheRoot = sourceSets.first().cacheRoot + format = sourceSets.first().format } - configuration = passesConfigurations.fold(initial) { acc, it: GradleDokkaConfigurationImpl -> + configuration = sourceSets.fold(initial) { acc, it: GradleDokkaConfigurationImpl -> if(acc.format != it.format || acc.cacheRoot != it.cacheRoot) throw IllegalStateException("Dokka task configurations differ on core arguments (format, cacheRoot)") acc.sourceSets = acc.sourceSets + it.sourceSets diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt new file mode 100644 index 00000000..3fadb4fd --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt @@ -0,0 +1,10 @@ +@file:Suppress("FunctionName") + +package org.jetbrains.dokka.gradle + +import org.gradle.api.Project +import org.jetbrains.dokka.DokkaSourceSetID + +internal fun DokkaSourceSetID(project: Project, sourceSetName: String): DokkaSourceSetID { + return DokkaSourceSetID(moduleName = project.path, sourceSetName = sourceSetName) +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index e27357c9..aac7e2a0 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -7,11 +7,9 @@ import org.gradle.api.file.FileCollection import org.gradle.api.internal.plugins.DslObject import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.tasks.* -import org.jetbrains.dokka.DokkaBootstrap +import org.jetbrains.dokka.* import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder import org.jetbrains.dokka.DokkaConfiguration.SourceRoot -import org.jetbrains.dokka.DokkaException -import org.jetbrains.dokka.Platform import org.jetbrains.dokka.ReflectDsl import org.jetbrains.dokka.ReflectDsl.isNotInstance import org.jetbrains.dokka.gradle.ConfigurationExtractor.PlatformData @@ -183,10 +181,7 @@ open class DokkaTask : DefaultTask(), Configurable { val defaultModulesConfiguration = configuredDokkaSourceSets .map { configureDefault(it, globalConfig) }.takeIf { it.isNotEmpty() } ?: listOf( - configureDefault( - configureDokkaSourceSet(GradleDokkaSourceSet("main")), - null - ) + configureDefault(configureDokkaSourceSet(GradleDokkaSourceSet("main", project)), null) ).takeIf { project.isNotMultiplatformProject() } ?: emptyList() if (defaultModulesConfiguration.isEmpty()) { @@ -288,28 +283,25 @@ open class DokkaTask : DefaultTask(), Configurable { protected fun mergeUserConfigurationAndPlatformData( userConfig: GradleDokkaSourceSet, autoConfig: PlatformData - ) = - userConfig.copy().apply { - sourceRoots.addAll(userConfig.sourceRoots.union(autoConfig.sourceRoots.toSourceRoots()).distinct()) - dependentSourceSets.addAll(userConfig.dependentSourceSets.union(autoConfig.dependentSourceSets).distinct()) - classpath = userConfig.classpath.union(autoConfig.classpath.map { it.absolutePath }).distinct() - if (userConfig.platform == null && autoConfig.platform != "") - platform = autoConfig.platform - } + ) = userConfig.copy().apply { + sourceRoots.addAll(userConfig.sourceRoots.union(autoConfig.sourceRoots.toSourceRoots()).distinct()) + dependentSourceSets.addAll(userConfig.dependentSourceSets) + dependentSourceSets.addAll(autoConfig.dependentSourceSets.map { DokkaSourceSetID(project, it) }) + classpath = userConfig.classpath.union(autoConfig.classpath.map { it.absolutePath }).distinct() + if (userConfig.platform == null && autoConfig.platform != "") + platform = autoConfig.platform + } protected fun configureDefault( config: GradleDokkaSourceSet, globalConfig: GradleDokkaSourceSet? ): GradleDokkaSourceSet { - if (config.moduleName.isBlank()) { - config.moduleName = project.name + if (config.moduleDisplayName.isBlank()) { + config.moduleDisplayName = project.name } - if (config.sourceSetID.isBlank()) { - config.sourceSetID = config.moduleName + "/" + config.name - } - config.dependentSourceSets = config.dependentSourceSets.map { config.moduleName + "/" + it }.toMutableList() + if (config.displayName.isBlank()) { - config.displayName = config.sourceSetID.substringBeforeLast("Main", config.platform.toString()) + config.displayName = config.name.substringBeforeLast("Main", config.platform.toString()) } config.classpath = (config.classpath as List).map { it.toString() }.distinct() // Workaround for Groovy's GStringImpl diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt index a28416d6..7b2d05a6 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt @@ -1,13 +1,19 @@ +@file:Suppress("FunctionName") + package org.jetbrains.dokka.gradle +import com.android.build.gradle.api.AndroidSourceSet import groovy.lang.Closure import org.gradle.api.Action +import org.gradle.api.Project import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Optional import org.gradle.util.ConfigureUtil import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.DokkaConfiguration.* import org.jetbrains.dokka.DokkaDefaults +import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.Platform import java.io.File import java.io.Serializable @@ -15,6 +21,8 @@ import java.net.URL import java.util.concurrent.Callable import kotlin.reflect.KMutableProperty import kotlin.reflect.full.memberProperties +import org.gradle.api.tasks.SourceSet as GradleSourceSet +import org.jetbrains.kotlin.gradle.model.SourceSet as KotlinSourceSet class GradleSourceRootImpl : SourceRoot, Serializable { override var path: String = "" @@ -25,64 +33,113 @@ class GradleSourceRootImpl : SourceRoot, Serializable { override fun toString(): String = path } -open class GradleDokkaSourceSet(@Transient val name: String = "") : DokkaSourceSet { +open class GradleDokkaSourceSet constructor( + @Transient val name: String, + @Transient internal val project: Project +) : DokkaSourceSet { + @Input @Optional override var classpath: List = emptyList() + @Input - override var moduleName: String = "" + override var moduleDisplayName: String = "" + @Input override var displayName: String = "" - @Input - override var sourceSetID: String = "" + + @get:Internal + override val sourceSetID: DokkaSourceSetID = DokkaSourceSetID(project, name) + @Input override var sourceRoots: MutableList = mutableListOf() + @Input - override var dependentSourceSets: MutableList = mutableListOf() + override var dependentSourceSets: MutableSet = mutableSetOf() + @Input override var samples: List = emptyList() + @Input override var includes: List = emptyList() + @Input override var includeNonPublic: Boolean = DokkaDefaults.includeNonPublic + @Input override var includeRootPackage: Boolean = DokkaDefaults.includeRootPackage + @Input override var reportUndocumented: Boolean = DokkaDefaults.reportUndocumented + @Input override var skipEmptyPackages: Boolean = DokkaDefaults.skipEmptyPackages + @Input override var skipDeprecated: Boolean = DokkaDefaults.skipDeprecated + @Input override var jdkVersion: Int = DokkaDefaults.jdkVersion + @Input override var sourceLinks: MutableList = mutableListOf() + @Input override var perPackageOptions: MutableList = mutableListOf() + @Input override var externalDocumentationLinks: MutableList = mutableListOf() + @Input @Optional override var languageVersion: String? = null + @Input @Optional override var apiVersion: String? = null + @Input override var noStdlibLink: Boolean = DokkaDefaults.noStdlibLink + @Input override var noJdkLink: Boolean = DokkaDefaults.noJdkLink + @Input var noAndroidSdkLink: Boolean = false + @Input override var suppressedFiles: List = emptyList() + @Input override var analysisPlatform: Platform = DokkaDefaults.analysisPlatform + @Input @Optional var platform: String? = null + @Transient var collectKotlinTasks: (() -> List?)? = null + fun DokkaSourceSetID(sourceSetName: String): DokkaSourceSetID { + return DokkaSourceSetID(project, sourceSetName) + } + + fun dependsOn(sourceSet: GradleSourceSet) { + dependsOn(DokkaSourceSetID(sourceSet.name)) + } + + fun dependsOn(sourceSet: DokkaSourceSet) { + dependsOn(sourceSet.sourceSetID) + } + + fun dependsOn(sourceSetName: String) { + dependsOn(DokkaSourceSetID(sourceSetName)) + } + + fun dependsOn(sourceSetID: DokkaSourceSetID) { + dependentSourceSets.add(sourceSetID) + } + fun kotlinTasks(taskSupplier: Callable>) { collectKotlinTasks = { taskSupplier.call() } } @@ -136,6 +193,18 @@ open class GradleDokkaSourceSet(@Transient val name: String = "") : DokkaSourceS } } +fun GradleDokkaSourceSet.dependsOn(sourceSet: KotlinSourceSet) { + dependsOn(DokkaSourceSetID(sourceSet.name)) +} + +fun GradleDokkaSourceSet.dependsOn(sourceSet: org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet) { + dependsOn(DokkaSourceSetID(sourceSet.name)) +} + +fun GradleDokkaSourceSet.dependsOn(sourceSet: AndroidSourceSet) { + dependsOn(DokkaSourceSetID(sourceSet.name)) +} + class GradleSourceLinkDefinitionImpl : SourceLinkDefinition, Serializable { override var path: String = "" override var url: String = "" @@ -174,16 +243,16 @@ class GradlePackageOptionsImpl : PackageOptions, Serializable { } internal fun GradleDokkaSourceSet.copy(): GradleDokkaSourceSet { - val newObj = GradleDokkaSourceSet(this.name) + val newObj = GradleDokkaSourceSet(this.name, this.project) this::class.memberProperties.forEach { field -> if (field is KMutableProperty<*>) { - val value = field.getter.call(this) - if (value is Collection<*>) { - field.setter.call(newObj, value.toMutableList()) - } else { - field.setter.call(newObj, field.getter.call(this)) + when (val value = field.getter.call(this)) { + is List<*> -> field.setter.call(newObj, value.toMutableList()) + is Set<*> -> field.setter.call(newObj, value.toMutableSet()) + else -> field.setter.call(newObj, field.getter.call(this)) } + } } return newObj -} \ No newline at end of file +} diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt index 92d63a40..a92f5475 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt @@ -53,7 +53,9 @@ open class DokkaPlugin : Plugin { project.tasks.create(DOKKA_TASK_NAME, taskClass) } project.tasks.withType(taskClass) { task -> - task.dokkaSourceSets = project.container(GradleDokkaSourceSet::class.java) + task.dokkaSourceSets = project.container(GradleDokkaSourceSet::class.java) { name -> + GradleDokkaSourceSet(name, project) + } task.dokkaRuntime = runtimeConfiguration task.pluginsClasspathConfiguration = pluginsConfiguration task.outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt index 0b80f4a2..da6daeea 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/KotlinDslDokkaTaskConfigurationTest.kt @@ -1,6 +1,9 @@ package org.jetbrains.dokka.gradle +import org.gradle.api.plugins.JavaPluginExtension import org.gradle.testfixtures.ProjectBuilder +import org.jetbrains.dokka.DokkaSourceSetID +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import kotlin.test.Test import kotlin.test.assertEquals @@ -16,4 +19,78 @@ class KotlinDslDokkaTaskConfigurationTest { assertEquals("test", dokkaTask.outputFormat) } } + + @Test + fun `sourceSet dependsOn by String`() { + val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + + project.dokka { + dokkaSourceSets.run { + val commonMain = create("commonMain") + val jvmMain = create("jvmMain") { + it.dependsOn("commonMain") + } + + assertEquals( + 0, commonMain.dependentSourceSets.size, + "Expected no dependent source set in commonMain" + ) + + assertEquals( + 1, jvmMain.dependentSourceSets.size, + "Expected only one dependent source set in jvmMain" + ) + + assertEquals( + commonMain.sourceSetID, jvmMain.dependentSourceSets.single(), + "Expected jvmMain to depend on commonMain" + ) + + assertEquals( + DokkaSourceSetID(project.path, "commonMain"), commonMain.sourceSetID + ) + } + } + } + + @Test + fun `sourceSet dependsOn by DokkaSourceSet`() { + val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + + project.dokka { + dokkaSourceSets.run { + val commonMain = create("commonMain") + val jvmMain = create("jvmMain") { + it.dependsOn(commonMain) + } + + assertEquals( + commonMain.sourceSetID, jvmMain.dependentSourceSets.single() + ) + } + } + } + + @Test + fun `sourceSet dependsOn by KotlinSourceSet`() { + val project = ProjectBuilder.builder().build() + project.plugins.apply("org.jetbrains.dokka") + project.plugins.apply("org.jetbrains.kotlin.jvm") + + val kotlin = project.extensions.getByName("kotlin") as KotlinJvmProjectExtension + + project.dokka { + dokkaSourceSets.run { + val special = create("special") { + it.dependsOn(kotlin.sourceSets.getByName("main")) + } + + assertEquals( + DokkaSourceSetID(project, "main"), special.dependentSourceSets.single() + ) + } + } + } } diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt index 4c10568c..8160ab87 100644 --- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt +++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt @@ -90,9 +90,6 @@ abstract class AbstractDokkaMojo : AbstractMojo() { @Parameter var sourceRoots: List = emptyList() - @Parameter - var dependentSourceSets: List = emptyList() - @Parameter var samples: List = emptyList() @@ -108,6 +105,9 @@ abstract class AbstractDokkaMojo : AbstractMojo() { @Parameter(required = true, defaultValue = "\${project.artifactId}") var moduleName: String = "" + @Parameter + var moduleDisplayName: String = "" + @Parameter(required = false, defaultValue = "false") var skip: Boolean = false @@ -201,12 +201,12 @@ abstract class AbstractDokkaMojo : AbstractMojo() { } val sourceSet = DokkaSourceSetImpl( - moduleName = moduleName, + moduleDisplayName = moduleDisplayName.takeIf(String::isNotBlank) ?: moduleName, displayName = displayName, - sourceSetID = sourceSetName, + sourceSetID = DokkaSourceSetID(moduleName, sourceSetName), classpath = classpath, sourceRoots = sourceDirectories.map { SourceRootImpl(it) }, - dependentSourceSets = dependentSourceSets, + dependentSourceSets = emptySet(), samples = samples, includes = includes, includeNonPublic = includeNonPublic, @@ -246,7 +246,7 @@ abstract class AbstractDokkaMojo : AbstractMojo() { offlineMode = offlineMode, cacheRoot = cacheRoot, sourceSets = listOf(sourceSet).also { - if (sourceSet.moduleName.isEmpty()) logger.warn("Not specified module name. It can result in unexpected behaviour while including documentation for module") + if (sourceSet.moduleDisplayName.isEmpty()) logger.warn("Not specified module name. It can result in unexpected behaviour while including documentation for module") }, pluginsClasspath = getArtifactByAether("org.jetbrains.dokka", "dokka-base", dokkaVersion) + dokkaPlugins.map { getArtifactByAether(it.groupId, it.artifactId, it.version) }.flatten(), diff --git a/testApi/src/main/kotlin/testApi/context/MockContext.kt b/testApi/src/main/kotlin/testApi/context/MockContext.kt index 07aedf28..97347695 100644 --- a/testApi/src/main/kotlin/testApi/context/MockContext.kt +++ b/testApi/src/main/kotlin/testApi/context/MockContext.kt @@ -1,7 +1,6 @@ package org.jetbrains.dokka.testApi.context import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.plugability.ExtensionPoint @@ -45,4 +44,4 @@ class MockContext( private fun DokkaPlugin.injectContext(context: DokkaContext) { (DokkaPlugin::class.memberProperties.single { it.name == "context" } as KMutableProperty<*>) .setter.call(this, context) -} \ No newline at end of file +} diff --git a/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt b/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt index ec2be689..d3127263 100644 --- a/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt +++ b/testApi/src/main/kotlin/testApi/testRunner/DokkaTestGenerator.kt @@ -1,7 +1,6 @@ package org.jetbrains.dokka.testApi.testRunner import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.DokkaGenerator import org.jetbrains.dokka.plugability.DokkaPlugin import org.jetbrains.dokka.utilities.DokkaLogger @@ -43,4 +42,4 @@ internal class DokkaTestGenerator( dokkaGenerator.reportAfterRendering(context) } -} \ No newline at end of file +} diff --git a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt index 057045a8..381fb2af 100644 --- a/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt +++ b/testApi/src/main/kotlin/testApi/testRunner/TestRunner.kt @@ -174,25 +174,26 @@ abstract class AbstractCoreTest { failOnWarning = failOnWarning ) - fun passes(block: Passes.() -> Unit) { - sourceSets.addAll(Passes().apply(block)) + fun sourceSets(block: SourceSetsBuilder.() -> Unit) { + sourceSets.addAll(SourceSetsBuilder().apply(block)) } } @DokkaConfigurationDsl - protected class Passes : ArrayList() { - fun pass(block: DokkaSourceSetBuilder.() -> Unit) = - add(DokkaSourceSetBuilder().apply(block).build()) + protected class SourceSetsBuilder : ArrayList() { + fun sourceSet(block: DokkaSourceSetBuilder.() -> Unit): DokkaSourceSet = + DokkaSourceSetBuilder().apply(block).build().apply(::add) } @DokkaConfigurationDsl protected class DokkaSourceSetBuilder( var moduleName: String = "root", - var sourceSetID: String = "main", + var moduleDisplayName: String? = null, + var name: String = "main", var displayName: String = "JVM", var classpath: List = emptyList(), var sourceRoots: List = emptyList(), - var dependentSourceSets: List = emptyList(), + var dependentSourceSets: Set = emptySet(), var samples: List = emptyList(), var includes: List = emptyList(), var includeNonPublic: Boolean = false, @@ -212,9 +213,9 @@ abstract class AbstractCoreTest { var sourceLinks: List = emptyList() ) { fun build() = DokkaSourceSetImpl( - moduleName = moduleName, + moduleDisplayName = moduleDisplayName ?: moduleName, displayName = displayName, - sourceSetID = sourceSetID, + sourceSetID = DokkaSourceSetID(moduleName, name), classpath = classpath, sourceRoots = sourceRoots.map { SourceRootImpl(it) }, dependentSourceSets = dependentSourceSets, -- cgit From daadf8431b9280d5f96cfce2698b83c5e11524f6 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Mon, 6 Jul 2020 15:32:08 +0200 Subject: Manually disable bintray tasks in root project (https://github.com/bintray/gradle-bintray-plugin/issues/267) --- build.gradle.kts | 9 ++++++++- buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- runners/cli/build.gradle.kts | 1 + settings.gradle.kts | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) (limited to 'runners/cli/build.gradle.kts') diff --git a/build.gradle.kts b/build.gradle.kts index 04f4afd4..bd73a251 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") apply false - id("com.jfrog.bintray") apply false id("java") } @@ -50,3 +49,11 @@ subprojects { } println("Publication version: $dokka_version") + +// Workaround for https://github.com/bintray/gradle-bintray-plugin/issues/267 +// Manually disable bintray tasks added to the root project +tasks.whenTaskAdded { + if ("bintray" in name) { + enabled = false + } +} diff --git a/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt b/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt index 78e4257f..c3d21d88 100644 --- a/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt +++ b/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt @@ -24,4 +24,4 @@ fun Project.configureBintrayPublication(vararg publications: String) { } setPublications(*publications) } -} \ No newline at end of file +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64a..bb8b2fc2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index bc09f2cd..00e459b2 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -2,6 +2,7 @@ import org.jetbrains.configureBintrayPublication plugins { id("com.github.johnrengelman.shadow") + id("com.jfrog.bintray") } repositories { diff --git a/settings.gradle.kts b/settings.gradle.kts index e634c7d2..b6233dc7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -26,7 +26,7 @@ pluginManagement { plugins { id("org.jetbrains.kotlin.jvm") version kotlin_version id("com.github.johnrengelman.shadow") version "5.2.0" - id("com.jfrog.bintray") version "1.8.4" + id("com.jfrog.bintray") version "1.8.5" id("com.gradle.plugin-publish") version "0.10.1" } -- cgit From 7001425367a4db79c6fcdf6b8d0c53508ba50aa7 Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Mon, 13 Jul 2020 18:33:28 -0700 Subject: Simplify publishing configuration and enable sourcejars --- .../org/jetbrains/PublicationConfiguration.kt | 34 ++++++++++++++++++++++ core/build.gradle.kts | 19 ++---------- core/dependencies/build.gradle.kts | 13 ++------- kotlin-analysis/build.gradle.kts | 13 ++------- kotlin-analysis/dependencies/build.gradle.kts | 15 ++-------- plugins/base/build.gradle.kts | 13 ++------- plugins/gfm/build.gradle.kts | 15 ++-------- plugins/javadoc/build.gradle.kts | 13 ++------- plugins/jekyll/build.gradle.kts | 15 ++-------- plugins/kotlin-as-java/build.gradle.kts | 13 ++------- plugins/mathjax/build.gradle.kts | 13 ++------- plugins/xml/build.gradle.kts | 11 ++----- runners/cli/build.gradle.kts | 13 ++------- runners/maven-plugin/build.gradle.kts | 15 ++-------- testApi/build.gradle.kts | 19 ++---------- 15 files changed, 65 insertions(+), 169 deletions(-) create mode 100644 buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt (limited to 'runners/cli/build.gradle.kts') diff --git a/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt b/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt new file mode 100644 index 00000000..5dbb8fb9 --- /dev/null +++ b/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt @@ -0,0 +1,34 @@ +package org.jetbrains + +import com.github.jengelman.gradle.plugins.shadow.ShadowExtension +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.get + +fun Project.configurePublication(artifactId: String, useShadow: Boolean = false) { + configure { + publications { + create("maven") { + this.artifactId = artifactId + if (useShadow) { + val shadow = extensions.getByType(ShadowExtension::class.java) + shadow.component(this) + } else { + from(components["java"]) + } + } + } + } + configureBintrayPublication("maven") + plugins.all { + if (this is JavaPlugin) { + val extension = extensions.getByType(JavaPluginExtension::class.java) + @Suppress("UnstableApiUsage") extension.withSourcesJar() + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 45ddccf3..030db5c6 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { `maven-publish` @@ -16,11 +16,6 @@ dependencies { testImplementation(kotlin("test-junit")) } -val sourceJar by tasks.registering(Jar::class) { - archiveClassifier.set("sources") - from(sourceSets["main"].allSource) -} - tasks { processResources { val dokka_version: String by project @@ -34,14 +29,4 @@ tasks { } } -publishing { - publications { - register("dokkaCore") { - artifactId = "dokka-core" - from(components["java"]) - artifact(sourceJar.get()) - } - } -} - -configureBintrayPublication("dokkaCore") +configurePublication("dokka-core") diff --git a/core/dependencies/build.gradle.kts b/core/dependencies/build.gradle.kts index a26d109e..082861b6 100644 --- a/core/dependencies/build.gradle.kts +++ b/core/dependencies/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { id("com.github.johnrengelman.shadow") @@ -28,13 +28,4 @@ tasks { } } -publishing { - publications { - register("dokkaCoreDependencies") { - artifactId = "dokka-core-dependencies" - project.shadow.component(this) - } - } -} - -configureBintrayPublication("dokkaCoreDependencies") +configurePublication("dokka-core-dependencies", useShadow = true) diff --git a/kotlin-analysis/build.gradle.kts b/kotlin-analysis/build.gradle.kts index 67480f82..5acc1f06 100644 --- a/kotlin-analysis/build.gradle.kts +++ b/kotlin-analysis/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { id("com.github.johnrengelman.shadow") @@ -15,13 +15,4 @@ dependencies { api(project(":kotlin-analysis:dependencies", configuration = "shadow")) } -publishing { - publications { - register("analysis") { - artifactId = "dokka-analysis" - from(components["java"]) - } - } -} - -configureBintrayPublication("analysis") +configurePublication("dokka-analysis") diff --git a/kotlin-analysis/dependencies/build.gradle.kts b/kotlin-analysis/dependencies/build.gradle.kts index 5bba6422..1fd13630 100644 --- a/kotlin-analysis/dependencies/build.gradle.kts +++ b/kotlin-analysis/dependencies/build.gradle.kts @@ -1,5 +1,4 @@ -import org.jetbrains.configureBintrayPublication - +import org.jetbrains.configurePublication plugins { id("com.github.johnrengelman.shadow") @@ -54,14 +53,4 @@ tasks { } } - -publishing { - publications { - register("kotlin-analysis-dependencies") { - artifactId = "kotlin-analysis-dependencies" - project.shadow.component(this) - } - } -} - -configureBintrayPublication("kotlin-analysis-dependencies") +configurePublication("kotlin-analysis-dependencies", useShadow = true) diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts index 1fe3dbc2..61e2ef01 100644 --- a/plugins/base/build.gradle.kts +++ b/plugins/base/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { id("com.jfrog.bintray") @@ -30,13 +30,4 @@ tasks { } } -publishing { - publications { - register("basePlugin") { - artifactId = "dokka-base" - from(components["java"]) - } - } -} - -configureBintrayPublication("basePlugin") +configurePublication("dokka-base") diff --git a/plugins/gfm/build.gradle.kts b/plugins/gfm/build.gradle.kts index fac2c1c0..73958046 100644 --- a/plugins/gfm/build.gradle.kts +++ b/plugins/gfm/build.gradle.kts @@ -1,18 +1,9 @@ -import org.jetbrains.configureBintrayPublication - -publishing { - publications { - register("gfmPlugin") { - artifactId = "gfm-plugin" - from(components["java"]) - } - } -} - -configureBintrayPublication("gfmPlugin") +import org.jetbrains.configurePublication dependencies { implementation(project(":plugins:base")) testImplementation(project(":plugins:base")) testImplementation(project(":plugins:base:test-utils")) } + +configurePublication("gfm-plugin") diff --git a/plugins/javadoc/build.gradle.kts b/plugins/javadoc/build.gradle.kts index ebf79f8f..5846ee62 100644 --- a/plugins/javadoc/build.gradle.kts +++ b/plugins/javadoc/build.gradle.kts @@ -1,13 +1,4 @@ -import org.jetbrains.configureBintrayPublication - -publishing { - publications { - register("javadocPlugin") { - artifactId = "javadoc-plugin" - from(components["java"]) - } - } -} +import org.jetbrains.configurePublication dependencies { implementation("com.soywiz.korlibs.korte:korte-jvm:1.10.3") @@ -19,4 +10,4 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") } -configureBintrayPublication("javadocPlugin") +configurePublication("javadoc-plugin") diff --git a/plugins/jekyll/build.gradle.kts b/plugins/jekyll/build.gradle.kts index 90002466..0d1e38d6 100644 --- a/plugins/jekyll/build.gradle.kts +++ b/plugins/jekyll/build.gradle.kts @@ -1,17 +1,8 @@ -import org.jetbrains.configureBintrayPublication - -publishing { - publications { - register("jekyllPlugin") { - artifactId = "jekyll-plugin" - from(components["java"]) - } - } -} - -configureBintrayPublication("jekyllPlugin") +import org.jetbrains.configurePublication dependencies { implementation(project(":plugins:base")) implementation(project(":plugins:gfm")) } + +configurePublication("jekyll-plugin") diff --git a/plugins/kotlin-as-java/build.gradle.kts b/plugins/kotlin-as-java/build.gradle.kts index bd08ab92..27e90f84 100644 --- a/plugins/kotlin-as-java/build.gradle.kts +++ b/plugins/kotlin-as-java/build.gradle.kts @@ -1,13 +1,4 @@ -import org.jetbrains.configureBintrayPublication - -publishing { - publications { - register("kotlinAsJavaPlugin") { - artifactId = "kotlin-as-java-plugin" - from(components["java"]) - } - } -} +import org.jetbrains.configurePublication dependencies { implementation(project(":plugins:base")) @@ -16,4 +7,4 @@ dependencies { testImplementation(project(":test-tools")) } -configureBintrayPublication("kotlinAsJavaPlugin") \ No newline at end of file +configurePublication("kotlin-as-java-plugin") diff --git a/plugins/mathjax/build.gradle.kts b/plugins/mathjax/build.gradle.kts index 67f4822f..ea4cdff0 100644 --- a/plugins/mathjax/build.gradle.kts +++ b/plugins/mathjax/build.gradle.kts @@ -1,12 +1,3 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication -publishing { - publications { - register("mathjaxPlugin") { - artifactId = "mathjax-plugin" - from(components["java"]) - } - } -} - -configureBintrayPublication("mathjaxPlugin") +configurePublication("mathjax-plugin") diff --git a/plugins/xml/build.gradle.kts b/plugins/xml/build.gradle.kts index cd65cfe4..5d3984bc 100644 --- a/plugins/xml/build.gradle.kts +++ b/plugins/xml/build.gradle.kts @@ -1,8 +1,3 @@ -publishing { - publications { - register("xmlPlugin") { - artifactId = "xml-plugin" - from(components["java"]) - } - } -} \ No newline at end of file +import org.jetbrains.configurePublication + +configurePublication("xml-plugin") \ No newline at end of file diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index 00e459b2..19a49346 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { id("com.github.johnrengelman.shadow") @@ -15,7 +15,6 @@ dependencies { implementation(kotlin("stdlib")) } - tasks { shadowJar { val dokka_version: String by project @@ -27,13 +26,5 @@ tasks { } } -publishing { - publications { - register("dokkaCli") { - artifactId = "dokka-cli" - project.shadow.component(this) - } - } -} +configurePublication("dokka-cli", useShadow = true) -configureBintrayPublication("dokkaCli") diff --git a/runners/maven-plugin/build.gradle.kts b/runners/maven-plugin/build.gradle.kts index 6214da6d..83d9f5af 100644 --- a/runners/maven-plugin/build.gradle.kts +++ b/runners/maven-plugin/build.gradle.kts @@ -1,7 +1,6 @@ -import org.jetbrains.configureBintrayPublication import org.jetbrains.CrossPlatformExec import org.jetbrains.SetupMaven - +import org.jetbrains.configurePublication val setupMaven by tasks.register("setupMaven") @@ -91,14 +90,4 @@ tasks.named("jar") { } } -publishing { - publications { - register("dokkaMavenPlugin") { - artifactId = "dokka-maven-plugin" - from(components["java"]) - artifact(sourceJar.get()) - } - } -} - -configureBintrayPublication("dokkaMavenPlugin") +configurePublication("dokka-maven-plugin") diff --git a/testApi/build.gradle.kts b/testApi/build.gradle.kts index c8b510a1..1576dd99 100644 --- a/testApi/build.gradle.kts +++ b/testApi/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configureBintrayPublication +import org.jetbrains.configurePublication plugins { `maven-publish` @@ -13,19 +13,4 @@ dependencies { implementation(kotlin("reflect")) } -val sourceJar by tasks.registering(Jar::class) { - archiveClassifier.set("sources") - from(sourceSets["main"].allSource) -} - -publishing { - publications { - register("dokkaTestAPI") { - artifactId = "dokka-test-api" - from(components["java"]) - artifact(sourceJar.get()) - } - } -} - -configureBintrayPublication("dokkaTestAPI") \ No newline at end of file +configurePublication("dokka-test-api") -- cgit From 7ff409fdf621932590dbf0118fff2c73dc76b951 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Tue, 14 Jul 2020 10:06:04 +0200 Subject: Adapt changes from "Simplify publishing configuration and enable sourcejars" --- build.gradle.kts | 2 + .../main/kotlin/org/jetbrains/BintrayPublishing.kt | 29 ----------- .../org/jetbrains/PublicationConfiguration.kt | 34 ------------- .../src/main/kotlin/org/jetbrains/publication.kt | 58 ++++++++++++++++++++++ core/build.gradle.kts | 6 ++- core/dependencies/build.gradle.kts | 8 ++- kotlin-analysis/build.gradle.kts | 6 ++- kotlin-analysis/dependencies/build.gradle.kts | 8 ++- plugins/base/build.gradle.kts | 6 ++- plugins/gfm/build.gradle.kts | 6 ++- plugins/javadoc/build.gradle.kts | 6 ++- plugins/jekyll/build.gradle.kts | 6 ++- plugins/kotlin-as-java/build.gradle.kts | 6 ++- plugins/mathjax/build.gradle.kts | 6 ++- runners/cli/build.gradle.kts | 8 ++- runners/gradle-plugin/build.gradle.kts | 4 +- runners/maven-plugin/build.gradle.kts | 11 ++-- testApi/build.gradle.kts | 6 ++- 18 files changed, 123 insertions(+), 93 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt delete mode 100644 buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/org/jetbrains/publication.kt (limited to 'runners/cli/build.gradle.kts') diff --git a/build.gradle.kts b/build.gradle.kts index 7cc0394f..c6335a31 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -42,6 +42,8 @@ subprojects { // Gradle metadata java { + @Suppress("UnstableApiUsage") + withSourcesJar() targetCompatibility = JavaVersion.VERSION_1_8 } } diff --git a/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt b/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt deleted file mode 100644 index 4180c445..00000000 --- a/buildSrc/src/main/kotlin/org/jetbrains/BintrayPublishing.kt +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains - -import com.jfrog.bintray.gradle.BintrayExtension -import org.gradle.api.Project -import org.gradle.kotlin.dsl.provideDelegate - -fun Project.configureBintrayPublication(vararg publications: String) { - val dokka_version: String by this - val dokka_publication_channel: String by this - extensions.configure("bintray") { - user = System.getenv("BINTRAY_USER") - key = System.getenv("BINTRAY_KEY") - dryRun = System.getenv("BINTRAY_DRY_RUN") == "true" || - project.properties["bintray_dry_run"] == "true" - pkg = PackageConfig().apply { - repo = dokka_publication_channel - name = "dokka" - userOrg = "kotlin" - desc = "Dokka, the Kotlin documentation tool" - vcsUrl = "https://github.com/kotlin/dokka.git" - setLicenses("Apache-2.0") - version = VersionConfig().apply { - name = dokka_version - } - } - setPublications(*publications) - } -} - diff --git a/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt b/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt deleted file mode 100644 index 5dbb8fb9..00000000 --- a/buildSrc/src/main/kotlin/org/jetbrains/PublicationConfiguration.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.jetbrains - -import com.github.jengelman.gradle.plugins.shadow.ShadowExtension -import org.gradle.api.Project -import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.plugins.JavaPluginExtension -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.get - -fun Project.configurePublication(artifactId: String, useShadow: Boolean = false) { - configure { - publications { - create("maven") { - this.artifactId = artifactId - if (useShadow) { - val shadow = extensions.getByType(ShadowExtension::class.java) - shadow.component(this) - } else { - from(components["java"]) - } - } - } - } - configureBintrayPublication("maven") - plugins.all { - if (this is JavaPlugin) { - val extension = extensions.getByType(JavaPluginExtension::class.java) - @Suppress("UnstableApiUsage") extension.withSourcesJar() - } - } -} diff --git a/buildSrc/src/main/kotlin/org/jetbrains/publication.kt b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt new file mode 100644 index 00000000..47fb23f2 --- /dev/null +++ b/buildSrc/src/main/kotlin/org/jetbrains/publication.kt @@ -0,0 +1,58 @@ +package org.jetbrains + +import com.github.jengelman.gradle.plugins.shadow.ShadowExtension +import com.jfrog.bintray.gradle.BintrayExtension +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.* + +class DokkaPublicationBuilder { + enum class Component { + Java, Shadow + } + var artifactId: String? = null + var component: Component = Component.Java +} + +fun Project.registerDokkaArtifactPublication(publicationName: String, configure: DokkaPublicationBuilder.() -> Unit) { + configure { + publications { + register(publicationName) { + val builder = DokkaPublicationBuilder().apply(configure) + this.artifactId = builder.artifactId + when (builder.component) { + DokkaPublicationBuilder.Component.Java -> from(components["java"]) + DokkaPublicationBuilder.Component.Shadow -> + extensions.getByType(ShadowExtension::class.java).component(this) + } + } + } + } + + configureBintrayPublication(publicationName) +} + +fun Project.configureBintrayPublication(vararg publications: String) { + val dokka_version: String by this + val dokka_publication_channel: String by this + extensions.configure("bintray") { + user = System.getenv("BINTRAY_USER") + key = System.getenv("BINTRAY_KEY") + dryRun = System.getenv("BINTRAY_DRY_RUN") == "true" || + project.properties["bintray_dry_run"] == "true" + pkg = PackageConfig().apply { + repo = dokka_publication_channel + name = "dokka" + userOrg = "kotlin" + desc = "Dokka, the Kotlin documentation tool" + vcsUrl = "https://github.com/kotlin/dokka.git" + setLicenses("Apache-2.0") + version = VersionConfig().apply { + name = dokka_version + } + } + setPublications(*publications) + } +} + diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 030db5c6..b52d3729 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication plugins { `maven-publish` @@ -29,4 +29,6 @@ tasks { } } -configurePublication("dokka-core") +registerDokkaArtifactPublication("dokkaCore") { + artifactId = "dokka-core" +} diff --git a/core/dependencies/build.gradle.kts b/core/dependencies/build.gradle.kts index 082861b6..a074958d 100644 --- a/core/dependencies/build.gradle.kts +++ b/core/dependencies/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.configurePublication +import org.jetbrains.DokkaPublicationBuilder.Component.Shadow +import org.jetbrains.registerDokkaArtifactPublication plugins { id("com.github.johnrengelman.shadow") @@ -28,4 +29,7 @@ tasks { } } -configurePublication("dokka-core-dependencies", useShadow = true) +registerDokkaArtifactPublication("dokkaCoreDependencies") { + artifactId = "dokka-core-dependencies" + component = Shadow +} diff --git a/kotlin-analysis/build.gradle.kts b/kotlin-analysis/build.gradle.kts index 5acc1f06..f87811e1 100644 --- a/kotlin-analysis/build.gradle.kts +++ b/kotlin-analysis/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication plugins { id("com.github.johnrengelman.shadow") @@ -15,4 +15,6 @@ dependencies { api(project(":kotlin-analysis:dependencies", configuration = "shadow")) } -configurePublication("dokka-analysis") +registerDokkaArtifactPublication("dokkaAnalysis") { + artifactId = "dokka-analysis" +} diff --git a/kotlin-analysis/dependencies/build.gradle.kts b/kotlin-analysis/dependencies/build.gradle.kts index 1fd13630..4aba6614 100644 --- a/kotlin-analysis/dependencies/build.gradle.kts +++ b/kotlin-analysis/dependencies/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.configurePublication +import org.jetbrains.DokkaPublicationBuilder.Component.Shadow +import org.jetbrains.registerDokkaArtifactPublication plugins { id("com.github.johnrengelman.shadow") @@ -53,4 +54,7 @@ tasks { } } -configurePublication("kotlin-analysis-dependencies", useShadow = true) +registerDokkaArtifactPublication("kotlinAnalysisDependencies"){ + artifactId = "kotlin-analysis-dependencies" + component = Shadow +} diff --git a/plugins/base/build.gradle.kts b/plugins/base/build.gradle.kts index 61e2ef01..0fc7f55c 100644 --- a/plugins/base/build.gradle.kts +++ b/plugins/base/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication plugins { id("com.jfrog.bintray") @@ -30,4 +30,6 @@ tasks { } } -configurePublication("dokka-base") +registerDokkaArtifactPublication("dokkaBase") { + artifactId = "dokka-base" +} diff --git a/plugins/gfm/build.gradle.kts b/plugins/gfm/build.gradle.kts index 73958046..3f69043d 100644 --- a/plugins/gfm/build.gradle.kts +++ b/plugins/gfm/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication dependencies { implementation(project(":plugins:base")) @@ -6,4 +6,6 @@ dependencies { testImplementation(project(":plugins:base:test-utils")) } -configurePublication("gfm-plugin") +registerDokkaArtifactPublication("gfmPlugin") { + artifactId = "gfm-plugin" +} diff --git a/plugins/javadoc/build.gradle.kts b/plugins/javadoc/build.gradle.kts index 5846ee62..5e2e5600 100644 --- a/plugins/javadoc/build.gradle.kts +++ b/plugins/javadoc/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication dependencies { implementation("com.soywiz.korlibs.korte:korte-jvm:1.10.3") @@ -10,4 +10,6 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") } -configurePublication("javadoc-plugin") +registerDokkaArtifactPublication("javadocPlugin") { + artifactId = "javadoc-plugin" +} diff --git a/plugins/jekyll/build.gradle.kts b/plugins/jekyll/build.gradle.kts index 0d1e38d6..64cf9800 100644 --- a/plugins/jekyll/build.gradle.kts +++ b/plugins/jekyll/build.gradle.kts @@ -1,8 +1,10 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication dependencies { implementation(project(":plugins:base")) implementation(project(":plugins:gfm")) } -configurePublication("jekyll-plugin") +registerDokkaArtifactPublication("jekyllPlugin") { + artifactId = "jekyll-plugin" +} diff --git a/plugins/kotlin-as-java/build.gradle.kts b/plugins/kotlin-as-java/build.gradle.kts index 27e90f84..eda6114f 100644 --- a/plugins/kotlin-as-java/build.gradle.kts +++ b/plugins/kotlin-as-java/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication dependencies { implementation(project(":plugins:base")) @@ -7,4 +7,6 @@ dependencies { testImplementation(project(":test-tools")) } -configurePublication("kotlin-as-java-plugin") +registerDokkaArtifactPublication("kotlinAsJavaPlugin") { + artifactId = "kotlin-as-java-plugin" +} diff --git a/plugins/mathjax/build.gradle.kts b/plugins/mathjax/build.gradle.kts index ea4cdff0..142e7dc4 100644 --- a/plugins/mathjax/build.gradle.kts +++ b/plugins/mathjax/build.gradle.kts @@ -1,3 +1,5 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication -configurePublication("mathjax-plugin") +registerDokkaArtifactPublication("mathjaxPlugin") { + artifactId = "mathjax-plugin" +} diff --git a/runners/cli/build.gradle.kts b/runners/cli/build.gradle.kts index 19a49346..4ad34192 100644 --- a/runners/cli/build.gradle.kts +++ b/runners/cli/build.gradle.kts @@ -1,4 +1,5 @@ -import org.jetbrains.configurePublication +import org.jetbrains.DokkaPublicationBuilder.Component.Shadow +import org.jetbrains.registerDokkaArtifactPublication plugins { id("com.github.johnrengelman.shadow") @@ -26,5 +27,8 @@ tasks { } } -configurePublication("dokka-cli", useShadow = true) +registerDokkaArtifactPublication("dokkaCli"){ + artifactId = "dokka-cli" + component = Shadow +} diff --git a/runners/gradle-plugin/build.gradle.kts b/runners/gradle-plugin/build.gradle.kts index 00e3602e..0222f5e0 100644 --- a/runners/gradle-plugin/build.gradle.kts +++ b/runners/gradle-plugin/build.gradle.kts @@ -47,15 +47,13 @@ gradlePlugin { publishing { publications { - maybeCreate("pluginMaven").apply { + register("pluginMaven") { artifactId = "dokka-gradle-plugin" - artifact(sourceJar.get()) } register("dokkaGradlePluginForIntegrationTests") { artifactId = "dokka-gradle-plugin" from(components["java"]) - artifact(sourceJar.get()) version = "for-integration-tests-SNAPSHOT" } } diff --git a/runners/maven-plugin/build.gradle.kts b/runners/maven-plugin/build.gradle.kts index 83d9f5af..fbd2b48a 100644 --- a/runners/maven-plugin/build.gradle.kts +++ b/runners/maven-plugin/build.gradle.kts @@ -1,6 +1,6 @@ import org.jetbrains.CrossPlatformExec import org.jetbrains.SetupMaven -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication val setupMaven by tasks.register("setupMaven") @@ -45,7 +45,10 @@ val generatePom by tasks.registering(Copy::class) { line.replace("dokka_version", "$dokka_version") } filter { line -> - line.replace("maven-plugin-plugin", "${setupMaven.mavenPluginToolsVersion}") + line.replace( + "maven-plugin-plugin", + "${setupMaven.mavenPluginToolsVersion}" + ) } } } @@ -90,4 +93,6 @@ tasks.named("jar") { } } -configurePublication("dokka-maven-plugin") +registerDokkaArtifactPublication("dokkaMavenPlugin") { + artifactId = "dokka-maven-plugin" +} diff --git a/testApi/build.gradle.kts b/testApi/build.gradle.kts index 1576dd99..fc882f44 100644 --- a/testApi/build.gradle.kts +++ b/testApi/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.configurePublication +import org.jetbrains.registerDokkaArtifactPublication plugins { `maven-publish` @@ -13,4 +13,6 @@ dependencies { implementation(kotlin("reflect")) } -configurePublication("dokka-test-api") +registerDokkaArtifactPublication("dokkaTestApi") { + artifactId = "dokka-test-api" +} -- cgit