diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/GraphQLClientGenerator.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/GraphQLClientGenerator.kt index e4b02c55ec..9f125036b2 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/GraphQLClientGenerator.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/GraphQLClientGenerator.kt @@ -179,13 +179,21 @@ class GraphQLClientGenerator( operationTypeSpec.addType(graphQLResponseTypeSpec) val polymorphicTypes = mutableListOf() + // prevent colocating duplicated type specs in the same packageName + val typeSpecByPackageName = mutableSetOf() for ((superClassName, implementations) in context.polymorphicTypes) { polymorphicTypes.add(superClassName) val polymorphicTypeSpec = FileSpec.builder(superClassName.packageName, superClassName.simpleName) for (implementation in implementations) { polymorphicTypes.add(implementation) context.typeSpecs[implementation]?.let { typeSpec -> - polymorphicTypeSpec.addType(typeSpec) + if ( + typeSpec.name != null && + !typeSpecByPackageName.contains("${superClassName.packageName}.${typeSpec.name}") + ) { + polymorphicTypeSpec.addType(typeSpec) + typeSpecByPackageName.add("${superClassName.packageName}.${typeSpec.name}") + } } } fileSpecs.add(polymorphicTypeSpec.build()) diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt index 8aaf5f47b0..75aa8e208d 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/types/generateInterfaceTypeSpec.kt @@ -213,7 +213,11 @@ private fun updateImplementationTypeSpecWithSuperInformation( } else { property } - builder.addProperty(updatedProperty) + + // add the property to the type builder only if the property was actually uptaded. + if (updatedProperty != property) { + builder.addProperty(updatedProperty) + } constructor.addParameter(updatedProperty.name, updatedProperty.type) } builder.primaryConstructor(constructor.build()) diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.graphql b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.graphql new file mode 100644 index 0000000000..c3452fda55 --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.graphql @@ -0,0 +1,25 @@ +query UnionSameSelections { + message1 { + __typename + ... on ProductRatingLink { + link { + text + } + action { + text + } + } + ... on EGDSPlainText { + text + } + } + message2 { + __typename + ... on EGDSParagraph { + text + } + ... on EGDSPlainText { + text + } + } +} diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.kt b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.kt new file mode 100644 index 0000000000..256e5bd86c --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/UnionSameSelections.kt @@ -0,0 +1,28 @@ +package com.expediagroup.graphql.generated + +import com.expediagroup.graphql.client.Generated +import com.expediagroup.graphql.client.types.GraphQLClientRequest +import com.expediagroup.graphql.generated.unionsameselections.ProductRatingSupportingMessage +import com.expediagroup.graphql.generated.unionsameselections.ProductSupportingMessage +import kotlin.String +import kotlin.collections.List +import kotlin.reflect.KClass + +public const val UNION_SAME_SELECTIONS: String = + "query UnionSameSelections {\n message1 {\n __typename\n ... on ProductRatingLink {\n link {\n text\n }\n action {\n text\n }\n }\n ... on EGDSPlainText {\n text\n }\n }\n message2 {\n __typename\n ... on EGDSParagraph {\n text\n }\n ... on EGDSPlainText {\n text\n }\n }\n}" + +@Generated +public class UnionSameSelections : GraphQLClientRequest { + override val query: String = UNION_SAME_SELECTIONS + + override val operationName: String = "UnionSameSelections" + + override fun responseType(): KClass = + UnionSameSelections.Result::class + + @Generated + public data class Result( + public val message1: List, + public val message2: List, + ) +} diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSProductRatingShowTextAction.kt b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSProductRatingShowTextAction.kt new file mode 100644 index 0000000000..5800a5d480 --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSProductRatingShowTextAction.kt @@ -0,0 +1,9 @@ +package com.expediagroup.graphql.generated.unionsameselections + +import com.expediagroup.graphql.client.Generated +import kotlin.String + +@Generated +public data class EGDSProductRatingShowTextAction( + public val text: String, +) diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSStandardLink.kt b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSStandardLink.kt new file mode 100644 index 0000000000..31bb01b2e2 --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/EGDSStandardLink.kt @@ -0,0 +1,9 @@ +package com.expediagroup.graphql.generated.unionsameselections + +import com.expediagroup.graphql.client.Generated +import kotlin.String + +@Generated +public data class EGDSStandardLink( + public val text: String, +) diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductRatingSupportingMessage.kt b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductRatingSupportingMessage.kt new file mode 100644 index 0000000000..daff3fda4e --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductRatingSupportingMessage.kt @@ -0,0 +1,39 @@ +package com.expediagroup.graphql.generated.unionsameselections + +import com.expediagroup.graphql.client.Generated +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.`annotation`.JsonTypeInfo.As.PROPERTY +import com.fasterxml.jackson.`annotation`.JsonTypeInfo.Id.NAME +import kotlin.String + +@Generated +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename", + defaultImpl = DefaultProductRatingSupportingMessageImplementation::class, +) +@JsonSubTypes(value = [com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = + ProductRatingLink::class, + name="ProductRatingLink"),com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = + EGDSPlainText::class, name="EGDSPlainText")]) +public interface ProductRatingSupportingMessage + +@Generated +public data class ProductRatingLink( + public val link: EGDSStandardLink, + public val action: EGDSProductRatingShowTextAction, +) : ProductRatingSupportingMessage + +@Generated +public data class EGDSPlainText( + public val text: String, +) : ProductRatingSupportingMessage, ProductSupportingMessage + +/** + * Fallback ProductRatingSupportingMessage implementation that will be used when unknown/unhandled + * type is encountered. + */ +@Generated +public class DefaultProductRatingSupportingMessageImplementation() : ProductRatingSupportingMessage diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductSupportingMessage.kt b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductSupportingMessage.kt new file mode 100644 index 0000000000..bb4f17a915 --- /dev/null +++ b/plugins/client/graphql-kotlin-client-generator/src/test/data/generator/union_same_selections/unionsameselections/ProductSupportingMessage.kt @@ -0,0 +1,33 @@ +package com.expediagroup.graphql.generated.unionsameselections + +import com.expediagroup.graphql.client.Generated +import com.fasterxml.jackson.`annotation`.JsonSubTypes +import com.fasterxml.jackson.`annotation`.JsonTypeInfo +import com.fasterxml.jackson.`annotation`.JsonTypeInfo.As.PROPERTY +import com.fasterxml.jackson.`annotation`.JsonTypeInfo.Id.NAME +import kotlin.String + +@Generated +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "__typename", + defaultImpl = DefaultProductSupportingMessageImplementation::class, +) +@JsonSubTypes(value = [com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = + EGDSParagraph::class, + name="EGDSParagraph"),com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = + EGDSPlainText::class, name="EGDSPlainText")]) +public interface ProductSupportingMessage + +@Generated +public data class EGDSParagraph( + public val text: String, +) : ProductSupportingMessage + +/** + * Fallback ProductSupportingMessage implementation that will be used when unknown/unhandled type is + * encountered. + */ +@Generated +public class DefaultProductSupportingMessageImplementation() : ProductSupportingMessage diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql index 5e6f9139c4..39423d9662 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql +++ b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql @@ -112,6 +112,8 @@ type Query { unionQuery: BasicUnion! "Query to test doc strings" docQuery: DocObject! + message1: [ProductRatingSupportingMessage!]! + message2: [ProductSupportingMessage!]! } "Wrapper that holds all supported scalar types" type ScalarWrapper { @@ -213,3 +215,26 @@ input ScalarWrapperInput { "List of custom scalar Locales" listLocale: [Locale!]! } + +interface EGDSText { + text: String! +} +type EGDSPlainText implements EGDSText { + text: String! +} +type ProductRatingLink { + action: EGDSProductRatingShowTextAction! + link: EGDSStandardLink! +} +type EGDSProductRatingShowTextAction { + text: String! +} +type EGDSStandardLink implements EGDSText { + text: String! +} +union ProductRatingSupportingMessage = EGDSPlainText | ProductRatingLink +union ProductSupportingMessage = EGDSParagraph | EGDSPlainText + +type EGDSParagraph implements EGDSText { + text: String! +}