Skip to content

Commit

Permalink
Merge pull request #18 from icerockdev/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex009 authored Aug 24, 2021
2 parents a06c8a9 + 5245680 commit 8e0be09
Show file tree
Hide file tree
Showing 21 changed files with 343 additions and 103 deletions.
98 changes: 82 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ buildscript {
maven("https://jitpack.io")
}
dependencies {
classpath("dev.icerock.moko:kswift-gradle-plugin:0.2.0")
classpath("dev.icerock.moko:kswift-gradle-plugin:0.3.0")
}
}
```
Expand Down Expand Up @@ -99,7 +99,7 @@ project where framework compiles `build.gradle`

```groovy
plugins {
id("dev.icerock.moko.kswift") version "0.2.0"
id("dev.icerock.moko.kswift") version "0.3.0"
}
```

Expand All @@ -119,7 +119,7 @@ project `build.gradle`

```groovy
dependencies {
commonMainApi("dev.icerock.moko:kswift-runtime:0.2.0") // if you want use annotations
commonMainApi("dev.icerock.moko:kswift-runtime:0.3.0") // if you want use annotations
}
```

Expand All @@ -129,12 +129,20 @@ dependencies {

Enable feature in project `build.gradle`:

```groovy
kotlin:
```kotlin
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature)
}
```

groovy:
```groovy
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature.factory)
}
```

That's all - after this setup all sealed classes and sealed interfaces will be parsed by plugin and
plugin will generate Swift enums for this classes.

Expand Down Expand Up @@ -182,34 +190,62 @@ For each generated entry in comment generated `selector` - value of this selecto
filter. By default all entries generated. But if generated code invalid (please report issue in this
case) you can disable generation of this particular entry:

```groovy
kotlin:
```kotlin
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature) {
filter = excludeFilter("ClassContext/moko-kswift.sample:mpp-library-pods/com/icerockdev/library/UIState")
}
}
```

groovy:
```groovy
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature.factory) {
it.filter = it.excludeFilter("ClassContext/moko-kswift.sample:mpp-library-pods/com/icerockdev/library/UIState")
}
}
```

As alternative you can use `includeFilter` to explicit setup each required for generation entries:

```groovy
kotlin:
```kotlin
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature) {
filter = includeFilter("ClassContext/moko-kswift.sample:mpp-library-pods/com/icerockdev/library/UIState")
}
}
```

groovy:
```groovy
kswift {
install(dev.icerock.moko.kswift.plugin.feature.SealedToSwiftEnumFeature.factory) {
it.filter = it.includeFilter("ClassContext/moko-kswift.sample:mpp-library-pods/com/icerockdev/library/UIState")
}
}
```

## Extensions from platform classes

Enable feature in project `build.gradle`:

```groovy
kotlin:
```kotlin
kswift {
install(dev.icerock.moko.kswift.plugin.feature.PlatformExtensionFunctionsFeature)
}
```

groovy:
```groovy
kswift {
install(dev.icerock.moko.kswift.plugin.feature.PlatformExtensionFunctionsFeature.factory)
}
```

That's all - after this setup all extension functions for classes from `platform.*` package will be
correct swift code.

Expand Down Expand Up @@ -259,11 +295,9 @@ repositories {
}
dependencies {
implementation("com.android.tools.build:gradle:7.1.0-alpha06")
implementation("com.android.tools.build:gradle:7.0.0")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
implementation("dev.icerock.moko:kswift-gradle-plugin:0.2.0")
implementation("com.github.icerockdev:swiftpoet:1.1.2")
implementation("org.jetbrains.kotlinx:kotlinx-metadata-klib:0.0.1")
}
```

Expand All @@ -277,7 +311,10 @@ import io.outfoxx.swiftpoet.DeclaredTypeName
import io.outfoxx.swiftpoet.ExtensionSpec
import io.outfoxx.swiftpoet.FileSpec

