Skip to content

Commit 4ad9831

Browse files
authored
Relaxed expect requirement (#352)
1 parent 08b7f1d commit 4ad9831

8 files changed

Lines changed: 17 additions & 33 deletions

File tree

demo-project/kmp/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ gradle.projectsEvaluated {
4545
}
4646

4747
buildConfig {
48-
buildConfigField("COMMON_VALUE", expect("aCommonValue")) // a constant for all platforms
48+
buildConfigField("COMMON_VALUE", "aCommonValue") // a constant for all platforms
49+
buildConfigField("PROVIDED_VALUE", lazyProvidedValue) // a provided constant for all platforms
4950
buildConfigField("PLATFORM", expect<String>()) // expect a platform specific value
5051
buildConfigField("DEBUG", expect(false)) // expect with a default
5152
buildConfigField("com.eygraber.uri.Uri", "ENDPOINT",
@@ -73,7 +74,6 @@ buildConfig {
7374

7475
sourceSets.named("test") {
7576
buildConfigField("TEST_VALUE", "aTestValue")
76-
buildConfigField("PROVIDED_VALUE", lazyProvidedValue)
7777
}
7878

7979
sourceSets.named("jvmMain") {

demo-project/kmp/src/commonTest/kotlin/com/github/gmazzo/buildconfig/demos/kmp/CommonBuildConfigTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ abstract class CommonBuildConfigTest(
1919
assertEquals(expectedDebug, BuildConfig.DEBUG)
2020
assertEquals(expectedUri, BuildConfig.ENDPOINT)
2121
assertEquals(expectedProduct, BuildConfig.PRODUCT_VALUE)
22+
assertEquals("aLazyProvidedValue", BuildConfig.PROVIDED_VALUE)
2223
}
2324

2425
@Test
@@ -35,7 +36,6 @@ abstract class CommonBuildConfigTest(
3536
@Test
3637
fun testTestProperties() {
3738
assertEquals("aTestValue", TestBuildConfig.TEST_VALUE)
38-
assertEquals("aLazyProvidedValue", TestBuildConfig.PROVIDED_VALUE)
3939
}
4040

4141
}

plugin/api/plugin.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ public abstract interface class com/github/gmazzo/buildconfig/BuildConfigClassSp
77
public fun buildConfigField (Ljava/lang/String;Ljava/lang/String;Lorg/gradle/api/provider/Provider;)Lcom/github/gmazzo/buildconfig/BuildConfigField;
88
public fun buildConfigField (Ljava/lang/String;Lorg/gradle/api/Action;)Lcom/github/gmazzo/buildconfig/BuildConfigField;
99
public fun className (Ljava/lang/String;)Lcom/github/gmazzo/buildconfig/BuildConfigClassSpec;
10+
public fun expect ()Ljava/io/Serializable;
1011
public fun expect (Lcom/github/gmazzo/buildconfig/BuildConfigValue;)Lcom/github/gmazzo/buildconfig/BuildConfigValue$Expect;
1112
public fun expect (Ljava/io/Serializable;)Ljava/io/Serializable;
12-
public static synthetic fun expect$default (Lcom/github/gmazzo/buildconfig/BuildConfigClassSpec;Ljava/io/Serializable;ILjava/lang/Object;)Ljava/io/Serializable;
1313
public fun expression (Ljava/lang/String;)Lcom/github/gmazzo/buildconfig/BuildConfigValue$Expression;
1414
public fun generator (Lcom/github/gmazzo/buildconfig/generators/BuildConfigGenerator;)Lcom/github/gmazzo/buildconfig/BuildConfigClassSpec;
1515
public abstract fun getBuildConfigFields ()Lorg/gradle/api/NamedDomainObjectContainer;

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/BuildConfigClassSpec.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ public interface BuildConfigClassSpec : Named {
160160
BuildConfigValue.Expression(expression)
161161

162162
@Suppress("UNCHECKED_CAST")
163-
public fun <Type : Serializable?> expect(defaultsTo: Type? = null): Type =
163+
public fun <Type : Serializable?> expect(): Type =
164+
BuildConfigValue.Expect(value = null) as Type
165+
166+
@Suppress("UNCHECKED_CAST")
167+
public fun <Type : Serializable?> expect(defaultsTo: Type?): Type =
164168
expect(BuildConfigValue.Literal(defaultsTo)) as Type
165169

166170
public fun expect(defaultsTo: BuildConfigValue): BuildConfigValue.Expect =

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/BuildConfigField.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.github.gmazzo.buildconfig
22

3-
import com.github.gmazzo.buildconfig.generators.BuildConfigKotlinGenerator
43
import com.github.gmazzo.buildconfig.internal.nameOf
54
import java.io.Serializable
65
import java.lang.reflect.Type
@@ -59,9 +58,6 @@ public interface BuildConfigField : Named, Comparable<BuildConfigField> {
5958
public fun value(literal: Serializable?): BuildConfigField = apply {
6059
value.value(
6160
when (literal) {
62-
is BuildConfigValue.Expect -> literal.also {
63-
tags.add(BuildConfigKotlinGenerator.TagExpect)
64-
}
6561
is BuildConfigValue -> literal
6662
else -> BuildConfigValue.Literal(literal)
6763
}

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/BuildConfigPlugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public class BuildConfigPlugin : Plugin<Project> {
163163
it.type.finalizeValueOnRead()
164164
it.value.finalizeValueOnRead()
165165
it.position.finalizeValueOnRead()
166-
it.tags.finalizeValueOnRead()
166+
// it.tags.finalizeValueOnRead() // tags can be modified later (e.g., to add expect/actual)
167167
}
168168

169169
/**

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/generators/BuildConfigKotlinGenerator.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ public open class BuildConfigKotlinGenerator(
7272
.writeTo(spec.outputDir)
7373
}
7474

75-
private fun Iterable<BuildConfigField>.asPropertiesSpec() = map { field ->
75+
private fun Iterable<BuildConfigField>.asPropertiesSpec() = mapNotNull { field ->
7676
try {
7777
val (expect, actual) = field.tags.getOrElse(emptySet())
7878
.let { tags -> (TagExpect in tags) to (TagActual in tags) }
79-
val value = field.value.get().unwrap()
79+
val value = field.value.get().let { (it as? BuildConfigValue.Expect)?.value ?: it }
8080
val typeName = field.type.get().toTypeName()
8181
.let { it.copy(nullable = it.isNullable || (!expect && value.value == null)) }
8282

@@ -105,7 +105,7 @@ public open class BuildConfigKotlinGenerator(
105105
is BuildConfigValue.Expect -> error("Field '${field.name}' should be have an expect value here: ${value}")
106106
}
107107
}
108-
return@map prop.build()
108+
return@mapNotNull prop.build()
109109

110110
} catch (e: Exception) {
111111
throw IllegalArgumentException(
@@ -115,9 +115,6 @@ public open class BuildConfigKotlinGenerator(
115115
}
116116
}
117117

118-
private fun BuildConfigValue.unwrap() =
119-
if (this is BuildConfigValue.Expect) value!! else this
120-
121118
private fun BuildConfigType.toTypeName(): TypeName {
122119
val kotlinClassName = runCatching { Class.forName(className).kotlin.qualifiedName!! }.getOrDefault(className)
123120
var type: TypeName = when (kotlinClassName.lowercase()) {

plugin/src/main/kotlin/com/github/gmazzo/buildconfig/internal/bindings/KotlinBinder.kt

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ internal object KotlinBinder {
116116

117117
val dependsOn = spec.allDependsOn
118118
.filter { !it.isSuperseded }
119-
.filter { it.hasExpects() }
120119
.toSet()
121120

122121
if (dependsOn.isNotEmpty()) {
@@ -133,7 +132,6 @@ internal object KotlinBinder {
133132
spec.extraSpecs.asSequence().map { extra ->
134133
extra to specDependsOn
135134
.mapNotNull { it.extraSpecs.findByName(extra.name) }
136-
.filter { it.hasExpects() }
137135
.toSet()
138136
}
139137
}
@@ -158,10 +156,7 @@ internal object KotlinBinder {
158156
for (dependsOnSpec in dependsOnSpecs) {
159157
val dependsOnField = dependsOnSpec.buildConfigFields.findByName(field.name) ?: continue
160158

161-
check(dependsOnField.isExpect) {
162-
"Field '${dependsOnField.name}' in '$dependsOnSpec' must be `expect`, since it's defined as `actual` in '$spec'"
163-
}
164-
159+
dependsOnField.tags.add(BuildConfigKotlinGenerator.TagExpect)
165160
field.tags.add(BuildConfigKotlinGenerator.TagActual)
166161
expectSpecs.add(dependsOnSpec)
167162

@@ -173,7 +168,8 @@ internal object KotlinBinder {
173168
// then, in case we have mixed expect and regular constants in the same spec, we promote them all to this spec
174169
for (expectSpec in expectSpecs) {
175170
for (expectField in expectSpec.buildConfigFields) {
176-
if (expectField.isExpectNoDefault) continue
171+
expectField.tags.add(BuildConfigKotlinGenerator.TagExpect)
172+
177173
if (spec.buildConfigFields.names.contains(expectField.name)) continue
178174

179175
spec.buildConfigField(expectField).tags.add(BuildConfigKotlinGenerator.TagActual)
@@ -188,8 +184,8 @@ internal object KotlinBinder {
188184
for (expectSpec in dependsOnSpecs) {
189185
for (expectField in expectSpec.buildConfigFields) {
190186
if (spec.buildConfigFields.names.contains(expectField.name)) continue
191-
if (expectField.isExpectNoDefault) continue
192187

188+
expectField.tags.add(BuildConfigKotlinGenerator.TagExpect)
193189
spec.buildConfigField(expectField)
194190
.tags.add(BuildConfigKotlinGenerator.TagActual)
195191

@@ -200,18 +196,9 @@ internal object KotlinBinder {
200196
}
201197
}
202198

203-
private fun BuildConfigClassSpec.hasExpects() =
204-
buildConfigFields.any { it.isExpect }
205-
206199
private fun BuildConfigClassSpec.hasActuals() =
207200
buildConfigFields.any { it.isActual }
208201

209-
private val BuildConfigField.isExpect: Boolean
210-
get() = BuildConfigKotlinGenerator.TagExpect in tags.get()
211-
212-
private val BuildConfigField.isExpectNoDefault: Boolean
213-
get() = isExpect && value.get().value == null
214-
215202
private val BuildConfigField.isActual: Boolean
216203
get() = BuildConfigKotlinGenerator.TagActual in tags.get()
217204

0 commit comments

Comments
 (0)