node_modules.graphql.language.parser.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apollo-client-maven-plugin Show documentation
Show all versions of apollo-client-maven-plugin Show documentation
Maven plugin for generating graphql clients
The newest version!
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parse = parse;
exports.parseValue = parseValue;
exports.parseType = parseType;
exports.parseConstValue = parseConstValue;
exports.parseTypeReference = parseTypeReference;
exports.parseNamedType = parseNamedType;
var _source = require('./source');
var _error = require('../error');
var _lexer = require('./lexer');
var _kinds = require('./kinds');
/**
* Given a GraphQL source, parses it into a Document.
* Throws GraphQLError if a syntax error is encountered.
*/
/**
* Configuration options to control parser behavior
*/
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
function parse(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
if (!(sourceObj instanceof _source.Source)) {
throw new TypeError('Must provide Source. Received: ' + String(sourceObj));
}
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
return parseDocument(lexer);
}
/**
* Given a string containing a GraphQL value (ex. `[42]`), parse the AST for
* that value.
* Throws GraphQLError if a syntax error is encountered.
*
* This is useful within tools that operate upon GraphQL Values directly and
* in isolation of complete GraphQL documents.
*
* Consider providing the results to the utility function: valueFromAST().
*/
function parseValue(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
expect(lexer, _lexer.TokenKind.SOF);
var value = parseValueLiteral(lexer, false);
expect(lexer, _lexer.TokenKind.EOF);
return value;
}
/**
* Given a string containing a GraphQL Type (ex. `[Int!]`), parse the AST for
* that type.
* Throws GraphQLError if a syntax error is encountered.
*
* This is useful within tools that operate upon GraphQL Types directly and
* in isolation of complete GraphQL documents.
*
* Consider providing the results to the utility function: typeFromAST().
*/
function parseType(source, options) {
var sourceObj = typeof source === 'string' ? new _source.Source(source) : source;
var lexer = (0, _lexer.createLexer)(sourceObj, options || {});
expect(lexer, _lexer.TokenKind.SOF);
var type = parseTypeReference(lexer);
expect(lexer, _lexer.TokenKind.EOF);
return type;
}
/**
* Converts a name lex token into a name parse node.
*/
function parseName(lexer) {
var token = expect(lexer, _lexer.TokenKind.NAME);
return {
kind: _kinds.NAME,
value: token.value,
loc: loc(lexer, token)
};
}
// Implements the parsing rules in the Document section.
/**
* Document : Definition+
*/
function parseDocument(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.SOF);
var definitions = [];
do {
definitions.push(parseDefinition(lexer));
} while (!skip(lexer, _lexer.TokenKind.EOF));
return {
kind: _kinds.DOCUMENT,
definitions: definitions,
loc: loc(lexer, start)
};
}
/**
* Definition :
* - OperationDefinition
* - FragmentDefinition
* - TypeSystemDefinition
*/
function parseDefinition(lexer) {
if (peek(lexer, _lexer.TokenKind.BRACE_L)) {
return parseOperationDefinition(lexer);
}
if (peek(lexer, _lexer.TokenKind.NAME)) {
switch (lexer.token.value) {
// Note: subscription is an experimental non-spec addition.
case 'query':
case 'mutation':
case 'subscription':
return parseOperationDefinition(lexer);
case 'fragment':
return parseFragmentDefinition(lexer);
// Note: the Type System IDL is an experimental non-spec addition.
case 'schema':
case 'scalar':
case 'type':
case 'interface':
case 'union':
case 'enum':
case 'input':
case 'extend':
case 'directive':
return parseTypeSystemDefinition(lexer);
}
}
throw unexpected(lexer);
}
// Implements the parsing rules in the Operations section.
/**
* OperationDefinition :
* - SelectionSet
* - OperationType Name? VariableDefinitions? Directives? SelectionSet
*/
function parseOperationDefinition(lexer) {
var start = lexer.token;
if (peek(lexer, _lexer.TokenKind.BRACE_L)) {
return {
kind: _kinds.OPERATION_DEFINITION,
operation: 'query',
name: null,
variableDefinitions: null,
directives: [],
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
var operation = parseOperationType(lexer);
var name = void 0;
if (peek(lexer, _lexer.TokenKind.NAME)) {
name = parseName(lexer);
}
return {
kind: _kinds.OPERATION_DEFINITION,
operation: operation,
name: name,
variableDefinitions: parseVariableDefinitions(lexer),
directives: parseDirectives(lexer),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* OperationType : one of query mutation subscription
*/
function parseOperationType(lexer) {
var operationToken = expect(lexer, _lexer.TokenKind.NAME);
switch (operationToken.value) {
case 'query':
return 'query';
case 'mutation':
return 'mutation';
// Note: subscription is an experimental non-spec addition.
case 'subscription':
return 'subscription';
}
throw unexpected(lexer, operationToken);
}
/**
* VariableDefinitions : ( VariableDefinition+ )
*/
function parseVariableDefinitions(lexer) {
return peek(lexer, _lexer.TokenKind.PAREN_L) ? many(lexer, _lexer.TokenKind.PAREN_L, parseVariableDefinition, _lexer.TokenKind.PAREN_R) : [];
}
/**
* VariableDefinition : Variable : Type DefaultValue?
*/
function parseVariableDefinition(lexer) {
var start = lexer.token;
return {
kind: _kinds.VARIABLE_DEFINITION,
variable: parseVariable(lexer),
type: (expect(lexer, _lexer.TokenKind.COLON), parseTypeReference(lexer)),
defaultValue: skip(lexer, _lexer.TokenKind.EQUALS) ? parseValueLiteral(lexer, true) : null,
loc: loc(lexer, start)
};
}
/**
* Variable : $ Name
*/
function parseVariable(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.DOLLAR);
return {
kind: _kinds.VARIABLE,
name: parseName(lexer),
loc: loc(lexer, start)
};
}
/**
* SelectionSet : { Selection+ }
*/
function parseSelectionSet(lexer) {
var start = lexer.token;
return {
kind: _kinds.SELECTION_SET,
selections: many(lexer, _lexer.TokenKind.BRACE_L, parseSelection, _lexer.TokenKind.BRACE_R),
loc: loc(lexer, start)
};
}
/**
* Selection :
* - Field
* - FragmentSpread
* - InlineFragment
*/
function parseSelection(lexer) {
return peek(lexer, _lexer.TokenKind.SPREAD) ? parseFragment(lexer) : parseField(lexer);
}
/**
* Field : Alias? Name Arguments? Directives? SelectionSet?
*
* Alias : Name :
*/
function parseField(lexer) {
var start = lexer.token;
var nameOrAlias = parseName(lexer);
var alias = void 0;
var name = void 0;
if (skip(lexer, _lexer.TokenKind.COLON)) {
alias = nameOrAlias;
name = parseName(lexer);
} else {
alias = null;
name = nameOrAlias;
}
return {
kind: _kinds.FIELD,
alias: alias,
name: name,
arguments: parseArguments(lexer),
directives: parseDirectives(lexer),
selectionSet: peek(lexer, _lexer.TokenKind.BRACE_L) ? parseSelectionSet(lexer) : null,
loc: loc(lexer, start)
};
}
/**
* Arguments : ( Argument+ )
*/
function parseArguments(lexer) {
return peek(lexer, _lexer.TokenKind.PAREN_L) ? many(lexer, _lexer.TokenKind.PAREN_L, parseArgument, _lexer.TokenKind.PAREN_R) : [];
}
/**
* Argument : Name : Value
*/
function parseArgument(lexer) {
var start = lexer.token;
return {
kind: _kinds.ARGUMENT,
name: parseName(lexer),
value: (expect(lexer, _lexer.TokenKind.COLON), parseValueLiteral(lexer, false)),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Fragments section.
/**
* Corresponds to both FragmentSpread and InlineFragment in the spec.
*
* FragmentSpread : ... FragmentName Directives?
*
* InlineFragment : ... TypeCondition? Directives? SelectionSet
*/
function parseFragment(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.SPREAD);
if (peek(lexer, _lexer.TokenKind.NAME) && lexer.token.value !== 'on') {
return {
kind: _kinds.FRAGMENT_SPREAD,
name: parseFragmentName(lexer),
directives: parseDirectives(lexer),
loc: loc(lexer, start)
};
}
var typeCondition = null;
if (lexer.token.value === 'on') {
lexer.advance();
typeCondition = parseNamedType(lexer);
}
return {
kind: _kinds.INLINE_FRAGMENT,
typeCondition: typeCondition,
directives: parseDirectives(lexer),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* FragmentDefinition :
* - fragment FragmentName on TypeCondition Directives? SelectionSet
*
* TypeCondition : NamedType
*/
function parseFragmentDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'fragment');
return {
kind: _kinds.FRAGMENT_DEFINITION,
name: parseFragmentName(lexer),
typeCondition: (expectKeyword(lexer, 'on'), parseNamedType(lexer)),
directives: parseDirectives(lexer),
selectionSet: parseSelectionSet(lexer),
loc: loc(lexer, start)
};
}
/**
* FragmentName : Name but not `on`
*/
function parseFragmentName(lexer) {
if (lexer.token.value === 'on') {
throw unexpected(lexer);
}
return parseName(lexer);
}
// Implements the parsing rules in the Values section.
/**
* Value[Const] :
* - [~Const] Variable
* - IntValue
* - FloatValue
* - StringValue
* - BooleanValue
* - NullValue
* - EnumValue
* - ListValue[?Const]
* - ObjectValue[?Const]
*
* BooleanValue : one of `true` `false`
*
* NullValue : `null`
*
* EnumValue : Name but not `true`, `false` or `null`
*/
function parseValueLiteral(lexer, isConst) {
var token = lexer.token;
switch (token.kind) {
case _lexer.TokenKind.BRACKET_L:
return parseList(lexer, isConst);
case _lexer.TokenKind.BRACE_L:
return parseObject(lexer, isConst);
case _lexer.TokenKind.INT:
lexer.advance();
return {
kind: _kinds.INT,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.FLOAT:
lexer.advance();
return {
kind: _kinds.FLOAT,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.STRING:
lexer.advance();
return {
kind: _kinds.STRING,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.NAME:
if (token.value === 'true' || token.value === 'false') {
lexer.advance();
return {
kind: _kinds.BOOLEAN,
value: token.value === 'true',
loc: loc(lexer, token)
};
} else if (token.value === 'null') {
lexer.advance();
return {
kind: _kinds.NULL,
loc: loc(lexer, token)
};
}
lexer.advance();
return {
kind: _kinds.ENUM,
value: token.value,
loc: loc(lexer, token)
};
case _lexer.TokenKind.DOLLAR:
if (!isConst) {
return parseVariable(lexer);
}
break;
}
throw unexpected(lexer);
}
function parseConstValue(lexer) {
return parseValueLiteral(lexer, true);
}
function parseValueValue(lexer) {
return parseValueLiteral(lexer, false);
}
/**
* ListValue[Const] :
* - [ ]
* - [ Value[?Const]+ ]
*/
function parseList(lexer, isConst) {
var start = lexer.token;
var item = isConst ? parseConstValue : parseValueValue;
return {
kind: _kinds.LIST,
values: any(lexer, _lexer.TokenKind.BRACKET_L, item, _lexer.TokenKind.BRACKET_R),
loc: loc(lexer, start)
};
}
/**
* ObjectValue[Const] :
* - { }
* - { ObjectField[?Const]+ }
*/
function parseObject(lexer, isConst) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.BRACE_L);
var fields = [];
while (!skip(lexer, _lexer.TokenKind.BRACE_R)) {
fields.push(parseObjectField(lexer, isConst));
}
return {
kind: _kinds.OBJECT,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* ObjectField[Const] : Name : Value[?Const]
*/
function parseObjectField(lexer, isConst) {
var start = lexer.token;
return {
kind: _kinds.OBJECT_FIELD,
name: parseName(lexer),
value: (expect(lexer, _lexer.TokenKind.COLON), parseValueLiteral(lexer, isConst)),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Directives section.
/**
* Directives : Directive+
*/
function parseDirectives(lexer) {
var directives = [];
while (peek(lexer, _lexer.TokenKind.AT)) {
directives.push(parseDirective(lexer));
}
return directives;
}
/**
* Directive : @ Name Arguments?
*/
function parseDirective(lexer) {
var start = lexer.token;
expect(lexer, _lexer.TokenKind.AT);
return {
kind: _kinds.DIRECTIVE,
name: parseName(lexer),
arguments: parseArguments(lexer),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Types section.
/**
* Type :
* - NamedType
* - ListType
* - NonNullType
*/
function parseTypeReference(lexer) {
var start = lexer.token;
var type = void 0;
if (skip(lexer, _lexer.TokenKind.BRACKET_L)) {
type = parseTypeReference(lexer);
expect(lexer, _lexer.TokenKind.BRACKET_R);
type = {
kind: _kinds.LIST_TYPE,
type: type,
loc: loc(lexer, start)
};
} else {
type = parseNamedType(lexer);
}
if (skip(lexer, _lexer.TokenKind.BANG)) {
return {
kind: _kinds.NON_NULL_TYPE,
type: type,
loc: loc(lexer, start)
};
}
return type;
}
/**
* NamedType : Name
*/
function parseNamedType(lexer) {
var start = lexer.token;
return {
kind: _kinds.NAMED_TYPE,
name: parseName(lexer),
loc: loc(lexer, start)
};
}
// Implements the parsing rules in the Type Definition section.
/**
* TypeSystemDefinition :
* - SchemaDefinition
* - TypeDefinition
* - TypeExtensionDefinition
* - DirectiveDefinition
*
* TypeDefinition :
* - ScalarTypeDefinition
* - ObjectTypeDefinition
* - InterfaceTypeDefinition
* - UnionTypeDefinition
* - EnumTypeDefinition
* - InputObjectTypeDefinition
*/
function parseTypeSystemDefinition(lexer) {
if (peek(lexer, _lexer.TokenKind.NAME)) {
switch (lexer.token.value) {
case 'schema':
return parseSchemaDefinition(lexer);
case 'scalar':
return parseScalarTypeDefinition(lexer);
case 'type':
return parseObjectTypeDefinition(lexer);
case 'interface':
return parseInterfaceTypeDefinition(lexer);
case 'union':
return parseUnionTypeDefinition(lexer);
case 'enum':
return parseEnumTypeDefinition(lexer);
case 'input':
return parseInputObjectTypeDefinition(lexer);
case 'extend':
return parseTypeExtensionDefinition(lexer);
case 'directive':
return parseDirectiveDefinition(lexer);
}
}
throw unexpected(lexer);
}
/**
* SchemaDefinition : schema Directives? { OperationTypeDefinition+ }
*
* OperationTypeDefinition : OperationType : NamedType
*/
function parseSchemaDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'schema');
var directives = parseDirectives(lexer);
var operationTypes = many(lexer, _lexer.TokenKind.BRACE_L, parseOperationTypeDefinition, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.SCHEMA_DEFINITION,
directives: directives,
operationTypes: operationTypes,
loc: loc(lexer, start)
};
}
function parseOperationTypeDefinition(lexer) {
var start = lexer.token;
var operation = parseOperationType(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseNamedType(lexer);
return {
kind: _kinds.OPERATION_TYPE_DEFINITION,
operation: operation,
type: type,
loc: loc(lexer, start)
};
}
/**
* ScalarTypeDefinition : scalar Name Directives?
*/
function parseScalarTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'scalar');
var name = parseName(lexer);
var directives = parseDirectives(lexer);
return {
kind: _kinds.SCALAR_TYPE_DEFINITION,
name: name,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* ObjectTypeDefinition :
* - type Name ImplementsInterfaces? Directives? { FieldDefinition+ }
*/
function parseObjectTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'type');
var name = parseName(lexer);
var interfaces = parseImplementsInterfaces(lexer);
var directives = parseDirectives(lexer);
var fields = any(lexer, _lexer.TokenKind.BRACE_L, parseFieldDefinition, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.OBJECT_TYPE_DEFINITION,
name: name,
interfaces: interfaces,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* ImplementsInterfaces : implements NamedType+
*/
function parseImplementsInterfaces(lexer) {
var types = [];
if (lexer.token.value === 'implements') {
lexer.advance();
do {
types.push(parseNamedType(lexer));
} while (peek(lexer, _lexer.TokenKind.NAME));
}
return types;
}
/**
* FieldDefinition : Name ArgumentsDefinition? : Type Directives?
*/
function parseFieldDefinition(lexer) {
var start = lexer.token;
var name = parseName(lexer);
var args = parseArgumentDefs(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseTypeReference(lexer);
var directives = parseDirectives(lexer);
return {
kind: _kinds.FIELD_DEFINITION,
name: name,
arguments: args,
type: type,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* ArgumentsDefinition : ( InputValueDefinition+ )
*/
function parseArgumentDefs(lexer) {
if (!peek(lexer, _lexer.TokenKind.PAREN_L)) {
return [];
}
return many(lexer, _lexer.TokenKind.PAREN_L, parseInputValueDef, _lexer.TokenKind.PAREN_R);
}
/**
* InputValueDefinition : Name : Type DefaultValue? Directives?
*/
function parseInputValueDef(lexer) {
var start = lexer.token;
var name = parseName(lexer);
expect(lexer, _lexer.TokenKind.COLON);
var type = parseTypeReference(lexer);
var defaultValue = null;
if (skip(lexer, _lexer.TokenKind.EQUALS)) {
defaultValue = parseConstValue(lexer);
}
var directives = parseDirectives(lexer);
return {
kind: _kinds.INPUT_VALUE_DEFINITION,
name: name,
type: type,
defaultValue: defaultValue,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* InterfaceTypeDefinition : interface Name Directives? { FieldDefinition+ }
*/
function parseInterfaceTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'interface');
var name = parseName(lexer);
var directives = parseDirectives(lexer);
var fields = any(lexer, _lexer.TokenKind.BRACE_L, parseFieldDefinition, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.INTERFACE_TYPE_DEFINITION,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* UnionTypeDefinition : union Name Directives? = UnionMembers
*/
function parseUnionTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'union');
var name = parseName(lexer);
var directives = parseDirectives(lexer);
expect(lexer, _lexer.TokenKind.EQUALS);
var types = parseUnionMembers(lexer);
return {
kind: _kinds.UNION_TYPE_DEFINITION,
name: name,
directives: directives,
types: types,
loc: loc(lexer, start)
};
}
/**
* UnionMembers :
* - `|`? NamedType
* - UnionMembers | NamedType
*/
function parseUnionMembers(lexer) {
// Optional leading pipe
skip(lexer, _lexer.TokenKind.PIPE);
var members = [];
do {
members.push(parseNamedType(lexer));
} while (skip(lexer, _lexer.TokenKind.PIPE));
return members;
}
/**
* EnumTypeDefinition : enum Name Directives? { EnumValueDefinition+ }
*/
function parseEnumTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'enum');
var name = parseName(lexer);
var directives = parseDirectives(lexer);
var values = many(lexer, _lexer.TokenKind.BRACE_L, parseEnumValueDefinition, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.ENUM_TYPE_DEFINITION,
name: name,
directives: directives,
values: values,
loc: loc(lexer, start)
};
}
/**
* EnumValueDefinition : EnumValue Directives?
*
* EnumValue : Name
*/
function parseEnumValueDefinition(lexer) {
var start = lexer.token;
var name = parseName(lexer);
var directives = parseDirectives(lexer);
return {
kind: _kinds.ENUM_VALUE_DEFINITION,
name: name,
directives: directives,
loc: loc(lexer, start)
};
}
/**
* InputObjectTypeDefinition : input Name Directives? { InputValueDefinition+ }
*/
function parseInputObjectTypeDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'input');
var name = parseName(lexer);
var directives = parseDirectives(lexer);
var fields = any(lexer, _lexer.TokenKind.BRACE_L, parseInputValueDef, _lexer.TokenKind.BRACE_R);
return {
kind: _kinds.INPUT_OBJECT_TYPE_DEFINITION,
name: name,
directives: directives,
fields: fields,
loc: loc(lexer, start)
};
}
/**
* TypeExtensionDefinition : extend ObjectTypeDefinition
*/
function parseTypeExtensionDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'extend');
var definition = parseObjectTypeDefinition(lexer);
return {
kind: _kinds.TYPE_EXTENSION_DEFINITION,
definition: definition,
loc: loc(lexer, start)
};
}
/**
* DirectiveDefinition :
* - directive @ Name ArgumentsDefinition? on DirectiveLocations
*/
function parseDirectiveDefinition(lexer) {
var start = lexer.token;
expectKeyword(lexer, 'directive');
expect(lexer, _lexer.TokenKind.AT);
var name = parseName(lexer);
var args = parseArgumentDefs(lexer);
expectKeyword(lexer, 'on');
var locations = parseDirectiveLocations(lexer);
return {
kind: _kinds.DIRECTIVE_DEFINITION,
name: name,
arguments: args,
locations: locations,
loc: loc(lexer, start)
};
}
/**
* DirectiveLocations :
* - `|`? Name
* - DirectiveLocations | Name
*/
function parseDirectiveLocations(lexer) {
// Optional leading pipe
skip(lexer, _lexer.TokenKind.PIPE);
var locations = [];
do {
locations.push(parseName(lexer));
} while (skip(lexer, _lexer.TokenKind.PIPE));
return locations;
}
// Core parsing utility functions
/**
* Returns a location object, used to identify the place in
* the source that created a given parsed object.
*/
function loc(lexer, startToken) {
if (!lexer.options.noLocation) {
return new Loc(startToken, lexer.lastToken, lexer.source);
}
}
function Loc(startToken, endToken, source) {
this.start = startToken.start;
this.end = endToken.end;
this.startToken = startToken;
this.endToken = endToken;
this.source = source;
}
// Print a simplified form when appearing in JSON/util.inspect.
Loc.prototype.toJSON = Loc.prototype.inspect = function toJSON() {
return { start: this.start, end: this.end };
};
/**
* Determines if the next token is of a given kind
*/
function peek(lexer, kind) {
return lexer.token.kind === kind;
}
/**
* If the next token is of the given kind, return true after advancing
* the lexer. Otherwise, do not change the parser state and return false.
*/
function skip(lexer, kind) {
var match = lexer.token.kind === kind;
if (match) {
lexer.advance();
}
return match;
}
/**
* If the next token is of the given kind, return that token after advancing
* the lexer. Otherwise, do not change the parser state and throw an error.
*/
function expect(lexer, kind) {
var token = lexer.token;
if (token.kind === kind) {
lexer.advance();
return token;
}
throw (0, _error.syntaxError)(lexer.source, token.start, 'Expected ' + kind + ', found ' + (0, _lexer.getTokenDesc)(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.
*/
function expectKeyword(lexer, value) {
var token = lexer.token;
if (token.kind === _lexer.TokenKind.NAME && token.value === value) {
lexer.advance();
return token;
}
throw (0, _error.syntaxError)(lexer.source, token.start, 'Expected "' + value + '", found ' + (0, _lexer.getTokenDesc)(token));
}
/**
* Helper function for creating an error when an unexpected lexed token
* is encountered.
*/
function unexpected(lexer, atToken) {
var token = atToken || lexer.token;
return (0, _error.syntaxError)(lexer.source, token.start, 'Unexpected ' + (0, _lexer.getTokenDesc)(token));
}
/**
* Returns a possibly empty list of parse nodes, determined by
* the parseFn. This list begins with a lex token of openKind
* and ends with a lex token of closeKind. Advances the parser
* to the next lex token after the closing token.
*/
function any(lexer, openKind, parseFn, closeKind) {
expect(lexer, openKind);
var nodes = [];
while (!skip(lexer, closeKind)) {
nodes.push(parseFn(lexer));
}
return nodes;
}
/**
* Returns a non-empty list of parse nodes, determined by
* the parseFn. This list begins with a lex token of openKind
* and ends with a lex token of closeKind. Advances the parser
* to the next lex token after the closing token.
*/
function many(lexer, openKind, parseFn, closeKind) {
expect(lexer, openKind);
var nodes = [parseFn(lexer)];
while (!skip(lexer, closeKind)) {
nodes.push(parseFn(lexer));
}
return nodes;
}