class MyKSwiftGenerator(filter: Filter<ClassContext>) : ProcessorFeature<ClassContext>(filter) {
class MyKSwiftGenerator(
override val featureContext: KClass<ClassContext>,
override val filter: Filter<ClassContext>
) : ProcessorFeature<ClassContext>() {
override fun doProcess(featureContext: ClassContext, processorContext: ProcessorContext) {
val fileSpec: FileSpec.Builder = processorContext.fileSpecBuilder
val frameworkName: String = processorContext.framework.baseName
Expand All @@ -293,15 +330,20 @@ class MyKSwiftGenerator(filter: Filter<ClassContext>) : ProcessorFeature<ClassCo
)
}

class Config(
var filter: Filter<ClassContext> = Filter.Exclude(emptySet())
)
class Config : BaseConfig<ClassContext> {
override var filter: Filter<ClassContext> = Filter.Exclude(emptySet())
}

companion object : Factory<ClassContext, MyKSwiftGenerator, Config> {
override fun create(block: Config.() -> Unit): MyKSwiftGenerator {
val config = Config().apply(block)
return MyKSwiftGenerator(config.filter)
return MyKSwiftGenerator(featureContext, config.filter)
}

override val featureContext: KClass<ClassContext> = ClassContext::class

@JvmStatic
override val factory = Companion
}
}
```
Expand All @@ -311,12 +353,36 @@ required `Context` to got required info from klib metadata.

last step - enable feature in gradle:

```groovy
kotlin:
```kotlin
kswift {
install(MyKSwiftGenerator)
}
```

groovy:
```groovy
kswift {
install(MyKSwiftGenerator.factory)
}
```

## Set iOS deployment target for podspec

kotlin:
```kotlin
kswift {
iosDeploymentTarget.set("11.0")
}
```

groovy:
```groovy
kswift {
iosDeploymentTarget = "11.0"
}
```

# FAQ

## Where destination directory for all generated sources?
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ androidLifecycleVersion = "2.1.0"
androidCoreTestingVersion = "2.1.0"
coroutinesVersion = "1.5.0-native-mt"
mokoTestVersion = "0.4.0"
mokoKSwiftVersion = "0.2.0"
mokoKSwiftVersion = "0.3.0"

mokoMvvmVersion = "0.11.0"
mokoResourcesVersion = "0.16.2"
Expand Down
8 changes: 5 additions & 3 deletions kswift-gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ group = "dev.icerock.moko"
version = libs.versions.mokoKSwiftVersion.get()

