Model mapping: support Android targets
This commit is contained in:
+6
-5
@@ -330,7 +330,7 @@ open class DefaultCompilationDetails<T : KotlinCommonOptions>(
|
||||
}
|
||||
}
|
||||
|
||||
internal open class DefaultCompilationDetailsWithRuntime<T : KotlinCommonOptions>(
|
||||
open class DefaultCompilationDetailsWithRuntime<T : KotlinCommonOptions>(
|
||||
target: KotlinTarget,
|
||||
compilationPurpose: String,
|
||||
createKotlinOptions: DefaultCompilationDetails<*>.() -> T
|
||||
@@ -517,18 +517,19 @@ internal class WithJavaCompilationDetails<T : KotlinCommonOptions>(
|
||||
}
|
||||
}
|
||||
|
||||
internal class AndroidCompilationDetails(
|
||||
class AndroidCompilationDetails(
|
||||
target: KotlinTarget,
|
||||
compilationPurpose: String,
|
||||
/** Workaround mutual creation order: a compilation is not added to the target's compilations collection until some point, pass it here */
|
||||
private val getCompilationInstance: () -> KotlinJvmAndroidCompilation
|
||||
) : DefaultCompilationDetailsWithRuntime<KotlinJvmOptions>(
|
||||
target,
|
||||
compilationPurpose,
|
||||
{ KotlinJvmOptionsImpl() }
|
||||
) {
|
||||
override val compilation: KotlinJvmAndroidCompilation
|
||||
get() = super.compilation as KotlinJvmAndroidCompilation
|
||||
override val compilation: KotlinJvmAndroidCompilation get() = getCompilationInstance()
|
||||
|
||||
val androidVariant = compilation.androidVariant
|
||||
val androidVariant get() = compilation.androidVariant
|
||||
|
||||
override val friendArtifacts: FileCollection
|
||||
get() = target.project.files(super.friendArtifacts, compilation.testedVariantArtifacts)
|
||||
|
||||
+2
-1
@@ -19,11 +19,12 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.unambiguousNameInProject
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.createDefaultSourceDirectorySet
|
||||
|
||||
class FragmentMappedKotlinSourceSet(
|
||||
private val sourceSetName: String,
|
||||
private val project: Project,
|
||||
internal val underlyingFragment: KotlinGradleFragment
|
||||
) : KotlinSourceSet {
|
||||
val displayName: String
|
||||
get() = underlyingFragment.unambiguousNameInProject
|
||||
get() = sourceSetName
|
||||
|
||||
override val apiConfigurationName: String get() = underlyingFragment.apiConfigurationName
|
||||
override val implementationConfigurationName: String get() = underlyingFragment.implementationConfigurationName
|
||||
|
||||
+1
-1
@@ -21,6 +21,6 @@ class FragmentMappedKotlinSourceSetFactory constructor(private val project: Proj
|
||||
val modules = project.kpmModules
|
||||
val fragment = modules.maybeCreate(moduleName).fragments.maybeCreate(fragmentName)
|
||||
/** TODO setup JS-specific attributes similar to [org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory]*/
|
||||
return FragmentMappedKotlinSourceSet(project, fragment)
|
||||
return FragmentMappedKotlinSourceSet(name, project, fragment)
|
||||
}
|
||||
}
|
||||
+31
-3
@@ -9,6 +9,9 @@ import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules
|
||||
|
||||
interface SourceSetMappedFragmentLocator {
|
||||
@@ -34,16 +37,41 @@ private class MultiplatformSourceSetMappedFragmentLocator : SourceSetMappedFragm
|
||||
override fun locateFragmentForSourceSet(project: Project, sourceSetName: String): SourceSetMappedFragmentLocator.FragmentLocation? {
|
||||
val camelCaseParts = sourceSetName.camelCaseParts()
|
||||
if (camelCaseParts.size < 2) {
|
||||
return null
|
||||
SourceSetMappedFragmentLocator.FragmentLocation(KotlinGradleModule.MAIN_MODULE_NAME, sourceSetName)
|
||||
}
|
||||
|
||||
val androidTarget = when (val ext = project.topLevelExtension) {
|
||||
is KotlinAndroidProjectExtension -> ext.target
|
||||
is KotlinMultiplatformExtension ->
|
||||
ext.targets.withType(KotlinAndroidTarget::class.java).singleOrNull()
|
||||
?: ext.presets.withType(KotlinAndroidTargetPreset::class.java).single().targetUnderConstruction
|
||||
else -> null
|
||||
}
|
||||
|
||||
val candidateModuleNames = (1..camelCaseParts.size).asSequence().map { camelCaseParts.takeLast(it).joinToString("").decapitalize() }
|
||||
|
||||
val moduleName =
|
||||
candidateModuleNames.firstOrNull { project.kpmModules.findByName(it) != null } ?: candidateModuleNames.first()
|
||||
val fragmentName = sourceSetName.dropLast(moduleName.length)
|
||||
run {
|
||||
if (androidTarget != null && sourceSetName.startsWith(androidTarget.name))
|
||||
androidSourceSetModuleName(androidTarget.name, sourceSetName)
|
||||
else null
|
||||
} ?: candidateModuleNames.firstOrNull { project.kpmModules.findByName(it) != null }
|
||||
?: KotlinGradleModule.MAIN_MODULE_NAME
|
||||
|
||||
val fragmentName =
|
||||
if (sourceSetName.endsWith(moduleName, ignoreCase = true)) sourceSetName.dropLast(moduleName.length) else sourceSetName
|
||||
|
||||
return SourceSetMappedFragmentLocator.FragmentLocation(moduleName, fragmentName)
|
||||
}
|
||||
|
||||
private fun androidSourceSetModuleName(targetName: String, sourceSetName: String): String? {
|
||||
val compilationName = sourceSetName.removePrefix(targetName).takeIf { it != sourceSetName } ?: return null
|
||||
return when {
|
||||
"Test" in compilationName -> "test"
|
||||
else -> KotlinGradleModule.MAIN_MODULE_NAME
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.camelCaseParts(): List<String> {
|
||||
val capitalizedMatches = Regex("[A-Z][^A-Z]*").findAll(this).toList()
|
||||
val firstNonCapitalizedWord = capitalizedMatches.firstOrNull()?.let { substring(it.range.first) } ?: this
|
||||
|
||||
+14
@@ -9,6 +9,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinAndroidPlugin.Companion.dynamicallyApplyWhenAndroidPluginIsApplied
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.PublicationRegistrationMode
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.mapTargetCompilationsToKpmVariants
|
||||
|
||||
class KotlinAndroidTargetPreset(
|
||||
private val project: Project
|
||||
@@ -20,12 +23,23 @@ class KotlinAndroidTargetPreset(
|
||||
val result = KotlinAndroidTarget(name, project).apply {
|
||||
disambiguationClassifier = name
|
||||
preset = this@KotlinAndroidTargetPreset
|
||||
targetUnderConstruction = this
|
||||
}
|
||||
|
||||
project.dynamicallyApplyWhenAndroidPluginIsApplied({ result })
|
||||
|
||||
if (project.hasKpmModel) {
|
||||
mapTargetCompilationsToKpmVariants(result, PublicationRegistrationMode.AFTER_EVALUATE)
|
||||
}
|
||||
|
||||
targetUnderConstruction = null
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/** This is a way to check if there's an Android target being configured now despite it not being added to the `kotlin.targets` yet */
|
||||
internal var targetUnderConstruction: KotlinAndroidTarget? = null
|
||||
|
||||
companion object {
|
||||
const val PRESET_NAME = "android"
|
||||
}
|
||||
|
||||
+2
-3
@@ -18,9 +18,8 @@ import org.jetbrains.kotlin.gradle.plugin.getJavaTaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.getTestedVariantData
|
||||
|
||||
class KotlinJvmAndroidCompilation(
|
||||
target: KotlinAndroidTarget,
|
||||
name: String
|
||||
) : AbstractKotlinCompilationToRunnableFiles<KotlinJvmOptions>(AndroidCompilationDetails(target, name)) {
|
||||
compilationDetails: AndroidCompilationDetails
|
||||
) : AbstractKotlinCompilationToRunnableFiles<KotlinJvmOptions>(compilationDetails) {
|
||||
|
||||
lateinit var androidVariant: BaseVariant
|
||||
internal set
|
||||
|
||||
+6
-2
@@ -16,6 +16,10 @@ class KotlinJvmAndroidCompilationFactory(
|
||||
override val itemClass: Class<KotlinJvmAndroidCompilation>
|
||||
get() = KotlinJvmAndroidCompilation::class.java
|
||||
|
||||
override fun create(name: String): KotlinJvmAndroidCompilation =
|
||||
KotlinJvmAndroidCompilation(target, name)
|
||||
override fun create(name: String): KotlinJvmAndroidCompilation {
|
||||
lateinit var result: KotlinJvmAndroidCompilation
|
||||
val details = AndroidCompilationDetails(target, name) { result }
|
||||
result = KotlinJvmAndroidCompilation(details)
|
||||
return result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user