aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/build.gradle.kts4
-rw-r--r--core/src/main/kotlin/configuration.kt17
-rw-r--r--core/src/main/kotlin/defaultConfiguration.kt35
-rw-r--r--core/src/main/kotlin/plugability/DokkaPlugin.kt30
-rw-r--r--core/src/main/kotlin/utilities/json.kt59
-rw-r--r--core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt68
6 files changed, 154 insertions, 59 deletions
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index fcb616e1..5051707b 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -3,15 +3,13 @@ import org.jetbrains.registerDokkaArtifactPublication
plugins {
`maven-publish`
id("com.jfrog.bintray")
- kotlin("plugin.serialization")
}
dependencies {
api("org.jetbrains:markdown:0.1.45")
implementation(kotlin("reflect"))
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0-1.4-M3")
- implementation("com.google.code.gson:gson:2.8.5")
implementation("org.jsoup:jsoup:1.12.1")
+ implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1")
testImplementation(project(":testApi"))
testImplementation(kotlin("test-junit"))
diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt
index bdb493b8..08a3f07a 100644
--- a/core/src/main/kotlin/configuration.kt
+++ b/core/src/main/kotlin/configuration.kt
@@ -2,10 +2,8 @@
package org.jetbrains.dokka
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.UnstableDefault
-import kotlinx.serialization.json.Json
-import kotlinx.serialization.json.JsonConfiguration
+import org.jetbrains.dokka.utilities.toJsonString
+import org.jetbrains.dokka.utilities.parseJson
import java.io.File
import java.net.URL
@@ -52,7 +50,6 @@ enum class Platform(val key: String) {
}
}
-@Serializable
data class DokkaSourceSetID(
val moduleName: String,
val sourceSetName: String
@@ -62,10 +59,12 @@ data class DokkaSourceSetID(
}
}
-@OptIn(UnstableDefault::class)
-fun DokkaConfigurationImpl(input: String): DokkaConfigurationImpl {
- val json = Json(JsonConfiguration.Default.copy(ignoreUnknownKeys = true))
- return json.parse(DokkaConfigurationImpl.serializer(), input)
+fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl {
+ return parseJson(json)
+}
+
+fun DokkaConfiguration.toJsonString(): String {
+ return toJsonString(this)
}
interface DokkaConfiguration {
diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt
index 4730bab4..8e38e8d5 100644
--- a/core/src/main/kotlin/defaultConfiguration.kt
+++ b/core/src/main/kotlin/defaultConfiguration.kt
@@ -1,23 +1,20 @@
package org.jetbrains.dokka
-import kotlinx.serialization.*
import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import java.io.File
import java.net.URL
-@Serializable
data class DokkaConfigurationImpl(
override val outputDir: String = DokkaDefaults.outputDir,
override val cacheRoot: String? = DokkaDefaults.cacheRoot,
override val offlineMode: Boolean = DokkaDefaults.offlineMode,
override val sourceSets: List<DokkaSourceSetImpl> = emptyList(),
- override val pluginsClasspath: List<@Serializable(with = FileSerializer::class) File> = emptyList(),
+ override val pluginsClasspath: List<File> = emptyList(),
override val pluginsConfiguration: Map<String, String> = emptyMap(),
override val modules: List<DokkaModuleDescriptionImpl> = emptyList(),
override val failOnWarning: Boolean = DokkaDefaults.failOnWarning
) : DokkaConfiguration
-@Serializable
data class DokkaSourceSetImpl(
override val moduleDisplayName: String,
override val displayName: String = DokkaDefaults.sourceSetDisplayName,
@@ -44,19 +41,16 @@ data class DokkaSourceSetImpl(
override val analysisPlatform: Platform = DokkaDefaults.analysisPlatform
) : DokkaSourceSet
-@Serializable
data class DokkaModuleDescriptionImpl(
override val name: String,
override val path: String,
override val docFile: String
) : DokkaConfiguration.DokkaModuleDescription
-@Serializable
data class SourceRootImpl(
override val path: String
) : DokkaConfiguration.SourceRoot
-@Serializable
data class SourceLinkDefinitionImpl(
override val path: String,
override val url: String,
@@ -73,7 +67,6 @@ data class SourceLinkDefinitionImpl(
}
}
-@Serializable
data class PackageOptionsImpl(
override val prefix: String,
override val includeNonPublic: Boolean,
@@ -82,28 +75,8 @@ data class PackageOptionsImpl(
override val suppress: Boolean
) : DokkaConfiguration.PackageOptions
-@Serializable
+
data class ExternalDocumentationLinkImpl(
- @Serializable(with = URLSerializer::class) override val url: URL,
- @Serializable(with = URLSerializer::class) override val packageListUrl: URL
+ override val url: URL,
+ override val packageListUrl: URL
) : DokkaConfiguration.ExternalDocumentationLink
-
-private object FileSerializer : KSerializer<File> {
- override val descriptor: SerialDescriptor = PrimitiveDescriptor("File", PrimitiveKind.STRING)
-
- override fun serialize(encoder: Encoder, value: File) {
- encoder.encodeString(value.path)
- }
-
- override fun deserialize(decoder: Decoder): File = File(decoder.decodeString())
-}
-
-private object URLSerializer : KSerializer<URL> {
- override val descriptor: SerialDescriptor = PrimitiveDescriptor("URL", PrimitiveKind.STRING)
-
- override fun serialize(encoder: Encoder, value: URL) {
- encoder.encodeString(value.toString())
- }
-
- override fun deserialize(decoder: Decoder): URL = URL(decoder.decodeString())
-}
diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt
index 2c755a49..a62327d2 100644
--- a/core/src/main/kotlin/plugability/DokkaPlugin.kt
+++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt
@@ -1,7 +1,8 @@
package org.jetbrains.dokka.plugability
-import com.google.gson.Gson
import org.jetbrains.dokka.DokkaConfiguration
+import org.jetbrains.dokka.utilities.parseJson
+import org.jetbrains.dokka.utilities.toJsonString
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
@@ -15,13 +16,12 @@ abstract class DokkaPlugin {
protected inline fun <reified T : DokkaPlugin> plugin(): T = context?.plugin(T::class) ?: throwIllegalQuery()
- protected fun <T : Any> extensionPoint() =
- object : ReadOnlyProperty<DokkaPlugin, ExtensionPoint<T>> {
- override fun getValue(thisRef: DokkaPlugin, property: KProperty<*>) = ExtensionPoint<T>(
- thisRef::class.qualifiedName ?: throw AssertionError("Plugin must be named class"),
- property.name
- )
- }
+ protected fun <T : Any> extensionPoint() = ReadOnlyProperty<DokkaPlugin, ExtensionPoint<T>> { thisRef, property ->
+ ExtensionPoint(
+ thisRef::class.qualifiedName ?: throw AssertionError("Plugin must be named class"),
+ property.name
+ )
+ }
protected fun <T : Any> extending(definition: ExtendingDSL.() -> Extension<T, *, *>) = ExtensionProvider(definition)
@@ -58,7 +58,7 @@ inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> Configurable
val instance = T::class.createInstance().apply(block)
val mutablePluginsConfiguration = pluginsConfiguration as MutableMap<String, String>
- mutablePluginsConfiguration[P::class.qualifiedName!!] = Gson().toJson(instance, T::class.java)
+ mutablePluginsConfiguration[P::class.qualifiedName!!] = toJsonString(instance)
}
inline fun <reified P : DokkaPlugin, reified E : Any> P.query(extension: P.() -> ExtensionPoint<E>): List<E> =
@@ -71,12 +71,10 @@ fun throwIllegalQuery(): Nothing =
throw IllegalStateException("Querying about plugins is only possible with dokka context initialised")
inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): ReadOnlyProperty<Any?, R> {
- return object : ReadOnlyProperty<Any?, R> {
- override fun getValue(thisRef: Any?, property: KProperty<*>): R {
- return context.configuration.pluginsConfiguration[T::class.qualifiedName
- ?: throw AssertionError("Plugin must be named class")].let {
- Gson().fromJson(it, R::class.java)
- }
- }
+ return ReadOnlyProperty { _, _ ->
+ val configuration = context.configuration.pluginsConfiguration[
+ T::class.qualifiedName ?: throw AssertionError("Plugin must be named class")
+ ]
+ parseJson(checkNotNull(configuration))
}
}
diff --git a/core/src/main/kotlin/utilities/json.kt b/core/src/main/kotlin/utilities/json.kt
new file mode 100644
index 00000000..d2e70d75
--- /dev/null
+++ b/core/src/main/kotlin/utilities/json.kt
@@ -0,0 +1,59 @@
+package org.jetbrains.dokka.utilities
+
+import com.fasterxml.jackson.core.JsonGenerator
+import com.fasterxml.jackson.databind.*
+import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper
+import com.fasterxml.jackson.databind.module.SimpleModule
+import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
+import java.io.File
+import java.lang.reflect.Type
+import com.fasterxml.jackson.core.type.TypeReference as JacksonTypeReference
+
+private val objectMapper = run {
+ val module = SimpleModule().apply {
+ addSerializer(FileSerializer)
+ }
+ jacksonObjectMapper()
+ .registerModule(module)
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+}
+
+@PublishedApi
+internal class TypeReference<T> private constructor(
+ internal val jackson: JacksonTypeReference<T>
+) {
+ companion object {
+ @OptIn(ExperimentalStdlibApi::class)
+ internal inline operator fun <reified T> invoke(): TypeReference<T> = TypeReference(jacksonTypeRef())
+ }
+}
+
+@PublishedApi
+internal fun toJsonString(value: Any): String = objectMapper.writeValueAsString(value)
+
+@PublishedApi
+internal inline fun <reified T : Any> parseJson(json: String): T {
+ return parseJson(json, TypeReference())
+}
+
+@PublishedApi
+internal fun <T : Any> parseJson(json: String, typeReference: TypeReference<T>): T {
+ return objectMapper.readValue(json, typeReference.jackson)
+}
+
+private object FileSerializer : StdScalarSerializer<File>(File::class.java) {
+ override fun serialize(value: File, g: JsonGenerator, provider: SerializerProvider) {
+ g.writeString(value.path)
+ }
+
+ override fun getSchema(provider: SerializerProvider, typeHint: Type): JsonNode {
+ return createSchemaNode("string", true)
+ }
+
+ @Throws(JsonMappingException::class)
+ override fun acceptJsonFormatVisitor(visitor: JsonFormatVisitorWrapper, typeHint: JavaType) {
+ visitStringFormat(visitor, typeHint)
+ }
+}
diff --git a/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt b/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt
new file mode 100644
index 00000000..d0cb55a1
--- /dev/null
+++ b/core/src/test/kotlin/utilities/DokkaConfigurationJsonTest.kt
@@ -0,0 +1,68 @@
+package utilities
+
+import org.jetbrains.dokka.*
+import java.io.File
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class DokkaConfigurationJsonTest {
+ @Test
+ fun `simple configuration toJsonString then parseJson`() {
+ val configuration = DokkaConfigurationImpl(
+ outputDir = "customOutputDir",
+ pluginsClasspath = listOf(File("plugins/customPlugin.jar")),
+ sourceSets = listOf(
+ DokkaSourceSetImpl(
+ moduleDisplayName = "customModuleDisplayName",
+ sourceRoots = listOf(SourceRootImpl("customSourceRoot")),
+ sourceSetID = DokkaSourceSetID("customModuleName", "customSourceSetName")
+ )
+ )
+ )
+
+ val jsonString = configuration.toJsonString()
+ val parsedConfiguration = DokkaConfigurationImpl(jsonString)
+ assertEquals(configuration, parsedConfiguration)
+ }
+
+ @Test
+ fun `parse simple configuration json`() {
+ val json = """
+ {
+ "outputDir": "customOutputDir",
+ "pluginsClasspath": [ "plugins/customPlugin.jar" ],
+ "sourceSets": [
+ {
+ "moduleDisplayName": "customModuleDisplayName",
+ "sourceSetID": {
+ "moduleName": "customModuleName",
+ "sourceSetName": "customSourceSetName"
+ },
+ "classpath": [],
+ "sourceRoots": [
+ {
+ "path": "customSourceRoot"
+ }
+ ]
+ }
+ ]
+ }
+ """.trimIndent()
+
+ val parsedConfiguration = DokkaConfigurationImpl(json)
+ assertEquals(
+ DokkaConfigurationImpl(
+ outputDir = "customOutputDir",
+ pluginsClasspath = listOf(File("plugins/customPlugin.jar")),
+ sourceSets = listOf(
+ DokkaSourceSetImpl(
+ moduleDisplayName = "customModuleDisplayName",
+ sourceRoots = listOf(SourceRootImpl("customSourceRoot")),
+ sourceSetID = DokkaSourceSetID("customModuleName", "customSourceSetName")
+ )
+ )
+ ),
+ parsedConfiguration
+ )
+ }
+}