dependencies {
implementation(gradleKotlinDsl())
compileOnly(libs.kotlinGradlePlugin)
implementation(libs.swiftPoet)

implementation(gradleKotlinDsl())
implementation(libs.kotlinCompilerEmbeddable)
implementation(libs.kotlinxMetadataKLib)

api(libs.swiftPoet)
api(libs.kotlinxMetadataKLib)

testImplementation(libs.kotlinTestJUnit)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class KLibProcessor(
private val extension: KSwiftExtension
) {
private val features: Map<KClass<out FeatureContext>, List<ProcessorFeature<*>>>
get() = extension.features
get() = extension.features.groupBy { it.featureContext }

fun processFeatureContext(library: File, outputDir: File, framework: Framework) {
@Suppress("TooGenericExceptionCaught")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,31 @@
package dev.icerock.moko.kswift.plugin

import dev.icerock.moko.kswift.plugin.context.FeatureContext
import dev.icerock.moko.kswift.plugin.feature.BaseConfig
import dev.icerock.moko.kswift.plugin.feature.ProcessorFeature
import kotlin.reflect.KClass
import org.gradle.api.DomainObjectSet
import org.gradle.api.provider.Property

open class KSwiftExtension {
internal val features: MutableMap<KClass<out FeatureContext>, List<ProcessorFeature<*>>> =
mutableMapOf()
abstract class KSwiftExtension {
abstract val features: DomainObjectSet<ProcessorFeature<*>>

internal val excludedLibs = mutableListOf<String>()
internal val includedLibs = mutableListOf<String>()
abstract val excludedLibs: DomainObjectSet<String>
abstract val includedLibs: DomainObjectSet<String>

fun <CTX : FeatureContext, F : ProcessorFeature<CTX>, Config> install(
featureContext: KClass<out CTX>,
featureFactory: ProcessorFeature.Factory<CTX, F, Config>,
config: Config.() -> Unit = {}
) {
val currentList: List<ProcessorFeature<*>> = features[featureContext] ?: emptyList()
val processorFeature: ProcessorFeature<CTX> = featureFactory.create(config)
features[featureContext] = currentList.plus(processorFeature)
}
abstract val projectPodspecName: Property<String>
abstract val iosDeploymentTarget: Property<String>

inline fun <reified CTX : FeatureContext, F : ProcessorFeature<CTX>, Config> install(
featureFactory: ProcessorFeature.Factory<CTX, F, Config>,
noinline config: Config.() -> Unit = {}
fun <CTX : FeatureContext, Config : BaseConfig<CTX>> install(
featureFactory: ProcessorFeature.Factory<CTX, *, Config>
) {
install(CTX::class, featureFactory, config)
}

fun <CTX : FeatureContext> excludeFilter(vararg names: String): ProcessorFeature.Filter.Exclude<CTX> {
return ProcessorFeature.Filter.Exclude(names.toSet())
features.add(featureFactory.create { })
}

fun <CTX : FeatureContext> includeFilter(vararg names: String): ProcessorFeature.Filter.Include<CTX> {
return ProcessorFeature.Filter.Include(names.toSet())
fun <CTX : FeatureContext, Config : BaseConfig<CTX>> install(
featureFactory: ProcessorFeature.Factory<CTX, *, Config>,
config: Config.() -> Unit
) {
features.add(featureFactory.create(config))
}

fun includeLibrary(libraryName: String) {
Expand All @@ -47,6 +39,4 @@ open class KSwiftExtension {
fun excludeLibrary(libraryName: String) {
excludedLibs.add(libraryName)
}

lateinit var projectPodspecName: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package dev.icerock.moko.kswift.plugin
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
Expand All @@ -18,7 +19,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
open class KSwiftPlugin : Plugin<Project> {
override fun apply(target: Project) {
val extension = target.extensions.create<KSwiftExtension>("kswift")
extension.projectPodspecName = target.name.replace('-', '_')
val podspecNameDefault = target.name.replace('-', '_')
extension.projectPodspecName.set(podspecNameDefault)

val processor = KLibProcessor(
logger = target.logger,
Expand All @@ -29,7 +31,7 @@ open class KSwiftPlugin : Plugin<Project> {
.withType<KotlinMultiplatformPluginWrapper>()
.configureEach { pluginWrapper ->
val multiplatformExtension = target.extensions
.getByType(pluginWrapper.projectExtensionClass.java)
.getByType(pluginWrapper.projectExtensionClass)

applyToKotlinMultiplatform(multiplatformExtension, processor, extension)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ open class KSwiftPodspecTask : DefaultTask() {
internal lateinit var kSwiftExtension: KSwiftExtension

private val projectPodspecName: String
get() = kSwiftExtension.projectPodspecName
get() = kSwiftExtension.projectPodspecName.get()

private val iosDeploymentTarget: String?
get() = kSwiftExtension.iosDeploymentTarget.orNull

private val moduleName: String
get() = "${linkTask.baseName}Swift"
Expand Down Expand Up @@ -54,7 +57,10 @@ open class KSwiftPodspecTask : DefaultTask() {
fun execute() {
frameworkDir.copyRecursively(outputCocoapodsDir, true)

val isStatic = linkTask.isStaticFramework
val isStatic: Boolean = linkTask.isStaticFramework
val iosDeploymentString: String = iosDeploymentTarget?.let {
"spec.ios.deployment_target = '$it'"
}.orEmpty()

@Suppress("MaxLineLength")
outputPodspec.writeText(
Expand All @@ -68,7 +74,8 @@ open class KSwiftPodspecTask : DefaultTask() {
spec.license = ''
spec.summary = 'Some description for a Kotlin/Native module'
spec.module_name = "$moduleName"
$iosDeploymentString
spec.static_framework = $isStatic
spec.dependency '$projectPodspecName'
spec.source_files = "build/cocoapods/framework/$moduleName/**/*.{h,m,swift}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

package dev.icerock.moko.kswift.plugin

import io.outfoxx.swiftpoet.ANY_OBJECT
import io.outfoxx.swiftpoet.BOOL
import io.outfoxx.swiftpoet.DeclaredTypeName
import io.outfoxx.swiftpoet.FunctionTypeName
Expand Down Expand Up @@ -43,6 +44,7 @@ fun KmType.toTypeName(moduleName: String, isUsedInGenerics: Boolean = false): Ty
returnType = outputType
).makeEscaping()
}
"kotlin/Any" -> ANY_OBJECT
else -> {
if (classifierName.startsWith("platform/")) {
DeclaredTypeName.typeName(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2021 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
*/

package dev.icerock.moko.kswift.plugin.feature

import dev.icerock.moko.kswift.plugin.context.FeatureContext

interface BaseConfig<CTX : FeatureContext> {
val filter: Filter<CTX>

fun excludeFilter(vararg names: String): Filter.Exclude<CTX> {
return Filter.Exclude(names.toSet())
}

fun includeFilter(vararg names: String): Filter.Include<CTX> {
return Filter.Include(names.toSet())
}
}
Loading

0 comments on commit 8e0be09

Please sign in to comment.