Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code generation incorrect for field 'self' #193

Closed
lilyball opened this issue Dec 8, 2017 · 11 comments · Fixed by apollographql/apollo-tooling#1515
Closed

Code generation incorrect for field 'self' #193

lilyball opened this issue Dec 8, 2017 · 11 comments · Fixed by apollographql/apollo-tooling#1515
Labels
codegen Issues related to or arising from code generation
Milestone

Comments

@lilyball
Copy link

lilyball commented Dec 8, 2017

If I have a field named self in a GraphQL query, the code generator produces code that references Self.selections, which is invalid as Self is a keyword and so the code fails to compile. The current workaround is to alias the field to a different name, though unfortunately the name self_ doesn't work as Apollo still produces the type name Self.

The code generator should recognize keywords and work around them somehow, either by judicious insertion of backticks in the generated code, or by renaming the type.

@JustinDSN
Copy link
Contributor

JustinDSN commented May 5, 2018

Hi @kballard I've tried to reproduce this issue with the latest version of Apollo-Codegen (apollographql/apollo-tooling@7723fcd).

I updated an existing test to have a property declaration with the name of 'self' and the generator correctly escaped it.

The Test File was found here: /apollo-codegen/test/swift/language.ts

it(`should generate an escaped struct declaration`, () => {
    generator.structDeclaration({ structName: 'Type' }, () => {
      generator.propertyDeclaration({ propertyName: 'name', typeName: 'String' });
      generator.propertyDeclaration({ propertyName: 'yearOfBirth', typeName: 'Int' });
      generator.propertyDeclaration({ propertyName: 'self', typeName: 'String' });
    });

    expect(generator.output).toBe(stripIndent`
      public struct \`Type\` {
        public var name: String
        public var yearOfBirth: Int
        public var \`self\`: String
      }
    `);
  });

I also verified that both 'self', and 'Self' are in the reserved keywords list defined here: https://github.com/apollographql/apollo-codegen/blob/master/src/swift/language.ts#L35-L53

Can you confirm if this is still an issue and better steps to reproduce?

@designatednerd
Copy link
Contributor

@lilyball Is this issue still occurring? The reserved keywords list has moved to here: https://github.com/apollographql/apollo-tooling/blob/master/packages/apollo-codegen-swift/src/language.ts#L41 and it does still contain both self and Self as reserved keywords.

@lilyball
Copy link
Author

lilyball commented Jul 1, 2019

Yes it's still occurring. I just added a self field to a query and regenerated using Apollo 2.15.0 and while it escaped the tokens in most places, it didn't do it in all places. In particular, in the diff I see

