Skip to content

Commit 06d0266

Browse files
fix: Parser errors when disallowed description provided
1 parent 88b71a0 commit 06d0266

File tree

1 file changed

+36
-56
lines changed

1 file changed

+36
-56
lines changed

Sources/GraphQL/Language/Parser.swift

Lines changed: 36 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -173,24 +173,45 @@ func parseDefinition(lexer: Lexer) throws -> Definition {
173173
return try parseOperationDefinition(lexer: lexer)
174174
}
175175

176-
if peek(lexer: lexer, kind: .name) {
177-
guard let value = lexer.token.value else {
176+
// Many definitions begin with a description and require a lookahead.
177+
let hasDescription = peekDescription(lexer: lexer)
178+
let keywordToken = hasDescription
179+
? try lexer.lookahead()
180+
: lexer.token
181+
182+
if keywordToken.kind == .name {
183+
guard let value = keywordToken.value else {
178184
throw GraphQLError(message: "Expected name token to have value: \(lexer.token)")
179185
}
186+
180187
switch value {
181-
case "query", "mutation", "subscription":
182-
return try parseOperationDefinition(lexer: lexer)
183-
case "fragment":
184-
return try parseFragmentDefinition(lexer: lexer)
185-
// Note: the Type System IDL is an experimental non-spec addition.
186-
case "schema", "scalar", "type", "interface", "union", "enum", "input", "extend",
187-
"directive":
188-
return try parseTypeSystemDefinition(lexer: lexer)
188+
case "schema": return try parseSchemaDefinition(lexer: lexer)
189+
case "scalar": return try parseScalarTypeDefinition(lexer: lexer)
190+
case "type": return try parseObjectTypeDefinition(lexer: lexer)
191+
case "interface": return try parseInterfaceTypeDefinition(lexer: lexer)
192+
case "union": return try parseUnionTypeDefinition(lexer: lexer)
193+
case "enum": return try parseEnumTypeDefinition(lexer: lexer)
194+
case "input": return try parseInputObjectTypeDefinition(lexer: lexer)
195+
case "directive": return try parseDirectiveDefinition(lexer: lexer)
189196
default:
190-
break
197+
if hasDescription {
198+
throw syntaxError(
199+
source: lexer.source,
200+
position: lexer.token.start,
201+
description: "Unexpected description, descriptions are supported only on type definitions."
202+
)
203+
}
204+
switch value {
205+
case "query", "mutation", "subscription":
206+
return try parseOperationDefinition(lexer: lexer)
207+
case "fragment":
208+
return try parseFragmentDefinition(lexer: lexer)
209+
case "extend":
210+
return try parseExtensionDefinition(lexer: lexer)
211+
default:
212+
break
213+
}
191214
}
192-
} else if peekDescription(lexer: lexer) {
193-
return try parseTypeSystemDefinition(lexer: lexer)
194215
}
195216

196217
throw unexpected(lexer: lexer)
@@ -675,47 +696,6 @@ func parseNamedType(lexer: Lexer) throws -> NamedType {
675696

676697
// Implements the parsing rules in the Type Definition section.
677698

678-
/**
679-
* TypeSystemDefinition :
680-
* - SchemaDefinition
681-
* - TypeDefinition
682-
* - TypeExtensionDefinition
683-
* - DirectiveDefinition
684-
*
685-
* TypeDefinition :
686-
* - ScalarTypeDefinition
687-
* - ObjectTypeDefinition
688-
* - InterfaceTypeDefinition
689-
* - UnionTypeDefinition
690-
* - EnumTypeDefinition
691-
* - InputObjectTypeDefinition
692-
*/
693-
func parseTypeSystemDefinition(lexer: Lexer) throws -> TypeSystemDefinition {
694-
let keywordToken = peekDescription(lexer: lexer)
695-
? try lexer.lookahead()
696-
: lexer.token
697-
698-
if keywordToken.kind == .name {
699-
guard let value = keywordToken.value else {
700-
throw GraphQLError(message: "Expected keyword token to have value: \(keywordToken)")
701-
}
702-
switch value {
703-
case "schema": return try parseSchemaDefinition(lexer: lexer)
704-
case "scalar": return try parseScalarTypeDefinition(lexer: lexer)
705-
case "type": return try parseObjectTypeDefinition(lexer: lexer)
706-
case "interface": return try parseInterfaceTypeDefinition(lexer: lexer)
707-
case "union": return try parseUnionTypeDefinition(lexer: lexer)
708-
case "enum": return try parseEnumTypeDefinition(lexer: lexer)
709-
case "input": return try parseInputObjectTypeDefinition(lexer: lexer)
710-
case "extend": return try parseExtensionDefinition(lexer: lexer)
711-
case "directive": return try parseDirectiveDefinition(lexer: lexer)
712-
default: break
713-
}
714-
}
715-
716-
throw unexpected(lexer: lexer, atToken: keywordToken)
717-
}
718-
719699
/**
720700
* SchemaDefinition : schema Directives? { OperationTypeDefinition+ }
721701
*
@@ -1124,8 +1104,8 @@ func parseScalarExtensionDefinition(lexer: Lexer) throws -> ScalarExtensionDefin
11241104
try expectKeyword(lexer: lexer, value: "scalar")
11251105
let name = try parseName(lexer: lexer)
11261106
let directives = try parseDirectives(lexer: lexer)
1127-
if (directives.isEmpty) {
1128-
throw unexpected(lexer: lexer)
1107+
if directives.isEmpty {
1108+
throw unexpected(lexer: lexer)
11291109
}
11301110
return ScalarExtensionDefinition(
11311111
loc: loc(lexer: lexer, startToken: start),

0 commit comments

Comments
 (0)