Skip to content

Commit

Permalink
Add support for default variable values. (#2704)
Browse files Browse the repository at this point in the history
This only works for scalar types and their list/optional variants, not
input object types

closes #2703 and part of #2686
  • Loading branch information
martinbonnin committed Oct 28, 2020
1 parent 93df14d commit d9039bf
Show file tree
Hide file tree
Showing 12 changed files with 1,239 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal fun Operation.ast(
typesPackageName = context.typesPackageName
),
isOptional = variable.optional(),
defaultValue = null,
defaultValue = variable.defaultValue,
description = ""
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ internal object KotlinCodeGen {
}
}

// TODO: fix for input object types
fun Any.toDefaultValueCodeBlock(typeName: TypeName, fieldType: FieldType): CodeBlock = when {
this is Number -> CodeBlock.of("%L%L", castTo(typeName), if (typeName == LONG) "L" else "")
fieldType is FieldType.Scalar.Enum -> CodeBlock.of("%T.safeValueOf(%S)", typeName, this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.createMapp
import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.marshallerFunSpec
import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.responseFieldsPropertySpec
import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.suppressWarningsAnnotation
import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.toDefaultValueCodeBlock
import com.apollographql.apollo.compiler.codegen.kotlin.KotlinCodeGen.toMapperFun
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.CodeBlock
Expand Down Expand Up @@ -165,13 +166,26 @@ private val OperationType.primaryConstructorSpec: FunSpec
return FunSpec
.constructorBuilder()
.addParameters(variables.fields.map { variable ->
val typeName = variable.type.asTypeName()
val typeName = variable.type.asTypeName().let {
if (variable.isOptional) Input::class.asClassName().parameterizedBy(it) else it
}
val defaultValue = variable.defaultValue?.toDefaultValueCodeBlock(typeName, variable.type)
.let { code ->
if (variable.isOptional) {
code?.let { CodeBlock.of("%T.optional(%L)", Input::class, it) } ?: CodeBlock.of("%T.absent()", Input::class)
} else {
code
}
}

ParameterSpec
.builder(
name = variable.name,
type = if (variable.isOptional) Input::class.asClassName().parameterizedBy(typeName) else typeName
type = typeName
)
.applyIf(variable.isOptional) { defaultValue("%T.absent()", Input::class.asClassName()) }
.applyIf(defaultValue != null) {
defaultValue(defaultValue!!)
}
.build()
})
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.apollographql.apollo.compiler.ir
data class Variable(
val name: String,
val type: String,
val defaultValue: Any?,
val sourceLocation: SourceLocation
) {
fun optional(): Boolean = !type.endsWith(suffix = "!")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.apollographql.apollo.compiler.parser.introspection.IntrospectionSchem
import com.apollographql.apollo.compiler.parser.introspection.asGraphQLType
import com.apollographql.apollo.compiler.parser.introspection.isAssignableFrom
import com.apollographql.apollo.compiler.parser.introspection.possibleTypes
import com.apollographql.apollo.compiler.parser.introspection.resolveType
import org.antlr.v4.runtime.ANTLRInputStream
import org.antlr.v4.runtime.BaseErrorListener
import org.antlr.v4.runtime.CommonTokenStream
Expand Down Expand Up @@ -232,10 +233,12 @@ class GraphQLDocumentParser(
message = "Unknown variable type `$type`",
token = type().start
)

return ParseResult(
result = Variable(
name = name,
type = type,
defaultValue = defaultValue()?.value()?.parse(schema.resolveType(type)),
sourceLocation = SourceLocation(variable().NAME().symbol)
),
usedTypes = setOf(schemaType.name)
Expand Down
Loading

0 comments on commit d9039bf

Please sign in to comment.