From 9cb8a32e91eb82b0dc9b93d6ba96887ca8b36074 Mon Sep 17 00:00:00 2001 From: Ivan Savytskyi Date: Tue, 13 Jun 2017 00:53:15 -0400 Subject: [PATCH 1/3] Fix missing symbol for input type with default enum value Closes #520 --- .../apollo/compiler/BuilderTypeSpecBuilder.kt | 17 +++++++++++++++-- .../compiler/InputObjectTypeSpecBuilder.kt | 9 ++++++++- .../compiler/OperationTypeSpecBuilder.kt | 17 ++++++++++++++--- .../compiler/VariablesTypeSpecBuilder.kt | 9 ++++++++- .../example/input_object_type/TestQuery.json | 6 ++++++ .../input_object_type/type/ReviewInput.java | 19 +++++++++++++++++-- apollo-compiler/src/test/graphql/schema.json | 10 ++++++++++ 7 files changed, 78 insertions(+), 9 deletions(-) diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt index 857000588b3..b59dce610a8 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt @@ -1,12 +1,14 @@ package com.apollographql.apollo.compiler +import com.apollographql.apollo.compiler.ir.TypeDeclaration import com.squareup.javapoet.* import javax.lang.model.element.Modifier class BuilderTypeSpecBuilder( val targetObjectClassName: ClassName, val fields: List>, - val fieldDefaultValues: Map + val fieldDefaultValues: Map, + val typeDeclarations: List ) { fun build(): TypeSpec { return TypeSpec.classBuilder(builderClassName) @@ -25,9 +27,17 @@ class BuilderTypeSpecBuilder( val defaultValue = fieldDefaultValues[fieldName]?.let { (it as? Number)?.castTo(fieldType.withoutAnnotations()) ?: it } + val initializerCode = defaultValue?.let { + val isEnum = fieldType.isEnum(typeDeclarations) + if (isEnum) + CodeBlock.of("\$T.\$L", fieldType.withoutAnnotations(), defaultValue) + else + CodeBlock.of("\$L", defaultValue) + } + fieldType.isEnum(typeDeclarations) FieldSpec.builder(fieldType, fieldName) .addModifiers(Modifier.PRIVATE) - .initializer(defaultValue?.let { CodeBlock.of("\$L", it) } ?: CodeBlock.of("")) + .let { if (initializerCode != null) it.initializer(initializerCode) else it } .build() }) @@ -83,5 +93,8 @@ class BuilderTypeSpecBuilder( } else { this } + + private fun TypeName.isEnum(typeDeclarations: List) = + ((this is ClassName) && typeDeclarations.count { it.kind == "EnumType" && it.name == simpleName() } > 0) } } diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/InputObjectTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/InputObjectTypeSpecBuilder.kt index 56e7ef29c55..e3e840485a2 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/InputObjectTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/InputObjectTypeSpecBuilder.kt @@ -56,7 +56,14 @@ class InputObjectTypeSpecBuilder( val builderFields = fields.map { it.name.decapitalize() to it.javaTypeName(context) } val builderFieldDefaultValues = fields.associate { it.name.decapitalize() to it.defaultValue } return addMethod(BuilderTypeSpecBuilder.builderFactoryMethod()) - .addType(BuilderTypeSpecBuilder(objectClassName, builderFields, builderFieldDefaultValues).build()) + .addType( + BuilderTypeSpecBuilder( + targetObjectClassName = objectClassName, + fields = builderFields, + fieldDefaultValues = builderFieldDefaultValues, + typeDeclarations = context.typeDeclarations + ).build() + ) } } diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/OperationTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/OperationTypeSpecBuilder.kt index 71bb75e4180..6a60bfb99e4 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/OperationTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/OperationTypeSpecBuilder.kt @@ -170,13 +170,24 @@ class OperationTypeSpecBuilder( private fun TypeSpec.Builder.addBuilder(context: CodeGenerationContext): TypeSpec.Builder { addMethod(BuilderTypeSpecBuilder.builderFactoryMethod()) if (operation.variables.isEmpty()) { - return BuilderTypeSpecBuilder(ClassName.get("", OPERATION_TYPE_NAME), emptyList(), emptyMap()) - .let { addType(it.build()) } + return BuilderTypeSpecBuilder( + targetObjectClassName = ClassName.get("", OPERATION_TYPE_NAME), + fields = emptyList(), + fieldDefaultValues = emptyMap(), + typeDeclarations = context.typeDeclarations + ).let { addType(it.build()) } } return operation.variables .map { it.name.decapitalize() to it.type } .map { it.first to JavaTypeResolver(context, context.typesPackage).resolve(it.second).unwrapOptionalType() } - .let { BuilderTypeSpecBuilder(ClassName.get("", OPERATION_TYPE_NAME), it, emptyMap()) } + .let { + BuilderTypeSpecBuilder( + targetObjectClassName = ClassName.get("", OPERATION_TYPE_NAME), + fields = it, + fieldDefaultValues = emptyMap(), + typeDeclarations = context.typeDeclarations + ) + } .let { addType(it.build()) } } diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/VariablesTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/VariablesTypeSpecBuilder.kt index 79fe7f6cac1..5dce16455c6 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/VariablesTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/VariablesTypeSpecBuilder.kt @@ -82,7 +82,14 @@ class VariablesTypeSpecBuilder( } else { val builderFields = variables.map { it.name.decapitalize() to it.javaTypeName(context, context.typesPackage) } return addMethod(BuilderTypeSpecBuilder.builderFactoryMethod()) - .addType(BuilderTypeSpecBuilder(VARIABLES_TYPE_NAME, builderFields, emptyMap()).build()) + .addType( + BuilderTypeSpecBuilder( + targetObjectClassName = VARIABLES_TYPE_NAME, + fields = builderFields, + fieldDefaultValues = emptyMap(), + typeDeclarations = context.typeDeclarations + ).build() + ) } } diff --git a/apollo-compiler/src/test/graphql/com/example/input_object_type/TestQuery.json b/apollo-compiler/src/test/graphql/com/example/input_object_type/TestQuery.json index b5b5525b195..4f9be5e9561 100644 --- a/apollo-compiler/src/test/graphql/com/example/input_object_type/TestQuery.json +++ b/apollo-compiler/src/test/graphql/com/example/input_object_type/TestQuery.json @@ -127,6 +127,12 @@ "name": "favoriteColor", "description": "Favorite color, optional", "type": "ColorInput!" + }, + { + "name": "enumWithDefaultValue", + "description": "for test purpose only", + "type": "Episode", + "defaultValue": "JEDI" } ] }, diff --git a/apollo-compiler/src/test/graphql/com/example/input_object_type/type/ReviewInput.java b/apollo-compiler/src/test/graphql/com/example/input_object_type/type/ReviewInput.java index e57f2daebfd..5434ca985d0 100644 --- a/apollo-compiler/src/test/graphql/com/example/input_object_type/type/ReviewInput.java +++ b/apollo-compiler/src/test/graphql/com/example/input_object_type/type/ReviewInput.java @@ -17,12 +17,16 @@ public final class ReviewInput { private final @Nonnull ColorInput favoriteColor; + private final @Nullable Episode enumWithDefaultValue; + ReviewInput(int stars, @Nullable Integer nullableIntFieldWithDefaultValue, - @Nullable String commentary, @Nonnull ColorInput favoriteColor) { + @Nullable String commentary, @Nonnull ColorInput favoriteColor, + @Nullable Episode enumWithDefaultValue) { this.stars = stars; this.nullableIntFieldWithDefaultValue = nullableIntFieldWithDefaultValue; this.commentary = commentary; this.favoriteColor = favoriteColor; + this.enumWithDefaultValue = enumWithDefaultValue; } public int stars() { @@ -41,6 +45,10 @@ public int stars() { return this.favoriteColor; } + public @Nullable Episode enumWithDefaultValue() { + return this.enumWithDefaultValue; + } + public static Builder builder() { return new Builder(); } @@ -54,6 +62,8 @@ public static final class Builder { private @Nonnull ColorInput favoriteColor; + private @Nullable Episode enumWithDefaultValue = Episode.JEDI; + Builder() { } @@ -77,9 +87,14 @@ public Builder favoriteColor(@Nonnull ColorInput favoriteColor) { return this; } + public Builder enumWithDefaultValue(@Nullable Episode enumWithDefaultValue) { + this.enumWithDefaultValue = enumWithDefaultValue; + return this; + } + public ReviewInput build() { if (favoriteColor == null) throw new IllegalStateException("favoriteColor can't be null"); - return new ReviewInput(stars, nullableIntFieldWithDefaultValue, commentary, favoriteColor); + return new ReviewInput(stars, nullableIntFieldWithDefaultValue, commentary, favoriteColor, enumWithDefaultValue); } } } diff --git a/apollo-compiler/src/test/graphql/schema.json b/apollo-compiler/src/test/graphql/schema.json index 0a19e5cefea..6ee6805e421 100644 --- a/apollo-compiler/src/test/graphql/schema.json +++ b/apollo-compiler/src/test/graphql/schema.json @@ -1643,6 +1643,16 @@ } }, "defaultValue": null + }, + { + "name": "enumWithDefaultValue", + "description": "for test purpose only", + "type": { + "kind": "ENUM", + "name": "Episode", + "ofType": null + }, + "defaultValue": "JEDI" } ], "interfaces": null, From 90422f5d4004bc4d01a1c47e1a159754c78d007f Mon Sep 17 00:00:00 2001 From: Ivan Savytskyi Date: Tue, 13 Jun 2017 00:54:56 -0400 Subject: [PATCH 2/3] Update --- .../apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt index b59dce610a8..e8fd83ec95b 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt @@ -28,8 +28,7 @@ class BuilderTypeSpecBuilder( (it as? Number)?.castTo(fieldType.withoutAnnotations()) ?: it } val initializerCode = defaultValue?.let { - val isEnum = fieldType.isEnum(typeDeclarations) - if (isEnum) + if (fieldType.isEnum(typeDeclarations)) CodeBlock.of("\$T.\$L", fieldType.withoutAnnotations(), defaultValue) else CodeBlock.of("\$L", defaultValue) From 5d9277c9ba3e7543be0786850482f24227459f16 Mon Sep 17 00:00:00 2001 From: Ivan Savytskyi Date: Tue, 13 Jun 2017 00:56:25 -0400 Subject: [PATCH 3/3] Update --- .../apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt index e8fd83ec95b..801d1166140 100644 --- a/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt +++ b/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/BuilderTypeSpecBuilder.kt @@ -32,11 +32,10 @@ class BuilderTypeSpecBuilder( CodeBlock.of("\$T.\$L", fieldType.withoutAnnotations(), defaultValue) else CodeBlock.of("\$L", defaultValue) - } - fieldType.isEnum(typeDeclarations) + } ?: CodeBlock.of("") FieldSpec.builder(fieldType, fieldName) .addModifiers(Modifier.PRIVATE) - .let { if (initializerCode != null) it.initializer(initializerCode) else it } + .initializer(initializerCode) .build() })