From aefe5fd8bf366a37cc2d403ba7d8d18537bcd0cb Mon Sep 17 00:00:00 2001 From: Matt Bossenbroek Date: Mon, 8 Jan 2024 14:57:23 -0800 Subject: [PATCH] Kotlin2: Update projection name to be derived from GQL name instead of kotlin name. This enables support for generic classes to be used in the type mapping. --- .../graphql/dgs/codegen/Kotlin2CodeGenTest.kt | 3 +- .../expected/types/EntityConnection.kt | 63 ------------------- .../expected/types/Query.kt | 14 +++-- .../kotlin2/GenerateKotlin2ClientTypes.kt | 17 ++--- 4 files changed, 20 insertions(+), 77 deletions(-) delete mode 100644 graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/EntityConnection.kt diff --git a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt b/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt index 9f647ae05..9942e0db4 100644 --- a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt +++ b/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/Kotlin2CodeGenTest.kt @@ -53,7 +53,8 @@ class Kotlin2CodeGenTest { "dataClassWithMappedTypes" -> mapOf( "Long" to "kotlin.Long", "DateTime" to "java.time.OffsetDateTime", - "PageInfo" to "graphql.relay.PageInfo" + "PageInfo" to "graphql.relay.PageInfo", + "EntityConnection" to "graphql.relay.SimpleListConnection" ) "dataClassWithMappedInterfaces" -> mapOf( "Node" to "com.netflix.graphql.dgs.codegen.fixtures.Node" diff --git a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/EntityConnection.kt b/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/EntityConnection.kt deleted file mode 100644 index 58452b3da..000000000 --- a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/EntityConnection.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.netflix.graphql.dgs.codegen.cases.dataClassWithMappedTypes.expected.types - -import com.fasterxml.jackson.`annotation`.JsonIgnoreProperties -import com.fasterxml.jackson.`annotation`.JsonProperty -import com.fasterxml.jackson.`annotation`.JsonTypeInfo -import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize -import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder -import graphql.relay.PageInfo -import java.lang.IllegalStateException -import kotlin.collections.List -import kotlin.jvm.JvmName - -@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) -@JsonDeserialize(builder = EntityConnection.Builder::class) -public class EntityConnection( - pageInfo: () -> PageInfo = pageInfoDefault, - edges: () -> List? = edgesDefault, -) { - private val _pageInfo: () -> PageInfo = pageInfo - - private val _edges: () -> List? = edges - - @get:JvmName("getPageInfo") - public val pageInfo: PageInfo - get() = _pageInfo.invoke() - - @get:JvmName("getEdges") - public val edges: List? - get() = _edges.invoke() - - public companion object { - private val pageInfoDefault: () -> PageInfo = - { throw IllegalStateException("Field `pageInfo` was not requested") } - - - private val edgesDefault: () -> List? = - { throw IllegalStateException("Field `edges` was not requested") } - - } - - @JsonPOJOBuilder - @JsonIgnoreProperties("__typename") - public class Builder { - private var pageInfo: () -> PageInfo = pageInfoDefault - - private var edges: () -> List? = edgesDefault - - @JsonProperty("pageInfo") - public fun withPageInfo(pageInfo: PageInfo): Builder = this.apply { - this.pageInfo = { pageInfo } - } - - @JsonProperty("edges") - public fun withEdges(edges: List?): Builder = this.apply { - this.edges = { edges } - } - - public fun build(): EntityConnection = EntityConnection( - pageInfo = pageInfo, - edges = edges, - ) - } -} diff --git a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/Query.kt b/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/Query.kt index 7edc9eb0e..09c9e59db 100644 --- a/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/Query.kt +++ b/graphql-dgs-codegen-core/src/integTest/kotlin/com/netflix/graphql/dgs/codegen/cases/dataClassWithMappedTypes/expected/types/Query.kt @@ -5,6 +5,7 @@ import com.fasterxml.jackson.`annotation`.JsonProperty import com.fasterxml.jackson.`annotation`.JsonTypeInfo import com.fasterxml.jackson.databind.`annotation`.JsonDeserialize import com.fasterxml.jackson.databind.`annotation`.JsonPOJOBuilder +import graphql.relay.SimpleListConnection import java.lang.IllegalStateException import kotlin.collections.List import kotlin.jvm.JvmName @@ -13,18 +14,18 @@ import kotlin.jvm.JvmName @JsonDeserialize(builder = Query.Builder::class) public class Query( entity: () -> List? = entityDefault, - entityConnection: () -> EntityConnection? = entityConnectionDefault, + entityConnection: () -> SimpleListConnection? = entityConnectionDefault, ) { private val _entity: () -> List? = entity - private val _entityConnection: () -> EntityConnection? = entityConnection + private val _entityConnection: () -> SimpleListConnection? = entityConnection @get:JvmName("getEntity") public val entity: List? get() = _entity.invoke() @get:JvmName("getEntityConnection") - public val entityConnection: EntityConnection? + public val entityConnection: SimpleListConnection? get() = _entityConnection.invoke() public companion object { @@ -32,7 +33,7 @@ public class Query( { throw IllegalStateException("Field `entity` was not requested") } - private val entityConnectionDefault: () -> EntityConnection? = + private val entityConnectionDefault: () -> SimpleListConnection? = { throw IllegalStateException("Field `entityConnection` was not requested") } } @@ -42,7 +43,7 @@ public class Query( public class Builder { private var entity: () -> List? = entityDefault - private var entityConnection: () -> EntityConnection? = entityConnectionDefault + private var entityConnection: () -> SimpleListConnection? = entityConnectionDefault @JsonProperty("entity") public fun withEntity(entity: List?): Builder = this.apply { @@ -50,7 +51,8 @@ public class Query( } @JsonProperty("entityConnection") - public fun withEntityConnection(entityConnection: EntityConnection?): Builder = this.apply { + public fun withEntityConnection(entityConnection: SimpleListConnection?): Builder = + this.apply { this.entityConnection = { entityConnection } } diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/GenerateKotlin2ClientTypes.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/GenerateKotlin2ClientTypes.kt index 223ae60e8..2252b0832 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/GenerateKotlin2ClientTypes.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/kotlin2/GenerateKotlin2ClientTypes.kt @@ -39,8 +39,11 @@ import com.squareup.kotlinpoet.asTypeName import graphql.language.Document import graphql.language.InputValueDefinition import graphql.language.InterfaceTypeDefinition +import graphql.language.ListType import graphql.language.NamedNode +import graphql.language.NonNullType import graphql.language.ObjectTypeDefinition +import graphql.language.Type import graphql.language.UnionTypeDefinition fun generateKotlin2ClientTypes( @@ -110,9 +113,8 @@ fun generateKotlin2ClientTypes( // otherwise it's a projection with optional args // !isScalar && hasArgs else -> { - val projectTypeName = - projectionTypeName(typeLookup.findReturnType(config.packageNameClient, field.type)) - val (projectionType, projection) = projectionType(config.packageNameClient, projectTypeName) + val projectionTypeName = projectionTypeName(field.type) + val (projectionType, projection) = projectionType(config.packageNameClient, projectionTypeName) FunSpec.builder(field.name) .addInputArgs(config, typeLookup, typeName, field.inputValueDefinitions) @@ -213,11 +215,12 @@ fun generateKotlin2ClientTypes( } // unpack the type to get the underlying type of the projection -private fun projectionTypeName(type: TypeName): String { +private fun projectionTypeName(type: Type<*>): String { return when (type) { - is ClassName -> type.simpleName - is ParameterizedTypeName -> projectionTypeName(type.typeArguments.first()) - else -> throw UnsupportedOperationException(type::class.simpleName) + is graphql.language.TypeName -> type.name + is ListType -> projectionTypeName(type.type) + is NonNullType -> projectionTypeName(type.type) + else -> throw UnsupportedOperationException(type::class.qualifiedName) } }