mirror of
https://github.com/fankes/moshi.git
synced 2025-10-18 23:49:21 +08:00
Switch from internal to experimental internal annotation (#1410)
This commit is contained in:
@@ -32,6 +32,7 @@ tasks.withType<KotlinCompile>().configureEach {
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xopt-in=com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview",
|
||||
"-Xopt-in=com.squareup.kotlinpoet.ksp.KotlinPoetKspPreview",
|
||||
"-Xopt-in=com.squareup.moshi.kotlin.codegen.api.InternalMoshiCodegenApi",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -52,12 +52,13 @@ private const val TO_STRING_PREFIX = "GeneratedJsonAdapter("
|
||||
private const val TO_STRING_SIZE_BASE = TO_STRING_PREFIX.length + 1 // 1 is the closing paren
|
||||
|
||||
/** Generates a JSON adapter for a target type. */
|
||||
internal class AdapterGenerator(
|
||||
@InternalMoshiCodegenApi
|
||||
public class AdapterGenerator(
|
||||
private val target: TargetType,
|
||||
private val propertyList: List<PropertyGenerator>
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private companion object {
|
||||
private val INT_TYPE_BLOCK = CodeBlock.of("%T::class.javaPrimitiveType", INT)
|
||||
private val DEFAULT_CONSTRUCTOR_MARKER_TYPE_BLOCK = CodeBlock.of(
|
||||
"%T.DEFAULT_CONSTRUCTOR_MARKER",
|
||||
@@ -166,7 +167,7 @@ internal class AdapterGenerator(
|
||||
.initializer("null")
|
||||
.build()
|
||||
|
||||
fun prepare(generateProguardRules: Boolean, typeHook: (TypeSpec) -> TypeSpec = { it }): PreparedAdapter {
|
||||
public fun prepare(generateProguardRules: Boolean, typeHook: (TypeSpec) -> TypeSpec = { it }): PreparedAdapter {
|
||||
val reservedSimpleNames = mutableSetOf<String>()
|
||||
for (property in nonTransientProperties) {
|
||||
// Allocate names for simple property types first to avoid collisions
|
||||
@@ -727,7 +728,8 @@ private fun FunSpec.Builder.addMissingPropertyCheck(property: PropertyGenerator,
|
||||
}
|
||||
|
||||
/** Represents a prepared adapter with its [spec] and optional associated [proguardConfig]. */
|
||||
internal data class PreparedAdapter(val spec: FileSpec, val proguardConfig: ProguardConfig?)
|
||||
@InternalMoshiCodegenApi
|
||||
public data class PreparedAdapter(val spec: FileSpec, val proguardConfig: ProguardConfig?)
|
||||
|
||||
private fun AsmType.toReflectionString(): String {
|
||||
return when (this) {
|
||||
|
@@ -36,15 +36,16 @@ import com.squareup.moshi.Types
|
||||
import java.util.Locale
|
||||
|
||||
/** A JsonAdapter that can be used to encode and decode a particular field. */
|
||||
internal data class DelegateKey(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class DelegateKey(
|
||||
private val type: TypeName,
|
||||
private val jsonQualifiers: List<AnnotationSpec>,
|
||||
private val instantiateAnnotations: Boolean
|
||||
) {
|
||||
val nullable get() = type.isNullable
|
||||
public val nullable: Boolean get() = type.isNullable
|
||||
|
||||
/** Returns an adapter to use when encoding and decoding this property. */
|
||||
fun generateProperty(
|
||||
internal fun generateProperty(
|
||||
nameAllocator: NameAllocator,
|
||||
typeRenderer: TypeRenderer,
|
||||
moshiParameter: ParameterSpec,
|
||||
|
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Square, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.squareup.moshi.kotlin.codegen.api
|
||||
|
||||
/** Internal Moshi code gen APIs. */
|
||||
@MustBeDocumented
|
||||
@Retention(value = AnnotationRetention.BINARY)
|
||||
@RequiresOptIn(
|
||||
level = RequiresOptIn.Level.WARNING,
|
||||
message = "This is an internal API and may change at any time."
|
||||
)
|
||||
public annotation class InternalMoshiCodegenApi
|
@@ -17,7 +17,8 @@ package com.squareup.moshi.kotlin.codegen.api
|
||||
|
||||
import com.squareup.kotlinpoet.ClassName
|
||||
|
||||
internal object Options {
|
||||
@InternalMoshiCodegenApi
|
||||
public object Options {
|
||||
/**
|
||||
* This processing option can be specified to have a `@Generated` annotation
|
||||
* included in the generated code. It is not encouraged unless you need it for static analysis
|
||||
@@ -27,14 +28,14 @@ internal object Options {
|
||||
* * `"javax.annotation.processing.Generated"` (JRE 9+)
|
||||
* * `"javax.annotation.Generated"` (JRE <9)
|
||||
*/
|
||||
const val OPTION_GENERATED: String = "moshi.generated"
|
||||
public const val OPTION_GENERATED: String = "moshi.generated"
|
||||
|
||||
/**
|
||||
* This boolean processing option can disable proguard rule generation.
|
||||
* Normally, this is not recommended unless end-users build their own JsonAdapter look-up tool.
|
||||
* This is enabled by default.
|
||||
*/
|
||||
const val OPTION_GENERATE_PROGUARD_RULES: String = "moshi.generateProguardRules"
|
||||
public const val OPTION_GENERATE_PROGUARD_RULES: String = "moshi.generateProguardRules"
|
||||
|
||||
/**
|
||||
* This boolean processing option controls whether or not Moshi will directly instantiate
|
||||
@@ -42,9 +43,9 @@ internal object Options {
|
||||
* but can be disabled to restore the legacy behavior of storing annotations on generated adapter
|
||||
* fields and looking them up reflectively.
|
||||
*/
|
||||
const val OPTION_INSTANTIATE_ANNOTATIONS: String = "moshi.instantiateAnnotations"
|
||||
public const val OPTION_INSTANTIATE_ANNOTATIONS: String = "moshi.instantiateAnnotations"
|
||||
|
||||
val POSSIBLE_GENERATED_NAMES = arrayOf(
|
||||
public val POSSIBLE_GENERATED_NAMES: Map<String, ClassName> = arrayOf(
|
||||
ClassName("javax.annotation.processing", "Generated"),
|
||||
ClassName("javax.annotation", "Generated")
|
||||
).associateBy { it.canonicalName }
|
||||
|
@@ -29,9 +29,11 @@ import com.squareup.kotlinpoet.ClassName
|
||||
* conditioned on usage of the original target type.
|
||||
*
|
||||
* To keep this processor as an ISOLATING incremental processor, we generate one file per target
|
||||
* class with a deterministic name (see [outputFile]) with an appropriate originating element.
|
||||
* class with a deterministic name (see [outputFilePathWithoutExtension]) with an appropriate
|
||||
* originating element.
|
||||
*/
|
||||
internal data class ProguardConfig(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class ProguardConfig(
|
||||
val targetClass: ClassName,
|
||||
val adapterName: String,
|
||||
val adapterConstructorParams: List<String>,
|
||||
@@ -39,11 +41,11 @@ internal data class ProguardConfig(
|
||||
val targetConstructorParams: List<String>,
|
||||
val qualifierProperties: Set<QualifierAdapterProperty>
|
||||
) {
|
||||
fun outputFilePathWithoutExtension(canonicalName: String): String {
|
||||
public fun outputFilePathWithoutExtension(canonicalName: String): String {
|
||||
return "META-INF/proguard/moshi-$canonicalName"
|
||||
}
|
||||
|
||||
fun writeTo(out: Appendable): Unit = out.run {
|
||||
public fun writeTo(out: Appendable): Unit = out.run {
|
||||
//
|
||||
// -if class {the target class}
|
||||
// -keepnames class {the target class}
|
||||
@@ -112,4 +114,5 @@ internal data class ProguardConfig(
|
||||
* Represents a qualified property with its [name] in the adapter fields and list of [qualifiers]
|
||||
* associated with it.
|
||||
*/
|
||||
internal data class QualifierAdapterProperty(val name: String, val qualifiers: Set<ClassName>)
|
||||
@InternalMoshiCodegenApi
|
||||
public data class QualifierAdapterProperty(val name: String, val qualifiers: Set<ClassName>)
|
||||
|
@@ -20,21 +20,22 @@ import com.squareup.kotlinpoet.NameAllocator
|
||||
import com.squareup.kotlinpoet.PropertySpec
|
||||
|
||||
/** Generates functions to encode and decode a property as JSON. */
|
||||
internal class PropertyGenerator(
|
||||
val target: TargetProperty,
|
||||
val delegateKey: DelegateKey,
|
||||
val isTransient: Boolean = false
|
||||
@InternalMoshiCodegenApi
|
||||
public class PropertyGenerator(
|
||||
public val target: TargetProperty,
|
||||
public val delegateKey: DelegateKey,
|
||||
public val isTransient: Boolean = false
|
||||
) {
|
||||
val name = target.name
|
||||
val jsonName = target.jsonName ?: target.name
|
||||
val hasDefault = target.hasDefault
|
||||
public val name: String = target.name
|
||||
public val jsonName: String = target.jsonName ?: target.name
|
||||
public val hasDefault: Boolean = target.hasDefault
|
||||
|
||||
lateinit var localName: String
|
||||
lateinit var localIsPresentName: String
|
||||
public lateinit var localName: String
|
||||
public lateinit var localIsPresentName: String
|
||||
|
||||
val isRequired get() = !delegateKey.nullable && !hasDefault
|
||||
public val isRequired: Boolean get() = !delegateKey.nullable && !hasDefault
|
||||
|
||||
val hasConstructorParameter get() = target.parameterIndex != -1
|
||||
public val hasConstructorParameter: Boolean get() = target.parameterIndex != -1
|
||||
|
||||
/**
|
||||
* IsPresent is required if the following conditions are met:
|
||||
@@ -46,15 +47,15 @@ internal class PropertyGenerator(
|
||||
* This is used to indicate that presence should be checked first before possible assigning null
|
||||
* to an absent value
|
||||
*/
|
||||
val hasLocalIsPresentName = !isTransient && hasDefault && !hasConstructorParameter && delegateKey.nullable
|
||||
val hasConstructorDefault = hasDefault && hasConstructorParameter
|
||||
public val hasLocalIsPresentName: Boolean = !isTransient && hasDefault && !hasConstructorParameter && delegateKey.nullable
|
||||
public val hasConstructorDefault: Boolean = hasDefault && hasConstructorParameter
|
||||
|
||||
fun allocateNames(nameAllocator: NameAllocator) {
|
||||
internal fun allocateNames(nameAllocator: NameAllocator) {
|
||||
localName = nameAllocator.newName(name)
|
||||
localIsPresentName = nameAllocator.newName("${name}Set")
|
||||
}
|
||||
|
||||
fun generateLocalProperty(): PropertySpec {
|
||||
internal fun generateLocalProperty(): PropertySpec {
|
||||
return PropertySpec.builder(localName, target.type.copy(nullable = true))
|
||||
.mutable(true)
|
||||
.apply {
|
||||
@@ -70,7 +71,7 @@ internal class PropertyGenerator(
|
||||
.build()
|
||||
}
|
||||
|
||||
fun generateLocalIsPresentProperty(): PropertySpec {
|
||||
internal fun generateLocalIsPresentProperty(): PropertySpec {
|
||||
return PropertySpec.builder(localIsPresentName, BOOLEAN)
|
||||
.mutable(true)
|
||||
.initializer("false")
|
||||
|
@@ -18,7 +18,8 @@ package com.squareup.moshi.kotlin.codegen.api
|
||||
import com.squareup.kotlinpoet.KModifier
|
||||
|
||||
/** A constructor in user code that should be called by generated code. */
|
||||
internal data class TargetConstructor(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class TargetConstructor(
|
||||
val parameters: LinkedHashMap<String, TargetParameter>,
|
||||
val visibility: KModifier,
|
||||
val signature: String?
|
||||
|
@@ -19,7 +19,8 @@ import com.squareup.kotlinpoet.AnnotationSpec
|
||||
import com.squareup.kotlinpoet.TypeName
|
||||
|
||||
/** A parameter in user code that should be populated by generated code. */
|
||||
internal data class TargetParameter(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class TargetParameter(
|
||||
val name: String,
|
||||
val index: Int,
|
||||
val type: TypeName,
|
||||
|
@@ -20,7 +20,8 @@ import com.squareup.kotlinpoet.PropertySpec
|
||||
import com.squareup.kotlinpoet.TypeName
|
||||
|
||||
/** A property in user code that maps to JSON. */
|
||||
internal data class TargetProperty(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class TargetProperty(
|
||||
val propertySpec: PropertySpec,
|
||||
val parameter: TargetParameter?,
|
||||
val visibility: KModifier,
|
||||
@@ -28,8 +29,8 @@ internal data class TargetProperty(
|
||||
) {
|
||||
val name: String get() = propertySpec.name
|
||||
val type: TypeName get() = propertySpec.type
|
||||
val parameterIndex get() = parameter?.index ?: -1
|
||||
val hasDefault get() = parameter?.hasDefault ?: true
|
||||
val parameterIndex: Int get() = parameter?.index ?: -1
|
||||
val hasDefault: Boolean get() = parameter?.hasDefault ?: true
|
||||
|
||||
override fun toString() = name
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
@@ -20,7 +20,8 @@ import com.squareup.kotlinpoet.TypeName
|
||||
import com.squareup.kotlinpoet.TypeVariableName
|
||||
|
||||
/** A user type that should be decoded and encoded by generated code. */
|
||||
internal data class TargetType(
|
||||
@InternalMoshiCodegenApi
|
||||
public data class TargetType(
|
||||
val typeName: TypeName,
|
||||
val constructor: TargetConstructor,
|
||||
val properties: Map<String, TargetProperty>,
|
||||
|
Reference in New Issue
Block a user