Skip to content

Commit c7b2852

Browse files
committed
Parser: Better names for parser util functions
Based @OlegIlyenko suggestion: graphql#1545 (comment)
1 parent da61380 commit c7b2852

File tree

1 file changed

+79
-68
lines changed

1 file changed

+79
-68
lines changed

src/language/parser.js

Lines changed: 79 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,9 @@ export function parseValue(
150150
): ValueNode {
151151
const sourceObj = typeof source === 'string' ? new Source(source) : source;
152152
const lexer = createLexer(sourceObj, options || {});
153-
expect(lexer, TokenKind.SOF);
153+
expectToken(lexer, TokenKind.SOF);
154154
const value = parseValueLiteral(lexer, false);
155-
expect(lexer, TokenKind.EOF);
155+
expectToken(lexer, TokenKind.EOF);
156156
return value;
157157
}
158158

@@ -172,17 +172,17 @@ export function parseType(
172172
): TypeNode {
173173
const sourceObj = typeof source === 'string' ? new Source(source) : source;
174174
const lexer = createLexer(sourceObj, options || {});
175-
expect(lexer, TokenKind.SOF);
175+
expectToken(lexer, TokenKind.SOF);
176176
const type = parseTypeReference(lexer);
177-
expect(lexer, TokenKind.EOF);
177+
expectToken(lexer, TokenKind.EOF);
178178
return type;
179179
}
180180

