diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 1971e11..13bfecc 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -16,17 +16,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- - uses: actions/setup-java@v2
- with:
- distribution: 'zulu'
- java-version: '19'
- - uses: gradle/gradle-build-action@v2
- with:
- arguments: check --continue --stacktrace -Pkotshi.createAnnotationsUsingConstructor=false
- testWithAnnotations:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
distribution: 'zulu'
@@ -34,17 +23,6 @@ jobs:
- uses: gradle/gradle-build-action@v2
with:
arguments: check --continue --stacktrace
- testWithLegacyDataClassRenderer:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-java@v2
- with:
- distribution: 'zulu'
- java-version: '19'
- - uses: gradle/gradle-build-action@v2
- with:
- arguments: check --continue --stacktrace -Pkotshi.useLegacyDataClassRenderer=true
testOldestSupportedMoshi:
runs-on: ubuntu-latest
steps:
@@ -58,7 +36,7 @@ jobs:
arguments: check --continue --stacktrace -Pkotshi.internal.useLegacyMoshi=true
deploySnapshot:
runs-on: ubuntu-latest
- needs: [test, testWithAnnotations, testWithLegacyDataClassRenderer, testOldestSupportedMoshi]
+ needs: [test, testOldestSupportedMoshi]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
diff --git a/README.md b/README.md
index 186c90b..1d75ecb 100644
--- a/README.md
+++ b/README.md
@@ -106,69 +106,6 @@ that extends `JsonAdapter` with `@RegisterJsonAdapter` and Kotshi will generate
### Options
-#### `kotshi.createAnnotationsUsingConstructor`
-This option enables a new way of creating annotations instances at runtime. Normally Kotshi uses reflection to create
-the qualifier annotations but as of 1.5.30 of Kotlin you can enable creating annotations by calling the constructor.
-
-This behavior is enabled by default when using language version 1.6 but can be explicitly enabled or disabled using this
-option.
-
-Examples:
-
- KSP
-
- ```kotlin
- ksp {
- arg("kotshi.createAnnotationsUsingConstructor", "false")
- }
- ```
-
-
-
-
- KAPT
-
- ```kotlin
- kapt {
- arguments {
- arg("kotshi.createAnnotationsUsingConstructor", false)
- }
- }
- ```
-
-
-See more about instantiating annotations here: https://kotlinlang.org/docs/whatsnew1530.html#instantiation-of-annotation-classes
-
-#### `kotshi.useLegacyDataClassRenderer`
-This option allows you to use the old way of creating classes with parameters that has default values.
-
-From 2.10.0 reflection is used create data classes, but by setting this option to `true` the old behavior can be used
-instead which used the `copy` method.
-
-Examples:
-
- KSP
-
- ```kotlin
- ksp {
- arg("kotshi.createAnnotationsUsingConstructor", "false")
- }
- ```
-
-
-
-
- KAPT
-
- ```kotlin
- kapt {
- arguments {
- arg("kotshi.useLegacyDataClassRenderer", true)
- }
- }
- ```
-
-
#### `kotshi.generatedAnnotation`
This option tells Kotshi to add the `@Generated` annotation to all generated classes which is disabled by default.
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/Options.kt b/compiler/src/main/kotlin/se/ansman/kotshi/Options.kt
index 7c30e5a..6122716 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/Options.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/Options.kt
@@ -1,8 +1,6 @@
package se.ansman.kotshi
object Options {
- const val createAnnotationsUsingConstructor = "kotshi.createAnnotationsUsingConstructor"
- const val useLegacyDataClassRenderer = "kotshi.useLegacyDataClassRenderer"
const val generatedAnnotation = "kotshi.generatedAnnotation"
val possibleGeneratedAnnotations = setOf(Types.Java.generatedJDK9, Types.Java.generatedPreJDK9)
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/AdaptersProcessingStep.kt b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/AdaptersProcessingStep.kt
index 8d3873e..93a4ab0 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/AdaptersProcessingStep.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/AdaptersProcessingStep.kt
@@ -38,8 +38,6 @@ class AdaptersProcessingStep(
private val types: Types,
private val elements: Elements,
private val generatedAnnotation: GeneratedAnnotation?,
- private val createAnnotationsUsingConstructor: Boolean?,
- private val useLegacyDataClassRenderer: Boolean,
) : KotshiProcessor.GeneratingProcessingStep() {
override val annotations: Set> =
setOf(
@@ -146,8 +144,6 @@ class AdaptersProcessingStep(
adapters += generator.generateAdapter(
generatedAnnotation = generatedAnnotation,
filer = filer,
- createAnnotationsUsingConstructor = createAnnotationsUsingConstructor,
- useLegacyDataClassRenderer = useLegacyDataClassRenderer
)
} catch (e: KaptProcessingError) {
messager.logKotshiError(e)
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/FactoryProcessingStep.kt b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/FactoryProcessingStep.kt
index ede8014..c87b581 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/FactoryProcessingStep.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/FactoryProcessingStep.kt
@@ -51,7 +51,6 @@ class FactoryProcessingStep(
private val generatedAnnotation: GeneratedAnnotation?,
private val generatedAdapters: List>,
private val metadataAccessor: MetadataAccessor,
- private val createAnnotationsUsingConstructor: Boolean?,
) : KotshiProcessor.GeneratingProcessingStep() {
@OptIn(ExperimentalKotshiApi::class)
@@ -101,9 +100,7 @@ class FactoryProcessingStep(
manuallyRegisteredAdapters = manuallyRegisteredAdapters,
)
- val createAnnotationsUsingConstructor =
- createAnnotationsUsingConstructor
- ?: metadataAccessor.getMetadata(element).supportsCreatingAnnotationsWithConstructor
+ val createAnnotationsUsingConstructor = metadataAccessor.getMetadata(element).supportsCreatingAnnotationsWithConstructor
JsonAdapterFactoryRenderer(factory, createAnnotationsUsingConstructor)
.render(generatedAnnotation) {
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/KotshiProcessor.kt b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/KotshiProcessor.kt
index 1534011..cfa7fb7 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/KotshiProcessor.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/KotshiProcessor.kt
@@ -27,8 +27,6 @@ import javax.lang.model.util.Types
@AutoService(Processor::class)
@IncrementalAnnotationProcessor(AGGREGATING)
class KotshiProcessor : AbstractProcessor() {
- private var createAnnotationsUsingConstructor: Boolean? = null
- private var useLegacyDataClassRenderer: Boolean = false
private var generatedAnnotation: GeneratedAnnotation? = null
private lateinit var elements: Elements
private lateinit var types: Types
@@ -49,8 +47,6 @@ class KotshiProcessor : AbstractProcessor() {
types = types,
elements = processingEnv.elementUtils,
generatedAnnotation = generatedAnnotation,
- createAnnotationsUsingConstructor = createAnnotationsUsingConstructor,
- useLegacyDataClassRenderer = useLegacyDataClassRenderer,
),
FactoryProcessingStep(
processor = this,
@@ -61,7 +57,6 @@ class KotshiProcessor : AbstractProcessor() {
generatedAnnotation = generatedAnnotation,
generatedAdapters = adapters,
metadataAccessor = metadataAccessor,
- createAnnotationsUsingConstructor = createAnnotationsUsingConstructor,
)
)
}
@@ -69,8 +64,6 @@ class KotshiProcessor : AbstractProcessor() {
@Synchronized
override fun init(processingEnv: ProcessingEnvironment) {
super.init(processingEnv)
- createAnnotationsUsingConstructor = processingEnv.options[Options.createAnnotationsUsingConstructor]?.toBooleanStrict()
- useLegacyDataClassRenderer = processingEnv.options[Options.useLegacyDataClassRenderer]?.toBooleanStrict() ?: useLegacyDataClassRenderer
generatedAnnotation = processingEnv.options[Options.generatedAnnotation]
?.let { name ->
Options.possibleGeneratedAnnotations[name] ?: run {
@@ -95,7 +88,7 @@ class KotshiProcessor : AbstractProcessor() {
override fun getSupportedAnnotationTypes(): Set =
getSupportedAnnotationClasses().mapTo(mutableSetOf()) { it.canonicalName }
- override fun getSupportedOptions(): Set = setOf("kotshi.createAnnotationsUsingConstructor")
+ override fun getSupportedOptions(): Set = setOf(Options.generatedAnnotation)
override fun process(annotations: Set, roundEnv: RoundEnvironment): Boolean {
if (!roundEnv.processingOver()) {
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/generators/AdapterGenerator.kt b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/generators/AdapterGenerator.kt
index c8c8e47..61cf319 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/kapt/generators/AdapterGenerator.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/kapt/generators/AdapterGenerator.kt
@@ -62,8 +62,6 @@ abstract class AdapterGenerator(
fun generateAdapter(
generatedAnnotation: GeneratedAnnotation?,
filer: Filer,
- createAnnotationsUsingConstructor: Boolean?,
- useLegacyDataClassRenderer: Boolean,
): GeneratedAdapter {
when {
kmClass.isInner ->
@@ -76,9 +74,7 @@ abstract class AdapterGenerator(
val generatedAdapter = getGeneratableJsonAdapter()
.createRenderer(
- createAnnotationsUsingConstructor = createAnnotationsUsingConstructor
- ?: metadataAccessor.getMetadata(targetElement).supportsCreatingAnnotationsWithConstructor,
- useLegacyDataClassRenderer = useLegacyDataClassRenderer,
+ createAnnotationsUsingConstructor = metadataAccessor.getMetadata(targetElement).supportsCreatingAnnotationsWithConstructor,
error = { KaptProcessingError(it, targetElement) },
)
.render(generatedAnnotation, originatingElement = targetElement) {
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/ksp/KotshiSymbolProcessor.kt b/compiler/src/main/kotlin/se/ansman/kotshi/ksp/KotshiSymbolProcessor.kt
index c7635fa..39e277c 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/ksp/KotshiSymbolProcessor.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/ksp/KotshiSymbolProcessor.kt
@@ -49,13 +49,7 @@ import se.ansman.kotshi.model.findKotshiConstructor
import se.ansman.kotshi.renderer.JsonAdapterFactoryRenderer
class KotshiSymbolProcessor(private val environment: SymbolProcessorEnvironment) : SymbolProcessor {
- private val createAnnotationsUsingConstructor = environment.options[Options.createAnnotationsUsingConstructor]
- ?.toBooleanStrict()
- ?: environment.kotlinVersion.isAtLeast(1, 6)
-
- private val useLegacyDataClassRenderer = environment.options[Options.useLegacyDataClassRenderer]
- ?.toBooleanStrict()
- ?: false
+ private val createAnnotationsUsingConstructor = environment.kotlinVersion.isAtLeast(1, 6)
private val generatedAnnotation = environment.options[Options.generatedAnnotation]
?.let { name ->
@@ -329,7 +323,6 @@ class KotshiSymbolProcessor(private val environment: SymbolProcessorEnvironment)
generator.generateAdapter(
createAnnotationsUsingConstructor = createAnnotationsUsingConstructor,
- useLegacyDataClassRenderer = useLegacyDataClassRenderer,
generatedAnnotation = generatedAnnotation,
)
} catch (e: KspProcessingError) {
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/ksp/generators/AdapterGenerator.kt b/compiler/src/main/kotlin/se/ansman/kotshi/ksp/generators/AdapterGenerator.kt
index 1624189..7049e79 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/ksp/generators/AdapterGenerator.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/ksp/generators/AdapterGenerator.kt
@@ -64,7 +64,6 @@ abstract class AdapterGenerator(
fun generateAdapter(
createAnnotationsUsingConstructor: Boolean,
- useLegacyDataClassRenderer: Boolean,
generatedAnnotation: GeneratedAnnotation?,
): GeneratedAdapter {
when {
@@ -81,7 +80,6 @@ abstract class AdapterGenerator(
val generatedAdapter = getGeneratableJsonAdapter()
.createRenderer(
createAnnotationsUsingConstructor = createAnnotationsUsingConstructor,
- useLegacyDataClassRenderer = useLegacyDataClassRenderer,
error = { KspProcessingError(it, targetElement) },
)
.render(generatedAnnotation, originatingElement = targetElement.containingFile!!) {
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/renderer/AdapterRenderer.kt b/compiler/src/main/kotlin/se/ansman/kotshi/renderer/AdapterRenderer.kt
index a2c35e5..d5d50fe 100644
--- a/compiler/src/main/kotlin/se/ansman/kotshi/renderer/AdapterRenderer.kt
+++ b/compiler/src/main/kotlin/se/ansman/kotshi/renderer/AdapterRenderer.kt
@@ -145,16 +145,10 @@ abstract class AdapterRenderer(private val adapter: GeneratableJsonAdapter) {
fun GeneratableJsonAdapter.createRenderer(
createAnnotationsUsingConstructor: Boolean,
- useLegacyDataClassRenderer: Boolean,
error: (String) -> Throwable,
): AdapterRenderer =
when (this) {
- is DataClassJsonAdapter ->
- if (useLegacyDataClassRenderer) {
- LegacyDataClassAdapterRenderer(this, createAnnotationsUsingConstructor)
- } else {
- DataClassAdapterRenderer(this, createAnnotationsUsingConstructor)
- }
+ is DataClassJsonAdapter -> DataClassAdapterRenderer(this, createAnnotationsUsingConstructor)
is EnumJsonAdapter -> EnumAdapterRenderer(this)
is ObjectJsonAdapter -> ObjectAdapterRenderer(this)
is SealedClassJsonAdapter -> SealedClassAdapterRenderer(this, error)
diff --git a/compiler/src/main/kotlin/se/ansman/kotshi/renderer/LegacyDataClassAdapterRenderer.kt b/compiler/src/main/kotlin/se/ansman/kotshi/renderer/LegacyDataClassAdapterRenderer.kt
deleted file mode 100644
index fd6d8f5..0000000
--- a/compiler/src/main/kotlin/se/ansman/kotshi/renderer/LegacyDataClassAdapterRenderer.kt
+++ /dev/null
@@ -1,392 +0,0 @@
-package se.ansman.kotshi.renderer
-
-import com.squareup.kotlinpoet.*
-import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.plusParameter
-import se.ansman.kotshi.*
-import se.ansman.kotshi.Types.Moshi.jsonDataException
-import se.ansman.kotshi.Types.Moshi.jsonReaderToken
-import se.ansman.kotshi.model.*
-
-class LegacyDataClassAdapterRenderer(
- private val adapter: DataClassJsonAdapter,
- private val createAnnotationsUsingConstructor: Boolean
-) : AdapterRenderer(adapter) {
- private val adapters = adapter.properties.generateAdapterProperties()
- private val propertyNames = adapter.properties.mapTo(mutableSetOf()) { it.jsonName }
- private val parentLabels = adapter.polymorphicLabels.filterKeys { it !in propertyNames }
- private val serializedNames = adapter.serializedProperties.map { it.jsonName }.toSet()
- private val optionsProperty = jsonOptionsProperty(serializedNames + parentLabels.keys)
-
- override fun TypeSpec.Builder.renderSetup() {
- primaryConstructor(
- FunSpec.constructorBuilder()
- .applyIf(adapters.isNotEmpty()) { addParameter(moshiParameterName, Types.Moshi.moshi) }
- .applyIf(adapters.any { it.key.type.hasTypeVariable }) {
- addParameter(typesParameterName, Types.Kotshi.typesArray)
- }
- .build()
- )
- addProperties(adapters.values)
- addProperty(optionsProperty)
- }
-
- private fun Iterable.generateAdapterProperties(): Map =
- asSequence()
- .filter { it.shouldUseAdapter }
- .associateWith { property ->
- PropertySpec
- .builder(
- nameAllocator.newName(property.suggestedAdapterName),
- Types.Moshi.jsonAdapter.plusParameter(property.type),
- KModifier.PRIVATE
- )
- .initializer(
- CodeBlock.builder()
- .add("«moshi.adapter(")
- .add(property.asRuntimeType { typeVariableName ->
- val genericIndex =
- adapter.targetTypeVariables.indexOfFirst { it.name == typeVariableName.name }
- require(genericIndex >= 0) {
- throw IllegalStateException("Element ${adapter.targetType} is generic but is of an unknown type")
- }
- CodeBlock.of("types[$genericIndex]")
- })
- .add(", %L", property.annotations(createAnnotationsUsingConstructor))
- .add(", %S", property.name)
- .add(")»")
- .build()
- )
- .build()
- }
-
- override fun FunSpec.Builder.renderToJson(
- writerParameter: ParameterSpec,
- valueParameter: ParameterSpec
- ) {
- fun addBody(): FunSpec.Builder =
- addStatement("%N.beginObject()", writerParameter)
- .applyEach(parentLabels.entries) { (key, value) ->
- addStatement("%N.name(%S).value(%S)", writerParameter, key, value)
- }
- .applyEach(adapter.serializedProperties) { property ->
- addStatement("%N.name(%S)", writerParameter, property.jsonName)
- val getter = CodeBlock.of("%N.%N", valueParameter, property.name)
-
- if (property.shouldUseAdapter) {
- addCode(
- "%N.toJson(%N, ", adapters.getValue(property),
- writerParameter
- )
- .addCode(getter)
- .addCode(")\n")
- } else when (property.type.notNull()) {
- STRING,
- INT,
- LONG,
- FLOAT,
- DOUBLE,
- SHORT,
- BOOLEAN -> addStatement("%N.value(%L)", writerParameter, getter)
-
- BYTE -> addStatement("%N.%M(%L)", writerParameter, Functions.Kotshi.byteValue, getter)
- CHAR -> addStatement("%N.%M(%L)", writerParameter, Functions.Kotshi.value, getter)
- else -> error("Property ${property.name} is not primitive ${property.type} but requested non adapter use")
- }
- }
- .addStatement("%N.endObject()", writerParameter)
-
- addIf("%N == null", valueParameter) {
- addStatement("%N.nullValue()", writerParameter)
- addStatement("return")
- }
-
- val serializeNullsEnabled = when (adapter.serializeNulls) {
- SerializeNulls.DEFAULT -> null
- SerializeNulls.ENABLED -> true
- SerializeNulls.DISABLED -> false
- }
- if (serializeNullsEnabled != null) {
- this
- .addStatement("val·serializeNulls·= %N.serializeNulls", writerParameter)
- .addStatement("%N.serializeNulls·= %L", writerParameter, serializeNullsEnabled)
- .beginControlFlow("try")
- .apply { addBody() }
- .nextControlFlow("finally")
- .addStatement("%N.serializeNulls·= serializeNulls", writerParameter)
- .endControlFlow()
- } else {
- addBody()
- }
- }
-
- override fun FunSpec.Builder.renderFromJson(readerParameter: ParameterSpec) {
- val variables = adapter.serializedProperties.associateBy({ it }, { it.createVariables() })
- this
- .addStatement(
- "if (%N.peek() == %T.NULL) return %N.nextNull()",
- readerParameter,
- jsonReaderToken,
- readerParameter
- )
- .addCode("\n")
- .applyEach(variables.values) { variable ->
- addCode("%L", variable.value)
- if (variable.helper != null) {
- addCode("%L", variable.helper)
- }
- }
- .addCode("\n")
- .addStatement("%N.beginObject()", readerParameter)
- .addWhile("%N.hasNext()", readerParameter) {
- addWhen("%N.selectName(%N)", readerParameter, optionsProperty) {
- variables.entries.forEachIndexed { index, (property, variable) ->
- addWhenBranch("%L", index) {
- if (property.shouldUseAdapter) {
- addStatement(
- "%N·= %N.fromJson(%N)",
- variable.value,
- adapters.getValue(property),
- readerParameter
- )
- if (variable.helper != null) {
- if (property.type.isNullable) {
- addStatement("%N·= true", variable.helper)
- } else {
- addStatement("?.also { %N = true }", variable.helper)
- }
- }
- } else {
- fun FunSpec.Builder.readPrimitive(functionName: String, vararg args: Any) {
- addIfElse(
- "%N.peek() == %T.NULL",
- readerParameter, jsonReaderToken
- ) {
- addStatement("%N.skipValue()", readerParameter)
- }
- addElse {
- addStatement(
- "%N·= %N.$functionName()",
- variable.value,
- readerParameter,
- *args
- )
- if (variable.helper != null && !property.type.isNullable) {
- addStatement("%N·= true", variable.helper)
- }
- }
- if (variable.helper != null && property.type.isNullable) {
- addStatement("%N·= true", variable.helper)
- }
- }
-
- when (property.type.notNull()) {
- STRING -> readPrimitive("nextString")
- BOOLEAN -> readPrimitive("nextBoolean")
- BYTE -> readPrimitive("%M", Functions.Kotshi.nextByte)
- SHORT -> readPrimitive("%M", Functions.Kotshi.nextShort)
- INT -> readPrimitive("nextInt")
- LONG -> readPrimitive("nextLong")
- CHAR -> readPrimitive("%M", Functions.Kotshi.nextChar)
- FLOAT -> readPrimitive("%M", Functions.Kotshi.nextFloat)
- DOUBLE -> readPrimitive("nextDouble")
- else -> error(
- "Internal Kotshi error when processing ${adapter.targetType}. " +
- "Expected property type to be a primitive but was ${property.type}. " +
- "Please open an issue here: https://github.com/ansman/kotshi/issues/new"
- )
- }
- }
- }
- }
- parentLabels.keys.forEachIndexed { i, name ->
- addWhenBranch("%L", variables.size + i) {
- addComment("Consumes the '%L' label key from the parent", name)
- addStatement("%N.nextString()", readerParameter)
- }
- }
- addWhenBranch("-1") {
- addStatement("%N.skipName()", readerParameter)
- addStatement("%N.skipValue()", readerParameter)
- }
- }
- }
- .addStatement("%N.endObject()", readerParameter)
- .addCode("\n")
- .apply {
- val propertiesToCheck = variables.entries
- .filter { (property, _) ->
- !property.type.isNullable && !property.hasDefaultValue
- }
-
- if (propertiesToCheck.isNotEmpty()) {
- val stringBuilder = PropertySpec
- .builder("errorBuilder", StringBuilder::class.asTypeName().nullable())
- .mutable()
- .initializer("null")
- .build()
- addCode("%L", stringBuilder)
- for ((property, variable) in propertiesToCheck) {
- addIf("%L", variable.isNotSet) {
- if (property.name == property.jsonName) {
- addStatement(
- "%N = %N.%M(%S)",
- stringBuilder,
- stringBuilder,
- Functions.Kotshi.appendNullableError,
- property.name
- )
- } else {
- addStatement(
- "%N = %N.%M(%S, %S)",
- stringBuilder,
- stringBuilder,
- Functions.Kotshi.appendNullableError,
- property.name,
- property.jsonName
- )
- }
- }
- }
-
- addIf("%N != null", stringBuilder) {
- addStatement(
- "%N.append(\" (at path \").append(%N.path).append(')')",
- stringBuilder,
- readerParameter
- )
- addStatement("throw %T(%N.toString())", jsonDataException, stringBuilder)
- }
- addCode("\n")
- }
- }
- .apply {
- val constructorProperties = adapter.properties.filter { !it.hasDefaultValue }
- val copyProperties = adapter.serializedProperties.filter { it.hasDefaultValue }
-
- addCode("return·%T(«", adapter.targetType)
- constructorProperties.forEachIndexed { index, property ->
- val variable = variables.getValue(property)
-
- if (index > 0) {
- addCode(",")
- }
- addCode("\n%N·= %N", property.name, variable.value.name)
- if (variable.value.type.isNullable && !property.type.isNullable) {
- addCode("!!")
- }
- }
- addCode("»")
- if (constructorProperties.isNotEmpty()) addCode("\n")
- addCode(")")
- if (copyProperties.isNotEmpty()) {
- addControlFlow(".let") {
- addCode("it.copy(«")
- copyProperties.forEachIndexed { index, property ->
- val variable = variables.getValue(property)
-
- if (index > 0) {
- addCode(",")
- }
- addCode("\n%N = ", property.name)
-
- if (variable.helper == null) {
- addCode("%N ?: it.%N", variable.value, property.name)
- } else {
- addCode("if (%L) %N else it.%N", variable.isSet, variable.value, property.name)
- }
- }
- addCode("»\n)\n")
- }
- }
- }
- }
-
- private fun Property.createVariables() =
- LegacyPropertyVariables(
- value = PropertySpec
- .builder(
- name = nameAllocator.newName(name),
- type = if (type.isPrimitive && !shouldUseAdapter) type else type.nullable()
- )
- .initializer(
- when {
- type.isPrimitive && !shouldUseAdapter ->
- when (type) {
- BOOLEAN -> CodeBlock.of("false")
- BYTE -> CodeBlock.of("0")
- SHORT -> CodeBlock.of("0")
- INT -> CodeBlock.of("0")
- LONG -> CodeBlock.of("0L")
- CHAR -> CodeBlock.of("'\\u0000'")
- FLOAT -> CodeBlock.of("0f")
- DOUBLE -> CodeBlock.of("0.0")
- else -> throw AssertionError()
- }
-
- else -> CodeBlock.of("null")
- }
- )
- .mutable()
- .build(),
- helper = if (type.isPrimitive && !shouldUseAdapter || type.isNullable && hasDefaultValue) {
- PropertySpec
- .builder(nameAllocator.newName("${name}IsSet"), BOOLEAN)
- .mutable()
- .initializer("false")
- .build()
- } else {
- null
- }
- )
-
-}
-
-private data class LegacyPropertyVariables(
- val value: PropertySpec,
- val helper: PropertySpec?
-) {
- val isNotSet: CodeBlock by lazy(LazyThreadSafetyMode.NONE) {
- if (helper == null) {
- CodeBlock.of("%N == null", value)
- } else {
- CodeBlock.of("!%N", helper)
- }
- }
- val isSet: CodeBlock by lazy(LazyThreadSafetyMode.NONE) {
- if (helper == null) {
- CodeBlock.of("%N != null", value)
- } else {
- CodeBlock.of("%N", helper)
- }
- }
-
-}
-
-private fun Property.annotations(createAnnotationsUsingConstructor: Boolean): CodeBlock =
- CodeBlock.builder()
- .add("%M(", Functions.Kotlin.setOf)
- .applyIf(jsonQualifiers.size > 1) {
- indent()
- add("\n")
- }
- .applyEachIndexed(jsonQualifiers.sortedBy { it.annotationName }) { index, qualifier ->
- if (index > 0) add(",\n")
- add(qualifier.render(createAnnotationsUsingConstructor))
- }
- .applyIf(jsonQualifiers.size > 1) {
- unindent()
- add("\n")
- }
- .add(")")
- .build()
-
-
-private val TypeName.hasTypeVariable: Boolean
- get() = when (this) {
- is ClassName -> false
- Dynamic -> false
- is LambdaTypeName -> receiver?.hasTypeVariable ?: false || parameters.any { it.type.hasTypeVariable } || returnType.hasTypeVariable
- is ParameterizedTypeName -> typeArguments.any { it.hasTypeVariable }
- is TypeVariableName -> true
- is WildcardTypeName -> inTypes.any { it.hasTypeVariable } || outTypes.any { it.hasTypeVariable }
- }
diff --git a/tests/ksp/build.gradle.kts b/tests/ksp/build.gradle.kts
index d2048d3..e9e0b5b 100644
--- a/tests/ksp/build.gradle.kts
+++ b/tests/ksp/build.gradle.kts
@@ -1,5 +1,3 @@
-import com.google.devtools.ksp.gradle.KspExtension
-
plugins {
id("test-library")
alias(libs.plugins.ksp)
@@ -17,16 +15,4 @@ kotlin {
dependencies {
ksp(projects.compiler)
testImplementation(libs.compileTesting.ksp)
-}
-
-fun KspExtension.argFromGradleProperty(name: String) {
- val value = providers.gradleProperty(name).orNull
- if (value != null) {
- arg(name, value)
- }
-}
-
-ksp {
- argFromGradleProperty("kotshi.createAnnotationsUsingConstructor")
- argFromGradleProperty("kotshi.useLegacyDataClassRenderer")
}
\ No newline at end of file