diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt index 90e277de7..abdd95c08 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/DataTypeGenerator.kt @@ -346,7 +346,7 @@ abstract class BaseDataTypeGenerator( javaType.addField(field) - val getterName = "get${fieldDefinition.name[0].uppercase()}${fieldDefinition.name.substring(1)}" + val getterName = typeUtils.transformIfDefaultClassMethodExists("get${fieldDefinition.name[0].uppercase()}${fieldDefinition.name.substring(1)}", TypeUtils.Companion.getClass) val getterMethodBuilder = MethodSpec.methodBuilder(getterName).addModifiers(Modifier.PUBLIC).returns(returnType).addStatement("return \$N", ReservedKeywordSanitizer.sanitize(fieldDefinition.name)) if (fieldDefinition.overrideGetter) { getterMethodBuilder.addAnnotation(Override::class.java) @@ -358,7 +358,7 @@ abstract class BaseDataTypeGenerator( javaType.addMethod(getterMethodBuilder.build()) - val setterName = "set${fieldDefinition.name[0].uppercase()}${fieldDefinition.name.substring(1)}" + val setterName = typeUtils.transformIfDefaultClassMethodExists("set${fieldDefinition.name[0].uppercase()}${fieldDefinition.name.substring(1)}", TypeUtils.Companion.setClass) javaType.addMethod( MethodSpec.methodBuilder(setterName) .addModifiers(Modifier.PUBLIC) diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt index 1a5aa1d6c..a1988c0ba 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt @@ -112,7 +112,7 @@ class InterfaceGenerator(private val config: CodeGenConfig, private val document val returnType = typeUtils.findReturnType(fieldDefinition.type, useInterfaceType) val fieldName = fieldDefinition.name - val getterBuilder = MethodSpec.methodBuilder("get${fieldName.capitalized()}") + val getterBuilder = MethodSpec.methodBuilder(typeUtils.transformIfDefaultClassMethodExists("get${fieldName.capitalized()}", TypeUtils.Companion.getClass)) .addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC) .returns(returnType) if (fieldDefinition.description != null) { @@ -121,7 +121,7 @@ class InterfaceGenerator(private val config: CodeGenConfig, private val document javaType.addMethod(getterBuilder.build()) if (config.generateInterfaceSetters) { - val setterBuilder = MethodSpec.methodBuilder("set${fieldName.capitalized()}") + val setterBuilder = MethodSpec.methodBuilder(typeUtils.transformIfDefaultClassMethodExists("set${fieldName.capitalized()}", TypeUtils.Companion.setClass)) .addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC) .addParameter(returnType, ReservedKeywordSanitizer.sanitize(fieldName)) diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/TypeUtils.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/TypeUtils.kt index 8ae078359..bb8f3eb6f 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/TypeUtils.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/TypeUtils.kt @@ -214,4 +214,17 @@ class TypeUtils(private val packageName: String, private val config: CodeGenConf return document.getDefinitionsOfType(InterfaceTypeDefinition::class.java) .any { node -> node.name == findInnerType(fieldDefinitionType).name } } + + fun transformIfDefaultClassMethodExists(originName: String, defaultMethodName: String): String { + return if (defaultMethodName == originName) { + return originName.plus("Field") + } else { + originName + } + } + + companion object { + const val getClass = "getClass" + const val setClass = "setClass" + } } diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt index f2d038362..16b15c106 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/KotlinCodeGenTest.kt @@ -2540,6 +2540,44 @@ It takes a title and such. assertCompilesKotlin(codeGenResult) } + @Test + fun `can generate code based on GraphQL type, which fields express java key-words`() { + val schema = """ + type Query { + bar: Bar + } + + interface Foo { + class: Int + } + + type Bar implements Foo { + object: Int + class: Int + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + language = Language.KOTLIN + ) + ).generate() + + assertThat(codeGenResult.kotlinDataTypes.size).isEqualTo(1) + assertThat(codeGenResult.kotlinDataTypes[0].name).isEqualTo("Bar") + assertThat(codeGenResult.kotlinDataTypes[0].members.size).isEqualTo(1) + + val dataTypeSpec = codeGenResult.kotlinDataTypes[0].members[0] as TypeSpec + + assertThat(dataTypeSpec.propertySpecs.size).isEqualTo(2) + assertThat(dataTypeSpec.propertySpecs[0].name).isEqualTo("object") + assertThat(dataTypeSpec.propertySpecs[1].name).isEqualTo("class") + + assertCompilesKotlin(codeGenResult) + } + @Test fun generateEnumKDoc() { val schema = """ diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt index 9018c7677..55d0c3a26 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/clientapi/ClientApiGenQueryTest.kt @@ -779,7 +779,8 @@ class ClientApiGenQueryTest { try: Boolean void: Boolean volatile: Boolean - while: Boolean + while: Boolean + class: Int } scalar Long @@ -857,7 +858,8 @@ class ClientApiGenQueryTest { "_try", "_void", "_volatile", - "_while" + "_while", + "_class" ) } @@ -959,4 +961,48 @@ class ClientApiGenQueryTest { assertCompilesJava(codeGenResult.javaQueryTypes) } + + @Test + fun `Should be able to generate successfully when java keywords are used as types`() { + val schema = """ + type Query { + bar: Bar + } + + interface Foo { + class: Int + } + + type Bar implements Foo { + object: Int + class: Int + } + """.trimIndent() + + val codeGenResult = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + packageName = basePackageName, + generateDataTypes = true, + generateClientApi = true, + includeQueries = setOf("bar") + ) + ).generate() + + assertThat(codeGenResult.javaDataTypes.size).isEqualTo(1) + + val typeSpec = codeGenResult.javaDataTypes[0].typeSpec + assertThat(typeSpec.name).isEqualTo("Bar") + assertThat(typeSpec.fieldSpecs[0].name).isEqualTo("object") + assertThat(typeSpec.fieldSpecs.size).isEqualTo(2) + assertThat(typeSpec.fieldSpecs[1].name).isEqualTo("_class") + + assertThat(typeSpec.methodSpecs.size).isGreaterThan(0) + assertThat(typeSpec.methodSpecs[0].name).isEqualTo("getObject") + assertThat(typeSpec.methodSpecs[1].name).isEqualTo("setObject") + assertThat(typeSpec.methodSpecs[2].name).isEqualTo("getClassField") + assertThat(typeSpec.methodSpecs[3].name).isEqualTo("setClassField") + + assertCompilesJava(codeGenResult.javaDataTypes + codeGenResult.javaInterfaces) + } }