Skip to content

Commit

Permalink
Add support for default variable values.
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 27, 2020
1 parent 745357d commit a9ab41a
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 a9ab41a

Please sign in to comment.