Fix broken behavior for several options on the same node (#105)

## Summary:
Previously, we actually allowed you to put several genqlient directives
on the same node, but the semantics were undocumented (and somewhat
confusing, when it comes to `typename`).  In order to support directives
on input options, we're actually going to be encouraging this usage (see
notes in #14), so it's time to fix it.  To avoid confusion, I just had
conflicting directives be an error, rather than defining which one
"wins".  The same applies to specifying the same option several
times in one directive.

I also fixed two small bugs:
- `typename` on an operation would incorrectly cascade down to
  all input types in a query (causing conflicts).
- directive parse errors had useless positions, now they're correct

## Test plan:
make check


Author: benjaminjkraft

Reviewers: StevenACoffman, dnerdy, aberkan, jvoll, mahtabsabet, MiguelCastillo

Required Reviewers: 

Approved By: StevenACoffman, dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Lint

Pull Request URL: https://github.com/Khan/genqlient/pull/105
This commit is contained in:
Ben Kraft
2021-09-24 11:16:46 -07:00
committed by GitHub
parent 8de55d352e
commit 6e2b1a5811
13 changed files with 293 additions and 39 deletions
+1
View File
@@ -28,6 +28,7 @@ When releasing a new version:
### New features:
- The new `bindings.marshaler` and `bindings.unmarshaler` options in `genqlient.yaml` allow binding to a type without using its standard JSON serialization; see the [documentation](genqlient.yaml) for details.
- Multiple genqlient directives may now be applied to the same node, as long as they don't conflict; see the [directive documentation](genqlient_directive.graphql) for details.
### Bug fixes:
+16 -4
View File
@@ -21,15 +21,25 @@
# # @genqlient(n: "c")
# query MyQuery(arg1: String,
# # @genqlient(n: "d")
# arg2: String, arg3: String,
# arg2: String, arg3: MyInput,
# arg4: String,
# ) {
# # @genqlient(n: "e")
# field1, field2
# field3
# # @genqlient(n: "f")
# field3 {
# field4
# }
# }
# the directive "a" is ignored, "b" and "c" apply to all relevant nodes in the
# query, "d" applies to arg2 and arg3, and "e" applies to field1 and field2.
# query, "d" applies to arg2 and arg3, "e" applies to field1 and field2, and
# "f" applies to field3.
#
# Except as noted below, directives on nodes take precedence over ones on the
# entire query (so "d", "e", and "f" take precedence over "b" and "c"), and
# multiple directives on the same node ("b" and "c") must not conflict. Note
# that directives on nodes do *not* apply to their "children", so "d" does not
# apply to the fields of MyInput, and "f" does not apply to field4.
directive genqlient(
# If set, this argument will be omitted if it has an empty value, defined
@@ -125,7 +135,9 @@ directive genqlient(
# down to all child fields (which would cause conflicts).
typename: String
) on
# Multiple genqlient directives are allowed in the same location, as long as
# they don't have conflicting options.
) repeatable on
# genqlient directives can go almost anywhere, although some options are only
# applicable in certain locations as described above.
| QUERY