Skip to content

Commit acf624b

Browse files
committed
Avoid parse ambiguity on type extensions
Partial fix to #564, adds lookahead constraints to type system extensions to remove ambiguity or inefficiency from the grammar. The GraphQL grammar should be parsed in linear type with at most one lookahead. Since extensions have an optional `{ }` body, finding the token `{` should always attempt to parse the relevant portion of the type extension rather than completing the type extension and attempting to parse the query shorthand SelectionSet.
1 parent dfd7571 commit acf624b

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

spec/Section 3 -- Type System.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,16 @@ type Query {
154154

155155
SchemaExtension :
156156
- extend schema Directives[Const]? { RootOperationTypeDefinition+ }
157-
- extend schema Directives[Const]
157+
- extend schema Directives[Const] [lookahead != SelectionSet]
158158

159159
Schema extensions are used to represent a schema which has been extended from
160160
an original schema. For example, this might be used by a GraphQL service which
161161
adds additional operation types, or additional directives to an existing schema.
162162

163+
Note: Extensions without additional operation types must not be followed by a
164+
{SelectionSet} query shorthand to avoid parsing ambiguity. This same limitation
165+
occurs on the type extensions below.
166+
163167
**Schema Validation**
164168

165169
Schema extensions have the potential to be invalid if incorrectly defined.
@@ -902,8 +906,8 @@ type ExampleType {
902906

903907
ObjectTypeExtension :
904908
- extend type Name ImplementsInterfaces? Directives[Const]? FieldsDefinition
905-
- extend type Name ImplementsInterfaces? Directives[Const]
906-
- extend type Name ImplementsInterfaces
909+
- extend type Name ImplementsInterfaces? Directives[Const] [lookahead != SelectionSet]
910+
- extend type Name ImplementsInterfaces [lookahead != SelectionSet]
907911

908912
Object type extensions are used to represent a type which has been extended from
909913
some original type. For example, this might be used to represent local data, or
@@ -1071,7 +1075,7 @@ Interface types have the potential to be invalid if incorrectly defined.
10711075

10721076
InterfaceTypeExtension :
10731077
- extend interface Name Directives[Const]? FieldsDefinition
1074-
- extend interface Name Directives[Const]
1078+
- extend interface Name Directives[Const] [lookahead != SelectionSet]
10751079

10761080
Interface type extensions are used to represent an interface which has been
10771081
extended from some original interface. For example, this might be used to
@@ -1294,7 +1298,7 @@ Enum types have the potential to be invalid if incorrectly defined.
12941298

12951299
EnumTypeExtension :
12961300
- extend enum Name Directives[Const]? EnumValuesDefinition
1297-
- extend enum Name Directives[Const]
1301+
- extend enum Name Directives[Const] [lookahead != SelectionSet]
12981302

12991303
Enum type extensions are used to represent an enum type which has been
13001304
extended from some original enum type. For example, this might be used to
@@ -1424,7 +1428,7 @@ Literal Value | Variables | Coerced Value
14241428

14251429
InputObjectTypeExtension :
14261430
- extend input Name Directives[Const]? InputFieldsDefinition
1427-
- extend input Name Directives[Const]
1431+
- extend input Name Directives[Const] [lookahead != SelectionSet]
14281432

14291433
Input object type extensions are used to represent an input object type which
14301434
has been extended from some original input object type. For example, this might

0 commit comments

Comments
 (0)