181181
/**
182182
* Converts a name lex token into a name parse node.
183183
*/
184184
function parseName(lexer: Lexer<*>): NameNode {
185-
const token = expect(lexer, TokenKind.NAME);
185+
const token = expectToken(lexer, TokenKind.NAME);
186186
return {
187187
kind: Kind.NAME,
188188
value: ((token.value: any): string),
@@ -302,7 +302,7 @@ function parseOperationDefinition(lexer: Lexer<*>): OperationDefinitionNode {
302302
* OperationType : one of query mutation subscription
303303
*/
304304
function parseOperationType(lexer: Lexer<*>): OperationTypeNode {
305-
const operationToken = expect(lexer, TokenKind.NAME);
305+
const operationToken = expectToken(lexer, TokenKind.NAME);
306306
switch (operationToken.value) {
307307
case 'query':
308308
return 'query';
@@ -334,8 +334,8 @@ function parseVariableDefinition(lexer: Lexer<*>): VariableDefinitionNode {
334334
return {
335335
kind: Kind.VARIABLE_DEFINITION,
336336
variable: parseVariable(lexer),
337-
type: (expect(lexer, TokenKind.COLON), parseTypeReference(lexer)),
338-
defaultValue: skip(lexer, TokenKind.EQUALS)
337+
type: (expectToken(lexer, TokenKind.COLON), parseTypeReference(lexer)),
338+
defaultValue: expectOptionalToken(lexer, TokenKind.EQUALS)
339339
? parseValueLiteral(lexer, true)
340340
: undefined,
341341
directives: parseDirectives(lexer, true),
@@ -348,7 +348,7 @@ function parseVariableDefinition(lexer: Lexer<*>): VariableDefinitionNode {
348348
*/
349349
function parseVariable(lexer: Lexer<*>): VariableNode {
350350
const start = lexer.token;
351-
expect(lexer, TokenKind.DOLLAR);
351+
expectToken(lexer, TokenKind.DOLLAR);
352352
return {
353353
kind: Kind.VARIABLE,
354354
name: parseName(lexer),
@@ -396,7 +396,7 @@ function parseField(lexer: Lexer<*>): FieldNode {
396396
const nameOrAlias = parseName(lexer);
397397
let alias;
398398
let name;
399-
if (skip(lexer, TokenKind.COLON)) {
399+
if (expectOptionalToken(lexer, TokenKind.COLON)) {
400400
alias = nameOrAlias;
401401
name = parseName(lexer);
402402
} else {
@@ -434,10 +434,13 @@ function parseArguments(
434434
*/
435435
function parseArgument(lexer: Lexer<*>): ArgumentNode {
436436
const start = lexer.token;
437+
const name = parseName(lexer);
438+
439+
expectToken(lexer, TokenKind.COLON);
437440
return {
438441
kind: Kind.ARGUMENT,
439-
name: parseName(lexer),
440-
value: (expect(lexer, TokenKind.COLON), parseValueLiteral(lexer, false)),
442+
name,
443+
value: parseValueLiteral(lexer, false),
441444
loc: loc(lexer, start),
442445
};
443446
}
@@ -447,7 +450,7 @@ function parseConstArgument(lexer: Lexer<*>): ArgumentNode {
447450
return {
448451
kind: Kind.ARGUMENT,
449452
name: parseName(lexer),
450-
value: (expect(lexer, TokenKind.COLON), parseConstValue(lexer)),
453+
value: (expectToken(lexer, TokenKind.COLON), parseConstValue(lexer)),
451454
loc: loc(lexer, start),
452455
};
453456
}
@@ -465,9 +468,9 @@ function parseFragment(
465468
lexer: Lexer<*>,
466469
): FragmentSpreadNode | InlineFragmentNode {
467470
const start = lexer.token;
468-
expect(lexer, TokenKind.SPREAD);
471+
expectToken(lexer, TokenKind.SPREAD);
469472

470-
const hasTypeCondition = skipKeyword(lexer, 'on');
473+
const hasTypeCondition = expectOptionalKeyword(lexer, 'on');
471474
if (!hasTypeCondition && peek(lexer, TokenKind.NAME)) {
472475
return {
473476
kind: Kind.FRAGMENT_SPREAD,
@@ -643,9 +646,9 @@ function parseList(lexer: Lexer<*>, isConst: boolean): ListValueNode {
643646
*/
644647
function parseObject(lexer: Lexer<*>, isConst: boolean): ObjectValueNode {
645648
const start = lexer.token;
646-
expect(lexer, TokenKind.BRACE_L);
649+
expectToken(lexer, TokenKind.BRACE_L);
647650
const fields = [];
648-
while (!skip(lexer, TokenKind.BRACE_R)) {
651+
while (!expectOptionalToken(lexer, TokenKind.BRACE_R)) {
649652
fields.push(parseObjectField(lexer, isConst));
650653
}
651654
return {
@@ -660,10 +663,13 @@ function parseObject(lexer: Lexer<*>, isConst: boolean): ObjectValueNode {
660663
*/
661664
function parseObjectField(lexer: Lexer<*>, isConst: boolean): ObjectFieldNode {
662665
const start = lexer.token;
666+
const name = parseName(lexer);
667+
expectToken(lexer, TokenKind.COLON);
668+
663669
return {
664670
kind: Kind.OBJECT_FIELD,
665-
name: parseName(lexer),
666-
value: (expect(lexer, TokenKind.COLON), parseValueLiteral(lexer, isConst)),
671+
name,
672+
value: parseValueLiteral(lexer, isConst),
667673
loc: loc(lexer, start),
668674
};
669675
}
@@ -689,7 +695,7 @@ function parseDirectives(
689695
*/
690696
function parseDirective(lexer: Lexer<*>, isConst: boolean): DirectiveNode {
691697
const start = lexer.token;
692-
expect(lexer, TokenKind.AT);
698+
expectToken(lexer, TokenKind.AT);
693699
return {
694700
kind: Kind.DIRECTIVE,
695701
name: parseName(lexer),
@@ -709,9 +715,9 @@ function parseDirective(lexer: Lexer<*>, isConst: boolean): DirectiveNode {
709715
export function parseTypeReference(lexer: Lexer<*>): TypeNode {
710716
const start = lexer.token;
711717
let type;
712-
if (skip(lexer, TokenKind.BRACKET_L)) {
718+
if (expectOptionalToken(lexer, TokenKind.BRACKET_L)) {
713719
type = parseTypeReference(lexer);
714-
expect(lexer, TokenKind.BRACKET_R);
720+
expectToken(lexer, TokenKind.BRACKET_R);
715721
type = ({
716722
kind: Kind.LIST_TYPE,
717723
type,
@@ -720,7 +726,7 @@ export function parseTypeReference(lexer: Lexer<*>): TypeNode {
720726
} else {
721727
type = parseNamedType(lexer);
722728
}
723-
if (skip(lexer, TokenKind.BANG)) {
729+
if (expectOptionalToken(lexer, TokenKind.BANG)) {
724730
return ({
725731
kind: Kind.NON_NULL_TYPE,
726732
type,
@@ -828,7 +834,7 @@ function parseOperationTypeDefinition(
828834
): OperationTypeDefinitionNode {
829835
const start = lexer.token;
830836
const operation = parseOperationType(lexer);
831-
expect(lexer, TokenKind.COLON);
837+
expectToken(lexer, TokenKind.COLON);
832838
const type = parseNamedType(lexer);
833839
return {
834840
kind: Kind.OPERATION_TYPE_DEFINITION,
@@ -887,13 +893,13 @@ function parseObjectTypeDefinition(lexer: Lexer<*>): ObjectTypeDefinitionNode {
887893
*/
888894
function parseImplementsInterfaces(lexer: Lexer<*>): Array<NamedTypeNode> {
889895
const types = [];
890-
if (skipKeyword(lexer, 'implements')) {
896+
if (expectOptionalKeyword(lexer, 'implements')) {
891897
// Optional leading ampersand
892-
skip(lexer, TokenKind.AMP);
898+
expectOptionalToken(lexer, TokenKind.AMP);
893899
do {
894900
types.push(parseNamedType(lexer));
895901
} while (
896-
skip(lexer, TokenKind.AMP) ||
902+
expectOptionalToken(lexer, TokenKind.AMP) ||
897903
// Legacy support for the SDL?
898904
(lexer.options.allowLegacySDLImplementsInterfaces &&
899905
peek(lexer, TokenKind.NAME))
@@ -930,7 +936,7 @@ function parseFieldDefinition(lexer: Lexer<*>): FieldDefinitionNode {
930936
const description = parseDescription(lexer);
931937
const name = parseName(lexer);
932938
const args = parseArgumentDefs(lexer);
933-
expect(lexer, TokenKind.COLON);
939+
expectToken(lexer, TokenKind.COLON);
934940
const type = parseTypeReference(lexer);
935941
const directives = parseDirectives(lexer, true);
936942
return {
@@ -962,10 +968,10 @@ function parseInputValueDef(lexer: Lexer<*>): InputValueDefinitionNode {
962968
const start = lexer.token;
963969
const description = parseDescription(lexer);
964970
const name = parseName(lexer);
965-
expect(lexer, TokenKind.COLON);
971+
expectToken(lexer, TokenKind.COLON);
966972
const type = parseTypeReference(lexer);
967973
let defaultValue;
968-
if (skip(lexer, TokenKind.EQUALS)) {
974+
if (expectOptionalToken(lexer, TokenKind.EQUALS)) {
969975
defaultValue = parseConstValue(lexer);
970976
}
971977
const directives = parseDirectives(lexer, true);
@@ -1031,12 +1037,12 @@ function parseUnionTypeDefinition(lexer: Lexer<*>): UnionTypeDefinitionNode {
10311037
*/
10321038
function parseUnionMemberTypes(lexer: Lexer<*>): Array<NamedTypeNode> {
10331039
const types = [];
1034-
if (skip(lexer, TokenKind.EQUALS)) {
1040+
if (expectOptionalToken(lexer, TokenKind.EQUALS)) {
10351041
// Optional leading pipe
1036-
skip(lexer, TokenKind.PIPE);
1042+
expectOptionalToken(lexer, TokenKind.PIPE);
10371043
do {
10381044
types.push(parseNamedType(lexer));
1039-
} while (skip(lexer, TokenKind.PIPE));
1045+
} while (expectOptionalToken(lexer, TokenKind.PIPE));
10401046
}
10411047
return types;
10421048
}
@@ -1358,7 +1364,7 @@ function parseDirectiveDefinition(lexer: Lexer<*>): DirectiveDefinitionNode {
13581364
const start = lexer.token;
13591365
const description = parseDescription(lexer);
13601366
expectKeyword(lexer, 'directive');
1361-
expect(lexer, TokenKind.AT);
1367+
expectToken(lexer, TokenKind.AT);
13621368
const name = parseName(lexer);
13631369
const args = parseArgumentDefs(lexer);
13641370
expectKeyword(lexer, 'on');
@@ -1380,11 +1386,11 @@ function parseDirectiveDefinition(lexer: Lexer<*>): DirectiveDefinitionNode {
13801386
*/
13811387
function parseDirectiveLocations(lexer: Lexer<*>): Array<NameNode> {
13821388
// Optional leading pipe
1383-
skip(lexer, TokenKind.PIPE);
1389+
expectOptionalToken(lexer, TokenKind.PIPE);
13841390
const locations = [];
13851391
do {
13861392
locations.push(parseDirectiveLocation(lexer));
1387-
} while (skip(lexer, TokenKind.PIPE));
1393+
} while (expectOptionalToken(lexer, TokenKind.PIPE));
13881394
return locations;
13891395
}
13901396

@@ -1456,28 +1462,17 @@ function peek(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
14561462
return lexer.token.kind === kind;
14571463
}
14581464

1459-
/**
1460-
* If the next token is of the given kind, return true after advancing
1461-
* the lexer. Otherwise, do not change the parser state and return false.
1462-
*/
1463-
function skip(lexer: Lexer<*>, kind: TokenKindEnum): boolean {
1464-
if (lexer.token.kind === kind) {
1465-
lexer.advance();
1466-
return true;
1467-
}
1468-
return false;
1469-
}
1470-
14711465
/**
14721466
* If the next token is of the given kind, return that token after advancing
14731467
* the lexer. Otherwise, do not change the parser state and throw an error.
14741468
*/
1475-
function expect(lexer: Lexer<*>, kind: TokenKindEnum): Token {
1469+
function expectToken(lexer: Lexer<*>, kind: TokenKindEnum): Token {
14761470
const token = lexer.token;
14771471
if (token.kind === kind) {
14781472
lexer.advance();
14791473
return token;
14801474
}
1475+
14811476
throw syntaxError(
14821477
lexer.source,
14831478
token.start,
@@ -1486,31 +1481,47 @@ function expect(lexer: Lexer<*>, kind: TokenKindEnum): Token {
14861481
}
14871482

14881483
/**
1489-
* If the next token is a keyword with the given value, return true after advancing
1490-
* the lexer. Otherwise, do not change the parser state and return false.
1484+
* If the next token is of the given kind, return that token after advancing
1485+
* the lexer. Otherwise, do not change the parser state and return undefined.
1486+
*/
1487+
function expectOptionalToken(lexer: Lexer<*>, kind: TokenKindEnum): ?Token {
1488+
const token = lexer.token;
1489+
if (token.kind === kind) {
1490+
lexer.advance();
1491+
return token;
1492+
}
1493+
return undefined;
1494+
}
1495+
1496+
/**
1497+
* If the next token is a given keyword, return that token after advancing
1498+
* the lexer. Otherwise, do not change the parser state and throw an error.
14911499
*/
1492-
function skipKeyword(lexer: Lexer<*>, value: string): boolean {
1500+
function expectKeyword(lexer: Lexer<*>, value: string): Token {
14931501
const token = lexer.token;
14941502
if (token.kind === TokenKind.NAME && token.value === value) {
14951503
lexer.advance();
1496-
return true;
1504+
return token;
14971505
}
1498-
return false;
1506+
1507+
throw syntaxError(
1508+
lexer.source,
1509+
lexer.token.start,
1510+
`Expected "${value}", found ${getTokenDesc(lexer.token)}`,
1511+
);
14991512
}
15001513

15011514
/**
1502-
* If the next token is a keyword with the given value, return that token after
1503-
* advancing the lexer. Otherwise, do not change the parser state and throw
1504-
* an error.
1515+
* If the next token is a given keyword, return that token after advancing
1516+
* the lexer. Otherwise, do not change the parser state and return undefined.
15051517
*/
1506-
function expectKeyword(lexer: Lexer<*>, value: string): void {
1507-
if (!skipKeyword(lexer, value)) {
1508-
throw syntaxError(
1509-
lexer.source,
1510-
lexer.token.start,
1511-
`Expected "${value}", found ${getTokenDesc(lexer.token)}`,
1512-
);
1518+
function expectOptionalKeyword(lexer: Lexer<*>, value: string): ?Token {
1519+
const token = lexer.token;
1520+
if (token.kind === TokenKind.NAME && token.value === value) {
1521+
lexer.advance();
1522+
return token;
15131523
}
1524+
return undefined;
15141525
}
15151526

15161527
/**
@@ -1538,9 +1549,9 @@ function any<T>(
15381549
parseFn: (lexer: Lexer<*>) => T,
15391550
closeKind: TokenKindEnum,
15401551
): Array<T> {
1541-
expect(lexer, openKind);
1552+
expectToken(lexer, openKind);
15421553
const nodes = [];
1543-
while (!skip(lexer, closeKind)) {
1554+
while (!expectOptionalToken(lexer, closeKind)) {
15441555
nodes.push(parseFn(lexer));
15451556
}
15461557
return nodes;
@@ -1558,9 +1569,9 @@ function many<T>(
15581569
parseFn: (lexer: Lexer<*>) => T,
15591570
closeKind: TokenKindEnum,
15601571
): Array<T> {
1561-
expect(lexer, openKind);
1572+
expectToken(lexer, openKind);
15621573
const nodes = [parseFn(lexer)];
1563-
while (!skip(lexer, closeKind)) {
1574+
while (!expectOptionalToken(lexer, closeKind)) {
15641575
nodes.push(parseFn(lexer));
15651576
}
15661577
return nodes;

0 commit comments

Comments
 (0)