From e510713d1e249370b2ca03f2050eca1033d0a4a6 Mon Sep 17 00:00:00 2001 From: Robin Daugherty Date: Wed, 28 Jul 2021 10:53:15 -0400 Subject: [PATCH] Include namespace in fragment struct type names to make sure that if the fragment is used in a query that has a node (and therefore type name) with the same name as the fragment's type name, Swift doesn't get confused about which type is being referred to. --- CHANGELOG.md | 2 +- .../apollo-codegen-swift/src/codeGeneration.ts | 4 +++- packages/apollo-codegen-swift/src/helpers.ts | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f58c0ff1f0..edd44f6838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ - `apollo-codegen-scala` - - `apollo-codegen-swift` - - + - Add namespace when a fragment struct is referenced (Fixes #2396) [PR #2397](https://github.com/apollographql/apollo-tooling/pull/2397) - `apollo-codegen-typescript` - - `apollo-codegen-core` diff --git a/packages/apollo-codegen-swift/src/codeGeneration.ts b/packages/apollo-codegen-swift/src/codeGeneration.ts index 949a09a4d1..1a8d372ad3 100644 --- a/packages/apollo-codegen-swift/src/codeGeneration.ts +++ b/packages/apollo-codegen-swift/src/codeGeneration.ts @@ -339,7 +339,9 @@ export class SwiftAPIGenerator extends SwiftGenerator { outputIndividualFiles: boolean, suppressMultilineStringLiterals: boolean ) { - const structName = this.helpers.structNameForFragmentName(fragmentName); + const structName = this.helpers.structDeclarationNameForFragmentName( + fragmentName + ); this.structDeclarationForSelectionSet( { diff --git a/packages/apollo-codegen-swift/src/helpers.ts b/packages/apollo-codegen-swift/src/helpers.ts index 8396e14c95..b0b53203de 100644 --- a/packages/apollo-codegen-swift/src/helpers.ts +++ b/packages/apollo-codegen-swift/src/helpers.ts @@ -125,7 +125,25 @@ export class Helpers { return pascalCase(Inflector.singularize(propertyName)); } + /** + * Returns the Swift name for a struct representing a fragment. This must contain + * the application namespace in case the fragment name is the same as the name of any + * field in the current query, otherwise, Swift will assume the type reference is to + * the struct that we're inside the namespace of. + */ structNameForFragmentName(fragmentName: string) { + const prefix = + this.options && this.options.namespace + ? `${this.options.namespace}.` + : ""; + return `${prefix}${pascalCase(fragmentName)}`; + } + + /** + * Returns the Swift struct name that is being declared. When declaring a struct in Swift, + * no namespace can be included in the name. + */ + structDeclarationNameForFragmentName(fragmentName: string) { return pascalCase(fragmentName); }