public var `self`: Self? {

and the usage of the unescaped Self here is wrong.

@designatednerd
Copy link
Contributor

Innnnteresting. I'll have a look! Thanks for confirming.

@designatednerd designatednerd added the codegen Issues related to or arising from code generation label Jul 10, 2019
@designatednerd
Copy link
Contributor

@lilyball OK finally gathering the courage to dive into typescript and deal with this. So I can understand better what's happening here, is Self a type in your GraphQL schema?

@lilyball
Copy link
Author

No, but self is a field, and each field in the query is given a nested type named after it in the generated Swift code.

@lilyball
Copy link
Author

Which is to say, if I use selfView: self { … } instead of self { … } then the generated code declares public var selfView: SelfView? { … } instead.

@designatednerd
Copy link
Contributor

OK - that will help me at least come up with some kind of test for it, at least. Thank you!

@designatednerd
Copy link
Contributor

Fix shipped with 0.14.0!

@lilyball
Copy link
Author

lilyball commented Aug 30, 2019

I finally got around to testing this and apollo version 2.18.0 is still broken. I see escaping in most places, except for optionals:

public var `self`: Self? {
    
}

I think the problem is the type is Self? instead of Self. escapeIdentifierIfNeeded seems to be doing just bare string matching. We should probably have escapeTypeNameIfNeeded that handles types. Not just Self? but I'd imagine we'd have to handle [Self] and even [Self?]?. A simple way to handle this that would be fairly generic would be to just identify all valid identifier substrings and escape those independently.

@designatednerd
Copy link
Contributor

Ergh, I agree - I'm going to add a task for this to the iOS Swift Codegen project so I don't forget about it.

@lilyball If you're interested in making a fix on the TypeScript stuff in the meantime, we'd love to see a PR on the tooling repo

lilyball added a commit to lilyball/apollo-tooling that referenced this issue Sep 9, 2019
The source generator now operates using a string wrapper type called
`SwiftSource`. Identifiers are escaped when converting into
`SwiftSource` values, with an alternative method for producing escaped
string literals. An escape hatch is provided for disabling escapes, but
the default behavior is to escape all identifiers in the dynamic input.

Most `SwiftSource` values are produced by a tagged template literal,
which allows for easy mixing of string literals containing Swift
keywords and dynamic input that needs escaping.

As part of this, rewrite string escaping such that it actually escapes
string contents properly. This required fixing a test that had a bad
spec enforcing broken behavior.

Fixes apollographql/apollo-ios#193.
Fixes apollographql/apollo-ios#752.
lilyball added a commit to lilyball/apollo-tooling that referenced this issue Sep 9, 2019
The source generator now operates using a string wrapper type called
`SwiftSource`. Identifiers are escaped when converting into
`SwiftSource` values, with an alternative method for producing escaped
string literals. An escape hatch is provided for disabling escapes, but
the default behavior is to escape all identifiers in the dynamic input.

Most `SwiftSource` values are produced by a tagged template literal,
which allows for easy mixing of string literals containing Swift
keywords and dynamic input that needs escaping.

As part of this, rewrite string escaping such that it actually escapes
string contents properly. This required fixing a test that had a bad
spec enforcing broken behavior.

Fixes apollographql/apollo-ios#193.
Fixes apollographql/apollo-ios#752.
lilyball added a commit to lilyball/apollo-tooling that referenced this issue Sep 10, 2019
The source generator now operates using a string wrapper type called
`SwiftSource`. Identifiers are escaped when converting into
`SwiftSource` values, with an alternative method for producing escaped
string literals. An escape hatch is provided for disabling escapes, but
the default behavior is to escape all identifiers in the dynamic input.

Most `SwiftSource` values are produced by a tagged template literal,
which allows for easy mixing of string literals containing Swift
keywords and dynamic input that needs escaping.

As part of this, rewrite string escaping such that it actually escapes
string contents properly. This required fixing a test that had a bad
spec enforcing broken behavior.

Fixes apollographql/apollo-ios#193.
Fixes apollographql/apollo-ios#752.
lilyball added a commit to lilyball/apollo-tooling that referenced this issue Sep 10, 2019
The source generator now operates using a string wrapper type called
`SwiftSource`. Identifiers are escaped when converting into
`SwiftSource` values, with an alternative method for producing escaped
string literals. An escape hatch is provided for disabling escapes, but
the default behavior is to escape all identifiers in the dynamic input.

Most `SwiftSource` values are produced by a tagged template literal,
which allows for easy mixing of string literals containing Swift
keywords and dynamic input that needs escaping.

As part of this, rewrite string escaping such that it actually escapes
string contents properly. This required fixing a test that had a bad
spec enforcing broken behavior.

Fixes apollographql/apollo-ios#193.
Fixes apollographql/apollo-ios#752.
lilyball added a commit to lilyball/apollo-tooling that referenced this issue Sep 10, 2019
The source generator now operates using a string wrapper type called
`SwiftSource`. Identifiers are escaped when converting into
`SwiftSource` values, with an alternative method for producing escaped
string literals. An escape hatch is provided for disabling escapes, but
the default behavior is to escape all identifiers in the dynamic input.

Most `SwiftSource` values are produced by a tagged template literal,
which allows for easy mixing of string literals containing Swift
keywords and dynamic input that needs escaping.

As part of this, rewrite string escaping such that it actually escapes
string contents properly. This required fixing a test that had a bad
spec enforcing broken behavior.

This commit makes the test added earlier pass.

Fixes apollographql/apollo-ios#193.
Fixes apollographql/apollo-ios#752.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codegen Issues related to or arising from code generation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants