Skip to content

Commit

Permalink
Parser: Add 'skipKeyword' function
Browse files Browse the repository at this point in the history
based on 'expectOptionalKeyword' from graphql#1541
  • Loading branch information
IvanGoncharov committed Oct 4, 2018
1 parent 94b3844 commit 59792e5
Showing 1 changed file with 28 additions and 22 deletions.
50 changes: 28 additions & 22 deletions src/language/parser.js
Expand Up @@ -488,22 +488,19 @@ function parseFragment(
): FragmentSpreadNode | InlineFragmentNode {
const start = lexer.token;
expect(lexer, TokenKind.SPREAD);
if (peek(lexer, TokenKind.NAME) && lexer.token.value !== 'on') {

const hasTypeCondition = skipKeyword(lexer, 'on');
if (!hasTypeCondition && peek(lexer, TokenKind.NAME)) {
return {
kind: Kind.FRAGMENT_SPREAD,
name: parseFragmentName(lexer),
directives: parseDirectives(lexer, false),
loc: loc(lexer, start),
};
}
let typeCondition;
if (lexer.token.value === 'on') {
lexer.advance();
typeCondition = parseNamedType(lexer);
}
return {
kind: Kind.INLINE_FRAGMENT,
typeCondition,
typeCondition: hasTypeCondition ? parseNamedType(lexer) : undefined,
directives: parseDirectives(lexer, false),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start),
Expand Down Expand Up @@ -912,8 +909,7 @@ function parseObjectTypeDefinition(lexer: Lexer<*>): ObjectTypeDefinitionNode {
*/
function parseImplementsInterfaces(lexer: Lexer<*>): Array<NamedTypeNode> {
const types = [];
if (lexer.token.value === 'implements') {
lexer.advance();
if (skipKeyword(lexer, 'implements')) {
// Optional leading ampersand
skip(lexer, TokenKind.AMP);
do {
Expand Down Expand Up @@ -1487,11 +1483,11 @@ function peek(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
* the lexer. Otherwise, do not change the parser state and return false.
*/
function skip(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
const match = lexer.token.kind === kind;
if (match) {
if (lexer.token.kind === kind) {
lexer.advance();
return true;
}
return match;
return false;
}

/**
Expand All @@ -1512,21 +1508,31 @@ function expect(lexer: Lexer<*>, kind: TokenKindEnum): Token {
}

/**
* If the next token is a keyword with the given value, return that token after
* advancing the lexer. Otherwise, do not change the parser state and return
* false.
* If the next token is a keyword with the given value, return true after advancing
* the lexer. Otherwise, do not change the parser state and return false.
*/
function expectKeyword(lexer: Lexer<*>, value: string): Token {
function skipKeyword(lexer: Lexer<*>, value: string): boolean {
const token = lexer.token;
if (token.kind === TokenKind.NAME && token.value === value) {
lexer.advance();
return token;
return true;
}
return false;
}

/**
* If the next token is a keyword with the given value, return that token after
* advancing the lexer. Otherwise, do not change the parser state and throw
* an error.
*/
function expectKeyword(lexer: Lexer<*>, value: string): void {
if (!skipKeyword(lexer, value)) {
throw syntaxError(
lexer.source,
lexer.token.start,
`Expected "${value}", found ${getTokenDesc(lexer.token)}`,
);
}
throw syntaxError(
lexer.source,
token.start,
`Expected "${value}", found ${getTokenDesc(token)}`,
);
}

/**
Expand Down

0 comments on commit 59792e5

Please sign in to comment.