Use JSON as the format for the Kotlin project structure metadata
This commit is contained in:
+6
-9
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.internals.MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
||||
import org.jetbrains.kotlin.gradle.internals.parseKotlinSourceSetMetadataFromXml
|
||||
import org.jetbrains.kotlin.gradle.internals.MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME
|
||||
import org.jetbrains.kotlin.gradle.internals.parseKotlinSourceSetMetadataFromJson
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.ModuleDependencyIdentifier
|
||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.gradle.util.checkedReplace
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
@@ -216,7 +215,7 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
)
|
||||
).use { publishedMetadataJar ->
|
||||
publishedMetadataJar.checkAllEntryNamesArePresent(
|
||||
"META-INF/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME",
|
||||
"META-INF/$MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME",
|
||||
|
||||
"commonMain/default/manifest",
|
||||
"commonMain/default/linkdata/package_com.example/",
|
||||
@@ -254,7 +253,7 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
)
|
||||
).use { publishedMetadataJar ->
|
||||
publishedMetadataJar.checkAllEntryNamesArePresent(
|
||||
"META-INF/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME",
|
||||
"META-INF/$MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME",
|
||||
|
||||
"commonMain/default/manifest",
|
||||
"commonMain/default/linkdata/package_com.example.bar/",
|
||||
@@ -441,10 +440,8 @@ class HierarchicalMppIT : BaseGradleIT() {
|
||||
}
|
||||
|
||||
private fun ZipFile.getProjectStructureMetadata(): KotlinProjectStructureMetadata {
|
||||
val documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
val document = getInputStream(getEntry("META-INF/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME"))
|
||||
.use { inputStream -> documentBuilder.parse(inputStream) }
|
||||
return checkNotNull(parseKotlinSourceSetMetadataFromXml(document))
|
||||
val json = getInputStream(getEntry("META-INF/$MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME")).reader().readText()
|
||||
return checkNotNull(parseKotlinSourceSetMetadataFromJson(json))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+5
-9
@@ -26,19 +26,15 @@ open class GenerateProjectStructureMetadata : DefaultTask() {
|
||||
|
||||
@get:OutputFile
|
||||
val resultXmlFile: File
|
||||
get() = project.buildDir.resolve("kotlinProjectStructureMetadata/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME")
|
||||
get() = project.buildDir.resolve("kotlinProjectStructureMetadata/$MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME")
|
||||
|
||||
@TaskAction
|
||||
fun generateMetadataXml() {
|
||||
resultXmlFile.parentFile.mkdirs()
|
||||
|
||||
val document = kotlinProjectStructureMetadata.toXmlDocument()
|
||||
|
||||
TransformerFactory.newInstance().newTransformer().apply {
|
||||
setOutputProperty(OutputKeys.INDENT, "yes")
|
||||
setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4")
|
||||
}.transform(DOMSource(document), StreamResult(resultXmlFile))
|
||||
val resultString = kotlinProjectStructureMetadata.toJson()
|
||||
resultXmlFile.writeText(resultString)
|
||||
}
|
||||
}
|
||||
|
||||
internal const val MULTIPLATFORM_PROJECT_METADATA_FILE_NAME = "kotlin-project-structure-metadata.xml"
|
||||
internal const val MULTIPLATFORM_PROJECT_METADATA_FILE_NAME = "kotlin-project-structure-metadata.xml"
|
||||
internal const val MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME = "kotlin-project-structure-metadata.json"
|
||||
+12
-7
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.util.*
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
@@ -344,16 +345,20 @@ private class JarArtifactMppDependencyMetadataExtractor(
|
||||
|
||||
val metadataArtifactBySourceSet: MutableMap<String, File> = mutableMapOf()
|
||||
|
||||
private fun parseJsonProjectStructureMetadata(input: InputStream) =
|
||||
parseKotlinSourceSetMetadataFromJson(input.reader().readText())
|
||||
|
||||
private fun parseXmlProjectStructureMetadata(input: InputStream) =
|
||||
parseKotlinSourceSetMetadataFromXml(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input))
|
||||
|
||||
override fun getProjectStructureMetadata(): KotlinProjectStructureMetadata? {
|
||||
return ZipFile(primaryArtifact).use { zip ->
|
||||
val metadata = zip.getEntry("META-INF/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME")
|
||||
?: return null
|
||||
val (metadata, parseFunction) =
|
||||
zip.getEntry("META-INF/$MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME")?.to(::parseJsonProjectStructureMetadata)
|
||||
?: zip.getEntry("META-INF/$MULTIPLATFORM_PROJECT_METADATA_FILE_NAME")?.to(::parseXmlProjectStructureMetadata)
|
||||
?: return null
|
||||
|
||||
val metadataXmlDocument = zip.getInputStream(metadata).use { inputStream ->
|
||||
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream)
|
||||
}
|
||||
|
||||
parseKotlinSourceSetMetadataFromXml(metadataXmlDocument)
|
||||
zip.getInputStream(metadata).use(parseFunction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+113
-62
@@ -5,6 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
@@ -18,6 +22,7 @@ import org.w3c.dom.Document
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.StringWriter
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
||||
data class ModuleDependencyIdentifier(
|
||||
@@ -34,6 +39,8 @@ sealed class SourceSetMetadataLayout(
|
||||
object METADATA : SourceSetMetadataLayout("metadata", "jar")
|
||||
object KLIB : SourceSetMetadataLayout("klib", "klib")
|
||||
|
||||
override fun toString(): String = name
|
||||
|
||||
companion object {
|
||||
private val values = listOf(METADATA, KLIB)
|
||||
|
||||
@@ -119,41 +126,40 @@ internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjec
|
||||
)
|
||||
}
|
||||
|
||||
internal fun KotlinProjectStructureMetadata.toXmlDocument(): Document {
|
||||
return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().apply {
|
||||
fun Node.node(name: String, action: Element.() -> Unit) = appendChild(createElement(name).apply(action))
|
||||
fun Node.textNode(name: String, value: String) =
|
||||
appendChild(createElement(name).apply { appendChild(createTextNode(value)) })
|
||||
internal fun <Serializer> KotlinProjectStructureMetadata.serialize(
|
||||
serializer: Serializer,
|
||||
node: Serializer.(name: String, Serializer.() -> Unit) -> Unit,
|
||||
multiNodes: Serializer.(name: String, Serializer.() -> Unit) -> Unit,
|
||||
multiNodesItem: Serializer.(name: String, Serializer.() -> Unit) -> Unit,
|
||||
value: Serializer.(key: String, value: String) -> Unit,
|
||||
multiValue: Serializer.(name: String, values: List<String>) -> Unit
|
||||
) = with(serializer) {
|
||||
node(ROOT_NODE_NAME) {
|
||||
value(FORMAT_VERSION_NODE_NAME, formatVersion)
|
||||
|
||||
node(ROOT_NODE_NAME) {
|
||||
textNode(FORMAT_VERSION_NODE_NAME, formatVersion)
|
||||
|
||||
node(VARIANTS_NODE_NAME) {
|
||||
sourceSetNamesByVariantName.forEach { (variantName, sourceSets) ->
|
||||
node(VARIANT_NODE_NAME) {
|
||||
textNode(NAME_NODE_NAME, variantName)
|
||||
sourceSets.forEach { sourceSetName -> textNode(SOURCE_SET_NODE_NAME, sourceSetName) }
|
||||
}
|
||||
multiNodes(VARIANTS_NODE_NAME) {
|
||||
sourceSetNamesByVariantName.forEach { (variantName, sourceSets) ->
|
||||
multiNodesItem(VARIANT_NODE_NAME) {
|
||||
value(NAME_NODE_NAME, variantName)
|
||||
multiValue(SOURCE_SET_NODE_NAME, sourceSets.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node(SOURCE_SETS_NODE_NAME) {
|
||||
val keys = sourceSetsDependsOnRelation.keys + sourceSetModuleDependencies.keys
|
||||
for (sourceSet in keys) {
|
||||
node(SOURCE_SET_NODE_NAME) {
|
||||
textNode(NAME_NODE_NAME, sourceSet)
|
||||
sourceSetsDependsOnRelation[sourceSet].orEmpty().forEach { dependsOn ->
|
||||
textNode(DEPENDS_ON_NODE_NAME, dependsOn)
|
||||
}
|
||||
sourceSetModuleDependencies[sourceSet].orEmpty().forEach { moduleDependency ->
|
||||
textNode(MODULE_DEPENDENCY_NODE_NAME, moduleDependency.groupId + ":" + moduleDependency.moduleId)
|
||||
}
|
||||
sourceSetBinaryLayout[sourceSet]?.let { binaryLayout ->
|
||||
textNode(BINARY_LAYOUT_NODE_NAME, binaryLayout.name)
|
||||
}
|
||||
if (sourceSet in hostSpecificSourceSets) {
|
||||
textNode(HOST_SPECIFIC_NODE_NAME, "true")
|
||||
}
|
||||
multiNodes(SOURCE_SETS_NODE_NAME) {
|
||||
val keys = sourceSetsDependsOnRelation.keys + sourceSetModuleDependencies.keys
|
||||
for (sourceSet in keys) {
|
||||
multiNodesItem(SOURCE_SET_NODE_NAME) {
|
||||
value(NAME_NODE_NAME, sourceSet)
|
||||
multiValue(DEPENDS_ON_NODE_NAME, sourceSetsDependsOnRelation[sourceSet].orEmpty().toList())
|
||||
multiValue(MODULE_DEPENDENCY_NODE_NAME, sourceSetModuleDependencies[sourceSet].orEmpty().map { moduleDependency ->
|
||||
moduleDependency.groupId + ":" + moduleDependency.moduleId
|
||||
})
|
||||
sourceSetBinaryLayout[sourceSet]?.let { binaryLayout ->
|
||||
value(BINARY_LAYOUT_NODE_NAME, binaryLayout.name)
|
||||
}
|
||||
if (sourceSet in hostSpecificSourceSets) {
|
||||
value(HOST_SPECIFIC_NODE_NAME, "true")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,21 +167,76 @@ internal fun KotlinProjectStructureMetadata.toXmlDocument(): Document {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KotlinProjectStructureMetadata.toXmlDocument(): Document {
|
||||
return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument().apply {
|
||||
val node: Node.(String, Node.() -> Unit) -> Unit = { name, content -> appendChild(createElement(name).apply(content)) }
|
||||
val textNode: Node.(String, String) -> Unit =
|
||||
{ name, value -> appendChild(createElement(name).apply { appendChild(createTextNode(value)) }) }
|
||||
serialize(this as Node, node, node, node, textNode, { name, values -> for (v in values) textNode(name, v) })
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KotlinProjectStructureMetadata.toJson(): String {
|
||||
val gson = GsonBuilder().setPrettyPrinting().create()
|
||||
val stringWriter = StringWriter()
|
||||
with(gson.newJsonWriter(stringWriter)) {
|
||||
val obj: JsonWriter.(String, JsonWriter.() -> Unit) -> Unit =
|
||||
{ name, content -> if (name.isNotEmpty()) name(name); beginObject(); content(); endObject() }
|
||||
val property: JsonWriter.(String, String) -> Unit = { name, value -> name(name); value(value) }
|
||||
val array: JsonWriter.(String, JsonWriter.() -> Unit) -> Unit =
|
||||
{ name, contents -> name(name); beginArray(); contents(); endArray() }
|
||||
|
||||
beginObject()
|
||||
serialize(this, obj, array, { _, fn -> obj("", fn) }, property, { key, values -> array(key) { values.forEach { value(it) } } })
|
||||
endObject()
|
||||
}
|
||||
return stringWriter.toString()
|
||||
}
|
||||
|
||||
private val NodeList.elements: Iterable<Element> get() = (0 until length).map { this@elements.item(it) }.filterIsInstance<Element>()
|
||||
|
||||
internal fun parseKotlinSourceSetMetadataFromJson(string: String): KotlinProjectStructureMetadata? {
|
||||
@Suppress("DEPRECATION") // The replacement doesn't compile against old dependencies such as AS 4.0
|
||||
val json = JsonParser().parse(string).asJsonObject
|
||||
val nodeNamed: JsonObject.(String) -> JsonObject? = { name -> get(name)?.asJsonObject }
|
||||
val valueNamed: JsonObject.(String) -> String? = { name -> get(name)?.asString }
|
||||
val multiObjects: JsonObject.(String?) -> Iterable<JsonObject> = { name -> get(name).asJsonArray.map { it.asJsonObject } }
|
||||
val multiValues: JsonObject.(String?) -> Iterable<String> = { name -> get(name).asJsonArray.map { it.asString } }
|
||||
|
||||
return parseKotlinSourceSetMetadata({ json.get(ROOT_NODE_NAME).asJsonObject }, valueNamed, multiObjects, multiValues)
|
||||
}
|
||||
|
||||
internal fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata? {
|
||||
val projectStructureNode = document.getElementsByTagName(ROOT_NODE_NAME).elements.single()
|
||||
val nodeNamed: Element.(String) -> Element? = { name -> getElementsByTagName(name).elements.singleOrNull() }
|
||||
val valueNamed: Element.(String) -> String? =
|
||||
{ name -> getElementsByTagName(name).run { if (length > 0) item(0).textContent else null } }
|
||||
val multiObjects: Element.(String) -> Iterable<Element> = { name -> nodeNamed(name)?.childNodes?.elements ?: emptyList()}
|
||||
val multiValues: Element.(String) -> Iterable<String> = { name -> getElementsByTagName(name).elements.map { it.textContent } }
|
||||
|
||||
val formatVersion = projectStructureNode.getElementsByTagName(FORMAT_VERSION_NODE_NAME).item(0).textContent
|
||||
return parseKotlinSourceSetMetadata(
|
||||
{ document.getElementsByTagName(ROOT_NODE_NAME).elements.single() },
|
||||
valueNamed,
|
||||
multiObjects,
|
||||
multiValues
|
||||
)
|
||||
}
|
||||
|
||||
val variantsNode = projectStructureNode.getElementsByTagName(VARIANTS_NODE_NAME).item(0) ?: return null
|
||||
internal fun <ParsingContext> parseKotlinSourceSetMetadata(
|
||||
getRoot: () -> ParsingContext,
|
||||
valueNamed: ParsingContext.(key: String) -> String?,
|
||||
multiObjects: ParsingContext.(named: String) -> Iterable<ParsingContext>,
|
||||
multiValues: ParsingContext.(named: String) -> Iterable<String>
|
||||
): KotlinProjectStructureMetadata? {
|
||||
val projectStructureNode = getRoot()
|
||||
|
||||
val formatVersion = checkNotNull(projectStructureNode.valueNamed(FORMAT_VERSION_NODE_NAME))
|
||||
val variantsNode = projectStructureNode.multiObjects(VARIANTS_NODE_NAME)
|
||||
|
||||
val sourceSetsByVariant = mutableMapOf<String, Set<String>>()
|
||||
|
||||
variantsNode.childNodes.elements.filter { it.tagName == VARIANT_NODE_NAME }.forEach { variantNode ->
|
||||
val variantName = variantNode.getElementsByTagName(NAME_NODE_NAME).elements.single().textContent
|
||||
val sourceSets =
|
||||
variantNode.childNodes.elements.filter { it.tagName == SOURCE_SET_NODE_NAME }.mapTo(mutableSetOf()) { it.textContent }
|
||||
variantsNode.forEach { variantNode ->
|
||||
val variantName = requireNotNull(variantNode.valueNamed(NAME_NODE_NAME))
|
||||
val sourceSets = variantNode.multiValues(SOURCE_SET_NODE_NAME).toSet()
|
||||
|
||||
sourceSetsByVariant[variantName] = sourceSets
|
||||
}
|
||||
@@ -185,34 +246,24 @@ internal fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProj
|
||||
val sourceSetBinaryLayout = mutableMapOf<String, SourceSetMetadataLayout>()
|
||||
val hostSpecificSourceSets = mutableSetOf<String>()
|
||||
|
||||
val sourceSetsNode = projectStructureNode.getElementsByTagName(SOURCE_SETS_NODE_NAME).item(0) ?: return null
|
||||
val sourceSetsNode = projectStructureNode.multiObjects(SOURCE_SETS_NODE_NAME)
|
||||
|
||||
sourceSetsNode.childNodes.elements.filter { it.tagName == SOURCE_SET_NODE_NAME }.forEach { sourceSetNode ->
|
||||
val sourceSetName = sourceSetNode.getElementsByTagName(NAME_NODE_NAME).elements.single().textContent
|
||||
sourceSetsNode.forEach { sourceSetNode ->
|
||||
val sourceSetName = checkNotNull(sourceSetNode.valueNamed(NAME_NODE_NAME))
|
||||
|
||||
val dependsOn = mutableSetOf<String>()
|
||||
val moduleDependencies = mutableSetOf<ModuleDependencyIdentifier>()
|
||||
|
||||
sourceSetNode.childNodes.elements.forEach { node ->
|
||||
when (node.tagName) {
|
||||
DEPENDS_ON_NODE_NAME -> dependsOn.add(node.textContent)
|
||||
MODULE_DEPENDENCY_NODE_NAME -> {
|
||||
val (groupId, moduleId) = node.textContent.split(":")
|
||||
moduleDependencies.add(ModuleDependencyIdentifier(groupId, moduleId))
|
||||
}
|
||||
BINARY_LAYOUT_NODE_NAME -> {
|
||||
SourceSetMetadataLayout.byName(node.textContent)?.let { binaryLayout ->
|
||||
sourceSetBinaryLayout[sourceSetName] = binaryLayout
|
||||
}
|
||||
}
|
||||
HOST_SPECIFIC_NODE_NAME -> {
|
||||
if (node.textContent == "true") {
|
||||
hostSpecificSourceSets.add(sourceSetName)
|
||||
}
|
||||
}
|
||||
}
|
||||
val dependsOn = sourceSetNode.multiValues(DEPENDS_ON_NODE_NAME).toSet()
|
||||
val moduleDependencies = sourceSetNode.multiValues(MODULE_DEPENDENCY_NODE_NAME).mapTo(mutableSetOf()) {
|
||||
val (groupId, moduleId) = it.split(":")
|
||||
ModuleDependencyIdentifier(groupId, moduleId)
|
||||
}
|
||||
|
||||
sourceSetNode.valueNamed(HOST_SPECIFIC_NODE_NAME)
|
||||
?.let { if (it.toBoolean()) hostSpecificSourceSets.add(sourceSetName) }
|
||||
|
||||
sourceSetNode.valueNamed(BINARY_LAYOUT_NODE_NAME)
|
||||
?.let { SourceSetMetadataLayout.byName(it) }
|
||||
?.let { sourceSetBinaryLayout[sourceSetName] = it }
|
||||
|
||||
sourceSetDependsOnRelation[sourceSetName] = dependsOn
|
||||
sourceSetModuleDependencies[sourceSetName] = moduleDependencies
|
||||
}
|
||||
|
||||
+1
-1
@@ -197,7 +197,7 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
|
||||
allMetadataJar.configure {
|
||||
it.from(generateMetadata.map { it.resultXmlFile }) { spec ->
|
||||
spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_FILE_NAME }
|
||||
spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -9,14 +9,13 @@ import org.jetbrains.kotlin.gradle.plugin.KOTLIN_12X_MPP_DEPRECATION_WARNING
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.NO_NATIVE_STDLIB_PROPERTY_WARNING
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.NO_NATIVE_STDLIB_WARNING
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinProjectStructureMetadata
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.parseKotlinSourceSetMetadataFromXml
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.parseKotlinSourceSetMetadataFromJson
|
||||
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
||||
import org.w3c.dom.Document
|
||||
|
||||
fun parseKotlinSourceSetMetadataFromXml(document: Document): KotlinProjectStructureMetadata? = parseKotlinSourceSetMetadataFromXml(document)
|
||||
fun parseKotlinSourceSetMetadataFromJson(json: String): KotlinProjectStructureMetadata? = parseKotlinSourceSetMetadataFromJson(json)
|
||||
|
||||
const val MULTIPLATFORM_PROJECT_METADATA_FILE_NAME = MULTIPLATFORM_PROJECT_METADATA_FILE_NAME
|
||||
const val MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME = MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME
|
||||
|
||||
const val DISABLED_NATIVE_TARGETS_REPORTER_DISABLE_WARNING_PROPERTY_NAME = DisabledNativeTargetsReporter.DISABLE_WARNING_PROPERTY_NAME
|
||||
|
||||
|
||||
Reference in New Issue
Block a user