Skip to content

Commit

Permalink
Generate input arguments for sub projections
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbakker committed Jun 17, 2021
1 parent 0a48fda commit 838dd35
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -200,29 +200,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
javaType.addMethod(noArgMethodBuilder.build())

if (it.first.inputValueDefinitions.isNotEmpty()) {
val methodBuilder = MethodSpec.methodBuilder(ReservedKeywordSanitizer.sanitize(it.first.name))
.returns(ClassName.get(getPackageName(), projectionName))
.addCode(
"""
$projectionName projection = new $projectionName(this, this);
getFields().put("${it.first.name}", projection);
getInputArguments().computeIfAbsent("${it.first.name}", k -> new ${'$'}T<>());
${it.first.inputValueDefinitions.joinToString("\n") { input ->
"""InputArgument ${input.name}Arg = new InputArgument("${input.name}", ${input.name});
getInputArguments().get("${it.first.name}").add(${input.name}Arg);
""".trimIndent()
}}
return projection;
""".trimIndent(),
ArrayList::class.java
)
.addModifiers(Modifier.PUBLIC)

it.first.inputValueDefinitions.forEach { input ->
methodBuilder.addParameter(ParameterSpec.builder(typeUtils.findReturnType(input.type), input.name).build())
}

javaType.addMethod(methodBuilder.build())
addFieldSelectionMethodWithArguments(it.first, projectionName, javaType)
}

val processedEdges = mutableSetOf<Pair<String, String>>()
Expand Down Expand Up @@ -257,6 +235,34 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
return CodeGenResult(clientProjections = listOf(javaFile)).merge(codeGenResult).merge(concreteTypesResult).merge(unionTypesResult)
}

private fun addFieldSelectionMethodWithArguments(fieldDefinition: FieldDefinition, projectionName: String, javaType: TypeSpec.Builder): TypeSpec.Builder? {
val methodBuilder = MethodSpec.methodBuilder(ReservedKeywordSanitizer.sanitize(fieldDefinition.name))
.returns(ClassName.get(getPackageName(), projectionName))
.addCode(
"""
$projectionName projection = new $projectionName(this, this);
getFields().put("${fieldDefinition.name}", projection);
getInputArguments().computeIfAbsent("${fieldDefinition.name}", k -> new ${'$'}T<>());
${
fieldDefinition.inputValueDefinitions.joinToString("\n") { input ->
"""InputArgument ${input.name}Arg = new InputArgument("${input.name}", ${input.name});
getInputArguments().get("${fieldDefinition.name}").add(${input.name}Arg);
""".trimIndent()
}
}
return projection;
""".trimIndent(),
ArrayList::class.java
)
.addModifiers(Modifier.PUBLIC)

fieldDefinition.inputValueDefinitions.forEach { input ->
println("addFieldSelectionMethodWithArguments: $fieldDefinition")
methodBuilder.addParameter(ParameterSpec.builder(typeUtils.findReturnType(input.type), input.name).build())
}
return javaType.addMethod(methodBuilder.build())
}

private fun createEntitiesRootProjection(federatedTypes: List<ObjectTypeDefinition>): CodeGenResult {
val clazzName = "EntitiesProjectionRoot"
val javaType = TypeSpec.classBuilder(clazzName)
Expand Down Expand Up @@ -415,6 +421,7 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
.addModifiers(Modifier.PUBLIC)
.build()
)

val updatedProcessedEdges = processedEdges.toMutableSet()
updatedProcessedEdges.add(Pair(it.second!!.name, type.name))
createSubProjection(it.second!!, javaType.build(), root, "${truncatePrefix(prefix)}_${it.first.name.capitalize()}", updatedProcessedEdges, queryDepth + 1)
Expand All @@ -437,6 +444,34 @@ class ClientApiGenerator(private val config: CodeGenConfig, private val document
.addModifiers(Modifier.PUBLIC)
.build()
)

if (it.inputValueDefinitions.isNotEmpty()) {
val methodWithInputArgumentsBuilder = MethodSpec.methodBuilder(ReservedKeywordSanitizer.sanitize(it.name))
.returns(ClassName.get(getPackageName(), javaType.build().name))
.addCode(
"""
getFields().put("${it.name}", null);
getInputArguments().computeIfAbsent("${it.name}", k -> new ${'$'}T<>());
${
it.inputValueDefinitions.joinToString("\n") { input ->
"""InputArgument ${input.name}Arg = new InputArgument("${input.name}", ${input.name});
getInputArguments().get("${it.name}").add(${input.name}Arg);
""".trimIndent()
}
}
return this;
""".trimIndent(),
ArrayList::class.java
)
.addModifiers(Modifier.PUBLIC)

it.inputValueDefinitions.forEach { input ->
methodWithInputArgumentsBuilder.addParameter(ParameterSpec.builder(typeUtils.findReturnType(input.type), input.name).build())
}

javaType.addMethod(methodWithInputArgumentsBuilder.build())
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ class ClientApiGenTest {
schemas = setOf(schema),
packageName = basePackageName,
generateClientApi = true,
writeToFiles = true
)
).generate()

Expand Down Expand Up @@ -1513,7 +1512,7 @@ class ClientApiGenTest {
}

@Test
fun `Input arguments on sub types should be support in the query API`() {
fun `Input arguments on root projections should be support in the query API`() {
val schema = """
type Query {
movies: [Movie]
Expand Down Expand Up @@ -1542,7 +1541,39 @@ class ClientApiGenTest {
val methodWithArgs = methodSpecs.find { it.parameters.size > 0 }
assertThat(methodWithArgs).isNotNull
assertThat(methodWithArgs!!.parameters[0].name).isEqualTo("leadCharactersOnly")
assertThat(methodWithArgs!!.parameters[0].type.toString()).isEqualTo("java.lang.Boolean")
assertThat(methodWithArgs.parameters[0].type.toString()).isEqualTo("java.lang.Boolean")
}

@Test
fun `Input arguments on sub projections should be support in the query API`() {
val schema = """
type Query {
movies: [Movie]
}
type Movie {
actors: [Actor]
}
type Actor {
awards(oscarsOnly: Boolean): String
}
""".trimIndent()

val codeGenResult = CodeGen(
CodeGenConfig(
schemas = setOf(schema),
packageName = basePackageName,
generateClientApi = true,
writeToFiles = true
)
).generate()

val methodSpecs = codeGenResult.clientProjections[1].typeSpec.methodSpecs
val methodWithArgs = methodSpecs.filter { !it.isConstructor }.find { it.parameters.size > 0 }
assertThat(methodWithArgs).isNotNull
assertThat(methodWithArgs!!.parameters[0].name).isEqualTo("oscarsOnly")
assertThat(methodWithArgs.parameters[0].type.toString()).isEqualTo("java.lang.Boolean")
}

private fun compileAndGetClass(dataTypes: List<JavaFile>, type: String): Class<*> {
Expand Down

0 comments on commit 838dd35

Please sign in to comment.