Fix handling of typealiases in non-classname envs + wildcard fix… (#987)

* Correctly render non-classname wildcard types

Resolves #984
Resolves #985

* Add thorough typealias test

* Expand unwrapTypeAlias to parameterized and wildcard types

Resolves #983

* Disable Werror for now
This commit is contained in:
Zac Sweers
2019-10-30 21:15:28 -04:00
committed by GitHub
parent ac789070e8
commit 092175ae90
4 changed files with 87 additions and 6 deletions

View File

@@ -40,13 +40,19 @@ import com.squareup.moshi.Types
abstract class TypeRenderer {
abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock
fun render(typeName: TypeName): CodeBlock {
fun render(typeName: TypeName, forceBox: Boolean = false): CodeBlock {
if (typeName.isNullable) {
return renderObjectType(typeName.copy(nullable = false))
}
return when (typeName) {
is ClassName -> CodeBlock.of("%T::class.java", typeName)
is ClassName -> {
if (forceBox) {
renderObjectType(typeName)
} else {
CodeBlock.of("%T::class.java", typeName)
}
}
is ParameterizedTypeName -> {
// If it's an Array type, we shortcut this to return Types.arrayOf()
@@ -88,7 +94,7 @@ abstract class TypeRenderer {
else -> throw IllegalArgumentException(
"Unrepresentable wildcard type. Cannot have more than one bound: $typeName")
}
CodeBlock.of("%T.%L(%T::class.java)", Types::class, method, target.copy(nullable = false))
CodeBlock.of("%T.%L(%L)", Types::class, method, render(target, forceBox = true))
}
is TypeVariableName -> renderTypeVariable(typeName)
@@ -111,4 +117,4 @@ abstract class TypeRenderer {
else -> false
}
}
}
}

View File

@@ -18,8 +18,13 @@ package com.squareup.moshi.kotlin.codegen
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.ParameterizedTypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.STAR
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.WildcardTypeName
import com.squareup.kotlinpoet.asClassName
import com.squareup.kotlinpoet.asTypeName
import com.squareup.kotlinpoet.classinspector.elements.ElementsClassInspector
@@ -315,5 +320,33 @@ private fun String.escapeDollarSigns(): String {
}
private fun TypeName.unwrapTypeAlias(): TypeName {
return tag<TypeNameAliasTag>()?.type ?: this
return when (this) {
is ClassName -> {
tag<TypeNameAliasTag>()?.type ?: this
}
is ParameterizedTypeName -> {
return (rawType.unwrapTypeAlias() as ClassName).parameterizedBy(typeArguments.map { it.unwrapTypeAlias() })
}
is TypeVariableName -> {
return copy(bounds = bounds.map { it.unwrapTypeAlias() })
}
is WildcardTypeName -> {
// TODO Would be nice if KotlinPoet modeled these easier.
// Producer type - empty inTypes, single element outTypes
// Consumer type - single element inTypes, single ANY element outType.
return when {
this == STAR -> this
outTypes.isNotEmpty() && inTypes.isEmpty() -> {
WildcardTypeName.producerOf(outTypes[0].unwrapTypeAlias())
.copy(nullable = isNullable, annotations = annotations)
}
inTypes.isNotEmpty() -> {
WildcardTypeName.consumerOf(inTypes[0].unwrapTypeAlias())
.copy(nullable = isNullable, annotations = annotations)
}
else -> throw UnsupportedOperationException("Not possible.")
}
}
else -> throw UnsupportedOperationException("Type '${javaClass.simpleName}' is illegal. Only classes, parameterized types, wildcard types, or type variables are allowed.")
}
}