From ca4d8f5e3433fe150a01374efdd330d27856217b Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Wed, 28 Nov 2018 22:20:07 -0500 Subject: [PATCH] Upgrade to KotlinPoet 1.0-RC3 --- kotlin/codegen/pom.xml | 2 +- .../moshi/kotlin/codegen/AdapterGenerator.kt | 56 ++++++++++--------- .../moshi/kotlin/codegen/DelegateKey.kt | 6 +- .../moshi/kotlin/codegen/PropertyGenerator.kt | 2 +- .../moshi/kotlin/codegen/TargetType.kt | 2 +- .../moshi/kotlin/codegen/TypeRenderer.kt | 14 ++--- .../moshi/kotlin/codegen/TypeResolver.kt | 16 +++--- .../moshi/kotlin/codegen/kotlintypes.kt | 2 +- .../squareup/moshi/kotlin/codegen/metadata.kt | 14 ++--- .../kotlin/codegen/KotlinCompilerCall.kt | 2 +- .../moshi/kotlin/codegen/TypeResolverTest.kt | 13 ++--- 11 files changed, 66 insertions(+), 63 deletions(-) diff --git a/kotlin/codegen/pom.xml b/kotlin/codegen/pom.xml index 40d7259..084278d 100644 --- a/kotlin/codegen/pom.xml +++ b/kotlin/codegen/pom.xml @@ -25,7 +25,7 @@ com.squareup kotlinpoet - 1.0.0-RC2 + 1.0.0-RC3 com.google.auto diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/AdapterGenerator.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/AdapterGenerator.kt index 587720d..90d2f02 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/AdapterGenerator.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/AdapterGenerator.kt @@ -71,7 +71,7 @@ internal class AdapterGenerator( .build() private val valueParam = ParameterSpec.builder( nameAllocator.newName("value"), - originalTypeName.asNullable()) + originalTypeName.copy(nullable = true)) .build() private val jsonAdapterTypeName = JsonAdapter::class.asClassName().parameterizedBy(originalTypeName) @@ -183,24 +183,24 @@ internal class AdapterGenerator( result.beginControlFlow("%L -> ", index) if (property.delegateKey.nullable) { result.addStatement("%N = %N.fromJson(%N)", - property.localName, nameAllocator.get(property.delegateKey), readerParam) + property.localName, nameAllocator[property.delegateKey], readerParam) } else { - result.addStatement("%N = %N.fromJson(%N)" + - " ?: throw %T(\"Non-null value '%N' was null at \${%N.path}\")", - property.localName, nameAllocator.get(property.delegateKey), readerParam, - JsonDataException::class, property.localName, readerParam) + result.addStatement("%N = %N.fromJson(%N) ?: throw·%T(%P)", + property.localName, nameAllocator[property.delegateKey], readerParam, + JsonDataException::class, + "Non-null value '${property.localName}' was null at \${${readerParam.name}.path}") } result.addStatement("%N = true", property.localIsPresentName) result.endControlFlow() } else { if (property.delegateKey.nullable) { result.addStatement("%L -> %N = %N.fromJson(%N)", - index, property.localName, nameAllocator.get(property.delegateKey), readerParam) + index, property.localName, nameAllocator[property.delegateKey], readerParam) } else { - result.addStatement("%L -> %N = %N.fromJson(%N)" + - " ?: throw %T(\"Non-null value '%N' was null at \${%N.path}\")", - index, property.localName, nameAllocator.get(property.delegateKey), readerParam, - JsonDataException::class, property.localName, readerParam) + result.addStatement("%L -> %N = %N.fromJson(%N) ?: throw·%T(%P)", + index, property.localName, nameAllocator[property.delegateKey], readerParam, + JsonDataException::class, + "Non-null value '${property.localName}' was null at \${${readerParam.name}.path}") } } } @@ -217,7 +217,7 @@ internal class AdapterGenerator( // Call the constructor providing only required parameters. var hasOptionalParameters = false - result.addCode("%[var %N = %T(", resultName, originalTypeName) + result.addCode("«var %N = %T(", resultName, originalTypeName) var separator = "\n" for (property in propertyList) { if (!property.hasConstructorParameter) { @@ -230,20 +230,20 @@ internal class AdapterGenerator( result.addCode(separator) result.addCode("%N = %N", property.name, property.localName) if (property.isRequired) { - result.addCode(" ?: throw %T(\"Required property '%L' missing at \${%N.path}\")", - JsonDataException::class, property.localName, readerParam) + result.addCode(" ?: throw·%T(%P)", JsonDataException::class, + "Required property '${property.localName}' missing at \${${readerParam.name}.path}") } separator = ",\n" } - result.addCode(")%]\n", originalTypeName) + result.addCode(")»\n", originalTypeName) // Call either the constructor again, or the copy() method, this time providing any optional // parameters that we have. if (hasOptionalParameters) { if (isDataClass) { - result.addCode("%[%1N = %1N.copy(", resultName) + result.addCode("«%1N = %1N.copy(", resultName) } else { - result.addCode("%[%1N = %2T(", resultName, originalTypeName) + result.addCode("«%1N = %2T(", resultName, originalTypeName) } separator = "\n" for (property in propertyList) { @@ -255,17 +255,21 @@ internal class AdapterGenerator( } result.addCode(separator) - if (property.differentiateAbsentFromNull) { - result.addCode("%2N = if (%3N) %4N else %1N.%2N", - resultName, property.name, property.localIsPresentName, property.localName) - } else if (property.isRequired) { - result.addCode("%1N = %2N", property.name, property.localName) - } else { - result.addCode("%2N = %3N ?: %1N.%2N", resultName, property.name, property.localName) + when { + property.differentiateAbsentFromNull -> { + result.addCode("%2N = if (%3N) %4N else %1N.%2N", + resultName, property.name, property.localIsPresentName, property.localName) + } + property.isRequired -> { + result.addCode("%1N = %2N", property.name, property.localName) + } + else -> { + result.addCode("%2N = %3N ?: %1N.%2N", resultName, property.name, property.localName) + } } separator = ",\n" } - result.addCode("%])\n") + result.addCode("»)\n") } // Assign properties not present in the constructor. @@ -301,7 +305,7 @@ internal class AdapterGenerator( propertyList.forEach { property -> result.addStatement("%N.name(%S)", writerParam, property.jsonName) result.addStatement("%N.toJson(%N, %N.%L)", - nameAllocator.get(property.delegateKey), writerParam, valueParam, property.name) + nameAllocator[property.delegateKey], writerParam, valueParam, property.name) } result.addStatement("%N.endObject()", writerParam) diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/DelegateKey.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/DelegateKey.kt index e9ef5f5..bc0a1ed 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/DelegateKey.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/DelegateKey.kt @@ -37,7 +37,7 @@ internal data class DelegateKey( private val type: TypeName, private val jsonQualifiers: List ) { - val nullable get() = type.nullable + val nullable get() = type.isNullable /** Returns an adapter to use when encoding and decoding this property. */ fun generateProperty( @@ -86,12 +86,12 @@ private fun TypeName.toVariableName(): String { val base = when (this) { is ClassName -> simpleName is ParameterizedTypeName -> rawType.simpleName + "Of" + typeArguments.toVariableNames() - is WildcardTypeName -> (lowerBounds + upperBounds).toVariableNames() + is WildcardTypeName -> (inTypes + outTypes).toVariableNames() is TypeVariableName -> name + bounds.toVariableNames() else -> throw IllegalArgumentException("Unrecognized type! $this") } - return if (nullable) { + return if (isNullable) { "Nullable$base" } else { base diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/PropertyGenerator.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/PropertyGenerator.kt index db33a5a..69d6317 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/PropertyGenerator.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/PropertyGenerator.kt @@ -44,7 +44,7 @@ internal class PropertyGenerator( } fun generateLocalProperty(): PropertySpec { - return PropertySpec.builder(localName, target.type.asNullable()) + return PropertySpec.builder(localName, target.type.copy(nullable = true)) .mutable(true) .initializer("null") .build() diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TargetType.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TargetType.kt index 305afd3..30a2e62 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TargetType.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TargetType.kt @@ -210,7 +210,7 @@ internal data class TargetType( bounds = *possibleBounds.toTypedArray(), variance = it.varianceModifier) } - return@map typeVar.reified(it.reified) + return@map typeVar.copy(reified = it.reified) } } diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeRenderer.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeRenderer.kt index a9d7f79..75347fc 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeRenderer.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeRenderer.kt @@ -41,8 +41,8 @@ abstract class TypeRenderer { abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock fun render(typeName: TypeName): CodeBlock { - if (typeName.nullable) { - return renderObjectType(typeName.asNonNull()) + if (typeName.isNullable) { + return renderObjectType(typeName.copy(nullable = false)) } return when (typeName) { @@ -77,18 +77,18 @@ abstract class TypeRenderer { val target: TypeName val method: String when { - typeName.lowerBounds.size == 1 -> { - target = typeName.lowerBounds[0] + typeName.inTypes.size == 1 -> { + target = typeName.inTypes[0] method = "supertypeOf" } - typeName.upperBounds.size == 1 -> { - target = typeName.upperBounds[0] + typeName.outTypes.size == 1 -> { + target = typeName.outTypes[0] method = "subtypeOf" } else -> throw IllegalArgumentException( "Unrepresentable wildcard type. Cannot have more than one bound: $typeName") } - CodeBlock.of("%T.%L(%T::class.java)", Types::class, method, target.asNonNull()) + CodeBlock.of("%T.%L(%T::class.java)", Types::class, method, target.copy(nullable = false)) } is TypeVariableName -> renderTypeVariable(typeName) diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeResolver.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeResolver.kt index 579d7b5..3843c92 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeResolver.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/TypeResolver.kt @@ -17,10 +17,10 @@ package com.squareup.moshi.kotlin.codegen import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.ParameterizedTypeName +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeVariableName import com.squareup.kotlinpoet.WildcardTypeName -import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy /** * Resolves type parameters against a type declaration. Use this to fill in type variables with @@ -35,18 +35,18 @@ open class TypeResolver { is ParameterizedTypeName -> { typeName.rawType.parameterizedBy(*(typeName.typeArguments.map { resolve(it) }.toTypedArray())) - .asNullableIf(typeName.nullable) + .asNullableIf(typeName.isNullable) } is WildcardTypeName -> { when { - typeName.lowerBounds.size == 1 -> { - WildcardTypeName.supertypeOf(resolve(typeName.lowerBounds[0])) - .asNullableIf(typeName.nullable) + typeName.inTypes.size == 1 -> { + WildcardTypeName.consumerOf(resolve(typeName.inTypes[0])) + .asNullableIf(typeName.isNullable) } - typeName.upperBounds.size == 1 -> { - WildcardTypeName.subtypeOf(resolve(typeName.upperBounds[0])) - .asNullableIf(typeName.nullable) + typeName.outTypes.size == 1 -> { + WildcardTypeName.producerOf(resolve(typeName.outTypes[0])) + .asNullableIf(typeName.isNullable) } else -> { throw IllegalArgumentException( diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/kotlintypes.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/kotlintypes.kt index 279dc75..b116943 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/kotlintypes.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/kotlintypes.kt @@ -28,5 +28,5 @@ internal fun TypeName.rawType(): ClassName { } internal fun TypeName.asNullableIf(condition: Boolean): TypeName { - return if (condition) asNullable() else this + return if (condition) copy(nullable = true) else this } diff --git a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/metadata.kt b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/metadata.kt index 9053b2e..5517352 100644 --- a/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/metadata.kt +++ b/kotlin/codegen/src/main/java/com/squareup/moshi/kotlin/codegen/metadata.kt @@ -15,10 +15,10 @@ */ package com.squareup.moshi.kotlin.codegen -import com.squareup.kotlinpoet.ANY import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.STAR import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeVariableName import com.squareup.kotlinpoet.WildcardTypeName @@ -75,11 +75,11 @@ internal fun Type.asTypeName( } if (hasFlexibleUpperBound()) { - return WildcardTypeName.subtypeOf( + return WildcardTypeName.producerOf( flexibleUpperBound.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType)) .asNullableIf(nullable) } else if (hasOuterType()) { - return WildcardTypeName.supertypeOf( + return WildcardTypeName.consumerOf( outerType.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType)) .asNullableIf(nullable) } @@ -107,15 +107,15 @@ internal fun Type.asTypeName( .let { argumentTypeName -> nullableProjection?.let { projection -> when (projection) { - Type.Argument.Projection.IN -> WildcardTypeName.supertypeOf(argumentTypeName) - Type.Argument.Projection.OUT -> WildcardTypeName.subtypeOf(argumentTypeName) - Type.Argument.Projection.STAR -> WildcardTypeName.STAR + Type.Argument.Projection.IN -> WildcardTypeName.consumerOf(argumentTypeName) + Type.Argument.Projection.OUT -> WildcardTypeName.producerOf(argumentTypeName) + Type.Argument.Projection.STAR -> STAR Type.Argument.Projection.INV -> TODO("INV projection is unsupported") } } ?: argumentTypeName } } else { - WildcardTypeName.STAR + STAR } }.toTypedArray() typeName = (typeName as ClassName).parameterizedBy(*remappedArgs) diff --git a/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/KotlinCompilerCall.kt b/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/KotlinCompilerCall.kt index 8b03a5c..90a9567 100644 --- a/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/KotlinCompilerCall.kt +++ b/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/KotlinCompilerCall.kt @@ -140,7 +140,7 @@ class KotlinCompilerCall(var scratchDir: File) { ZipEntry("META-INF/services/${entry.key.qualifiedName}")) val serviceFile = Okio.buffer(Okio.sink(zipOutputStream)) for (implementation in entry.value) { - serviceFile.writeUtf8(implementation.qualifiedName) + serviceFile.writeUtf8(implementation.qualifiedName!!) serviceFile.writeUtf8("\n") } serviceFile.emit() // Don't close the entry; that closes the file. diff --git a/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/TypeResolverTest.kt b/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/TypeResolverTest.kt index e6290b0..e7ab974 100644 --- a/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/TypeResolverTest.kt +++ b/kotlin/codegen/src/test/java/com/squareup/moshi/kotlin/codegen/TypeResolverTest.kt @@ -26,22 +26,21 @@ class TypeResolverTest { @Test fun ensureClassNameNullabilityIsPreserved() { - assertThat(resolver.resolve(Int::class.asClassName().asNullable()).nullable).isTrue() + assertThat(resolver.resolve(Int::class.asClassName().copy(nullable = true)).isNullable).isTrue() } @Test fun ensureParameterizedNullabilityIsPreserved() { - val nullableTypeName = List::class.plusParameter(String::class) - .asNullable() + val nullableTypeName = List::class.plusParameter(String::class).copy(nullable = true) - assertThat(resolver.resolve(nullableTypeName).nullable).isTrue() + assertThat(resolver.resolve(nullableTypeName).isNullable).isTrue() } @Test fun ensureWildcardNullabilityIsPreserved() { - val nullableTypeName = WildcardTypeName.subtypeOf(List::class.asClassName()) - .asNullable() + val nullableTypeName = WildcardTypeName.producerOf(List::class.asClassName()) + .copy(nullable = true) - assertThat(resolver.resolve(nullableTypeName).nullable).isTrue() + assertThat(resolver.resolve(nullableTypeName).isNullable).isTrue() } }