Skip to content

Commit 26c9874

Browse files
Parser: Add 'skipKeyword' function (#1545)
based on 'expectOptionalKeyword' from #1541
1 parent 3296b72 commit 26c9874

File tree

1 file changed

+28
-22
lines changed

1 file changed

+28
-22
lines changed

src/language/parser.js

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -465,22 +465,19 @@ function parseFragment(
465465
): FragmentSpreadNode | InlineFragmentNode {
466466
const start = lexer.token;
467467
expect(lexer, TokenKind.SPREAD);
468-
if (peek(lexer, TokenKind.NAME) && lexer.token.value !== 'on') {
468+
469+
const hasTypeCondition = skipKeyword(lexer, 'on');
470+
if (!hasTypeCondition && peek(lexer, TokenKind.NAME)) {
469471
return {
470472
kind: Kind.FRAGMENT_SPREAD,
471473
name: parseFragmentName(lexer),
472474
directives: parseDirectives(lexer, false),
473475
loc: loc(lexer, start),
474476
};
475477
}
476-
let typeCondition;
477-
if (lexer.token.value === 'on') {
478-
lexer.advance();
479-
typeCondition = parseNamedType(lexer);
480-
}
481478
return {
482479
kind: Kind.INLINE_FRAGMENT,
483-
typeCondition,
480+
typeCondition: hasTypeCondition ? parseNamedType(lexer) : undefined,
484481
directives: parseDirectives(lexer, false),
485482
selectionSet: parseSelectionSet(lexer),
486483
loc: loc(lexer, start),
@@ -889,8 +886,7 @@ function parseObjectTypeDefinition(lexer: Lexer<*>): ObjectTypeDefinitionNode {
889886
*/
890887
function parseImplementsInterfaces(lexer: Lexer<*>): Array<NamedTypeNode> {
891888
const types = [];
892-
if (lexer.token.value === 'implements') {
893-
lexer.advance();
889+
if (skipKeyword(lexer, 'implements')) {
894890
// Optional leading ampersand
895891
skip(lexer, TokenKind.AMP);
896892
do {
@@ -1464,11 +1460,11 @@ function peek(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
14641460
* the lexer. Otherwise, do not change the parser state and return false.
14651461
*/
14661462
function skip(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
1467-
const match = lexer.token.kind === kind;
1468-
if (match) {
1463+
if (lexer.token.kind === kind) {
14691464
lexer.advance();
1465+
return true;
14701466
}
1471-
return match;
1467+
return false;
14721468
}
14731469

14741470
/**
@@ -1489,21 +1485,31 @@ function expect(lexer: Lexer<*>, kind: TokenKindEnum): Token {
14891485
}
14901486

14911487
/**
1492-
* If the next token is a keyword with the given value, return that token after
1493-
* advancing the lexer. Otherwise, do not change the parser state and return
1494-
* false.
1488+
* If the next token is a keyword with the given value, return true after advancing
1489+
* the lexer. Otherwise, do not change the parser state and return false.
14951490
*/
1496-
function expectKeyword(lexer: Lexer<*>, value: string): Token {
1491+
function skipKeyword(lexer: Lexer<*>, value: string): boolean {
14971492
const token = lexer.token;
14981493
if (token.kind === TokenKind.NAME && token.value === value) {
14991494
lexer.advance();
1500-
return token;
1495+
return true;
1496+
}
1497+
return false;
1498+
}
1499+
1500+
/**
1501+
* If the next token is a keyword with the given value, return that token after
1502+
* advancing the lexer. Otherwise, do not change the parser state and throw
1503+
* an error.
1504+
*/
1505+
function expectKeyword(lexer: Lexer<*>, value: string): void {
1506+
if (!skipKeyword(lexer, value)) {
1507+
throw syntaxError(
1508+
lexer.source,
1509+
lexer.token.start,
1510+
`Expected "${value}", found ${getTokenDesc(lexer.token)}`,
1511+
);
15011512
}
1502-
throw syntaxError(
1503-
lexer.source,
1504-
token.start,
1505-
`Expected "${value}", found ${getTokenDesc(token)}`,
1506-
);
15071513
}
15081514

15091515
/**

0 commit comments

Comments
 (0)