Merge pull request #764 from square/jwilson.1128.kp10rc3

Upgrade to KotlinPoet 1.0-RC3
This commit is contained in:
Jesse Wilson 2018-11-29 07:03:27 -05:00 committed by GitHub
commit 2e241bff6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 66 additions and 63 deletions

View file

@ -25,7 +25,7 @@
<dependency> <dependency>
<groupId>com.squareup</groupId> <groupId>com.squareup</groupId>
<artifactId>kotlinpoet</artifactId> <artifactId>kotlinpoet</artifactId>
<version>1.0.0-RC2</version> <version>1.0.0-RC3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.auto</groupId> <groupId>com.google.auto</groupId>

View file

@ -71,7 +71,7 @@ internal class AdapterGenerator(
.build() .build()
private val valueParam = ParameterSpec.builder( private val valueParam = ParameterSpec.builder(
nameAllocator.newName("value"), nameAllocator.newName("value"),
originalTypeName.asNullable()) originalTypeName.copy(nullable = true))
.build() .build()
private val jsonAdapterTypeName = JsonAdapter::class.asClassName().parameterizedBy(originalTypeName) private val jsonAdapterTypeName = JsonAdapter::class.asClassName().parameterizedBy(originalTypeName)
@ -183,24 +183,24 @@ internal class AdapterGenerator(
result.beginControlFlow("%L -> ", index) result.beginControlFlow("%L -> ", index)
if (property.delegateKey.nullable) { if (property.delegateKey.nullable) {
result.addStatement("%N = %N.fromJson(%N)", result.addStatement("%N = %N.fromJson(%N)",
property.localName, nameAllocator.get(property.delegateKey), readerParam) property.localName, nameAllocator[property.delegateKey], readerParam)
} else { } else {
result.addStatement("%N = %N.fromJson(%N)" + result.addStatement("%N = %N.fromJson(%N) ?: throw·%T(%P)",
" ?: throw %T(\"Non-null value '%N' was null at \${%N.path}\")", property.localName, nameAllocator[property.delegateKey], readerParam,
property.localName, nameAllocator.get(property.delegateKey), readerParam, JsonDataException::class,
JsonDataException::class, property.localName, readerParam) "Non-null value '${property.localName}' was null at \${${readerParam.name}.path}")
} }
result.addStatement("%N = true", property.localIsPresentName) result.addStatement("%N = true", property.localIsPresentName)
result.endControlFlow() result.endControlFlow()
} else { } else {
if (property.delegateKey.nullable) { if (property.delegateKey.nullable) {
result.addStatement("%L -> %N = %N.fromJson(%N)", result.addStatement("%L -> %N = %N.fromJson(%N)",
index, property.localName, nameAllocator.get(property.delegateKey), readerParam) index, property.localName, nameAllocator[property.delegateKey], readerParam)
} else { } else {
result.addStatement("%L -> %N = %N.fromJson(%N)" + result.addStatement("%L -> %N = %N.fromJson(%N) ?: throw·%T(%P)",
" ?: throw %T(\"Non-null value '%N' was null at \${%N.path}\")", index, property.localName, nameAllocator[property.delegateKey], readerParam,
index, property.localName, nameAllocator.get(property.delegateKey), readerParam, JsonDataException::class,
JsonDataException::class, property.localName, readerParam) "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. // Call the constructor providing only required parameters.
var hasOptionalParameters = false var hasOptionalParameters = false
result.addCode("%[var %N = %T(", resultName, originalTypeName) result.addCode("«var %N = %T(", resultName, originalTypeName)
var separator = "\n" var separator = "\n"
for (property in propertyList) { for (property in propertyList) {
if (!property.hasConstructorParameter) { if (!property.hasConstructorParameter) {
@ -230,20 +230,20 @@ internal class AdapterGenerator(
result.addCode(separator) result.addCode(separator)
result.addCode("%N = %N", property.name, property.localName) result.addCode("%N = %N", property.name, property.localName)
if (property.isRequired) { if (property.isRequired) {
result.addCode(" ?: throw %T(\"Required property '%L' missing at \${%N.path}\")", result.addCode(" ?: throw·%T(%P)", JsonDataException::class,
JsonDataException::class, property.localName, readerParam) "Required property '${property.localName}' missing at \${${readerParam.name}.path}")
} }
separator = ",\n" separator = ",\n"
} }
result.addCode(")%]\n", originalTypeName) result.addCode(")»\n", originalTypeName)
// Call either the constructor again, or the copy() method, this time providing any optional // Call either the constructor again, or the copy() method, this time providing any optional
// parameters that we have. // parameters that we have.
if (hasOptionalParameters) { if (hasOptionalParameters) {
if (isDataClass) { if (isDataClass) {
result.addCode("%[%1N = %1N.copy(", resultName) result.addCode("«%1N = %1N.copy(", resultName)
} else { } else {
result.addCode("%[%1N = %2T(", resultName, originalTypeName) result.addCode("«%1N = %2T(", resultName, originalTypeName)
} }
separator = "\n" separator = "\n"
for (property in propertyList) { for (property in propertyList) {
@ -255,17 +255,21 @@ internal class AdapterGenerator(
} }
result.addCode(separator) result.addCode(separator)
if (property.differentiateAbsentFromNull) { when {
property.differentiateAbsentFromNull -> {
result.addCode("%2N = if (%3N) %4N else %1N.%2N", result.addCode("%2N = if (%3N) %4N else %1N.%2N",
resultName, property.name, property.localIsPresentName, property.localName) resultName, property.name, property.localIsPresentName, property.localName)
} else if (property.isRequired) { }
property.isRequired -> {
result.addCode("%1N = %2N", property.name, property.localName) result.addCode("%1N = %2N", property.name, property.localName)
} else { }
else -> {
result.addCode("%2N = %3N ?: %1N.%2N", resultName, property.name, property.localName) result.addCode("%2N = %3N ?: %1N.%2N", resultName, property.name, property.localName)
} }
}
separator = ",\n" separator = ",\n"
} }
result.addCode("%])\n") result.addCode("»)\n")
} }
// Assign properties not present in the constructor. // Assign properties not present in the constructor.
@ -301,7 +305,7 @@ internal class AdapterGenerator(
propertyList.forEach { property -> propertyList.forEach { property ->
result.addStatement("%N.name(%S)", writerParam, property.jsonName) result.addStatement("%N.name(%S)", writerParam, property.jsonName)
result.addStatement("%N.toJson(%N, %N.%L)", 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) result.addStatement("%N.endObject()", writerParam)

View file

@ -37,7 +37,7 @@ internal data class DelegateKey(
private val type: TypeName, private val type: TypeName,
private val jsonQualifiers: List<AnnotationSpec> private val jsonQualifiers: List<AnnotationSpec>
) { ) {
val nullable get() = type.nullable val nullable get() = type.isNullable
/** Returns an adapter to use when encoding and decoding this property. */ /** Returns an adapter to use when encoding and decoding this property. */
fun generateProperty( fun generateProperty(
@ -86,12 +86,12 @@ private fun TypeName.toVariableName(): String {
val base = when (this) { val base = when (this) {
is ClassName -> simpleName is ClassName -> simpleName
is ParameterizedTypeName -> rawType.simpleName + "Of" + typeArguments.toVariableNames() is ParameterizedTypeName -> rawType.simpleName + "Of" + typeArguments.toVariableNames()
is WildcardTypeName -> (lowerBounds + upperBounds).toVariableNames() is WildcardTypeName -> (inTypes + outTypes).toVariableNames()
is TypeVariableName -> name + bounds.toVariableNames() is TypeVariableName -> name + bounds.toVariableNames()
else -> throw IllegalArgumentException("Unrecognized type! $this") else -> throw IllegalArgumentException("Unrecognized type! $this")
} }
return if (nullable) { return if (isNullable) {
"Nullable$base" "Nullable$base"
} else { } else {
base base

View file

@ -44,7 +44,7 @@ internal class PropertyGenerator(
} }
fun generateLocalProperty(): PropertySpec { fun generateLocalProperty(): PropertySpec {
return PropertySpec.builder(localName, target.type.asNullable()) return PropertySpec.builder(localName, target.type.copy(nullable = true))
.mutable(true) .mutable(true)
.initializer("null") .initializer("null")
.build() .build()

View file

@ -210,7 +210,7 @@ internal data class TargetType(
bounds = *possibleBounds.toTypedArray(), bounds = *possibleBounds.toTypedArray(),
variance = it.varianceModifier) variance = it.varianceModifier)
} }
return@map typeVar.reified(it.reified) return@map typeVar.copy(reified = it.reified)
} }
} }

View file

@ -41,8 +41,8 @@ abstract class TypeRenderer {
abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock
fun render(typeName: TypeName): CodeBlock { fun render(typeName: TypeName): CodeBlock {
if (typeName.nullable) { if (typeName.isNullable) {
return renderObjectType(typeName.asNonNull()) return renderObjectType(typeName.copy(nullable = false))
} }
return when (typeName) { return when (typeName) {
@ -77,18 +77,18 @@ abstract class TypeRenderer {
val target: TypeName val target: TypeName
val method: String val method: String
when { when {
typeName.lowerBounds.size == 1 -> { typeName.inTypes.size == 1 -> {
target = typeName.lowerBounds[0] target = typeName.inTypes[0]
method = "supertypeOf" method = "supertypeOf"
} }
typeName.upperBounds.size == 1 -> { typeName.outTypes.size == 1 -> {
target = typeName.upperBounds[0] target = typeName.outTypes[0]
method = "subtypeOf" method = "subtypeOf"
} }
else -> throw IllegalArgumentException( else -> throw IllegalArgumentException(
"Unrepresentable wildcard type. Cannot have more than one bound: $typeName") "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) is TypeVariableName -> renderTypeVariable(typeName)

View file

@ -17,10 +17,10 @@ package com.squareup.moshi.kotlin.codegen
import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.ParameterizedTypeName import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeVariableName import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.WildcardTypeName 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 * Resolves type parameters against a type declaration. Use this to fill in type variables with
@ -35,18 +35,18 @@ open class TypeResolver {
is ParameterizedTypeName -> { is ParameterizedTypeName -> {
typeName.rawType.parameterizedBy(*(typeName.typeArguments.map { resolve(it) }.toTypedArray())) typeName.rawType.parameterizedBy(*(typeName.typeArguments.map { resolve(it) }.toTypedArray()))
.asNullableIf(typeName.nullable) .asNullableIf(typeName.isNullable)
} }
is WildcardTypeName -> { is WildcardTypeName -> {
when { when {
typeName.lowerBounds.size == 1 -> { typeName.inTypes.size == 1 -> {
WildcardTypeName.supertypeOf(resolve(typeName.lowerBounds[0])) WildcardTypeName.consumerOf(resolve(typeName.inTypes[0]))
.asNullableIf(typeName.nullable) .asNullableIf(typeName.isNullable)
} }
typeName.upperBounds.size == 1 -> { typeName.outTypes.size == 1 -> {
WildcardTypeName.subtypeOf(resolve(typeName.upperBounds[0])) WildcardTypeName.producerOf(resolve(typeName.outTypes[0]))
.asNullableIf(typeName.nullable) .asNullableIf(typeName.isNullable)
} }
else -> { else -> {
throw IllegalArgumentException( throw IllegalArgumentException(

View file

@ -28,5 +28,5 @@ internal fun TypeName.rawType(): ClassName {
} }
internal fun TypeName.asNullableIf(condition: Boolean): TypeName { internal fun TypeName.asNullableIf(condition: Boolean): TypeName {
return if (condition) asNullable() else this return if (condition) copy(nullable = true) else this
} }

View file

@ -15,10 +15,10 @@
*/ */
package com.squareup.moshi.kotlin.codegen package com.squareup.moshi.kotlin.codegen
import com.squareup.kotlinpoet.ANY
import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.STAR
import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeVariableName import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.WildcardTypeName import com.squareup.kotlinpoet.WildcardTypeName
@ -75,11 +75,11 @@ internal fun Type.asTypeName(
} }
if (hasFlexibleUpperBound()) { if (hasFlexibleUpperBound()) {
return WildcardTypeName.subtypeOf( return WildcardTypeName.producerOf(
flexibleUpperBound.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType)) flexibleUpperBound.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType))
.asNullableIf(nullable) .asNullableIf(nullable)
} else if (hasOuterType()) { } else if (hasOuterType()) {
return WildcardTypeName.supertypeOf( return WildcardTypeName.consumerOf(
outerType.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType)) outerType.asTypeName(nameResolver, getTypeParameter, useAbbreviatedType))
.asNullableIf(nullable) .asNullableIf(nullable)
} }
@ -107,15 +107,15 @@ internal fun Type.asTypeName(
.let { argumentTypeName -> .let { argumentTypeName ->
nullableProjection?.let { projection -> nullableProjection?.let { projection ->
when (projection) { when (projection) {
Type.Argument.Projection.IN -> WildcardTypeName.supertypeOf(argumentTypeName) Type.Argument.Projection.IN -> WildcardTypeName.consumerOf(argumentTypeName)
Type.Argument.Projection.OUT -> WildcardTypeName.subtypeOf(argumentTypeName) Type.Argument.Projection.OUT -> WildcardTypeName.producerOf(argumentTypeName)
Type.Argument.Projection.STAR -> WildcardTypeName.STAR Type.Argument.Projection.STAR -> STAR
Type.Argument.Projection.INV -> TODO("INV projection is unsupported") Type.Argument.Projection.INV -> TODO("INV projection is unsupported")
} }
} ?: argumentTypeName } ?: argumentTypeName
} }
} else { } else {
WildcardTypeName.STAR STAR
} }
}.toTypedArray() }.toTypedArray()
typeName = (typeName as ClassName).parameterizedBy(*remappedArgs) typeName = (typeName as ClassName).parameterizedBy(*remappedArgs)

View file

@ -140,7 +140,7 @@ class KotlinCompilerCall(var scratchDir: File) {
ZipEntry("META-INF/services/${entry.key.qualifiedName}")) ZipEntry("META-INF/services/${entry.key.qualifiedName}"))
val serviceFile = Okio.buffer(Okio.sink(zipOutputStream)) val serviceFile = Okio.buffer(Okio.sink(zipOutputStream))
for (implementation in entry.value) { for (implementation in entry.value) {
serviceFile.writeUtf8(implementation.qualifiedName) serviceFile.writeUtf8(implementation.qualifiedName!!)
serviceFile.writeUtf8("\n") serviceFile.writeUtf8("\n")
} }
serviceFile.emit() // Don't close the entry; that closes the file. serviceFile.emit() // Don't close the entry; that closes the file.

View file

@ -26,22 +26,21 @@ class TypeResolverTest {
@Test @Test
fun ensureClassNameNullabilityIsPreserved() { fun ensureClassNameNullabilityIsPreserved() {
assertThat(resolver.resolve(Int::class.asClassName().asNullable()).nullable).isTrue() assertThat(resolver.resolve(Int::class.asClassName().copy(nullable = true)).isNullable).isTrue()
} }
@Test @Test
fun ensureParameterizedNullabilityIsPreserved() { fun ensureParameterizedNullabilityIsPreserved() {
val nullableTypeName = List::class.plusParameter(String::class) val nullableTypeName = List::class.plusParameter(String::class).copy(nullable = true)
.asNullable()
assertThat(resolver.resolve(nullableTypeName).nullable).isTrue() assertThat(resolver.resolve(nullableTypeName).isNullable).isTrue()
} }
@Test @Test
fun ensureWildcardNullabilityIsPreserved() { fun ensureWildcardNullabilityIsPreserved() {
val nullableTypeName = WildcardTypeName.subtypeOf(List::class.asClassName()) val nullableTypeName = WildcardTypeName.producerOf(List::class.asClassName())
.asNullable() .copy(nullable = true)
assertThat(resolver.resolve(nullableTypeName).nullable).isTrue() assertThat(resolver.resolve(nullableTypeName).isNullable).isTrue()
} }
} }