From 375de5b2072c31b5d02065fdecf6c85a53379c97 Mon Sep 17 00:00:00 2001 From: Naman Kumar Date: Sun, 30 Aug 2020 03:54:37 +0530 Subject: [PATCH 1/5] Adding experimental online parser --- resources/build-npm.js | 2 +- src/language/online-parser/index.d.ts | 2 + src/language/online-parser/index.js | 2 + src/language/online-parser/language.d.ts | 4 + src/language/online-parser/language.js | 1 + src/language/online-parser/parser.d.ts | 54 ++ src/language/online-parser/parser.js | 650 ++++++++++++++++ src/language/online-parser/rules.json | 938 +++++++++++++++++++++++ src/language/online-parser/types.d.ts | 139 ++++ src/language/online-parser/types.js | 151 ++++ 10 files changed, 1942 insertions(+), 1 deletion(-) create mode 100644 src/language/online-parser/index.d.ts create mode 100644 src/language/online-parser/index.js create mode 100644 src/language/online-parser/language.d.ts create mode 100644 src/language/online-parser/language.js create mode 100644 src/language/online-parser/parser.d.ts create mode 100644 src/language/online-parser/parser.js create mode 100644 src/language/online-parser/rules.json create mode 100644 src/language/online-parser/types.d.ts create mode 100644 src/language/online-parser/types.js diff --git a/resources/build-npm.js b/resources/build-npm.js index fbc26c73e2..21f0b7c30a 100644 --- a/resources/build-npm.js +++ b/resources/build-npm.js @@ -26,7 +26,7 @@ if (require.main === module) { const mjs = babelBuild(srcPath, { envName: 'mjs' }); fs.writeFileSync(destPath.replace(/\.js$/, '.mjs'), mjs); - } else if (filepath.endsWith('.d.ts')) { + } else if (filepath.endsWith('.d.ts') || filepath.endsWith('.json')) { fs.copyFileSync(srcPath, destPath); } } diff --git a/src/language/online-parser/index.d.ts b/src/language/online-parser/index.d.ts new file mode 100644 index 0000000000..d8ff9e2b21 --- /dev/null +++ b/src/language/online-parser/index.d.ts @@ -0,0 +1,2 @@ +export { Parser } from './parser'; +export * from './types'; diff --git a/src/language/online-parser/index.js b/src/language/online-parser/index.js new file mode 100644 index 0000000000..d8ff9e2b21 --- /dev/null +++ b/src/language/online-parser/index.js @@ -0,0 +1,2 @@ +export { Parser } from './parser'; +export * from './types'; diff --git a/src/language/online-parser/language.d.ts b/src/language/online-parser/language.d.ts new file mode 100644 index 0000000000..94a3a0362d --- /dev/null +++ b/src/language/online-parser/language.d.ts @@ -0,0 +1,4 @@ +import { LanguageType } from './types'; + +declare const Language: LanguageType; +export default Language; diff --git a/src/language/online-parser/language.js b/src/language/online-parser/language.js new file mode 100644 index 0000000000..544e34f226 --- /dev/null +++ b/src/language/online-parser/language.js @@ -0,0 +1 @@ +export { default } from './rules'; diff --git a/src/language/online-parser/parser.d.ts b/src/language/online-parser/parser.d.ts new file mode 100644 index 0000000000..c2c8bd39ef --- /dev/null +++ b/src/language/online-parser/parser.d.ts @@ -0,0 +1,54 @@ +import { Lexer } from '../lexer'; + +import { + Token, + Styles, + ParserState, + ParserConfig, + ParserConfigOption, + Rule, +} from './types'; + +export declare class Parser { + state: ParserState; + lexer: Lexer; + styles: Styles; + config: ParserConfig; + constructor({ + state, + styles, + config, + source, + }: { + state?: ParserState; + styles?: Styles; + config?: ParserConfigOption; + source: string; + }); + static startState(): ParserState; + static copyState(state: ParserState): ParserState; + sol(): boolean; + parseToken(): Token; + indentation(): number; + private readonly parseTokenConstraint; + private readonly parseListOfTypeConstraint; + private readonly parseOfTypeConstraint; + private readonly parsePeekConstraint; + private readonly parseConstraintsSetRule; + private readonly matchToken; + private readonly butNot; + private readonly transformLexerToken; + private readonly getNextRule; + private readonly popMatchedRule; + private readonly rollbackRule; + pushRule( + rule: Rule, + depth: number, + name?: string, + step?: number, + state?: string, + ): void; + private readonly getRuleKind; + private readonly advanceToken; + private readonly lookAhead; +} diff --git a/src/language/online-parser/parser.js b/src/language/online-parser/parser.js new file mode 100644 index 0000000000..96476f208d --- /dev/null +++ b/src/language/online-parser/parser.js @@ -0,0 +1,650 @@ +import { Lexer } from '../lexer'; +import { Source } from '../source'; + +import Language from './language'; +import { RuleKind, TokenKind } from './types'; +import type { + Token, + LexerToken, + Styles, + ParserRule, + ParserState, + ParserConfig, + ParserConfigOption, + Rule, + RuleName, + RuleConstraint, + TokenParserRule, + OfTypeParserRule, + ListOfTypeParserRule, + PeekParserRule, + ConstraintsSetRule, + OfTypeConstraint, + ListOfTypeConstraint, + TokenConstraint, + PeekConstraint, + ConstraintsSet, +} from './types'; + +export class Parser { + state: ParserState; + lexer: Lexer; + styles: Styles; + config: ParserConfig; + + constructor({ + state, + styles, + config, + source, + }: {| + state: ?ParserState, + styles: ?Styles, + config: ?ParserConfigOption, + source: string, + |}) { + this.state = state || Parser.startState(); + this.styles = styles || {}; + this.config = { + tabSize: typeof config?.tabSize === 'number' ? config.tabSize : 2, + }; + this.lexer = new Lexer(new Source(source)); + } + + static startState(): ParserState { + return { + rules: [ + { + name: 'Document', + state: 'Document', + kind: 'ListOfTypeConstraint', + ...Language.rules.Document, + expanded: false, + depth: 1, + step: 1, + }, + ], + name: null, + type: null, + levels: [], + indentLevel: 0, + kind(): string { + return this.rules[this.rules.length - 1]?.state || ''; + }, + step(): number { + return this.rules[this.rules.length - 1]?.step || 0; + }, + }; + } + + static copyState(state: ParserState): ParserState { + return { + name: state.name, + type: state.type, + rules: JSON.parse(JSON.stringify(state.rules)), + levels: [...state.levels], + indentLevel: state.indentLevel, + kind(): string { + return this.rules[this.rules.length - 1]?.state || ''; + }, + step(): number { + return this.rules[this.rules.length - 1]?.step || 0; + }, + }; + } + + sol(): boolean { + return ( + this.lexer.source.locationOffset.line === 1 && + this.lexer.source.locationOffset.column === 1 + ); + } + + parseToken(): Token { + const rule = (this.getNextRule(): any); + + if (this.sol()) { + this.state.indentLevel = Math.floor( + this.indentation() / this.config.tabSize, + ); + } + + if (!rule) { + return { + kind: TokenKind.INVALID, + style: this.styles[TokenKind.INVALID], + value: '', + }; + } + + let token; + + if (this.lookAhead().kind === '') { + return { + kind: TokenKind.EOF, + style: this.styles[TokenKind.EOF], + value: '', + }; + } + + switch (rule.kind) { + case RuleKind.TOKEN_CONSTRAINT: + token = this.parseTokenConstraint(rule); + break; + case RuleKind.LIST_OF_TYPE_CONSTRAINT: + token = this.parseListOfTypeConstraint(rule); + break; + case RuleKind.OF_TYPE_CONSTRAINT: + token = this.parseOfTypeConstraint(rule); + break; + case RuleKind.PEEK_CONSTRAINT: + token = this.parsePeekConstraint(rule); + break; + case RuleKind.CONSTRAINTS_SET_ROOT: + token = this.parseConstraintsSetRule(rule); + break; + default: + return { + kind: TokenKind.INVALID, + style: this.styles[TokenKind.INVALID], + value: '', + }; + } + + if (token && token.kind === TokenKind.INVALID) { + if (rule.optional === true) { + this.state.rules.pop(); + } else { + this.rollbackRule(); + } + + return this.parseToken() || token; + } + + return token; + } + + indentation(): number { + const match = this.lexer.source.body.match(/\s*/); + let indent = 0; + + if (match && match.length === 0) { + const whiteSpaces = match[0]; + let pos = 0; + while (whiteSpaces.length > pos) { + if (whiteSpaces.charCodeAt(pos) === 9) { + indent += 2; + } else { + indent++; + } + pos++; + } + } + + return indent; + } + + parseTokenConstraint(rule: TokenParserRule): Token { + rule.expanded = true; + + const token = this.lookAhead(); + + if (!this.matchToken(token, rule)) { + return { + kind: TokenKind.INVALID, + style: this.styles[TokenKind.INVALID], + value: '', + }; + } + + this.advanceToken(); + const parserToken = this.transformLexerToken(token, rule); + this.popMatchedRule(parserToken); + + return parserToken; + } + + parseListOfTypeConstraint(rule: ListOfTypeParserRule): Token { + this.pushRule( + Language.rules[rule.listOfType], + rule.depth + 1, + rule.listOfType, + 1, + rule.state, + ); + + rule.expanded = true; + + const token = this.parseToken(); + + return token; + } + + parseOfTypeConstraint(rule: OfTypeParserRule): Token { + if (rule.expanded) { + this.popMatchedRule(); + return this.parseToken(); + } + + this.pushRule(rule.ofType, rule.depth + 1, rule.tokenName, 1, rule.state); + rule.expanded = true; + + const token = this.parseToken(); + + return token; + } + + parsePeekConstraint(rule: PeekParserRule): Token { + if (rule.expanded) { + this.popMatchedRule(); + return this.parseToken(); + } + + while (!rule.matched && rule.index < rule.peek.length - 1) { + rule.index++; + const constraint = rule.peek[rule.index]; + + let { ifCondition } = constraint; + if (typeof ifCondition === 'string') { + ifCondition = Language.rules[ifCondition]; + } + + let token = this.lookAhead(); + if (ifCondition && this.matchToken(token, ifCondition)) { + rule.matched = true; + rule.expanded = true; + this.pushRule(constraint.expect, rule.depth + 1, '', 1, rule.state); + + token = this.parseToken(); + + return token; + } + } + + return { + kind: TokenKind.INVALID, + style: this.styles[TokenKind.INVALID], + value: '', + }; + } + + parseConstraintsSetRule(rule: ConstraintsSetRule): Token { + if (rule.expanded) { + this.popMatchedRule(); + return this.parseToken(); + } + + for (let index = rule.constraints.length - 1; index >= 0; index--) { + this.pushRule( + rule.constraints[index], + rule.depth + 1, + '', + index, + rule.state, + ); + } + rule.expanded = true; + + return this.parseToken(); + } + + matchToken(token: Token | LexerToken, rule: TokenConstraint): boolean { + if (typeof token.value === 'string') { + if ( + (typeof rule.ofValue === 'string' && token.value !== rule.ofValue) || + (Array.isArray(rule.oneOf) && !rule.oneOf.includes(token.value)) || + (typeof rule.ofValue !== 'string' && + !Array.isArray(rule.oneOf) && + token.kind !== rule.token) + ) { + return false; + } + + return this.butNot(token, rule); + } + + if (token.kind !== rule.token) { + return false; + } + + return this.butNot(token, rule); + } + + butNot(token: Token | LexerToken, rule: RuleConstraint): boolean { + if (rule.butNot) { + if (Array.isArray(rule.butNot)) { + if ( + rule.butNot.reduce( + (matched, constraint) => + matched || this.matchToken(token, constraint), + false, + ) + ) { + return false; + } + + return true; + } + + return !this.matchToken(token, rule.butNot); + } + + return true; + } + + transformLexerToken(lexerToken: LexerToken, rule: any): Token { + let token; + const ruleName = rule.name || ''; + const tokenName = rule.tokenName || ''; + + if (lexerToken.kind === '' || lexerToken.value !== undefined) { + token = { + kind: lexerToken.kind, + value: lexerToken.value || '', + style: + this.styles[tokenName] || + this.styles[ruleName] || + this.styles[lexerToken.kind], + }; + + if (token.kind === TokenKind.STRING) { + token.value = `"${token.value}"`; + } else if (token.kind === TokenKind.BLOCK_STRING) { + token.value = `"""${token.value}"""`; + } + } else { + token = { + kind: TokenKind.PUNCTUATION, + value: lexerToken.kind, + style: + this.styles[tokenName] || + this.styles[ruleName] || + this.styles[TokenKind.PUNCTUATION], + }; + + if (/^[{([]/.test(token.value)) { + if (this.state.indentLevel !== undefined) { + this.state.levels = this.state.levels.concat( + this.state.indentLevel + 1, + ); + } + } else if (/^[})\]]/.test(token.value)) { + this.state.levels.pop(); + } + } + + return token; + } + + getNextRule(): ParserRule | null { + return this.state.rules[this.state.rules.length - 1] || null; + } + + popMatchedRule(token: ?Token) { + const rule = this.state.rules.pop(); + if (!rule) { + return; + } + + if (token && rule.kind === RuleKind.TOKEN_CONSTRAINT) { + const constraint = rule; + if (typeof constraint.definitionName === 'string') { + this.state.name = token.value || null; + } else if (typeof constraint.typeName === 'string') { + this.state.type = token.value || null; + } + } + + const nextRule = this.getNextRule(); + if (!nextRule) { + return; + } + + if ( + nextRule.depth === rule.depth - 1 && + nextRule.expanded && + nextRule.kind === RuleKind.CONSTRAINTS_SET_ROOT + ) { + this.state.rules.pop(); + } + + if ( + nextRule.depth === rule.depth - 1 && + nextRule.expanded && + nextRule.kind === RuleKind.LIST_OF_TYPE_CONSTRAINT + ) { + nextRule.expanded = false; + nextRule.optional = true; + } + } + + rollbackRule() { + if (!this.state.rules.length) { + return; + } + + const popRule = () => { + const lastPoppedRule = this.state.rules.pop(); + + if (lastPoppedRule.eatNextOnFail === true) { + this.state.rules.pop(); + } + }; + + const poppedRule = this.state.rules.pop(); + if (!poppedRule) { + return; + } + + let popped = 0; + let nextRule = this.getNextRule(); + while ( + nextRule && + (poppedRule.kind !== RuleKind.LIST_OF_TYPE_CONSTRAINT || + nextRule.expanded) && + nextRule.depth > poppedRule.depth - 1 + ) { + this.state.rules.pop(); + popped++; + nextRule = this.getNextRule(); + } + + if (nextRule && nextRule.expanded) { + if (nextRule.optional === true) { + popRule(); + } else { + if ( + nextRule.kind === RuleKind.LIST_OF_TYPE_CONSTRAINT && + popped === 1 + ) { + this.state.rules.pop(); + return; + } + this.rollbackRule(); + } + } + } + + pushRule( + baseRule: any, + depth: number, + name?: string, + step?: number, + state?: string, + ) { + this.state.name = null; + this.state.type = null; + let rule = baseRule; + + switch (this.getRuleKind(rule)) { + case RuleKind.RULE_NAME: + rule = (rule: RuleName); + this.pushRule( + Language.rules[rule], + depth, + (typeof name === 'string' ? name : undefined) || rule, + step, + state, + ); + break; + case RuleKind.CONSTRAINTS_SET: + rule = (rule: ConstraintsSet); + this.state.rules.push({ + name: name || '', + depth, + expanded: false, + constraints: rule, + constraintsSet: true, + kind: RuleKind.CONSTRAINTS_SET_ROOT, + state: + (typeof name === 'string' ? name : undefined) || + (typeof state === 'string' ? state : undefined) || + this.getNextRule()?.state || + '', + step: + typeof step === 'number' + ? step + : (this.getNextRule()?.step || 0) + 1, + }); + break; + case RuleKind.OF_TYPE_CONSTRAINT: + rule = (rule: OfTypeConstraint); + this.state.rules.push({ + name: name || '', + ofType: rule.ofType, + optional: Boolean(rule.optional), + butNot: rule.butNot, + eatNextOnFail: Boolean(rule.eatNextOnFail), + depth, + expanded: false, + kind: RuleKind.OF_TYPE_CONSTRAINT, + state: + (typeof rule.tokenName === 'string' ? rule.tokenName : undefined) || + (typeof name === 'string' ? name : undefined) || + (typeof state === 'string' ? state : undefined) || + this.getNextRule()?.state || + '', + step: + typeof step === 'number' + ? step + : (this.getNextRule()?.step || 0) + 1, + }); + break; + case RuleKind.LIST_OF_TYPE_CONSTRAINT: + rule = (rule: ListOfTypeConstraint); + this.state.rules.push({ + listOfType: rule.listOfType, + optional: Boolean(rule.optional), + butNot: rule.butNot, + eatNextOnFail: Boolean(rule.eatNextOnFail), + name: name || '', + depth, + expanded: false, + kind: RuleKind.LIST_OF_TYPE_CONSTRAINT, + state: + (typeof name === 'string' ? name : undefined) || + (typeof state === 'string' ? state : undefined) || + this.getNextRule()?.state || + '', + step: + typeof step === 'number' + ? step + : (this.getNextRule()?.step || 0) + 1, + }); + break; + case RuleKind.TOKEN_CONSTRAINT: + rule = (rule: TokenConstraint); + this.state.rules.push({ + token: rule.token, + ofValue: rule.ofValue, + oneOf: rule.oneOf, + definitionName: Boolean(rule.definitionName), + typeName: Boolean(rule.typeName), + optional: Boolean(rule.optional), + butNot: rule.butNot, + eatNextOnFail: Boolean(rule.eatNextOnFail), + name: name || '', + depth, + expanded: false, + kind: RuleKind.TOKEN_CONSTRAINT, + state: + (typeof rule.tokenName === 'string' ? rule.tokenName : undefined) || + (typeof state === 'string' ? state : undefined) || + this.getNextRule()?.state || + '', + step: + typeof step === 'number' + ? step + : (this.getNextRule()?.step || 0) + 1, + }); + break; + case RuleKind.PEEK_CONSTRAINT: + rule = (rule: PeekConstraint); + this.state.rules.push({ + peek: rule.peek, + optional: Boolean(rule.optional), + butNot: rule.butNot, + eatNextOnFail: Boolean(rule.eatNextOnFail), + name: name || '', + depth, + index: -1, + matched: false, + expanded: false, + kind: RuleKind.PEEK_CONSTRAINT, + state: + (typeof state === 'string' ? state : undefined) || + this.getNextRule()?.state || + '', + step: + typeof step === 'number' + ? step + : (this.getNextRule()?.step || 0) + 1, + }); + break; + } + } + + getRuleKind(rule: Rule | ParserRule): string { + if (Array.isArray(rule)) { + return RuleKind.CONSTRAINTS_SET; + } + + if (rule.constraintsSet === true) { + return RuleKind.CONSTRAINTS_SET_ROOT; + } + + if (typeof rule === 'string') { + return RuleKind.RULE_NAME; + } + + if (Object.prototype.hasOwnProperty.call(rule, 'ofType')) { + return RuleKind.OF_TYPE_CONSTRAINT; + } + + if (Object.prototype.hasOwnProperty.call(rule, 'listOfType')) { + return RuleKind.LIST_OF_TYPE_CONSTRAINT; + } + + if (Object.prototype.hasOwnProperty.call(rule, 'peek')) { + return RuleKind.PEEK_CONSTRAINT; + } + + if (Object.prototype.hasOwnProperty.call(rule, 'token')) { + return RuleKind.TOKEN_CONSTRAINT; + } + + return RuleKind.INVALID; + } + + advanceToken(): LexerToken { + return (this.lexer.advance(): any); + } + + lookAhead(): LexerToken { + try { + return (this.lexer.lookahead(): any); + } catch (err) { + return { kind: TokenKind.INVALID, value: '' }; + } + } +} diff --git a/src/language/online-parser/rules.json b/src/language/online-parser/rules.json new file mode 100644 index 0000000000..cdb0c0538f --- /dev/null +++ b/src/language/online-parser/rules.json @@ -0,0 +1,938 @@ +{ + "rules": { + "Name": { "token": "Name" }, + "String": { "token": "String" }, + "BlockString": { "token": "BlockString" }, + + "Document": { "listOfType": "Definition" }, + "Definition": { + "peek": [ + { + "ifCondition": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"] + }, + "expect": "OperationDefinition" + }, + { + "ifCondition": { "token": "Name", "ofValue": "fragment" }, + "expect": "FragmentDefinition" + }, + { + "ifCondition": { + "token": "Name", + "oneOf": [ + "schema", + "scalar", + "type", + "interface", + "union", + "enum", + "input", + "directive" + ] + }, + "expect": "TypeSystemDefinition" + }, + { + "ifCondition": { "token": "Name", "ofValue": "extend" }, + "expect": "TypeSystemExtension" + }, + { + "ifCondition": { "token": "{" }, + "expect": "OperationDefinition" + }, + { + "ifCondition": "String", + "expect": "TypeSystemDefinition" + }, + { + "ifCondition": "BlockString", + "expect": "TypeSystemDefinition" + } + ] + }, + + "OperationDefinition": { + "peek": [ + { + "ifCondition": { "token": "{" }, + "expect": "SelectionSet" + }, + { + "ifCondition": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"] + }, + "expect": [ + "OperationType", + { + "token": "Name", + "optional": true, + "tokenName": "OperationName", + "definitionName": true + }, + { "ofType": "VariableDefinitions", "optional": true }, + { "ofType": "Directives", "optional": true }, + "SelectionSet" + ] + } + ] + }, + "OperationType": { + "ofType": "OperationTypeName" + }, + "OperationTypeName": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"], + "definitionName": true + }, + "SelectionSet": [ + { "token": "{" }, + { "listOfType": "Selection" }, + { "token": "}" } + ], + "Selection": { + "peek": [ + { + "ifCondition": { "token": "..." }, + "expect": "Fragment" + }, + { + "ifCondition": { "token": "Name" }, + "expect": "Field" + } + ] + }, + + "Field": [ + { + "ofType": "Alias", + "optional": true, + "eatNextOnFail": true, + "definitionName": true + }, + { "token": "Name", "tokenName": "FieldName", "definitionName": true }, + { "ofType": "Arguments", "optional": true }, + { "ofType": "Directives", "optional": true }, + { "ofType": "SelectionSet", "optional": true } + ], + + "Arguments": [ + { "token": "(" }, + { "listOfType": "Argument" }, + { "token": ")" } + ], + "Argument": [ + { "token": "Name", "tokenName": "ArgumentName", "definitionName": true }, + { "token": ":" }, + "Value" + ], + + "Alias": [ + { "token": "Name", "tokenName": "AliasName", "definitionName": true }, + { "token": ":" } + ], + + "Fragment": [ + { "token": "..." }, + { + "peek": [ + { + "ifCondition": "FragmentName", + "expect": "FragmentSpread" + }, + { + "ifCondition": { "token": "Name", "ofValue": "on" }, + "expect": "InlineFragment" + }, + { + "ifCondition": { "token": "@" }, + "expect": "InlineFragment" + }, + { + "ifCondition": { "token": "{" }, + "expect": "InlineFragment" + } + ] + } + ], + + "FragmentSpread": [ + "FragmentName", + { "ofType": "Directives", "optional": true } + ], + "FragmentDefinition": [ + { + "token": "Name", + "ofValue": "fragment", + "tokenName": "FragmentDefinitionKeyword" + }, + "FragmentName", + "TypeCondition", + { "ofType": "Directives", "optional": true }, + "SelectionSet" + ], + "FragmentName": { + "token": "Name", + "butNot": { "token": "Name", "ofValue": "on" }, + "definitionName": true + }, + + "TypeCondition": [ + { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, + "TypeName" + ], + + "InlineFragment": [ + { "ofType": "TypeCondition", "optional": true }, + { "ofType": "Directives", "optional": true }, + "SelectionSet" + ], + + "Value": { + "peek": [ + { + "ifCondition": { "token": "$" }, + "expect": "Variable" + }, + { + "ifCondition": "IntValue", + "expect": { "ofType": "IntValue", "tokenName": "NumberValue" } + }, + { + "ifCondition": "FloatValue", + "expect": { "ofType": "FloatValue", "tokenName": "NumberValue" } + }, + { + "ifCondition": "BooleanValue", + "expect": { "ofType": "BooleanValue", "tokenName": "BooleanValue" } + }, + { + "ifCondition": "EnumValue", + "expect": { "ofType": "EnumValue", "tokenName": "EnumValue" } + }, + { + "ifCondition": "String", + "expect": { "ofType": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": "BlockString", + "expect": { "ofType": "BlockString", "tokenName": "StringValue" } + }, + { + "ifCondition": "NullValue", + "expect": { "ofType": "NullValue", "tokenName": "NullValue" } + }, + { + "ifCondition": { "token": "[" }, + "expect": "ListValue" + }, + { + "ifCondition": { "token": "{" }, + "expect": "ObjectValue" + } + ] + }, + + "ConstValue": { + "peek": [ + { + "ifCondition": "IntValue", + "expect": { "ofType": "IntValue" } + }, + { + "ifCondition": "FloatValue", + "expect": { "ofType": "FloatValue" } + }, + { + "ifCondition": "BooleanValue", + "expect": "BooleanValue" + }, + { + "ifCondition": "EnumValue", + "expect": "EnumValue" + }, + { + "ifCondition": "String", + "expect": { "ofType": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": "BlockString", + "expect": { "token": "BlockString", "tokenName": "StringValue" } + }, + { + "ifCondition": "NullValue", + "expect": "NullValue" + }, + { + "ifCondition": { "token": "[" }, + "expect": "ConstListValue" + }, + { + "ifCondition": { "token": "{" }, + "expect": "ObjectValue" + } + ] + }, + + "IntValue": { "token": "Int" }, + + "FloatValue": { "token": "Float" }, + + "StringValue": { + "peek": [ + { + "ifCondition": { "token": "String" }, + "expect": { "token": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": { "token": "BlockString" }, + "expect": { "token": "BlockString", "tokenName": "StringValue" } + } + ] + }, + + "BooleanValue": { + "token": "Name", + "oneOf": ["true", "false"], + "tokenName": "BooleanValue" + }, + + "NullValue": { + "token": "Name", + "ofValue": "null", + "tokenName": "NullValue" + }, + + "EnumValue": { + "token": "Name", + "butNot": { "token": "Name", "oneOf": ["null", "true", "false"] }, + "tokenName": "EnumValue" + }, + + "ListValue": [ + { "token": "[" }, + { "listOfType": "Value", "optional": true }, + { "token": "]" } + ], + + "ConstListValue": [ + { "token": "[" }, + { "listOfType": "ConstValue", "optional": true }, + { "token": "]" } + ], + + "ObjectValue": [ + { "token": "{" }, + { "listOfType": "ObjectField", "optional": true }, + { "token": "}" } + ], + "ObjectField": [ + { "token": "Name", "tokenName": "ObjectFieldName" }, + { "token": ":" }, + { "ofType": "ConstValue" } + ], + + "Variable": [ + { "token": "$", "tokenName": "VariableName" }, + { "token": "Name", "tokenName": "VariableName" } + ], + "VariableDefinitions": [ + { "token": "(" }, + { "listOfType": "VariableDefinition" }, + { "token": ")" } + ], + "VariableDefinition": [ + "Variable", + { "token": ":" }, + "Type", + { "ofType": "DefaultValue", "optional": true } + ], + "DefaultValue": [{ "token": "=" }, "ConstValue"], + + "TypeName": { "token": "Name", "tokenName": "TypeName", "typeName": true }, + + "Type": { + "peek": [ + { + "ifCondition": { "token": "Name" }, + "expect": ["TypeName", { "token": "!", "optional": true }] + }, + { + "ifCondition": { "token": "[" }, + "expect": "ListType" + } + ] + }, + "ListType": [ + { "token": "[" }, + { "listOfType": "Type" }, + { "token": "]" }, + { "token": "!", "optional": true } + ], + + "Directives": { "listOfType": "Directive" }, + "Directive": [ + { "token": "@", "tokenName": "DirectiveName" }, + { "token": "Name", "tokenName": "DirectiveName" }, + { "ofType": "Arguments", "optional": true } + ], + + "TypeSystemDefinition": [ + { "ofType": "Description", "optional": true }, + { + "peek": [ + { + "ifCondition": { + "target": "Name", + "ofValue": "schema" + }, + "expect": "SchemaDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "scalar" + }, + "expect": "ScalarTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "type" + }, + "expect": "ObjectTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "interface" + }, + "expect": "InterfaceTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "union" + }, + "expect": "UnionTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "enum" + }, + "expect": "EnumTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "input" + }, + "expect": "InputObjectTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "directive" + }, + "expect": "DirectiveDefinition" + } + ] + } + ], + + "TypeSystemExtension": { + "peek": [ + { + "ifCondition": { + "target": "Name", + "ofValue": "schema" + }, + "expect": "SchemaExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "scalar" + }, + "expect": "ScalarTypeExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "type" + }, + "expect": "ObjectTypeExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "interface" + }, + "expect": "InterfaceTypeExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "union" + }, + "expect": "UnionTypeExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "enum" + }, + "expect": "EnumTypeExtension" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "input" + }, + "expect": "InputObjectTypeExtension" + } + ] + }, + + "SchemaDefinition": [ + { + "token": "Name", + "ofValue": "schema", + "tokenName": "SchemaDefinitionKeyword" + }, + { "ofType": "Directives", "optional": true }, + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ], + "RootOperationTypeDefinition": [ + "OperationType", + { "token": ":" }, + { "token": "Name", "tokenName": "OperationTypeDefinitionName" } + ], + + "SchemaExtension": [ + { "token": "Name", "ofValue": "extend" }, + { "token": "Name", "ofValue": "schema" }, + "Name", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { + "ofType": [ + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ], + "optional": true + } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": [ + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ] + } + ] + } + ], + + "Description": "StringValue", + + "ScalarTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "scalar", + "tokenName": "ScalarDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true } + ], + + "ScalarTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "scalar", + "tokenName": "ScalarDefinitionKeyword" + }, + "TypeName", + "Directives" + ], + + "ObjectTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "type", + "tokenName": "TypeDefinitionKeyword" + }, + "TypeName", + { "ofType": "ImplementsInterfaces", "optional": true }, + { "ofType": "Directives", "optional": true }, + { "ofType": "FieldsDefinition", "optional": true } + ], + "ImplementsInterfaces": [ + { + "token": "Name", + "ofValue": "implements", + "tokenName": "ImplementsKeyword" + }, + { "token": "&", "optional": true }, + "TypeName", + { + "listOfType": "ImplementsAdditionalInterfaceName", + "optional": true + } + ], + "ImplementsAdditionalInterfaceName": [{ "token": "&" }, "TypeName"], + "FieldsDefinition": [ + { "token": "{" }, + { "listOfType": "FieldDefinition" }, + { "token": "}" } + ], + "FieldDefinition": [ + { "ofType": "Description", "optional": true }, + { "token": "Name", "tokenName": "AliasName", "definitionName": true }, + { "ofType": "ArgumentsDefinition", "optional": true }, + { "token": ":" }, + "Type", + { "ofType": "Directives", "optional": true } + ], + + "ArgumentsDefinition": [ + { "token": "(" }, + { "listOfType": "InputValueDefinition" }, + { "token": ")" } + ], + "InputValueDefinition": [ + { "ofType": "Description", "optional": true }, + { "tokenName": "Name", "tokenName": "ArgumentName" }, + { "token": ":" }, + "Type", + { "ofType": "DefaultValue", "optional": true }, + { "ofType": "Directives", "optional": true } + ], + + "ObjectTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "type", + "tokenName": "TypeDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "Name", "ofValue": "interface" }, + "expect": [ + "ImplementsInterfaces", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ], + "optional": true + } + ] + }, + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ] + } + ], + + "InterfaceTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "interface", + "tokenName": "InterfaceDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "FieldsDefinition", "optional": true } + ], + + "InterfaceTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "interface", + "tokenName": "InterfaceDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ] + } + ], + + "UnionTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "union", + "tokenName": "UnionDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "UnionMemberTypes", "optional": true } + ], + + "UnionMemberTypes": [ + { "token": "=" }, + { "token": "|", "optional": true }, + "Name", + { + "listOfType": "UnionMemberAdditionalTypeName", + "optional": true + } + ], + + "UnionMemberAdditionalTypeName": [{ "token": "|" }, "TypeName"], + + "UnionTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "union", + "tokenName": "UnionDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "UnionMemberTypes", "optional": true } + ] + }, + { + "ifCondition": { "token": "=" }, + "expect": "UnionMemberTypes" + } + ] + } + ], + + "EnumTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "enum", + "tokenName": "EnumDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "EnumValuesDefinition", "optional": true } + ], + "EnumValuesDefinition": [ + { "token": "{" }, + { "listOfType": "EnumValueDefinition" }, + { "token": "}" } + ], + "EnumValueDefinition": [ + { "ofType": "Description", "optional": true }, + "EnumValue", + { "ofType": "Directives", "optional": true } + ], + + "EnumTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "enum", + "tokenName": "EnumDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "EnumValuesDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "EnumValuesDefinition" + } + ] + } + ], + + "InputObjectTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "input", + "tokenName": "InputDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "InputFieldsDefinition", "optional": true } + ], + "InputFieldsDefinition": [ + { "token": "{" }, + { "listOfType": "InputValueDefinition" }, + { "token": "}" } + ], + + "InputObjectTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "input", + "tokenName": "InputDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "InputFieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "InputFieldsDefinition" + } + ] + } + ], + + "DirectiveDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "directive", + "tokenName": "DirectiveDefinitionKeyword" + }, + { "token": "@", "tokenName": "DirectiveName" }, + { "token": "Name", "tokenName": "DirectiveName" }, + { "ofType": "ArgumentsDefinition", "optional": true }, + { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, + "DirectiveLocations" + ], + "DirectiveLocations": [ + { "token": "|", "optional": true }, + "DirectiveLocation", + { + "listOfType": "DirectiveLocationAdditionalName", + "optional": true + } + ], + "DirectiveLocationAdditionalName": [{ "token": "|" }, "DirectiveLocation"], + "DirectiveLocation": { + "peek": [ + { + "ifCondition": "ExecutableDirectiveLocation", + "expect": "ExecutableDirectiveLocation" + }, + { + "ifCondition": "TypeSystemDirectiveLocation", + "expect": "TypeSystemDirectiveLocation" + } + ] + }, + "ExecutableDirectiveLocation": { + "token": "Name", + "oneOf": [ + "QUERY", + "MUTATION", + "SUBSCRIPTION", + "FIELD", + "FRAGMENT_DEFINITION", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "tokenName": "EnumValue" + }, + "TypeSystemDirectiveLocation": { + "token": "Name", + "oneOf": [ + "SCHEMA", + "SCALAR", + "OBJECT", + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "INTERFACE", + "UNION", + "ENUM", + "ENUM_VALUE", + "INPUT_OBJECT", + "INPUT_FIELD_DEFINITION" + ], + "tokenName": "EnumValue" + } + } +} diff --git a/src/language/online-parser/types.d.ts b/src/language/online-parser/types.d.ts new file mode 100644 index 0000000000..5b1b0d2e2a --- /dev/null +++ b/src/language/online-parser/types.d.ts @@ -0,0 +1,139 @@ +export declare const TokenKind: { + NAME: string; + INT: string; + FLOAT: string; + STRING: string; + BLOCK_STRING: string; + COMMENT: string; + PUNCTUATION: string; + EOF: string; + INVALID: string; +}; +export declare const RuleKind: { + TOKEN_CONSTRAINT: string; + OF_TYPE_CONSTRAINT: string; + LIST_OF_TYPE_CONSTRAINT: string; + PEEK_CONSTRAINT: string; + CONSTRAINTS_SET: string; + CONSTRAINTS_SET_ROOT: string; + RULE_NAME: string; + INVALID: string; +}; +export interface LanguageType { + rules: Rules; +} +export interface Rules { + [name: string]: Rule; +} +export declare type Rule = RuleName | RuleConstraint | ConstraintsSet; +export declare type RuleName = string; +export declare type RuleConstraint = + | TokenConstraint + | OfTypeConstraint + | ListOfTypeConstraint + | PeekConstraint; +export declare type ConstraintsSet = Array; +export interface BaseRuleConstraint { + butNot?: TokenConstraint | Array; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface TokenConstraint extends BaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: string; + oneOf?: Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} +export interface OfTypeConstraint extends BaseRuleConstraint { + ofType: Rule; + tokenName?: string; +} +export interface ListOfTypeConstraint extends BaseRuleConstraint { + listOfType: RuleName; +} +export interface PeekConstraint extends BaseRuleConstraint { + peek: Array; +} +export interface PeekCondition { + ifCondition: TokenConstraint; + expect: Rule; + end?: boolean; +} +export interface BaseParserRule { + kind: string; + name?: string; + depth: number; + step: number; + expanded: boolean; + state: string; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface TokenParserRule extends BaseParserRule, TokenConstraint {} +export interface OfTypeParserRule extends BaseParserRule, OfTypeConstraint {} +export interface ListOfTypeParserRule + extends BaseParserRule, + ListOfTypeConstraint {} +export interface PeekParserRule extends BaseParserRule, PeekConstraint { + index: number; + matched: boolean; +} +export interface ConstraintsSetRule extends BaseParserRule { + constraintsSet: boolean; + constraints: ConstraintsSet; +} +export declare type ParserRule = + | TokenParserRule + | OfTypeParserRule + | ListOfTypeParserRule + | PeekParserRule + | ConstraintsSetRule; +export interface ParserState { + rules: Array; + kind: () => string; + step: () => number; + levels: Array; + indentLevel: number | undefined; + name: string | null; + type: string | null; +} +export interface Token { + kind: string; + value?: string; + style?: string; +} +export interface LexerToken { + kind: string; + value?: string; +} +export declare type Styles = { + [name: string]: string; +}; +export declare type ParserConfig = { + tabSize: number; +}; +export declare type ParserConfigOption = { + tabSize?: number; +}; diff --git a/src/language/online-parser/types.js b/src/language/online-parser/types.js new file mode 100644 index 0000000000..bda7f050a2 --- /dev/null +++ b/src/language/online-parser/types.js @@ -0,0 +1,151 @@ +// @flow + +export const TokenKind = { + NAME: 'Name', + INT: 'Int', + FLOAT: 'Float', + STRING: 'String', + BLOCK_STRING: 'BlockString', + COMMENT: 'Comment', + PUNCTUATION: 'Punctuation', + EOF: '', + INVALID: 'Invalid', +}; + +export const RuleKind = { + TOKEN_CONSTRAINT: 'TokenConstraint', + OF_TYPE_CONSTRAINT: 'OfTypeConstraint', + LIST_OF_TYPE_CONSTRAINT: 'ListOfTypeConstraint', + PEEK_CONSTRAINT: 'PeekConstraint', + CONSTRAINTS_SET: 'ConstraintsSet', + CONSTRAINTS_SET_ROOT: 'ConstraintsSetRoot', + RULE_NAME: 'RuleName', + INVALID: 'Invalid', +}; + +export type LanguageType = {| + rules: Rules, +|}; + +export interface Rules { + [name: string]: Rule; +} +export type RuleName = string; +export type RuleConstraint = + | TokenConstraint + | OfTypeConstraint + | ListOfTypeConstraint + | PeekConstraint; +export type ConstraintsSet = Array; +export type Rule = RuleName | RuleConstraint | ConstraintsSet; +export interface BaseRuleConstraint { + butNot?: ?TokenConstraint | ?Array; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface TokenConstraint extends BaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: ?string; + oneOf?: ?Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} +export interface OfTypeConstraint extends BaseRuleConstraint { + ofType: Rule; + tokenName?: string; +} +export interface ListOfTypeConstraint extends BaseRuleConstraint { + listOfType: RuleName; +} +export interface PeekConstraint extends BaseRuleConstraint { + peek: Array; +} +export interface PeekCondition { + ifCondition: TokenConstraint; + expect: Rule; + end?: boolean; +} +export interface BaseParserRule { + kind: string; + name?: string; + depth: number; + step: number; + expanded: boolean; + state: string; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface TokenParserRule extends BaseParserRule, TokenConstraint {} +export interface OfTypeParserRule extends BaseParserRule, OfTypeConstraint {} +export interface ListOfTypeParserRule + extends BaseParserRule, + ListOfTypeConstraint {} +export interface PeekParserRule extends BaseParserRule, PeekConstraint { + index: number; + matched: boolean; +} +export interface ConstraintsSetRule extends BaseParserRule { + constraintsSet: boolean; + constraints: ConstraintsSet; +} + +export type ParserRule = + | TokenParserRule + | OfTypeParserRule + | ListOfTypeParserRule + | PeekParserRule + | ConstraintsSetRule; + +export type ParserState = {| + rules: Array, + kind: () => string, + step: () => number, + levels: Array, + indentLevel: number, + name: string | null, + type: string | null, +|}; + +export type Token = {| + kind: string, + value: string, + style: ?string, +|}; + +export type LexerToken = {| + kind: string, + value: ?string, +|}; + +export type Styles = {| + [name: string]: string, +|}; + +export type ParserConfig = {| + tabSize: number, +|}; + +export type ParserConfigOption = {| + tabSize: ?number, +|}; From eba06204375c48e0c4889215edd2d3432b1e09b2 Mon Sep 17 00:00:00 2001 From: Naman Kumar Date: Sun, 30 Aug 2020 20:01:31 +0530 Subject: [PATCH 2/5] Improve Typings --- .../experimentalOnlineParser/README.md | 26 ++ .../grammarTypes.d.ts | 82 +++++ .../experimentalOnlineParser/grammarTypes.js | 76 ++++ .../experimentalOnlineParser/index.d.ts | 1 + .../experimentalOnlineParser/index.js | 1 + .../onlineParser.d.ts | 125 +++++++ .../onlineParser.js} | 337 +++++++++++------- .../rules.json | 0 src/language/online-parser/index.d.ts | 2 - src/language/online-parser/index.js | 2 - src/language/online-parser/language.d.ts | 4 - src/language/online-parser/language.js | 1 - src/language/online-parser/parser.d.ts | 54 --- src/language/online-parser/types.d.ts | 139 -------- src/language/online-parser/types.js | 151 -------- 15 files changed, 515 insertions(+), 486 deletions(-) create mode 100644 src/language/experimentalOnlineParser/README.md create mode 100644 src/language/experimentalOnlineParser/grammarTypes.d.ts create mode 100644 src/language/experimentalOnlineParser/grammarTypes.js create mode 100644 src/language/experimentalOnlineParser/index.d.ts create mode 100644 src/language/experimentalOnlineParser/index.js create mode 100644 src/language/experimentalOnlineParser/onlineParser.d.ts rename src/language/{online-parser/parser.js => experimentalOnlineParser/onlineParser.js} (63%) rename src/language/{online-parser => experimentalOnlineParser}/rules.json (100%) delete mode 100644 src/language/online-parser/index.d.ts delete mode 100644 src/language/online-parser/index.js delete mode 100644 src/language/online-parser/language.d.ts delete mode 100644 src/language/online-parser/language.js delete mode 100644 src/language/online-parser/parser.d.ts delete mode 100644 src/language/online-parser/types.d.ts delete mode 100644 src/language/online-parser/types.js diff --git a/src/language/experimentalOnlineParser/README.md b/src/language/experimentalOnlineParser/README.md new file mode 100644 index 0000000000..dfcd9996d7 --- /dev/null +++ b/src/language/experimentalOnlineParser/README.md @@ -0,0 +1,26 @@ +## Experimental Online Parser + +This directory contains an experimental online parser based on JSON rules set. It is a state-full parser which parses a source string incrementally i.e. emits a token each time. + +The parser is being migrated from graphiql to graphql-js and may have frequent breaking changes. + +Example: + +```js +import { OnlineParser } from 'graphql/language/experimentalOnlineParser'; + +const source = ` + query SomeQuery { + some_field { + another_field + } + } +`; + +const parser = new OnlineParser(source); +let token; + +do { + token = parser.parseToken(); +} while (token.kind !== '' && token.kind !== 'Invalid'); +``` diff --git a/src/language/experimentalOnlineParser/grammarTypes.d.ts b/src/language/experimentalOnlineParser/grammarTypes.d.ts new file mode 100644 index 0000000000..da1d16e8a2 --- /dev/null +++ b/src/language/experimentalOnlineParser/grammarTypes.d.ts @@ -0,0 +1,82 @@ +export interface GraphQLGrammarType { + rules: GraphQLGrammarRules; +} + +export interface GraphQLGrammarRules { + [name: string]: GraphQLGrammarRule; +} + +export declare type GraphQLGrammarRule = + | GraphQLGrammarRuleName + | GraphQLGrammarRuleConstraint + | GraphQLGrammarConstraintsSet; + +export declare type GraphQLGrammarRuleName = string; + +export declare type GraphQLGrammarRuleConstraint = + | GraphQLGrammarTokenConstraint + | GraphQLGrammarOfTypeConstraint + | GraphQLGrammarListOfTypeConstraint + | GraphQLGrammarPeekConstraint; + +export declare type GraphQLGrammarConstraintsSet = Array< + GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint +>; + +export interface GraphQLGrammarBaseRuleConstraint { + butNot?: GraphQLGrammarTokenConstraint | Array; + optional?: boolean; + eatNextOnFail?: boolean; +} + +export interface GraphQLGrammarTokenConstraint + extends GraphQLGrammarBaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: string; + oneOf?: Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} + +export interface GraphQLGrammarOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + ofType: GraphQLGrammarRule; + tokenName?: string; +} + +export interface GraphQLGrammarListOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + listOfType: GraphQLGrammarRuleName; +} + +export interface GraphQLGrammarPeekConstraint + extends GraphQLGrammarBaseRuleConstraint { + peek: Array; +} + +export interface GraphQLGrammarPeekConstraintCondition { + ifCondition: GraphQLGrammarTokenConstraint; + expect: GraphQLGrammarRule; + end?: boolean; +} diff --git a/src/language/experimentalOnlineParser/grammarTypes.js b/src/language/experimentalOnlineParser/grammarTypes.js new file mode 100644 index 0000000000..9c0a34a216 --- /dev/null +++ b/src/language/experimentalOnlineParser/grammarTypes.js @@ -0,0 +1,76 @@ +// @flow + +export type GraphQLGrammarType = {| + rules: GraphQLGrammarRules, +|}; + +export interface GraphQLGrammarRules { + [name: string]: GraphQLGrammarRule; +} +export type GraphQLGrammarRuleName = string; +export type GraphQLGrammarRuleConstraint = + | GraphQLGrammarTokenConstraint + | GraphQLGrammarOfTypeConstraint + | GraphQLGrammarListOfTypeConstraint + | GraphQLGrammarPeekConstraint; +export type GraphQLGrammarConstraintsSet = Array< + GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint, +>; +export type GraphQLGrammarRule = + | GraphQLGrammarRuleName + | GraphQLGrammarRuleConstraint + | GraphQLGrammarConstraintsSet; +export interface GraphQLGrammarBaseRuleConstraint { + butNot?: + | ?GraphQLGrammarTokenConstraint + | ?Array; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface GraphQLGrammarTokenConstraint + extends GraphQLGrammarBaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: ?string; + oneOf?: ?Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} +export interface GraphQLGrammarOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + ofType: GraphQLGrammarRule; + tokenName?: string; +} +export interface GraphQLGrammarListOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + listOfType: GraphQLGrammarRuleName; +} +export interface GraphQLGrammarPeekConstraint + extends GraphQLGrammarBaseRuleConstraint { + peek: Array; +} +export interface GraphQLGrammarPeekConstraintCondition { + ifCondition: GraphQLGrammarTokenConstraint; + expect: GraphQLGrammarRule; + end?: boolean; +} diff --git a/src/language/experimentalOnlineParser/index.d.ts b/src/language/experimentalOnlineParser/index.d.ts new file mode 100644 index 0000000000..45277bc046 --- /dev/null +++ b/src/language/experimentalOnlineParser/index.d.ts @@ -0,0 +1 @@ +export { OnlineParser, RuleKind, TokenKind } from './onlineParser'; diff --git a/src/language/experimentalOnlineParser/index.js b/src/language/experimentalOnlineParser/index.js new file mode 100644 index 0000000000..45277bc046 --- /dev/null +++ b/src/language/experimentalOnlineParser/index.js @@ -0,0 +1 @@ +export { OnlineParser, RuleKind, TokenKind } from './onlineParser'; diff --git a/src/language/experimentalOnlineParser/onlineParser.d.ts b/src/language/experimentalOnlineParser/onlineParser.d.ts new file mode 100644 index 0000000000..bbbcc1f2d9 --- /dev/null +++ b/src/language/experimentalOnlineParser/onlineParser.d.ts @@ -0,0 +1,125 @@ +import { Lexer } from '../lexer'; + +import { + GraphQLGrammarTokenConstraint, + GraphQLGrammarOfTypeConstraint, + GraphQLGrammarListOfTypeConstraint, + GraphQLGrammarPeekConstraint, + GraphQLGrammarConstraintsSet, +} from './grammarTypes'; + +interface BaseOnlineParserRule { + kind: string; + name?: string; + depth: number; + step: number; + expanded: boolean; + state: string; + optional?: boolean; + eatNextOnFail?: boolean; +} +interface TokenOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarTokenConstraint {} +interface OfTypeOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarOfTypeConstraint {} +interface ListOfTypeOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarListOfTypeConstraint {} +interface PeekOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarPeekConstraint { + index: number; + matched: boolean; +} +interface ConstraintsSetOnlineParserRule extends BaseOnlineParserRule { + constraintsSet: boolean; + constraints: GraphQLGrammarConstraintsSet; +} + +declare type OnlineParserRule = + | TokenOnlineParserRule + | OfTypeOnlineParserRule + | ListOfTypeOnlineParserRule + | PeekOnlineParserRule + | ConstraintsSetOnlineParserRule; + +declare interface OnlineParserState { + rules: Array; + kind: () => string; + step: () => number; + levels: Array; + indentLevel: number | undefined; + name: string | null; + type: string | null; +} + +declare interface Token { + kind: string; + value?: string; + tokenName?: string | undefined; + ruleName?: string | undefined; +} + +declare type OnlineParserConfig = { + tabSize: number; +}; + +declare type OnlineParserConfigOption = { + tabSize?: number; +}; + +export declare class OnlineParser { + state: OnlineParserState; + _lexer: Lexer; + _config: OnlineParserConfig; + constructor( + source: string, + state?: OnlineParserState, + config?: OnlineParserConfigOption, + ); + static startState(): OnlineParserState; + static copyState(state: OnlineParserState): OnlineParserState; + sol(): boolean; + parseToken(): Token; + indentation(): number; + private readonly _parseTokenConstraint; + private readonly _parseListOfTypeConstraint; + private readonly _parseOfTypeConstraint; + private readonly _parsePeekConstraint; + private readonly _parseConstraintsSetRule; + private readonly _matchToken; + private readonly _butNot; + private readonly _transformLexerToken; + private readonly _getNextRule; + private readonly _popMatchedRule; + private readonly _rollbackRule; + private readonly _pushRule; + private readonly _getRuleKind; + private readonly _advanceToken; + private readonly _lookAhead; +} + +export declare const TokenKind: { + NAME: string; + INT: string; + FLOAT: string; + STRING: string; + BLOCK_STRING: string; + COMMENT: string; + PUNCTUATION: string; + EOF: string; + INVALID: string; +}; + +export declare const RuleKind: { + TOKEN_CONSTRAINT: string; + OF_TYPE_CONSTRAINT: string; + LIST_OF_TYPE_CONSTRAINT: string; + PEEK_CONSTRAINT: string; + CONSTRAINTS_SET: string; + CONSTRAINTS_SET_ROOT: string; + RULE_NAME: string; + INVALID: string; +}; diff --git a/src/language/online-parser/parser.js b/src/language/experimentalOnlineParser/onlineParser.js similarity index 63% rename from src/language/online-parser/parser.js rename to src/language/experimentalOnlineParser/onlineParser.js index 96476f208d..76f65c9677 100644 --- a/src/language/online-parser/parser.js +++ b/src/language/experimentalOnlineParser/onlineParser.js @@ -1,64 +1,133 @@ import { Lexer } from '../lexer'; import { Source } from '../source'; -import Language from './language'; -import { RuleKind, TokenKind } from './types'; +import GraphQLGrammar from './rules'; import type { - Token, - LexerToken, - Styles, - ParserRule, - ParserState, - ParserConfig, - ParserConfigOption, - Rule, - RuleName, - RuleConstraint, - TokenParserRule, - OfTypeParserRule, - ListOfTypeParserRule, - PeekParserRule, - ConstraintsSetRule, - OfTypeConstraint, - ListOfTypeConstraint, - TokenConstraint, - PeekConstraint, - ConstraintsSet, -} from './types'; - -export class Parser { - state: ParserState; - lexer: Lexer; - styles: Styles; - config: ParserConfig; - - constructor({ - state, - styles, - config, - source, - }: {| - state: ?ParserState, - styles: ?Styles, - config: ?ParserConfigOption, + GraphQLGrammarRule, + GraphQLGrammarRuleName, + GraphQLGrammarRuleConstraint, + GraphQLGrammarTokenConstraint, + GraphQLGrammarOfTypeConstraint, + GraphQLGrammarListOfTypeConstraint, + GraphQLGrammarPeekConstraint, + GraphQLGrammarConstraintsSet, +} from './grammarTypes'; + +export const TokenKind = { + NAME: 'Name', + INT: 'Int', + FLOAT: 'Float', + STRING: 'String', + BLOCK_STRING: 'BlockString', + COMMENT: 'Comment', + PUNCTUATION: 'Punctuation', + EOF: '', + INVALID: 'Invalid', +}; + +export const RuleKind = { + TOKEN_CONSTRAINT: 'TokenConstraint', + OF_TYPE_CONSTRAINT: 'OfTypeConstraint', + LIST_OF_TYPE_CONSTRAINT: 'ListOfTypeConstraint', + PEEK_CONSTRAINT: 'PeekConstraint', + CONSTRAINTS_SET: 'ConstraintsSet', + CONSTRAINTS_SET_ROOT: 'ConstraintsSetRoot', + RULE_NAME: 'RuleName', + INVALID: 'Invalid', +}; + +interface BaseOnlineParserRule { + kind: string; + name?: string; + depth: number; + step: number; + expanded: boolean; + state: string; + optional?: boolean; + eatNextOnFail?: boolean; +} +interface TokenOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarTokenConstraint {} +interface OfTypeOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarOfTypeConstraint {} +interface ListOfTypeOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarListOfTypeConstraint {} +interface PeekOnlineParserRule + extends BaseOnlineParserRule, + GraphQLGrammarPeekConstraint { + index: number; + matched: boolean; +} +interface ConstraintsSetOnlineParserRule extends BaseOnlineParserRule { + constraintsSet: boolean; + constraints: GraphQLGrammarConstraintsSet; +} + +type OnlineParserRule = + | TokenOnlineParserRule + | OfTypeOnlineParserRule + | ListOfTypeOnlineParserRule + | PeekOnlineParserRule + | ConstraintsSetOnlineParserRule; + +type OnlineParserState = {| + rules: Array, + kind: () => string, + step: () => number, + levels: Array, + indentLevel: number, + name: string | null, + type: string | null, +|}; + +type Token = {| + kind: string, + value: string, + tokenName?: ?string, + ruleName?: ?string, +|}; + +type LexerToken = {| + kind: string, + value: ?string, +|}; + +type OnlineParserConfig = {| + tabSize: number, +|}; + +type OnlineParserConfigOption = {| + tabSize: ?number, +|}; + +export class OnlineParser { + state: OnlineParserState; + _lexer: Lexer; + _config: OnlineParserConfig; + + constructor( source: string, - |}) { - this.state = state || Parser.startState(); - this.styles = styles || {}; - this.config = { - tabSize: typeof config?.tabSize === 'number' ? config.tabSize : 2, + state?: OnlineParserState, + config?: OnlineParserConfigOption, + ) { + this.state = state || OnlineParser.startState(); + this._config = { + tabSize: config?.tabSize ?? 2, }; - this.lexer = new Lexer(new Source(source)); + this._lexer = new Lexer(new Source(source)); } - static startState(): ParserState { + static startState(): OnlineParserState { return { rules: [ { name: 'Document', state: 'Document', kind: 'ListOfTypeConstraint', - ...Language.rules.Document, + ...GraphQLGrammar.rules.Document, expanded: false, depth: 1, step: 1, @@ -77,7 +146,7 @@ export class Parser { }; } - static copyState(state: ParserState): ParserState { + static copyState(state: OnlineParserState): OnlineParserState { return { name: state.name, type: state.type, @@ -95,59 +164,58 @@ export class Parser { sol(): boolean { return ( - this.lexer.source.locationOffset.line === 1 && - this.lexer.source.locationOffset.column === 1 + this._lexer.source.locationOffset.line === 1 && + this._lexer.source.locationOffset.column === 1 ); } parseToken(): Token { - const rule = (this.getNextRule(): any); + const rule = (this._getNextRule(): any); if (this.sol()) { this.state.indentLevel = Math.floor( - this.indentation() / this.config.tabSize, + this.indentation() / this._config.tabSize, ); } if (!rule) { return { kind: TokenKind.INVALID, - style: this.styles[TokenKind.INVALID], value: '', }; } let token; - if (this.lookAhead().kind === '') { + if (this._lookAhead().kind === '') { return { kind: TokenKind.EOF, - style: this.styles[TokenKind.EOF], value: '', + ruleName: rule.name, }; } switch (rule.kind) { case RuleKind.TOKEN_CONSTRAINT: - token = this.parseTokenConstraint(rule); + token = this._parseTokenConstraint(rule); break; case RuleKind.LIST_OF_TYPE_CONSTRAINT: - token = this.parseListOfTypeConstraint(rule); + token = this._parseListOfTypeConstraint(rule); break; case RuleKind.OF_TYPE_CONSTRAINT: - token = this.parseOfTypeConstraint(rule); + token = this._parseOfTypeConstraint(rule); break; case RuleKind.PEEK_CONSTRAINT: - token = this.parsePeekConstraint(rule); + token = this._parsePeekConstraint(rule); break; case RuleKind.CONSTRAINTS_SET_ROOT: - token = this.parseConstraintsSetRule(rule); + token = this._parseConstraintsSetRule(rule); break; default: return { kind: TokenKind.INVALID, - style: this.styles[TokenKind.INVALID], value: '', + ruleName: rule.name, }; } @@ -155,7 +223,7 @@ export class Parser { if (rule.optional === true) { this.state.rules.pop(); } else { - this.rollbackRule(); + this._rollbackRule(); } return this.parseToken() || token; @@ -165,7 +233,7 @@ export class Parser { } indentation(): number { - const match = this.lexer.source.body.match(/\s*/); + const match = this._lexer.source.body.match(/\s*/); let indent = 0; if (match && match.length === 0) { @@ -184,29 +252,30 @@ export class Parser { return indent; } - parseTokenConstraint(rule: TokenParserRule): Token { + _parseTokenConstraint(rule: TokenOnlineParserRule): Token { rule.expanded = true; - const token = this.lookAhead(); + const token = this._lookAhead(); - if (!this.matchToken(token, rule)) { + if (!this._matchToken(token, rule)) { return { kind: TokenKind.INVALID, - style: this.styles[TokenKind.INVALID], value: '', + tokenName: rule.tokenName, + ruleName: rule.name, }; } - this.advanceToken(); - const parserToken = this.transformLexerToken(token, rule); - this.popMatchedRule(parserToken); + this._advanceToken(); + const parserToken = this._transformLexerToken(token, rule); + this._popMatchedRule(parserToken); return parserToken; } - parseListOfTypeConstraint(rule: ListOfTypeParserRule): Token { - this.pushRule( - Language.rules[rule.listOfType], + _parseListOfTypeConstraint(rule: ListOfTypeOnlineParserRule): Token { + this._pushRule( + GraphQLGrammar.rules[rule.listOfType], rule.depth + 1, rule.listOfType, 1, @@ -220,13 +289,13 @@ export class Parser { return token; } - parseOfTypeConstraint(rule: OfTypeParserRule): Token { + _parseOfTypeConstraint(rule: OfTypeOnlineParserRule): Token { if (rule.expanded) { - this.popMatchedRule(); + this._popMatchedRule(); return this.parseToken(); } - this.pushRule(rule.ofType, rule.depth + 1, rule.tokenName, 1, rule.state); + this._pushRule(rule.ofType, rule.depth + 1, rule.tokenName, 1, rule.state); rule.expanded = true; const token = this.parseToken(); @@ -234,9 +303,9 @@ export class Parser { return token; } - parsePeekConstraint(rule: PeekParserRule): Token { + _parsePeekConstraint(rule: PeekOnlineParserRule): Token { if (rule.expanded) { - this.popMatchedRule(); + this._popMatchedRule(); return this.parseToken(); } @@ -246,14 +315,14 @@ export class Parser { let { ifCondition } = constraint; if (typeof ifCondition === 'string') { - ifCondition = Language.rules[ifCondition]; + ifCondition = GraphQLGrammar.rules[ifCondition]; } - let token = this.lookAhead(); - if (ifCondition && this.matchToken(token, ifCondition)) { + let token = this._lookAhead(); + if (ifCondition && this._matchToken(token, ifCondition)) { rule.matched = true; rule.expanded = true; - this.pushRule(constraint.expect, rule.depth + 1, '', 1, rule.state); + this._pushRule(constraint.expect, rule.depth + 1, '', 1, rule.state); token = this.parseToken(); @@ -263,19 +332,19 @@ export class Parser { return { kind: TokenKind.INVALID, - style: this.styles[TokenKind.INVALID], value: '', + ruleName: rule.name, }; } - parseConstraintsSetRule(rule: ConstraintsSetRule): Token { + _parseConstraintsSetRule(rule: ConstraintsSetOnlineParserRule): Token { if (rule.expanded) { - this.popMatchedRule(); + this._popMatchedRule(); return this.parseToken(); } for (let index = rule.constraints.length - 1; index >= 0; index--) { - this.pushRule( + this._pushRule( rule.constraints[index], rule.depth + 1, '', @@ -288,7 +357,10 @@ export class Parser { return this.parseToken(); } - matchToken(token: Token | LexerToken, rule: TokenConstraint): boolean { + _matchToken( + token: Token | LexerToken, + rule: GraphQLGrammarTokenConstraint, + ): boolean { if (typeof token.value === 'string') { if ( (typeof rule.ofValue === 'string' && token.value !== rule.ofValue) || @@ -300,23 +372,26 @@ export class Parser { return false; } - return this.butNot(token, rule); + return this._butNot(token, rule); } if (token.kind !== rule.token) { return false; } - return this.butNot(token, rule); + return this._butNot(token, rule); } - butNot(token: Token | LexerToken, rule: RuleConstraint): boolean { + _butNot( + token: Token | LexerToken, + rule: GraphQLGrammarRuleConstraint, + ): boolean { if (rule.butNot) { if (Array.isArray(rule.butNot)) { if ( rule.butNot.reduce( (matched, constraint) => - matched || this.matchToken(token, constraint), + matched || this._matchToken(token, constraint), false, ) ) { @@ -326,13 +401,13 @@ export class Parser { return true; } - return !this.matchToken(token, rule.butNot); + return !this._matchToken(token, rule.butNot); } return true; } - transformLexerToken(lexerToken: LexerToken, rule: any): Token { + _transformLexerToken(lexerToken: LexerToken, rule: any): Token { let token; const ruleName = rule.name || ''; const tokenName = rule.tokenName || ''; @@ -341,10 +416,8 @@ export class Parser { token = { kind: lexerToken.kind, value: lexerToken.value || '', - style: - this.styles[tokenName] || - this.styles[ruleName] || - this.styles[lexerToken.kind], + tokenName, + ruleName, }; if (token.kind === TokenKind.STRING) { @@ -356,10 +429,8 @@ export class Parser { token = { kind: TokenKind.PUNCTUATION, value: lexerToken.kind, - style: - this.styles[tokenName] || - this.styles[ruleName] || - this.styles[TokenKind.PUNCTUATION], + tokenName, + ruleName, }; if (/^[{([]/.test(token.value)) { @@ -376,11 +447,11 @@ export class Parser { return token; } - getNextRule(): ParserRule | null { + _getNextRule(): OnlineParserRule | null { return this.state.rules[this.state.rules.length - 1] || null; } - popMatchedRule(token: ?Token) { + _popMatchedRule(token: ?Token) { const rule = this.state.rules.pop(); if (!rule) { return; @@ -395,7 +466,7 @@ export class Parser { } } - const nextRule = this.getNextRule(); + const nextRule = this._getNextRule(); if (!nextRule) { return; } @@ -418,7 +489,7 @@ export class Parser { } } - rollbackRule() { + _rollbackRule() { if (!this.state.rules.length) { return; } @@ -437,7 +508,7 @@ export class Parser { } let popped = 0; - let nextRule = this.getNextRule(); + let nextRule = this._getNextRule(); while ( nextRule && (poppedRule.kind !== RuleKind.LIST_OF_TYPE_CONSTRAINT || @@ -446,7 +517,7 @@ export class Parser { ) { this.state.rules.pop(); popped++; - nextRule = this.getNextRule(); + nextRule = this._getNextRule(); } if (nextRule && nextRule.expanded) { @@ -460,12 +531,12 @@ export class Parser { this.state.rules.pop(); return; } - this.rollbackRule(); + this._rollbackRule(); } } } - pushRule( + _pushRule( baseRule: any, depth: number, name?: string, @@ -476,11 +547,11 @@ export class Parser { this.state.type = null; let rule = baseRule; - switch (this.getRuleKind(rule)) { + switch (this._getRuleKind(rule)) { case RuleKind.RULE_NAME: - rule = (rule: RuleName); - this.pushRule( - Language.rules[rule], + rule = (rule: GraphQLGrammarRuleName); + this._pushRule( + GraphQLGrammar.rules[rule], depth, (typeof name === 'string' ? name : undefined) || rule, step, @@ -488,7 +559,7 @@ export class Parser { ); break; case RuleKind.CONSTRAINTS_SET: - rule = (rule: ConstraintsSet); + rule = (rule: GraphQLGrammarConstraintsSet); this.state.rules.push({ name: name || '', depth, @@ -499,16 +570,16 @@ export class Parser { state: (typeof name === 'string' ? name : undefined) || (typeof state === 'string' ? state : undefined) || - this.getNextRule()?.state || + this._getNextRule()?.state || '', step: typeof step === 'number' ? step - : (this.getNextRule()?.step || 0) + 1, + : (this._getNextRule()?.step || 0) + 1, }); break; case RuleKind.OF_TYPE_CONSTRAINT: - rule = (rule: OfTypeConstraint); + rule = (rule: GraphQLGrammarOfTypeConstraint); this.state.rules.push({ name: name || '', ofType: rule.ofType, @@ -522,16 +593,16 @@ export class Parser { (typeof rule.tokenName === 'string' ? rule.tokenName : undefined) || (typeof name === 'string' ? name : undefined) || (typeof state === 'string' ? state : undefined) || - this.getNextRule()?.state || + this._getNextRule()?.state || '', step: typeof step === 'number' ? step - : (this.getNextRule()?.step || 0) + 1, + : (this._getNextRule()?.step || 0) + 1, }); break; case RuleKind.LIST_OF_TYPE_CONSTRAINT: - rule = (rule: ListOfTypeConstraint); + rule = (rule: GraphQLGrammarListOfTypeConstraint); this.state.rules.push({ listOfType: rule.listOfType, optional: Boolean(rule.optional), @@ -544,16 +615,16 @@ export class Parser { state: (typeof name === 'string' ? name : undefined) || (typeof state === 'string' ? state : undefined) || - this.getNextRule()?.state || + this._getNextRule()?.state || '', step: typeof step === 'number' ? step - : (this.getNextRule()?.step || 0) + 1, + : (this._getNextRule()?.step || 0) + 1, }); break; case RuleKind.TOKEN_CONSTRAINT: - rule = (rule: TokenConstraint); + rule = (rule: GraphQLGrammarTokenConstraint); this.state.rules.push({ token: rule.token, ofValue: rule.ofValue, @@ -570,16 +641,16 @@ export class Parser { state: (typeof rule.tokenName === 'string' ? rule.tokenName : undefined) || (typeof state === 'string' ? state : undefined) || - this.getNextRule()?.state || + this._getNextRule()?.state || '', step: typeof step === 'number' ? step - : (this.getNextRule()?.step || 0) + 1, + : (this._getNextRule()?.step || 0) + 1, }); break; case RuleKind.PEEK_CONSTRAINT: - rule = (rule: PeekConstraint); + rule = (rule: GraphQLGrammarPeekConstraint); this.state.rules.push({ peek: rule.peek, optional: Boolean(rule.optional), @@ -593,18 +664,18 @@ export class Parser { kind: RuleKind.PEEK_CONSTRAINT, state: (typeof state === 'string' ? state : undefined) || - this.getNextRule()?.state || + this._getNextRule()?.state || '', step: typeof step === 'number' ? step - : (this.getNextRule()?.step || 0) + 1, + : (this._getNextRule()?.step || 0) + 1, }); break; } } - getRuleKind(rule: Rule | ParserRule): string { + _getRuleKind(rule: GraphQLGrammarRule | OnlineParserRule): string { if (Array.isArray(rule)) { return RuleKind.CONSTRAINTS_SET; } @@ -636,13 +707,13 @@ export class Parser { return RuleKind.INVALID; } - advanceToken(): LexerToken { - return (this.lexer.advance(): any); + _advanceToken(): LexerToken { + return (this._lexer.advance(): any); } - lookAhead(): LexerToken { + _lookAhead(): LexerToken { try { - return (this.lexer.lookahead(): any); + return (this._lexer.lookahead(): any); } catch (err) { return { kind: TokenKind.INVALID, value: '' }; } diff --git a/src/language/online-parser/rules.json b/src/language/experimentalOnlineParser/rules.json similarity index 100% rename from src/language/online-parser/rules.json rename to src/language/experimentalOnlineParser/rules.json diff --git a/src/language/online-parser/index.d.ts b/src/language/online-parser/index.d.ts deleted file mode 100644 index d8ff9e2b21..0000000000 --- a/src/language/online-parser/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Parser } from './parser'; -export * from './types'; diff --git a/src/language/online-parser/index.js b/src/language/online-parser/index.js deleted file mode 100644 index d8ff9e2b21..0000000000 --- a/src/language/online-parser/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { Parser } from './parser'; -export * from './types'; diff --git a/src/language/online-parser/language.d.ts b/src/language/online-parser/language.d.ts deleted file mode 100644 index 94a3a0362d..0000000000 --- a/src/language/online-parser/language.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { LanguageType } from './types'; - -declare const Language: LanguageType; -export default Language; diff --git a/src/language/online-parser/language.js b/src/language/online-parser/language.js deleted file mode 100644 index 544e34f226..0000000000 --- a/src/language/online-parser/language.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './rules'; diff --git a/src/language/online-parser/parser.d.ts b/src/language/online-parser/parser.d.ts deleted file mode 100644 index c2c8bd39ef..0000000000 --- a/src/language/online-parser/parser.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Lexer } from '../lexer'; - -import { - Token, - Styles, - ParserState, - ParserConfig, - ParserConfigOption, - Rule, -} from './types'; - -export declare class Parser { - state: ParserState; - lexer: Lexer; - styles: Styles; - config: ParserConfig; - constructor({ - state, - styles, - config, - source, - }: { - state?: ParserState; - styles?: Styles; - config?: ParserConfigOption; - source: string; - }); - static startState(): ParserState; - static copyState(state: ParserState): ParserState; - sol(): boolean; - parseToken(): Token; - indentation(): number; - private readonly parseTokenConstraint; - private readonly parseListOfTypeConstraint; - private readonly parseOfTypeConstraint; - private readonly parsePeekConstraint; - private readonly parseConstraintsSetRule; - private readonly matchToken; - private readonly butNot; - private readonly transformLexerToken; - private readonly getNextRule; - private readonly popMatchedRule; - private readonly rollbackRule; - pushRule( - rule: Rule, - depth: number, - name?: string, - step?: number, - state?: string, - ): void; - private readonly getRuleKind; - private readonly advanceToken; - private readonly lookAhead; -} diff --git a/src/language/online-parser/types.d.ts b/src/language/online-parser/types.d.ts deleted file mode 100644 index 5b1b0d2e2a..0000000000 --- a/src/language/online-parser/types.d.ts +++ /dev/null @@ -1,139 +0,0 @@ -export declare const TokenKind: { - NAME: string; - INT: string; - FLOAT: string; - STRING: string; - BLOCK_STRING: string; - COMMENT: string; - PUNCTUATION: string; - EOF: string; - INVALID: string; -}; -export declare const RuleKind: { - TOKEN_CONSTRAINT: string; - OF_TYPE_CONSTRAINT: string; - LIST_OF_TYPE_CONSTRAINT: string; - PEEK_CONSTRAINT: string; - CONSTRAINTS_SET: string; - CONSTRAINTS_SET_ROOT: string; - RULE_NAME: string; - INVALID: string; -}; -export interface LanguageType { - rules: Rules; -} -export interface Rules { - [name: string]: Rule; -} -export declare type Rule = RuleName | RuleConstraint | ConstraintsSet; -export declare type RuleName = string; -export declare type RuleConstraint = - | TokenConstraint - | OfTypeConstraint - | ListOfTypeConstraint - | PeekConstraint; -export declare type ConstraintsSet = Array; -export interface BaseRuleConstraint { - butNot?: TokenConstraint | Array; - optional?: boolean; - eatNextOnFail?: boolean; -} -export interface TokenConstraint extends BaseRuleConstraint { - token: - | '!' - | '$' - | '&' - | '(' - | ')' - | '...' - | ':' - | '=' - | '@' - | '[' - | ']' - | '{' - | '}' - | '|' - | 'Name' - | 'Int' - | 'Float' - | 'String' - | 'BlockString' - | 'Comment'; - ofValue?: string; - oneOf?: Array; - tokenName?: string; - definitionName?: boolean; - typeName?: boolean; -} -export interface OfTypeConstraint extends BaseRuleConstraint { - ofType: Rule; - tokenName?: string; -} -export interface ListOfTypeConstraint extends BaseRuleConstraint { - listOfType: RuleName; -} -export interface PeekConstraint extends BaseRuleConstraint { - peek: Array; -} -export interface PeekCondition { - ifCondition: TokenConstraint; - expect: Rule; - end?: boolean; -} -export interface BaseParserRule { - kind: string; - name?: string; - depth: number; - step: number; - expanded: boolean; - state: string; - optional?: boolean; - eatNextOnFail?: boolean; -} -export interface TokenParserRule extends BaseParserRule, TokenConstraint {} -export interface OfTypeParserRule extends BaseParserRule, OfTypeConstraint {} -export interface ListOfTypeParserRule - extends BaseParserRule, - ListOfTypeConstraint {} -export interface PeekParserRule extends BaseParserRule, PeekConstraint { - index: number; - matched: boolean; -} -export interface ConstraintsSetRule extends BaseParserRule { - constraintsSet: boolean; - constraints: ConstraintsSet; -} -export declare type ParserRule = - | TokenParserRule - | OfTypeParserRule - | ListOfTypeParserRule - | PeekParserRule - | ConstraintsSetRule; -export interface ParserState { - rules: Array; - kind: () => string; - step: () => number; - levels: Array; - indentLevel: number | undefined; - name: string | null; - type: string | null; -} -export interface Token { - kind: string; - value?: string; - style?: string; -} -export interface LexerToken { - kind: string; - value?: string; -} -export declare type Styles = { - [name: string]: string; -}; -export declare type ParserConfig = { - tabSize: number; -}; -export declare type ParserConfigOption = { - tabSize?: number; -}; diff --git a/src/language/online-parser/types.js b/src/language/online-parser/types.js deleted file mode 100644 index bda7f050a2..0000000000 --- a/src/language/online-parser/types.js +++ /dev/null @@ -1,151 +0,0 @@ -// @flow - -export const TokenKind = { - NAME: 'Name', - INT: 'Int', - FLOAT: 'Float', - STRING: 'String', - BLOCK_STRING: 'BlockString', - COMMENT: 'Comment', - PUNCTUATION: 'Punctuation', - EOF: '', - INVALID: 'Invalid', -}; - -export const RuleKind = { - TOKEN_CONSTRAINT: 'TokenConstraint', - OF_TYPE_CONSTRAINT: 'OfTypeConstraint', - LIST_OF_TYPE_CONSTRAINT: 'ListOfTypeConstraint', - PEEK_CONSTRAINT: 'PeekConstraint', - CONSTRAINTS_SET: 'ConstraintsSet', - CONSTRAINTS_SET_ROOT: 'ConstraintsSetRoot', - RULE_NAME: 'RuleName', - INVALID: 'Invalid', -}; - -export type LanguageType = {| - rules: Rules, -|}; - -export interface Rules { - [name: string]: Rule; -} -export type RuleName = string; -export type RuleConstraint = - | TokenConstraint - | OfTypeConstraint - | ListOfTypeConstraint - | PeekConstraint; -export type ConstraintsSet = Array; -export type Rule = RuleName | RuleConstraint | ConstraintsSet; -export interface BaseRuleConstraint { - butNot?: ?TokenConstraint | ?Array; - optional?: boolean; - eatNextOnFail?: boolean; -} -export interface TokenConstraint extends BaseRuleConstraint { - token: - | '!' - | '$' - | '&' - | '(' - | ')' - | '...' - | ':' - | '=' - | '@' - | '[' - | ']' - | '{' - | '}' - | '|' - | 'Name' - | 'Int' - | 'Float' - | 'String' - | 'BlockString' - | 'Comment'; - ofValue?: ?string; - oneOf?: ?Array; - tokenName?: string; - definitionName?: boolean; - typeName?: boolean; -} -export interface OfTypeConstraint extends BaseRuleConstraint { - ofType: Rule; - tokenName?: string; -} -export interface ListOfTypeConstraint extends BaseRuleConstraint { - listOfType: RuleName; -} -export interface PeekConstraint extends BaseRuleConstraint { - peek: Array; -} -export interface PeekCondition { - ifCondition: TokenConstraint; - expect: Rule; - end?: boolean; -} -export interface BaseParserRule { - kind: string; - name?: string; - depth: number; - step: number; - expanded: boolean; - state: string; - optional?: boolean; - eatNextOnFail?: boolean; -} -export interface TokenParserRule extends BaseParserRule, TokenConstraint {} -export interface OfTypeParserRule extends BaseParserRule, OfTypeConstraint {} -export interface ListOfTypeParserRule - extends BaseParserRule, - ListOfTypeConstraint {} -export interface PeekParserRule extends BaseParserRule, PeekConstraint { - index: number; - matched: boolean; -} -export interface ConstraintsSetRule extends BaseParserRule { - constraintsSet: boolean; - constraints: ConstraintsSet; -} - -export type ParserRule = - | TokenParserRule - | OfTypeParserRule - | ListOfTypeParserRule - | PeekParserRule - | ConstraintsSetRule; - -export type ParserState = {| - rules: Array, - kind: () => string, - step: () => number, - levels: Array, - indentLevel: number, - name: string | null, - type: string | null, -|}; - -export type Token = {| - kind: string, - value: string, - style: ?string, -|}; - -export type LexerToken = {| - kind: string, - value: ?string, -|}; - -export type Styles = {| - [name: string]: string, -|}; - -export type ParserConfig = {| - tabSize: number, -|}; - -export type ParserConfigOption = {| - tabSize: ?number, -|}; From e2a388188efccb8bd2d38357df076fc0db89f731 Mon Sep 17 00:00:00 2001 From: Naman Kumar Date: Fri, 4 Sep 2020 18:35:08 +0530 Subject: [PATCH 3/5] Update grammar structure --- .../grammarTypes.d.ts | 12 +- .../experimentalOnlineParser/grammarTypes.js | 8 +- .../experimentalOnlineParser/index.d.ts | 7 +- .../experimentalOnlineParser/index.js | 7 +- .../onlineParser.d.ts | 16 +- .../experimentalOnlineParser/onlineParser.js | 10 +- .../experimentalOnlineParser/rules.json | 1638 ++++++++--------- 7 files changed, 848 insertions(+), 850 deletions(-) diff --git a/src/language/experimentalOnlineParser/grammarTypes.d.ts b/src/language/experimentalOnlineParser/grammarTypes.d.ts index da1d16e8a2..9766dc2dbb 100644 --- a/src/language/experimentalOnlineParser/grammarTypes.d.ts +++ b/src/language/experimentalOnlineParser/grammarTypes.d.ts @@ -1,25 +1,21 @@ export interface GraphQLGrammarType { - rules: GraphQLGrammarRules; -} - -export interface GraphQLGrammarRules { [name: string]: GraphQLGrammarRule; } -export declare type GraphQLGrammarRule = +export type GraphQLGrammarRule = | GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint | GraphQLGrammarConstraintsSet; -export declare type GraphQLGrammarRuleName = string; +export type GraphQLGrammarRuleName = string; -export declare type GraphQLGrammarRuleConstraint = +export type GraphQLGrammarRuleConstraint = | GraphQLGrammarTokenConstraint | GraphQLGrammarOfTypeConstraint | GraphQLGrammarListOfTypeConstraint | GraphQLGrammarPeekConstraint; -export declare type GraphQLGrammarConstraintsSet = Array< +export type GraphQLGrammarConstraintsSet = Array< GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint >; diff --git a/src/language/experimentalOnlineParser/grammarTypes.js b/src/language/experimentalOnlineParser/grammarTypes.js index 9c0a34a216..a1b12150c4 100644 --- a/src/language/experimentalOnlineParser/grammarTypes.js +++ b/src/language/experimentalOnlineParser/grammarTypes.js @@ -1,10 +1,4 @@ -// @flow - -export type GraphQLGrammarType = {| - rules: GraphQLGrammarRules, -|}; - -export interface GraphQLGrammarRules { +export interface GraphQLGrammarType { [name: string]: GraphQLGrammarRule; } export type GraphQLGrammarRuleName = string; diff --git a/src/language/experimentalOnlineParser/index.d.ts b/src/language/experimentalOnlineParser/index.d.ts index 45277bc046..039446a16c 100644 --- a/src/language/experimentalOnlineParser/index.d.ts +++ b/src/language/experimentalOnlineParser/index.d.ts @@ -1 +1,6 @@ -export { OnlineParser, RuleKind, TokenKind } from './onlineParser'; +export { + OnlineParser, + RuleKind, + TokenKind, + OnlineParserState, +} from './onlineParser'; diff --git a/src/language/experimentalOnlineParser/index.js b/src/language/experimentalOnlineParser/index.js index 45277bc046..039446a16c 100644 --- a/src/language/experimentalOnlineParser/index.js +++ b/src/language/experimentalOnlineParser/index.js @@ -1 +1,6 @@ -export { OnlineParser, RuleKind, TokenKind } from './onlineParser'; +export { + OnlineParser, + RuleKind, + TokenKind, + OnlineParserState, +} from './onlineParser'; diff --git a/src/language/experimentalOnlineParser/onlineParser.d.ts b/src/language/experimentalOnlineParser/onlineParser.d.ts index bbbcc1f2d9..798f011767 100644 --- a/src/language/experimentalOnlineParser/onlineParser.d.ts +++ b/src/language/experimentalOnlineParser/onlineParser.d.ts @@ -38,14 +38,14 @@ interface ConstraintsSetOnlineParserRule extends BaseOnlineParserRule { constraints: GraphQLGrammarConstraintsSet; } -declare type OnlineParserRule = +type OnlineParserRule = | TokenOnlineParserRule | OfTypeOnlineParserRule | ListOfTypeOnlineParserRule | PeekOnlineParserRule | ConstraintsSetOnlineParserRule; -declare interface OnlineParserState { +export interface OnlineParserState { rules: Array; kind: () => string; step: () => number; @@ -55,22 +55,22 @@ declare interface OnlineParserState { type: string | null; } -declare interface Token { +interface Token { kind: string; value?: string; tokenName?: string | undefined; ruleName?: string | undefined; } -declare type OnlineParserConfig = { +type OnlineParserConfig = { tabSize: number; }; -declare type OnlineParserConfigOption = { +type OnlineParserConfigOption = { tabSize?: number; }; -export declare class OnlineParser { +export class OnlineParser { state: OnlineParserState; _lexer: Lexer; _config: OnlineParserConfig; @@ -101,7 +101,7 @@ export declare class OnlineParser { private readonly _lookAhead; } -export declare const TokenKind: { +export const TokenKind: { NAME: string; INT: string; FLOAT: string; @@ -113,7 +113,7 @@ export declare const TokenKind: { INVALID: string; }; -export declare const RuleKind: { +export const RuleKind: { TOKEN_CONSTRAINT: string; OF_TYPE_CONSTRAINT: string; LIST_OF_TYPE_CONSTRAINT: string; diff --git a/src/language/experimentalOnlineParser/onlineParser.js b/src/language/experimentalOnlineParser/onlineParser.js index 76f65c9677..1ee9f14b83 100644 --- a/src/language/experimentalOnlineParser/onlineParser.js +++ b/src/language/experimentalOnlineParser/onlineParser.js @@ -73,7 +73,7 @@ type OnlineParserRule = | PeekOnlineParserRule | ConstraintsSetOnlineParserRule; -type OnlineParserState = {| +export type OnlineParserState = {| rules: Array, kind: () => string, step: () => number, @@ -127,7 +127,7 @@ export class OnlineParser { name: 'Document', state: 'Document', kind: 'ListOfTypeConstraint', - ...GraphQLGrammar.rules.Document, + ...GraphQLGrammar.Document, expanded: false, depth: 1, step: 1, @@ -275,7 +275,7 @@ export class OnlineParser { _parseListOfTypeConstraint(rule: ListOfTypeOnlineParserRule): Token { this._pushRule( - GraphQLGrammar.rules[rule.listOfType], + GraphQLGrammar[rule.listOfType], rule.depth + 1, rule.listOfType, 1, @@ -315,7 +315,7 @@ export class OnlineParser { let { ifCondition } = constraint; if (typeof ifCondition === 'string') { - ifCondition = GraphQLGrammar.rules[ifCondition]; + ifCondition = GraphQLGrammar[ifCondition]; } let token = this._lookAhead(); @@ -551,7 +551,7 @@ export class OnlineParser { case RuleKind.RULE_NAME: rule = (rule: GraphQLGrammarRuleName); this._pushRule( - GraphQLGrammar.rules[rule], + GraphQLGrammar[rule], depth, (typeof name === 'string' ? name : undefined) || rule, step, diff --git a/src/language/experimentalOnlineParser/rules.json b/src/language/experimentalOnlineParser/rules.json index cdb0c0538f..3682caea3a 100644 --- a/src/language/experimentalOnlineParser/rules.json +++ b/src/language/experimentalOnlineParser/rules.json @@ -1,938 +1,936 @@ { - "rules": { - "Name": { "token": "Name" }, - "String": { "token": "String" }, - "BlockString": { "token": "BlockString" }, + "Name": { "token": "Name" }, + "String": { "token": "String" }, + "BlockString": { "token": "BlockString" }, - "Document": { "listOfType": "Definition" }, - "Definition": { - "peek": [ - { - "ifCondition": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"] - }, - "expect": "OperationDefinition" - }, - { - "ifCondition": { "token": "Name", "ofValue": "fragment" }, - "expect": "FragmentDefinition" - }, - { - "ifCondition": { - "token": "Name", - "oneOf": [ - "schema", - "scalar", - "type", - "interface", - "union", - "enum", - "input", - "directive" - ] - }, - "expect": "TypeSystemDefinition" - }, - { - "ifCondition": { "token": "Name", "ofValue": "extend" }, - "expect": "TypeSystemExtension" - }, - { - "ifCondition": { "token": "{" }, - "expect": "OperationDefinition" - }, - { - "ifCondition": "String", - "expect": "TypeSystemDefinition" - }, - { - "ifCondition": "BlockString", - "expect": "TypeSystemDefinition" - } - ] - }, - - "OperationDefinition": { - "peek": [ - { - "ifCondition": { "token": "{" }, - "expect": "SelectionSet" + "Document": { "listOfType": "Definition" }, + "Definition": { + "peek": [ + { + "ifCondition": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"] }, - { - "ifCondition": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"] - }, - "expect": [ - "OperationType", - { - "token": "Name", - "optional": true, - "tokenName": "OperationName", - "definitionName": true - }, - { "ofType": "VariableDefinitions", "optional": true }, - { "ofType": "Directives", "optional": true }, - "SelectionSet" + "expect": "OperationDefinition" + }, + { + "ifCondition": { "token": "Name", "ofValue": "fragment" }, + "expect": "FragmentDefinition" + }, + { + "ifCondition": { + "token": "Name", + "oneOf": [ + "schema", + "scalar", + "type", + "interface", + "union", + "enum", + "input", + "directive" ] - } - ] - }, - "OperationType": { - "ofType": "OperationTypeName" - }, - "OperationTypeName": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"], - "definitionName": true - }, - "SelectionSet": [ - { "token": "{" }, - { "listOfType": "Selection" }, - { "token": "}" } - ], - "Selection": { - "peek": [ - { - "ifCondition": { "token": "..." }, - "expect": "Fragment" }, - { - "ifCondition": { "token": "Name" }, - "expect": "Field" - } - ] - }, - - "Field": [ + "expect": "TypeSystemDefinition" + }, { - "ofType": "Alias", - "optional": true, - "eatNextOnFail": true, - "definitionName": true + "ifCondition": { "token": "Name", "ofValue": "extend" }, + "expect": "TypeSystemExtension" }, - { "token": "Name", "tokenName": "FieldName", "definitionName": true }, - { "ofType": "Arguments", "optional": true }, - { "ofType": "Directives", "optional": true }, - { "ofType": "SelectionSet", "optional": true } - ], - - "Arguments": [ - { "token": "(" }, - { "listOfType": "Argument" }, - { "token": ")" } - ], - "Argument": [ - { "token": "Name", "tokenName": "ArgumentName", "definitionName": true }, - { "token": ":" }, - "Value" - ], - - "Alias": [ - { "token": "Name", "tokenName": "AliasName", "definitionName": true }, - { "token": ":" } - ], + { + "ifCondition": { "token": "{" }, + "expect": "OperationDefinition" + }, + { + "ifCondition": "String", + "expect": "TypeSystemDefinition" + }, + { + "ifCondition": "BlockString", + "expect": "TypeSystemDefinition" + } + ] + }, - "Fragment": [ - { "token": "..." }, + "OperationDefinition": { + "peek": [ { - "peek": [ - { - "ifCondition": "FragmentName", - "expect": "FragmentSpread" - }, - { - "ifCondition": { "token": "Name", "ofValue": "on" }, - "expect": "InlineFragment" - }, + "ifCondition": { "token": "{" }, + "expect": "SelectionSet" + }, + { + "ifCondition": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"] + }, + "expect": [ + "OperationType", { - "ifCondition": { "token": "@" }, - "expect": "InlineFragment" + "token": "Name", + "optional": true, + "tokenName": "OperationName", + "definitionName": true }, - { - "ifCondition": { "token": "{" }, - "expect": "InlineFragment" - } + { "ofType": "VariableDefinitions", "optional": true }, + { "ofType": "Directives", "optional": true }, + "SelectionSet" ] } - ], - - "FragmentSpread": [ - "FragmentName", - { "ofType": "Directives", "optional": true } - ], - "FragmentDefinition": [ - { - "token": "Name", - "ofValue": "fragment", - "tokenName": "FragmentDefinitionKeyword" + ] + }, + "OperationType": { + "ofType": "OperationTypeName" + }, + "OperationTypeName": { + "token": "Name", + "oneOf": ["query", "mutation", "subscription"], + "definitionName": true + }, + "SelectionSet": [ + { "token": "{" }, + { "listOfType": "Selection" }, + { "token": "}" } + ], + "Selection": { + "peek": [ + { + "ifCondition": { "token": "..." }, + "expect": "Fragment" }, - "FragmentName", - "TypeCondition", - { "ofType": "Directives", "optional": true }, - "SelectionSet" - ], - "FragmentName": { - "token": "Name", - "butNot": { "token": "Name", "ofValue": "on" }, + { + "ifCondition": { "token": "Name" }, + "expect": "Field" + } + ] + }, + + "Field": [ + { + "ofType": "Alias", + "optional": true, + "eatNextOnFail": true, "definitionName": true }, - - "TypeCondition": [ - { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, - "TypeName" - ], - - "InlineFragment": [ - { "ofType": "TypeCondition", "optional": true }, - { "ofType": "Directives", "optional": true }, - "SelectionSet" - ], - - "Value": { + { "token": "Name", "tokenName": "FieldName", "definitionName": true }, + { "ofType": "Arguments", "optional": true }, + { "ofType": "Directives", "optional": true }, + { "ofType": "SelectionSet", "optional": true } + ], + + "Arguments": [ + { "token": "(" }, + { "listOfType": "Argument" }, + { "token": ")" } + ], + "Argument": [ + { "token": "Name", "tokenName": "ArgumentName", "definitionName": true }, + { "token": ":" }, + "Value" + ], + + "Alias": [ + { "token": "Name", "tokenName": "AliasName", "definitionName": true }, + { "token": ":" } + ], + + "Fragment": [ + { "token": "..." }, + { "peek": [ { - "ifCondition": { "token": "$" }, - "expect": "Variable" - }, - { - "ifCondition": "IntValue", - "expect": { "ofType": "IntValue", "tokenName": "NumberValue" } - }, - { - "ifCondition": "FloatValue", - "expect": { "ofType": "FloatValue", "tokenName": "NumberValue" } - }, - { - "ifCondition": "BooleanValue", - "expect": { "ofType": "BooleanValue", "tokenName": "BooleanValue" } - }, - { - "ifCondition": "EnumValue", - "expect": { "ofType": "EnumValue", "tokenName": "EnumValue" } - }, - { - "ifCondition": "String", - "expect": { "ofType": "String", "tokenName": "StringValue" } + "ifCondition": "FragmentName", + "expect": "FragmentSpread" }, { - "ifCondition": "BlockString", - "expect": { "ofType": "BlockString", "tokenName": "StringValue" } + "ifCondition": { "token": "Name", "ofValue": "on" }, + "expect": "InlineFragment" }, { - "ifCondition": "NullValue", - "expect": { "ofType": "NullValue", "tokenName": "NullValue" } - }, - { - "ifCondition": { "token": "[" }, - "expect": "ListValue" + "ifCondition": { "token": "@" }, + "expect": "InlineFragment" }, { "ifCondition": { "token": "{" }, - "expect": "ObjectValue" + "expect": "InlineFragment" } ] - }, - - "ConstValue": { - "peek": [ - { - "ifCondition": "IntValue", - "expect": { "ofType": "IntValue" } - }, - { - "ifCondition": "FloatValue", - "expect": { "ofType": "FloatValue" } - }, - { - "ifCondition": "BooleanValue", - "expect": "BooleanValue" - }, - { - "ifCondition": "EnumValue", - "expect": "EnumValue" - }, - { - "ifCondition": "String", - "expect": { "ofType": "String", "tokenName": "StringValue" } - }, - { - "ifCondition": "BlockString", - "expect": { "token": "BlockString", "tokenName": "StringValue" } - }, - { - "ifCondition": "NullValue", - "expect": "NullValue" - }, - { - "ifCondition": { "token": "[" }, - "expect": "ConstListValue" - }, - { - "ifCondition": { "token": "{" }, - "expect": "ObjectValue" - } - ] - }, - - "IntValue": { "token": "Int" }, - - "FloatValue": { "token": "Float" }, - - "StringValue": { - "peek": [ - { - "ifCondition": { "token": "String" }, - "expect": { "token": "String", "tokenName": "StringValue" } - }, - { - "ifCondition": { "token": "BlockString" }, - "expect": { "token": "BlockString", "tokenName": "StringValue" } - } - ] - }, - - "BooleanValue": { - "token": "Name", - "oneOf": ["true", "false"], - "tokenName": "BooleanValue" - }, - - "NullValue": { - "token": "Name", - "ofValue": "null", - "tokenName": "NullValue" - }, - - "EnumValue": { + } + ], + + "FragmentSpread": [ + "FragmentName", + { "ofType": "Directives", "optional": true } + ], + "FragmentDefinition": [ + { "token": "Name", - "butNot": { "token": "Name", "oneOf": ["null", "true", "false"] }, - "tokenName": "EnumValue" + "ofValue": "fragment", + "tokenName": "FragmentDefinitionKeyword" }, + "FragmentName", + "TypeCondition", + { "ofType": "Directives", "optional": true }, + "SelectionSet" + ], + "FragmentName": { + "token": "Name", + "butNot": { "token": "Name", "ofValue": "on" }, + "definitionName": true + }, + + "TypeCondition": [ + { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, + "TypeName" + ], + + "InlineFragment": [ + { "ofType": "TypeCondition", "optional": true }, + { "ofType": "Directives", "optional": true }, + "SelectionSet" + ], + + "Value": { + "peek": [ + { + "ifCondition": { "token": "$" }, + "expect": "Variable" + }, + { + "ifCondition": "IntValue", + "expect": { "ofType": "IntValue", "tokenName": "NumberValue" } + }, + { + "ifCondition": "FloatValue", + "expect": { "ofType": "FloatValue", "tokenName": "NumberValue" } + }, + { + "ifCondition": "BooleanValue", + "expect": { "ofType": "BooleanValue", "tokenName": "BooleanValue" } + }, + { + "ifCondition": "EnumValue", + "expect": { "ofType": "EnumValue", "tokenName": "EnumValue" } + }, + { + "ifCondition": "String", + "expect": { "ofType": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": "BlockString", + "expect": { "ofType": "BlockString", "tokenName": "StringValue" } + }, + { + "ifCondition": "NullValue", + "expect": { "ofType": "NullValue", "tokenName": "NullValue" } + }, + { + "ifCondition": { "token": "[" }, + "expect": "ListValue" + }, + { + "ifCondition": { "token": "{" }, + "expect": "ObjectValue" + } + ] + }, - "ListValue": [ - { "token": "[" }, - { "listOfType": "Value", "optional": true }, - { "token": "]" } - ], - - "ConstListValue": [ - { "token": "[" }, - { "listOfType": "ConstValue", "optional": true }, - { "token": "]" } - ], - - "ObjectValue": [ - { "token": "{" }, - { "listOfType": "ObjectField", "optional": true }, - { "token": "}" } - ], - "ObjectField": [ - { "token": "Name", "tokenName": "ObjectFieldName" }, - { "token": ":" }, - { "ofType": "ConstValue" } - ], - - "Variable": [ - { "token": "$", "tokenName": "VariableName" }, - { "token": "Name", "tokenName": "VariableName" } - ], - "VariableDefinitions": [ - { "token": "(" }, - { "listOfType": "VariableDefinition" }, - { "token": ")" } - ], - "VariableDefinition": [ - "Variable", - { "token": ":" }, - "Type", - { "ofType": "DefaultValue", "optional": true } - ], - "DefaultValue": [{ "token": "=" }, "ConstValue"], - - "TypeName": { "token": "Name", "tokenName": "TypeName", "typeName": true }, + "ConstValue": { + "peek": [ + { + "ifCondition": "IntValue", + "expect": { "ofType": "IntValue" } + }, + { + "ifCondition": "FloatValue", + "expect": { "ofType": "FloatValue" } + }, + { + "ifCondition": "BooleanValue", + "expect": "BooleanValue" + }, + { + "ifCondition": "EnumValue", + "expect": "EnumValue" + }, + { + "ifCondition": "String", + "expect": { "ofType": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": "BlockString", + "expect": { "token": "BlockString", "tokenName": "StringValue" } + }, + { + "ifCondition": "NullValue", + "expect": "NullValue" + }, + { + "ifCondition": { "token": "[" }, + "expect": "ConstListValue" + }, + { + "ifCondition": { "token": "{" }, + "expect": "ObjectValue" + } + ] + }, - "Type": { - "peek": [ - { - "ifCondition": { "token": "Name" }, - "expect": ["TypeName", { "token": "!", "optional": true }] - }, - { - "ifCondition": { "token": "[" }, - "expect": "ListType" - } - ] - }, - "ListType": [ - { "token": "[" }, - { "listOfType": "Type" }, - { "token": "]" }, - { "token": "!", "optional": true } - ], + "IntValue": { "token": "Int" }, - "Directives": { "listOfType": "Directive" }, - "Directive": [ - { "token": "@", "tokenName": "DirectiveName" }, - { "token": "Name", "tokenName": "DirectiveName" }, - { "ofType": "Arguments", "optional": true } - ], + "FloatValue": { "token": "Float" }, - "TypeSystemDefinition": [ - { "ofType": "Description", "optional": true }, + "StringValue": { + "peek": [ { - "peek": [ - { - "ifCondition": { - "target": "Name", - "ofValue": "schema" - }, - "expect": "SchemaDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "scalar" - }, - "expect": "ScalarTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "type" - }, - "expect": "ObjectTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "interface" - }, - "expect": "InterfaceTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "union" - }, - "expect": "UnionTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "enum" - }, - "expect": "EnumTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "input" - }, - "expect": "InputObjectTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "directive" - }, - "expect": "DirectiveDefinition" - } - ] + "ifCondition": { "token": "String" }, + "expect": { "token": "String", "tokenName": "StringValue" } + }, + { + "ifCondition": { "token": "BlockString" }, + "expect": { "token": "BlockString", "tokenName": "StringValue" } } - ], - - "TypeSystemExtension": { + ] + }, + + "BooleanValue": { + "token": "Name", + "oneOf": ["true", "false"], + "tokenName": "BooleanValue" + }, + + "NullValue": { + "token": "Name", + "ofValue": "null", + "tokenName": "NullValue" + }, + + "EnumValue": { + "token": "Name", + "butNot": { "token": "Name", "oneOf": ["null", "true", "false"] }, + "tokenName": "EnumValue" + }, + + "ListValue": [ + { "token": "[" }, + { "listOfType": "Value", "optional": true }, + { "token": "]" } + ], + + "ConstListValue": [ + { "token": "[" }, + { "listOfType": "ConstValue", "optional": true }, + { "token": "]" } + ], + + "ObjectValue": [ + { "token": "{" }, + { "listOfType": "ObjectField", "optional": true }, + { "token": "}" } + ], + "ObjectField": [ + { "token": "Name", "tokenName": "ObjectFieldName" }, + { "token": ":" }, + { "ofType": "ConstValue" } + ], + + "Variable": [ + { "token": "$", "tokenName": "VariableName" }, + { "token": "Name", "tokenName": "VariableName" } + ], + "VariableDefinitions": [ + { "token": "(" }, + { "listOfType": "VariableDefinition" }, + { "token": ")" } + ], + "VariableDefinition": [ + "Variable", + { "token": ":" }, + "Type", + { "ofType": "DefaultValue", "optional": true } + ], + "DefaultValue": [{ "token": "=" }, "ConstValue"], + + "TypeName": { "token": "Name", "tokenName": "TypeName", "typeName": true }, + + "Type": { + "peek": [ + { + "ifCondition": { "token": "Name" }, + "expect": ["TypeName", { "token": "!", "optional": true }] + }, + { + "ifCondition": { "token": "[" }, + "expect": "ListType" + } + ] + }, + "ListType": [ + { "token": "[" }, + { "listOfType": "Type" }, + { "token": "]" }, + { "token": "!", "optional": true } + ], + + "Directives": { "listOfType": "Directive" }, + "Directive": [ + { "token": "@", "tokenName": "DirectiveName" }, + { "token": "Name", "tokenName": "DirectiveName" }, + { "ofType": "Arguments", "optional": true } + ], + + "TypeSystemDefinition": [ + { "ofType": "Description", "optional": true }, + { "peek": [ { "ifCondition": { "target": "Name", "ofValue": "schema" }, - "expect": "SchemaExtension" + "expect": "SchemaDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "scalar" }, - "expect": "ScalarTypeExtension" + "expect": "ScalarTypeDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "type" }, - "expect": "ObjectTypeExtension" + "expect": "ObjectTypeDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "interface" }, - "expect": "InterfaceTypeExtension" + "expect": "InterfaceTypeDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "union" }, - "expect": "UnionTypeExtension" + "expect": "UnionTypeDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "enum" }, - "expect": "EnumTypeExtension" + "expect": "EnumTypeDefinition" }, { "ifCondition": { "target": "Name", "ofValue": "input" }, - "expect": "InputObjectTypeExtension" + "expect": "InputObjectTypeDefinition" + }, + { + "ifCondition": { + "target": "Name", + "ofValue": "directive" + }, + "expect": "DirectiveDefinition" } ] - }, - - "SchemaDefinition": [ - { - "token": "Name", - "ofValue": "schema", - "tokenName": "SchemaDefinitionKeyword" - }, - { "ofType": "Directives", "optional": true }, - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ], - "RootOperationTypeDefinition": [ - "OperationType", - { "token": ":" }, - { "token": "Name", "tokenName": "OperationTypeDefinitionName" } - ], - - "SchemaExtension": [ - { "token": "Name", "ofValue": "extend" }, - { "token": "Name", "ofValue": "schema" }, - "Name", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { - "ofType": [ - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ], - "optional": true - } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": [ - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ] - } - ] - } - ], - - "Description": "StringValue", - - "ScalarTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "scalar", - "tokenName": "ScalarDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true } - ], + } + ], - "ScalarTypeExtension": [ + "TypeSystemExtension": { + "peek": [ { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "schema" + }, + "expect": "SchemaExtension" }, { - "token": "Name", - "ofValue": "scalar", - "tokenName": "ScalarDefinitionKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "scalar" + }, + "expect": "ScalarTypeExtension" }, - "TypeName", - "Directives" - ], - - "ObjectTypeDefinition": [ - { "ofType": "Description", "optional": true }, { - "token": "Name", - "ofValue": "type", - "tokenName": "TypeDefinitionKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "type" + }, + "expect": "ObjectTypeExtension" }, - "TypeName", - { "ofType": "ImplementsInterfaces", "optional": true }, - { "ofType": "Directives", "optional": true }, - { "ofType": "FieldsDefinition", "optional": true } - ], - "ImplementsInterfaces": [ { - "token": "Name", - "ofValue": "implements", - "tokenName": "ImplementsKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "interface" + }, + "expect": "InterfaceTypeExtension" }, - { "token": "&", "optional": true }, - "TypeName", - { - "listOfType": "ImplementsAdditionalInterfaceName", - "optional": true - } - ], - "ImplementsAdditionalInterfaceName": [{ "token": "&" }, "TypeName"], - "FieldsDefinition": [ - { "token": "{" }, - { "listOfType": "FieldDefinition" }, - { "token": "}" } - ], - "FieldDefinition": [ - { "ofType": "Description", "optional": true }, - { "token": "Name", "tokenName": "AliasName", "definitionName": true }, - { "ofType": "ArgumentsDefinition", "optional": true }, - { "token": ":" }, - "Type", - { "ofType": "Directives", "optional": true } - ], - - "ArgumentsDefinition": [ - { "token": "(" }, - { "listOfType": "InputValueDefinition" }, - { "token": ")" } - ], - "InputValueDefinition": [ - { "ofType": "Description", "optional": true }, - { "tokenName": "Name", "tokenName": "ArgumentName" }, - { "token": ":" }, - "Type", - { "ofType": "DefaultValue", "optional": true }, - { "ofType": "Directives", "optional": true } - ], - - "ObjectTypeExtension": [ { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "union" + }, + "expect": "UnionTypeExtension" }, { - "token": "Name", - "ofValue": "type", - "tokenName": "TypeDefinitionKeyword" + "ifCondition": { + "target": "Name", + "ofValue": "enum" + }, + "expect": "EnumTypeExtension" }, - "TypeName", { - "peek": [ - { - "ifCondition": { "token": "Name", "ofValue": "interface" }, - "expect": [ - "ImplementsInterfaces", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ], - "optional": true - } - ] - }, - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ] + "ifCondition": { + "target": "Name", + "ofValue": "input" + }, + "expect": "InputObjectTypeExtension" } - ], + ] + }, - "InterfaceTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "interface", - "tokenName": "InterfaceDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "FieldsDefinition", "optional": true } - ], + "SchemaDefinition": [ + { + "token": "Name", + "ofValue": "schema", + "tokenName": "SchemaDefinitionKeyword" + }, + { "ofType": "Directives", "optional": true }, + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ], + "RootOperationTypeDefinition": [ + "OperationType", + { "token": ":" }, + { "token": "Name", "tokenName": "OperationTypeDefinitionName" } + ], + + "SchemaExtension": [ + { "token": "Name", "ofValue": "extend" }, + { "token": "Name", "ofValue": "schema" }, + "Name", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { + "ofType": [ + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ], + "optional": true + } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": [ + { "token": "{" }, + { "listOfType": "RootOperationTypeDefinition" }, + { "token": "}" } + ] + } + ] + } + ], - "InterfaceTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "interface", - "tokenName": "InterfaceDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ] - } - ], + "Description": "StringValue", - "UnionTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "union", - "tokenName": "UnionDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "UnionMemberTypes", "optional": true } - ], + "ScalarTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "scalar", + "tokenName": "ScalarDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true } + ], - "UnionMemberTypes": [ - { "token": "=" }, - { "token": "|", "optional": true }, - "Name", - { - "listOfType": "UnionMemberAdditionalTypeName", - "optional": true - } - ], + "ScalarTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "scalar", + "tokenName": "ScalarDefinitionKeyword" + }, + "TypeName", + "Directives" + ], - "UnionMemberAdditionalTypeName": [{ "token": "|" }, "TypeName"], + "ObjectTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "type", + "tokenName": "TypeDefinitionKeyword" + }, + "TypeName", + { "ofType": "ImplementsInterfaces", "optional": true }, + { "ofType": "Directives", "optional": true }, + { "ofType": "FieldsDefinition", "optional": true } + ], + "ImplementsInterfaces": [ + { + "token": "Name", + "ofValue": "implements", + "tokenName": "ImplementsKeyword" + }, + { "token": "&", "optional": true }, + "TypeName", + { + "listOfType": "ImplementsAdditionalInterfaceName", + "optional": true + } + ], + "ImplementsAdditionalInterfaceName": [{ "token": "&" }, "TypeName"], + "FieldsDefinition": [ + { "token": "{" }, + { "listOfType": "FieldDefinition" }, + { "token": "}" } + ], + "FieldDefinition": [ + { "ofType": "Description", "optional": true }, + { "token": "Name", "tokenName": "AliasName", "definitionName": true }, + { "ofType": "ArgumentsDefinition", "optional": true }, + { "token": ":" }, + "Type", + { "ofType": "Directives", "optional": true } + ], + + "ArgumentsDefinition": [ + { "token": "(" }, + { "listOfType": "InputValueDefinition" }, + { "token": ")" } + ], + "InputValueDefinition": [ + { "ofType": "Description", "optional": true }, + { "tokenName": "Name", "tokenName": "ArgumentName" }, + { "token": ":" }, + "Type", + { "ofType": "DefaultValue", "optional": true }, + { "ofType": "Directives", "optional": true } + ], + + "ObjectTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "type", + "tokenName": "TypeDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "Name", "ofValue": "interface" }, + "expect": [ + "ImplementsInterfaces", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ], + "optional": true + } + ] + }, + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ] + } + ], - "UnionTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "union", - "tokenName": "UnionDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "UnionMemberTypes", "optional": true } - ] - }, - { - "ifCondition": { "token": "=" }, - "expect": "UnionMemberTypes" - } - ] - } - ], + "InterfaceTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "interface", + "tokenName": "InterfaceDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "FieldsDefinition", "optional": true } + ], - "EnumTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "enum", - "tokenName": "EnumDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "EnumValuesDefinition", "optional": true } - ], - "EnumValuesDefinition": [ - { "token": "{" }, - { "listOfType": "EnumValueDefinition" }, - { "token": "}" } - ], - "EnumValueDefinition": [ - { "ofType": "Description", "optional": true }, - "EnumValue", - { "ofType": "Directives", "optional": true } - ], + "InterfaceTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "interface", + "tokenName": "InterfaceDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "FieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "FieldsDefinition" + } + ] + } + ], - "EnumTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "enum", - "tokenName": "EnumDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "EnumValuesDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "EnumValuesDefinition" - } - ] - } - ], + "UnionTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "union", + "tokenName": "UnionDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "UnionMemberTypes", "optional": true } + ], + + "UnionMemberTypes": [ + { "token": "=" }, + { "token": "|", "optional": true }, + "Name", + { + "listOfType": "UnionMemberAdditionalTypeName", + "optional": true + } + ], - "InputObjectTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "input", - "tokenName": "InputDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "InputFieldsDefinition", "optional": true } - ], - "InputFieldsDefinition": [ - { "token": "{" }, - { "listOfType": "InputValueDefinition" }, - { "token": "}" } - ], + "UnionMemberAdditionalTypeName": [{ "token": "|" }, "TypeName"], - "InputObjectTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "input", - "tokenName": "InputDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "InputFieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "InputFieldsDefinition" - } - ] - } - ], + "UnionTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "union", + "tokenName": "UnionDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "UnionMemberTypes", "optional": true } + ] + }, + { + "ifCondition": { "token": "=" }, + "expect": "UnionMemberTypes" + } + ] + } + ], - "DirectiveDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "directive", - "tokenName": "DirectiveDefinitionKeyword" - }, - { "token": "@", "tokenName": "DirectiveName" }, - { "token": "Name", "tokenName": "DirectiveName" }, - { "ofType": "ArgumentsDefinition", "optional": true }, - { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, - "DirectiveLocations" - ], - "DirectiveLocations": [ - { "token": "|", "optional": true }, - "DirectiveLocation", - { - "listOfType": "DirectiveLocationAdditionalName", - "optional": true - } - ], - "DirectiveLocationAdditionalName": [{ "token": "|" }, "DirectiveLocation"], - "DirectiveLocation": { + "EnumTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "enum", + "tokenName": "EnumDefinitionKeyword" + }, + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "EnumValuesDefinition", "optional": true } + ], + "EnumValuesDefinition": [ + { "token": "{" }, + { "listOfType": "EnumValueDefinition" }, + { "token": "}" } + ], + "EnumValueDefinition": [ + { "ofType": "Description", "optional": true }, + "EnumValue", + { "ofType": "Directives", "optional": true } + ], + + "EnumTypeExtension": [ + { + "token": "Name", + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" + }, + { + "token": "Name", + "ofValue": "enum", + "tokenName": "EnumDefinitionKeyword" + }, + "TypeName", + { "peek": [ { - "ifCondition": "ExecutableDirectiveLocation", - "expect": "ExecutableDirectiveLocation" + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "EnumValuesDefinition", "optional": true } + ] }, { - "ifCondition": "TypeSystemDirectiveLocation", - "expect": "TypeSystemDirectiveLocation" + "ifCondition": { "token": "{" }, + "expect": "EnumValuesDefinition" } ] + } + ], + + "InputObjectTypeDefinition": [ + { "ofType": "Description", "optional": true }, + { + "token": "Name", + "ofValue": "input", + "tokenName": "InputDefinitionKeyword" }, - "ExecutableDirectiveLocation": { + "TypeName", + { "ofType": "Directives", "optional": true }, + { "ofType": "InputFieldsDefinition", "optional": true } + ], + "InputFieldsDefinition": [ + { "token": "{" }, + { "listOfType": "InputValueDefinition" }, + { "token": "}" } + ], + + "InputObjectTypeExtension": [ + { "token": "Name", - "oneOf": [ - "QUERY", - "MUTATION", - "SUBSCRIPTION", - "FIELD", - "FRAGMENT_DEFINITION", - "FRAGMENT_SPREAD", - "INLINE_FRAGMENT" - ], - "tokenName": "EnumValue" + "ofValue": "extend", + "tokenName": "ExtendDefinitionKeyword" }, - "TypeSystemDirectiveLocation": { + { + "token": "Name", + "ofValue": "input", + "tokenName": "InputDefinitionKeyword" + }, + "TypeName", + { + "peek": [ + { + "ifCondition": { "token": "@" }, + "expect": [ + "Directives", + { "ofType": "InputFieldsDefinition", "optional": true } + ] + }, + { + "ifCondition": { "token": "{" }, + "expect": "InputFieldsDefinition" + } + ] + } + ], + + "DirectiveDefinition": [ + { "ofType": "Description", "optional": true }, + { "token": "Name", - "oneOf": [ - "SCHEMA", - "SCALAR", - "OBJECT", - "FIELD_DEFINITION", - "ARGUMENT_DEFINITION", - "INTERFACE", - "UNION", - "ENUM", - "ENUM_VALUE", - "INPUT_OBJECT", - "INPUT_FIELD_DEFINITION" - ], - "tokenName": "EnumValue" + "ofValue": "directive", + "tokenName": "DirectiveDefinitionKeyword" + }, + { "token": "@", "tokenName": "DirectiveName" }, + { "token": "Name", "tokenName": "DirectiveName" }, + { "ofType": "ArgumentsDefinition", "optional": true }, + { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, + "DirectiveLocations" + ], + "DirectiveLocations": [ + { "token": "|", "optional": true }, + "DirectiveLocation", + { + "listOfType": "DirectiveLocationAdditionalName", + "optional": true } + ], + "DirectiveLocationAdditionalName": [{ "token": "|" }, "DirectiveLocation"], + "DirectiveLocation": { + "peek": [ + { + "ifCondition": "ExecutableDirectiveLocation", + "expect": "ExecutableDirectiveLocation" + }, + { + "ifCondition": "TypeSystemDirectiveLocation", + "expect": "TypeSystemDirectiveLocation" + } + ] + }, + "ExecutableDirectiveLocation": { + "token": "Name", + "oneOf": [ + "QUERY", + "MUTATION", + "SUBSCRIPTION", + "FIELD", + "FRAGMENT_DEFINITION", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "tokenName": "EnumValue" + }, + "TypeSystemDirectiveLocation": { + "token": "Name", + "oneOf": [ + "SCHEMA", + "SCALAR", + "OBJECT", + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "INTERFACE", + "UNION", + "ENUM", + "ENUM_VALUE", + "INPUT_OBJECT", + "INPUT_FIELD_DEFINITION" + ], + "tokenName": "EnumValue" } } From 3acae6a62d2b66e7e4b99230e43e68a38b100f73 Mon Sep 17 00:00:00 2001 From: Naman Kumar Date: Tue, 8 Sep 2020 16:52:27 +0530 Subject: [PATCH 4/5] Move rules to js --- .../experimentalOnlineParser/grammar.d.ts | 1006 +++++++++++++++++ .../experimentalOnlineParser/grammar.js | 888 +++++++++++++++ .../grammarTypes.d.ts | 78 -- .../experimentalOnlineParser/grammarTypes.js | 70 -- .../onlineParser.d.ts | 2 +- .../experimentalOnlineParser/onlineParser.js | 4 +- .../experimentalOnlineParser/rules.json | 936 --------------- 7 files changed, 1897 insertions(+), 1087 deletions(-) create mode 100644 src/language/experimentalOnlineParser/grammar.d.ts create mode 100644 src/language/experimentalOnlineParser/grammar.js delete mode 100644 src/language/experimentalOnlineParser/grammarTypes.d.ts delete mode 100644 src/language/experimentalOnlineParser/grammarTypes.js delete mode 100644 src/language/experimentalOnlineParser/rules.json diff --git a/src/language/experimentalOnlineParser/grammar.d.ts b/src/language/experimentalOnlineParser/grammar.d.ts new file mode 100644 index 0000000000..6e71a66a72 --- /dev/null +++ b/src/language/experimentalOnlineParser/grammar.d.ts @@ -0,0 +1,1006 @@ +export interface GraphQLGrammarType { + [name: string]: GraphQLGrammarRule; +} + +export type GraphQLGrammarRule = + | GraphQLGrammarRuleName + | GraphQLGrammarRuleConstraint + | GraphQLGrammarConstraintsSet; + +export type GraphQLGrammarRuleName = string; + +export type GraphQLGrammarRuleConstraint = + | GraphQLGrammarTokenConstraint + | GraphQLGrammarOfTypeConstraint + | GraphQLGrammarListOfTypeConstraint + | GraphQLGrammarPeekConstraint; + +export type GraphQLGrammarConstraintsSet = Array< + GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint +>; + +export interface GraphQLGrammarBaseRuleConstraint { + butNot?: GraphQLGrammarTokenConstraint | Array; + optional?: boolean; + eatNextOnFail?: boolean; +} + +export interface GraphQLGrammarTokenConstraint + extends GraphQLGrammarBaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: string; + oneOf?: Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} + +export interface GraphQLGrammarOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + ofType: GraphQLGrammarRule; + tokenName?: string; +} + +export interface GraphQLGrammarListOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { + listOfType: GraphQLGrammarRuleName; +} + +export interface GraphQLGrammarPeekConstraint + extends GraphQLGrammarBaseRuleConstraint { + peek: Array; +} + +export interface GraphQLGrammarPeekConstraintCondition { + ifCondition: GraphQLGrammarTokenConstraint; + expect: GraphQLGrammarRule; + end?: boolean; +} + +const grammar: GraphQLGrammarType = { + Name: { token: 'Name' }, + String: { token: 'String' }, + BlockString: { token: 'BlockString' }, + + Document: { listOfType: 'Definition' }, + Definition: { + peek: [ + { + ifCondition: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + }, + expect: 'OperationDefinition', + }, + { + ifCondition: { token: 'Name', ofValue: 'fragment' }, + expect: 'FragmentDefinition', + }, + { + ifCondition: { + token: 'Name', + oneOf: [ + 'schema', + 'scalar', + 'type', + 'interface', + 'union', + 'enum', + 'input', + 'directive', + ], + }, + expect: 'TypeSystemDefinition', + }, + { + ifCondition: { token: 'Name', ofValue: 'extend' }, + expect: 'TypeSystemExtension', + }, + { + ifCondition: { token: '{' }, + expect: 'OperationDefinition', + }, + { + ifCondition: 'String', + expect: 'TypeSystemDefinition', + }, + { + ifCondition: 'BlockString', + expect: 'TypeSystemDefinition', + }, + ], + }, + + OperationDefinition: { + peek: [ + { + ifCondition: { token: '{' }, + expect: 'SelectionSet', + }, + { + ifCondition: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + }, + expect: [ + 'OperationType', + { + token: 'Name', + optional: true, + tokenName: 'OperationName', + definitionName: true, + }, + { ofType: 'VariableDefinitions', optional: true }, + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + }, + ], + }, + OperationType: { + ofType: 'OperationTypeName', + }, + OperationTypeName: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + definitionName: true, + }, + SelectionSet: [{ token: '{' }, { listOfType: 'Selection' }, { token: '}' }], + Selection: { + peek: [ + { + ifCondition: { token: '...' }, + expect: 'Fragment', + }, + { + ifCondition: { token: 'Name' }, + expect: 'Field', + }, + ], + }, + + Field: [ + { + ofType: 'Alias', + optional: true, + eatNextOnFail: true, + definitionName: true, + }, + { token: 'Name', tokenName: 'FieldName', definitionName: true }, + { ofType: 'Arguments', optional: true }, + { ofType: 'Directives', optional: true }, + { ofType: 'SelectionSet', optional: true }, + ], + + Arguments: [{ token: '(' }, { listOfType: 'Argument' }, { token: ')' }], + Argument: [ + { token: 'Name', tokenName: 'ArgumentName', definitionName: true }, + { token: ':' }, + 'Value', + ], + + Alias: [ + { token: 'Name', tokenName: 'AliasName', definitionName: true }, + { token: ':' }, + ], + + Fragment: [ + { token: '...' }, + { + peek: [ + { + ifCondition: 'FragmentName', + expect: 'FragmentSpread', + }, + { + ifCondition: { token: 'Name', ofValue: 'on' }, + expect: 'InlineFragment', + }, + { + ifCondition: { token: '@' }, + expect: 'InlineFragment', + }, + { + ifCondition: { token: '{' }, + expect: 'InlineFragment', + }, + ], + }, + ], + + FragmentSpread: ['FragmentName', { ofType: 'Directives', optional: true }], + FragmentDefinition: [ + { + token: 'Name', + ofValue: 'fragment', + tokenName: 'FragmentDefinitionKeyword', + }, + 'FragmentName', + 'TypeCondition', + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + FragmentName: { + token: 'Name', + butNot: { token: 'Name', ofValue: 'on' }, + definitionName: true, + }, + + TypeCondition: [ + { token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, + 'TypeName', + ], + + InlineFragment: [ + { ofType: 'TypeCondition', optional: true }, + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + + Value: { + peek: [ + { + ifCondition: { token: '$' }, + expect: 'Variable', + }, + { + ifCondition: 'IntValue', + expect: { ofType: 'IntValue', tokenName: 'NumberValue' }, + }, + { + ifCondition: 'FloatValue', + expect: { ofType: 'FloatValue', tokenName: 'NumberValue' }, + }, + { + ifCondition: 'BooleanValue', + expect: { ofType: 'BooleanValue', tokenName: 'BooleanValue' }, + }, + { + ifCondition: 'EnumValue', + expect: { ofType: 'EnumValue', tokenName: 'EnumValue' }, + }, + { + ifCondition: 'String', + expect: { ofType: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: 'BlockString', + expect: { ofType: 'BlockString', tokenName: 'StringValue' }, + }, + { + ifCondition: 'NullValue', + expect: { ofType: 'NullValue', tokenName: 'NullValue' }, + }, + { + ifCondition: { token: '[' }, + expect: 'ListValue', + }, + { + ifCondition: { token: '{' }, + expect: 'ObjectValue', + }, + ], + }, + + ConstValue: { + peek: [ + { + ifCondition: 'IntValue', + expect: { ofType: 'IntValue' }, + }, + { + ifCondition: 'FloatValue', + expect: { ofType: 'FloatValue' }, + }, + { + ifCondition: 'BooleanValue', + expect: 'BooleanValue', + }, + { + ifCondition: 'EnumValue', + expect: 'EnumValue', + }, + { + ifCondition: 'String', + expect: { ofType: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: 'BlockString', + expect: { token: 'BlockString', tokenName: 'StringValue' }, + }, + { + ifCondition: 'NullValue', + expect: 'NullValue', + }, + { + ifCondition: { token: '[' }, + expect: 'ConstListValue', + }, + { + ifCondition: { token: '{' }, + expect: 'ObjectValue', + }, + ], + }, + + IntValue: { token: 'Int' }, + + FloatValue: { token: 'Float' }, + + StringValue: { + peek: [ + { + ifCondition: { token: 'String' }, + expect: { token: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: { token: 'BlockString' }, + expect: { token: 'BlockString', tokenName: 'StringValue' }, + }, + ], + }, + + BooleanValue: { + token: 'Name', + oneOf: ['true', 'false'], + tokenName: 'BooleanValue', + }, + + NullValue: { + token: 'Name', + ofValue: 'null', + tokenName: 'NullValue', + }, + + EnumValue: { + token: 'Name', + butNot: { token: 'Name', oneOf: ['null', 'true', 'false'] }, + tokenName: 'EnumValue', + }, + + ListValue: [ + { token: '[' }, + { listOfType: 'Value', optional: true }, + { token: ']' }, + ], + + ConstListValue: [ + { token: '[' }, + { listOfType: 'ConstValue', optional: true }, + { token: ']' }, + ], + + ObjectValue: [ + { token: '{' }, + { listOfType: 'ObjectField', optional: true }, + { token: '}' }, + ], + ObjectField: [ + { token: 'Name', tokenName: 'ObjectFieldName' }, + { token: ':' }, + { ofType: 'ConstValue' }, + ], + + Variable: [ + { token: '$', tokenName: 'VariableName' }, + { token: 'Name', tokenName: 'VariableName' }, + ], + VariableDefinitions: [ + { token: '(' }, + { listOfType: 'VariableDefinition' }, + { token: ')' }, + ], + VariableDefinition: [ + 'Variable', + { token: ':' }, + 'Type', + { ofType: 'DefaultValue', optional: true }, + ], + DefaultValue: [{ token: '=' }, 'ConstValue'], + + TypeName: { token: 'Name', tokenName: 'TypeName', typeName: true }, + + Type: { + peek: [ + { + ifCondition: { token: 'Name' }, + expect: ['TypeName', { token: '!', optional: true }], + }, + { + ifCondition: { token: '[' }, + expect: 'ListType', + }, + ], + }, + ListType: [ + { token: '[' }, + { listOfType: 'Type' }, + { token: ']' }, + { token: '!', optional: true }, + ], + + Directives: { listOfType: 'Directive' }, + Directive: [ + { token: '@', tokenName: 'DirectiveName' }, + { token: 'Name', tokenName: 'DirectiveName' }, + { ofType: 'Arguments', optional: true }, + ], + + TypeSystemDefinition: [ + { ofType: 'Description', optional: true }, + { + peek: [ + { + ifCondition: { + target: 'Name', + ofValue: 'schema', + }, + expect: 'SchemaDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'scalar', + }, + expect: 'ScalarTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'type', + }, + expect: 'ObjectTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'interface', + }, + expect: 'InterfaceTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'union', + }, + expect: 'UnionTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'enum', + }, + expect: 'EnumTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'input', + }, + expect: 'InputObjectTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'directive', + }, + expect: 'DirectiveDefinition', + }, + ], + }, + ], + + TypeSystemExtension: { + peek: [ + { + ifCondition: { + target: 'Name', + ofValue: 'schema', + }, + expect: 'SchemaExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'scalar', + }, + expect: 'ScalarTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'type', + }, + expect: 'ObjectTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'interface', + }, + expect: 'InterfaceTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'union', + }, + expect: 'UnionTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'enum', + }, + expect: 'EnumTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'input', + }, + expect: 'InputObjectTypeExtension', + }, + ], + }, + + SchemaDefinition: [ + { + token: 'Name', + ofValue: 'schema', + tokenName: 'SchemaDefinitionKeyword', + }, + { ofType: 'Directives', optional: true }, + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], + RootOperationTypeDefinition: [ + 'OperationType', + { token: ':' }, + { token: 'Name', tokenName: 'OperationTypeDefinitionName' }, + ], + + SchemaExtension: [ + { token: 'Name', ofValue: 'extend' }, + { token: 'Name', ofValue: 'schema' }, + 'Name', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { + ofType: [ + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], + optional: true, + }, + ], + }, + { + ifCondition: { token: '{' }, + expect: [ + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], + }, + ], + }, + ], + + Description: 'StringValue', + + ScalarTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'scalar', + tokenName: 'ScalarDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + ], + + ScalarTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'scalar', + tokenName: 'ScalarDefinitionKeyword', + }, + 'TypeName', + 'Directives', + ], + + ObjectTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'type', + tokenName: 'TypeDefinitionKeyword', + }, + 'TypeName', + { ofType: 'ImplementsInterfaces', optional: true }, + { ofType: 'Directives', optional: true }, + { ofType: 'FieldsDefinition', optional: true }, + ], + ImplementsInterfaces: [ + { + token: 'Name', + ofValue: 'implements', + tokenName: 'ImplementsKeyword', + }, + { token: '&', optional: true }, + 'TypeName', + { + listOfType: 'ImplementsAdditionalInterfaceName', + optional: true, + }, + ], + ImplementsAdditionalInterfaceName: [{ token: '&' }, 'TypeName'], + FieldsDefinition: [ + { token: '{' }, + { listOfType: 'FieldDefinition' }, + { token: '}' }, + ], + FieldDefinition: [ + { ofType: 'Description', optional: true }, + { token: 'Name', tokenName: 'AliasName', definitionName: true }, + { ofType: 'ArgumentsDefinition', optional: true }, + { token: ':' }, + 'Type', + { ofType: 'Directives', optional: true }, + ], + + ArgumentsDefinition: [ + { token: '(' }, + { listOfType: 'InputValueDefinition' }, + { token: ')' }, + ], + InputValueDefinition: [ + { ofType: 'Description', optional: true }, + { token: 'Name', tokenName: 'ArgumentName' }, + { token: ':' }, + 'Type', + { ofType: 'DefaultValue', optional: true }, + { ofType: 'Directives', optional: true }, + ], + + ObjectTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'type', + tokenName: 'TypeDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: 'Name', ofValue: 'interface' }, + expect: [ + 'ImplementsInterfaces', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + optional: true, + }, + ], + }, + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + }, + ], + + InterfaceTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'interface', + tokenName: 'InterfaceDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'FieldsDefinition', optional: true }, + ], + + InterfaceTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'interface', + tokenName: 'InterfaceDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + }, + ], + + UnionTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'union', + tokenName: 'UnionDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'UnionMemberTypes', optional: true }, + ], + + UnionMemberTypes: [ + { token: '=' }, + { token: '|', optional: true }, + 'Name', + { + listOfType: 'UnionMemberAdditionalTypeName', + optional: true, + }, + ], + + UnionMemberAdditionalTypeName: [{ token: '|' }, 'TypeName'], + + UnionTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'union', + tokenName: 'UnionDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'UnionMemberTypes', optional: true }, + ], + }, + { + ifCondition: { token: '=' }, + expect: 'UnionMemberTypes', + }, + ], + }, + ], + + EnumTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'enum', + tokenName: 'EnumDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'EnumValuesDefinition', optional: true }, + ], + EnumValuesDefinition: [ + { token: '{' }, + { listOfType: 'EnumValueDefinition' }, + { token: '}' }, + ], + EnumValueDefinition: [ + { ofType: 'Description', optional: true }, + 'EnumValue', + { ofType: 'Directives', optional: true }, + ], + + EnumTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'enum', + tokenName: 'EnumDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'EnumValuesDefinition', optional: true }, + ], + }, + { + ifCondition: { token: '{' }, + expect: 'EnumValuesDefinition', + }, + ], + }, + ], + + InputObjectTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'input', + tokenName: 'InputDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'InputFieldsDefinition', optional: true }, + ], + InputFieldsDefinition: [ + { token: '{' }, + { listOfType: 'InputValueDefinition' }, + { token: '}' }, + ], + + InputObjectTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'input', + tokenName: 'InputDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { ofType: 'InputFieldsDefinition', optional: true }, + ], + }, + { + ifCondition: { token: '{' }, + expect: 'InputFieldsDefinition', + }, + ], + }, + ], + + DirectiveDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'directive', + tokenName: 'DirectiveDefinitionKeyword', + }, + { token: '@', tokenName: 'DirectiveName' }, + { token: 'Name', tokenName: 'DirectiveName' }, + { ofType: 'ArgumentsDefinition', optional: true }, + { token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, + 'DirectiveLocations', + ], + DirectiveLocations: [ + { token: '|', optional: true }, + 'DirectiveLocation', + { + listOfType: 'DirectiveLocationAdditionalName', + optional: true, + }, + ], + DirectiveLocationAdditionalName: [{ token: '|' }, 'DirectiveLocation'], + DirectiveLocation: { + peek: [ + { + ifCondition: 'ExecutableDirectiveLocation', + expect: 'ExecutableDirectiveLocation', + }, + { + ifCondition: 'TypeSystemDirectiveLocation', + expect: 'TypeSystemDirectiveLocation', + }, + ], + }, + ExecutableDirectiveLocation: { + token: 'Name', + oneOf: [ + 'QUERY', + 'MUTATION', + 'SUBSCRIPTION', + 'FIELD', + 'FRAGMENT_DEFINITION', + 'FRAGMENT_SPREAD', + 'INLINE_FRAGMENT', + ], + tokenName: 'EnumValue', + }, + TypeSystemDirectiveLocation: { + token: 'Name', + oneOf: [ + 'SCHEMA', + 'SCALAR', + 'OBJECT', + 'FIELD_DEFINITION', + 'ARGUMENT_DEFINITION', + 'INTERFACE', + 'UNION', + 'ENUM', + 'ENUM_VALUE', + 'INPUT_OBJECT', + 'INPUT_FIELD_DEFINITION', + ], + tokenName: 'EnumValue', + }, +}; + +export default grammar; diff --git a/src/language/experimentalOnlineParser/grammar.js b/src/language/experimentalOnlineParser/grammar.js new file mode 100644 index 0000000000..a9200daf99 --- /dev/null +++ b/src/language/experimentalOnlineParser/grammar.js @@ -0,0 +1,888 @@ +export type GraphQLGrammarType = { + [string]: GraphQLGrammarRule, +}; +export type GraphQLGrammarRuleName = string; +export type GraphQLGrammarRuleConstraint = + | GraphQLGrammarTokenConstraint + | GraphQLGrammarOfTypeConstraint + | GraphQLGrammarListOfTypeConstraint + | GraphQLGrammarPeekConstraint; +export type GraphQLGrammarConstraintsSet = Array; +export type GraphQLGrammarRule = GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint | GraphQLGrammarConstraintsSet; +export interface GraphQLGrammarBaseRuleConstraint { + butNot?: ?GraphQLGrammarTokenConstraint | ?Array; + optional?: boolean; + eatNextOnFail?: boolean; +} +export interface GraphQLGrammarTokenConstraint extends GraphQLGrammarBaseRuleConstraint { + token: + | '!' + | '$' + | '&' + | '(' + | ')' + | '...' + | ':' + | '=' + | '@' + | '[' + | ']' + | '{' + | '}' + | '|' + | 'Name' + | 'Int' + | 'Float' + | 'String' + | 'BlockString' + | 'Comment'; + ofValue?: ?string; + oneOf?: ?Array; + tokenName?: string; + definitionName?: boolean; + typeName?: boolean; +} +export interface GraphQLGrammarOfTypeConstraint extends GraphQLGrammarBaseRuleConstraint { + ofType: GraphQLGrammarRule; + tokenName?: string; +} +export interface GraphQLGrammarListOfTypeConstraint extends GraphQLGrammarBaseRuleConstraint { + listOfType: GraphQLGrammarRuleName; +} +export interface GraphQLGrammarPeekConstraint extends GraphQLGrammarBaseRuleConstraint { + peek: Array; +} +export interface GraphQLGrammarPeekConstraintCondition { + ifCondition: GraphQLGrammarTokenConstraint; + expect: GraphQLGrammarRule; + end?: boolean; +} + +const grammar: GraphQLGrammarType = { + Name: ({ token: 'Name' }: GraphQLGrammarTokenConstraint), + String: ({ token: 'String' }: GraphQLGrammarTokenConstraint), + BlockString: ({ token: 'BlockString' }: GraphQLGrammarTokenConstraint), + + Document: { listOfType: 'Definition' }, + Definition: { + peek: [ + { + ifCondition: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + }, + expect: 'OperationDefinition', + }, + { + ifCondition: { token: 'Name', ofValue: 'fragment' }, + expect: 'FragmentDefinition', + }, + { + ifCondition: { + token: 'Name', + oneOf: ['schema', 'scalar', 'type', 'interface', 'union', 'enum', 'input', 'directive'], + }, + expect: 'TypeSystemDefinition', + }, + { + ifCondition: { token: 'Name', ofValue: 'extend' }, + expect: 'TypeSystemExtension', + }, + { + ifCondition: { token: '{' }, + expect: 'OperationDefinition', + }, + { + ifCondition: 'String', + expect: 'TypeSystemDefinition', + }, + { + ifCondition: 'BlockString', + expect: 'TypeSystemDefinition', + }, + ], + }, + + OperationDefinition: ({ + peek: [ + { + ifCondition: { token: '{' }, + expect: 'SelectionSet', + }, + { + ifCondition: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + }, + expect: [ + 'OperationType', + { + token: 'Name', + optional: true, + tokenName: 'OperationName', + definitionName: true, + }, + { ofType: 'VariableDefinitions', optional: true }, + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + }, + ], + }: GraphQLGrammarPeekConstraint), + OperationType: { + ofType: 'OperationTypeName', + }, + OperationTypeName: { + token: 'Name', + oneOf: ['query', 'mutation', 'subscription'], + definitionName: true, + }, + SelectionSet: [{ token: '{' }, { listOfType: 'Selection' }, { token: '}' }], + Selection: { + peek: [ + { + ifCondition: { token: '...' }, + expect: 'Fragment', + }, + { + ifCondition: { token: 'Name' }, + expect: 'Field', + }, + ], + }, + + Field: [ + { + ofType: 'Alias', + optional: true, + eatNextOnFail: true, + definitionName: true, + }, + { token: 'Name', tokenName: 'FieldName', definitionName: true }, + { ofType: 'Arguments', optional: true }, + { ofType: 'Directives', optional: true }, + { ofType: 'SelectionSet', optional: true }, + ], + + Arguments: [{ token: '(' }, { listOfType: 'Argument' }, { token: ')' }], + Argument: [{ token: 'Name', tokenName: 'ArgumentName', definitionName: true }, { token: ':' }, 'Value'], + + Alias: [{ token: 'Name', tokenName: 'AliasName', definitionName: true }, { token: ':' }], + + Fragment: [ + { token: '...' }, + { + peek: [ + { + ifCondition: 'FragmentName', + expect: 'FragmentSpread', + }, + { + ifCondition: { token: 'Name', ofValue: 'on' }, + expect: 'InlineFragment', + }, + { + ifCondition: { token: '@' }, + expect: 'InlineFragment', + }, + { + ifCondition: { token: '{' }, + expect: 'InlineFragment', + }, + ], + }, + ], + + FragmentSpread: ['FragmentName', { ofType: 'Directives', optional: true }], + FragmentDefinition: [ + { + token: 'Name', + ofValue: 'fragment', + tokenName: 'FragmentDefinitionKeyword', + }, + 'FragmentName', + 'TypeCondition', + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + FragmentName: { + token: 'Name', + butNot: { token: 'Name', ofValue: 'on' }, + definitionName: true, + }, + + TypeCondition: [{ token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, 'TypeName'], + + InlineFragment: [ + { ofType: 'TypeCondition', optional: true }, + { ofType: 'Directives', optional: true }, + 'SelectionSet', + ], + + Value: { + peek: [ + { + ifCondition: { token: '$' }, + expect: 'Variable', + }, + { + ifCondition: 'IntValue', + expect: { ofType: 'IntValue', tokenName: 'NumberValue' }, + }, + { + ifCondition: 'FloatValue', + expect: { ofType: 'FloatValue', tokenName: 'NumberValue' }, + }, + { + ifCondition: 'BooleanValue', + expect: { ofType: 'BooleanValue', tokenName: 'BooleanValue' }, + }, + { + ifCondition: 'EnumValue', + expect: { ofType: 'EnumValue', tokenName: 'EnumValue' }, + }, + { + ifCondition: 'String', + expect: { ofType: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: 'BlockString', + expect: { ofType: 'BlockString', tokenName: 'StringValue' }, + }, + { + ifCondition: 'NullValue', + expect: { ofType: 'NullValue', tokenName: 'NullValue' }, + }, + { + ifCondition: { token: '[' }, + expect: 'ListValue', + }, + { + ifCondition: { token: '{' }, + expect: 'ObjectValue', + }, + ], + }, + + ConstValue: { + peek: [ + { + ifCondition: 'IntValue', + expect: { ofType: 'IntValue' }, + }, + { + ifCondition: 'FloatValue', + expect: { ofType: 'FloatValue' }, + }, + { + ifCondition: 'BooleanValue', + expect: 'BooleanValue', + }, + { + ifCondition: 'EnumValue', + expect: 'EnumValue', + }, + { + ifCondition: 'String', + expect: { ofType: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: 'BlockString', + expect: { token: 'BlockString', tokenName: 'StringValue' }, + }, + { + ifCondition: 'NullValue', + expect: 'NullValue', + }, + { + ifCondition: { token: '[' }, + expect: 'ConstListValue', + }, + { + ifCondition: { token: '{' }, + expect: 'ObjectValue', + }, + ], + }, + + IntValue: { token: 'Int' }, + + FloatValue: { token: 'Float' }, + + StringValue: { + peek: [ + { + ifCondition: { token: 'String' }, + expect: { token: 'String', tokenName: 'StringValue' }, + }, + { + ifCondition: { token: 'BlockString' }, + expect: { token: 'BlockString', tokenName: 'StringValue' }, + }, + ], + }, + + BooleanValue: { + token: 'Name', + oneOf: ['true', 'false'], + tokenName: 'BooleanValue', + }, + + NullValue: { + token: 'Name', + ofValue: 'null', + tokenName: 'NullValue', + }, + + EnumValue: { + token: 'Name', + butNot: { token: 'Name', oneOf: ['null', 'true', 'false'] }, + tokenName: 'EnumValue', + }, + + ListValue: [{ token: '[' }, { listOfType: 'Value', optional: true }, { token: ']' }], + + ConstListValue: [{ token: '[' }, { listOfType: 'ConstValue', optional: true }, { token: ']' }], + + ObjectValue: [{ token: '{' }, { listOfType: 'ObjectField', optional: true }, { token: '}' }], + ObjectField: [{ token: 'Name', tokenName: 'ObjectFieldName' }, { token: ':' }, { ofType: 'ConstValue' }], + + Variable: [ + { token: '$', tokenName: 'VariableName' }, + { token: 'Name', tokenName: 'VariableName' }, + ], + VariableDefinitions: [{ token: '(' }, { listOfType: 'VariableDefinition' }, { token: ')' }], + VariableDefinition: ['Variable', { token: ':' }, 'Type', { ofType: 'DefaultValue', optional: true }], + DefaultValue: [{ token: '=' }, 'ConstValue'], + + TypeName: { token: 'Name', tokenName: 'TypeName', typeName: true }, + + Type: { + peek: [ + { + ifCondition: { token: 'Name' }, + expect: ['TypeName', { token: '!', optional: true }], + }, + { + ifCondition: { token: '[' }, + expect: 'ListType', + }, + ], + }, + ListType: [{ token: '[' }, { listOfType: 'Type' }, { token: ']' }, { token: '!', optional: true }], + + Directives: { listOfType: 'Directive' }, + Directive: [ + { token: '@', tokenName: 'DirectiveName' }, + { token: 'Name', tokenName: 'DirectiveName' }, + { ofType: 'Arguments', optional: true }, + ], + + TypeSystemDefinition: [ + { ofType: 'Description', optional: true }, + { + peek: [ + { + ifCondition: { + target: 'Name', + ofValue: 'schema', + }, + expect: 'SchemaDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'scalar', + }, + expect: 'ScalarTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'type', + }, + expect: 'ObjectTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'interface', + }, + expect: 'InterfaceTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'union', + }, + expect: 'UnionTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'enum', + }, + expect: 'EnumTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'input', + }, + expect: 'InputObjectTypeDefinition', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'directive', + }, + expect: 'DirectiveDefinition', + }, + ], + }, + ], + + TypeSystemExtension: { + peek: [ + { + ifCondition: { + target: 'Name', + ofValue: 'schema', + }, + expect: 'SchemaExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'scalar', + }, + expect: 'ScalarTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'type', + }, + expect: 'ObjectTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'interface', + }, + expect: 'InterfaceTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'union', + }, + expect: 'UnionTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'enum', + }, + expect: 'EnumTypeExtension', + }, + { + ifCondition: { + target: 'Name', + ofValue: 'input', + }, + expect: 'InputObjectTypeExtension', + }, + ], + }, + + SchemaDefinition: [ + { + token: 'Name', + ofValue: 'schema', + tokenName: 'SchemaDefinitionKeyword', + }, + { ofType: 'Directives', optional: true }, + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], + RootOperationTypeDefinition: [ + 'OperationType', + { token: ':' }, + { token: 'Name', tokenName: 'OperationTypeDefinitionName' }, + ], + + SchemaExtension: [ + { token: 'Name', ofValue: 'extend' }, + { token: 'Name', ofValue: 'schema' }, + 'Name', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: [ + 'Directives', + { + ofType: [{ token: '{' }, { listOfType: 'RootOperationTypeDefinition' }, { token: '}' }], + optional: true, + }, + ], + }, + { + ifCondition: { token: '{' }, + expect: [{ token: '{' }, { listOfType: 'RootOperationTypeDefinition' }, { token: '}' }], + }, + ], + }, + ], + + Description: 'StringValue', + + ScalarTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'scalar', + tokenName: 'ScalarDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + ], + + ScalarTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'scalar', + tokenName: 'ScalarDefinitionKeyword', + }, + 'TypeName', + 'Directives', + ], + + ObjectTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'type', + tokenName: 'TypeDefinitionKeyword', + }, + 'TypeName', + { ofType: 'ImplementsInterfaces', optional: true }, + { ofType: 'Directives', optional: true }, + { ofType: 'FieldsDefinition', optional: true }, + ], + ImplementsInterfaces: [ + { + token: 'Name', + ofValue: 'implements', + tokenName: 'ImplementsKeyword', + }, + { token: '&', optional: true }, + 'TypeName', + { + listOfType: 'ImplementsAdditionalInterfaceName', + optional: true, + }, + ], + ImplementsAdditionalInterfaceName: [{ token: '&' }, 'TypeName'], + FieldsDefinition: [{ token: '{' }, { listOfType: 'FieldDefinition' }, { token: '}' }], + FieldDefinition: [ + { ofType: 'Description', optional: true }, + { token: 'Name', tokenName: 'AliasName', definitionName: true }, + { ofType: 'ArgumentsDefinition', optional: true }, + { token: ':' }, + 'Type', + { ofType: 'Directives', optional: true }, + ], + + ArgumentsDefinition: [{ token: '(' }, { listOfType: 'InputValueDefinition' }, { token: ')' }], + InputValueDefinition: [ + { ofType: 'Description', optional: true }, + { token: 'Name', tokenName: 'ArgumentName' }, + { token: ':' }, + 'Type', + { ofType: 'DefaultValue', optional: true }, + { ofType: 'Directives', optional: true }, + ], + + ObjectTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'type', + tokenName: 'TypeDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: 'Name', ofValue: 'interface' }, + expect: [ + 'ImplementsInterfaces', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + optional: true, + }, + ], + }, + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + }, + ], + + InterfaceTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'interface', + tokenName: 'InterfaceDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'FieldsDefinition', optional: true }, + ], + + InterfaceTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'interface', + tokenName: 'InterfaceDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + }, + { + ifCondition: { token: '{' }, + expect: 'FieldsDefinition', + }, + ], + }, + ], + + UnionTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'union', + tokenName: 'UnionDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'UnionMemberTypes', optional: true }, + ], + + UnionMemberTypes: [ + { token: '=' }, + { token: '|', optional: true }, + 'Name', + { + listOfType: 'UnionMemberAdditionalTypeName', + optional: true, + }, + ], + + UnionMemberAdditionalTypeName: [{ token: '|' }, 'TypeName'], + + UnionTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'union', + tokenName: 'UnionDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'UnionMemberTypes', optional: true }], + }, + { + ifCondition: { token: '=' }, + expect: 'UnionMemberTypes', + }, + ], + }, + ], + + EnumTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'enum', + tokenName: 'EnumDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'EnumValuesDefinition', optional: true }, + ], + EnumValuesDefinition: [{ token: '{' }, { listOfType: 'EnumValueDefinition' }, { token: '}' }], + EnumValueDefinition: [ + { ofType: 'Description', optional: true }, + 'EnumValue', + { ofType: 'Directives', optional: true }, + ], + + EnumTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'enum', + tokenName: 'EnumDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'EnumValuesDefinition', optional: true }], + }, + { + ifCondition: { token: '{' }, + expect: 'EnumValuesDefinition', + }, + ], + }, + ], + + InputObjectTypeDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'input', + tokenName: 'InputDefinitionKeyword', + }, + 'TypeName', + { ofType: 'Directives', optional: true }, + { ofType: 'InputFieldsDefinition', optional: true }, + ], + InputFieldsDefinition: [{ token: '{' }, { listOfType: 'InputValueDefinition' }, { token: '}' }], + + InputObjectTypeExtension: [ + { + token: 'Name', + ofValue: 'extend', + tokenName: 'ExtendDefinitionKeyword', + }, + { + token: 'Name', + ofValue: 'input', + tokenName: 'InputDefinitionKeyword', + }, + 'TypeName', + { + peek: [ + { + ifCondition: { token: '@' }, + expect: ['Directives', { ofType: 'InputFieldsDefinition', optional: true }], + }, + { + ifCondition: { token: '{' }, + expect: 'InputFieldsDefinition', + }, + ], + }, + ], + + DirectiveDefinition: [ + { ofType: 'Description', optional: true }, + { + token: 'Name', + ofValue: 'directive', + tokenName: 'DirectiveDefinitionKeyword', + }, + { token: '@', tokenName: 'DirectiveName' }, + { token: 'Name', tokenName: 'DirectiveName' }, + { ofType: 'ArgumentsDefinition', optional: true }, + { token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, + 'DirectiveLocations', + ], + DirectiveLocations: [ + { token: '|', optional: true }, + 'DirectiveLocation', + { + listOfType: 'DirectiveLocationAdditionalName', + optional: true, + }, + ], + DirectiveLocationAdditionalName: [{ token: '|' }, 'DirectiveLocation'], + DirectiveLocation: { + peek: [ + { + ifCondition: 'ExecutableDirectiveLocation', + expect: 'ExecutableDirectiveLocation', + }, + { + ifCondition: 'TypeSystemDirectiveLocation', + expect: 'TypeSystemDirectiveLocation', + }, + ], + }, + ExecutableDirectiveLocation: { + token: 'Name', + oneOf: ['QUERY', 'MUTATION', 'SUBSCRIPTION', 'FIELD', 'FRAGMENT_DEFINITION', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'], + tokenName: 'EnumValue', + }, + TypeSystemDirectiveLocation: ({ + token: 'Name', + oneOf: [ + 'SCHEMA', + 'SCALAR', + 'OBJECT', + 'FIELD_DEFINITION', + 'ARGUMENT_DEFINITION', + 'INTERFACE', + 'UNION', + 'ENUM', + 'ENUM_VALUE', + 'INPUT_OBJECT', + 'INPUT_FIELD_DEFINITION', + ], + tokenName: 'EnumValue', + }: GraphQLGrammarTokenConstraint), +}; + +export default grammar; diff --git a/src/language/experimentalOnlineParser/grammarTypes.d.ts b/src/language/experimentalOnlineParser/grammarTypes.d.ts deleted file mode 100644 index 9766dc2dbb..0000000000 --- a/src/language/experimentalOnlineParser/grammarTypes.d.ts +++ /dev/null @@ -1,78 +0,0 @@ -export interface GraphQLGrammarType { - [name: string]: GraphQLGrammarRule; -} - -export type GraphQLGrammarRule = - | GraphQLGrammarRuleName - | GraphQLGrammarRuleConstraint - | GraphQLGrammarConstraintsSet; - -export type GraphQLGrammarRuleName = string; - -export type GraphQLGrammarRuleConstraint = - | GraphQLGrammarTokenConstraint - | GraphQLGrammarOfTypeConstraint - | GraphQLGrammarListOfTypeConstraint - | GraphQLGrammarPeekConstraint; - -export type GraphQLGrammarConstraintsSet = Array< - GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint ->; - -export interface GraphQLGrammarBaseRuleConstraint { - butNot?: GraphQLGrammarTokenConstraint | Array; - optional?: boolean; - eatNextOnFail?: boolean; -} - -export interface GraphQLGrammarTokenConstraint - extends GraphQLGrammarBaseRuleConstraint { - token: - | '!' - | '$' - | '&' - | '(' - | ')' - | '...' - | ':' - | '=' - | '@' - | '[' - | ']' - | '{' - | '}' - | '|' - | 'Name' - | 'Int' - | 'Float' - | 'String' - | 'BlockString' - | 'Comment'; - ofValue?: string; - oneOf?: Array; - tokenName?: string; - definitionName?: boolean; - typeName?: boolean; -} - -export interface GraphQLGrammarOfTypeConstraint - extends GraphQLGrammarBaseRuleConstraint { - ofType: GraphQLGrammarRule; - tokenName?: string; -} - -export interface GraphQLGrammarListOfTypeConstraint - extends GraphQLGrammarBaseRuleConstraint { - listOfType: GraphQLGrammarRuleName; -} - -export interface GraphQLGrammarPeekConstraint - extends GraphQLGrammarBaseRuleConstraint { - peek: Array; -} - -export interface GraphQLGrammarPeekConstraintCondition { - ifCondition: GraphQLGrammarTokenConstraint; - expect: GraphQLGrammarRule; - end?: boolean; -} diff --git a/src/language/experimentalOnlineParser/grammarTypes.js b/src/language/experimentalOnlineParser/grammarTypes.js deleted file mode 100644 index a1b12150c4..0000000000 --- a/src/language/experimentalOnlineParser/grammarTypes.js +++ /dev/null @@ -1,70 +0,0 @@ -export interface GraphQLGrammarType { - [name: string]: GraphQLGrammarRule; -} -export type GraphQLGrammarRuleName = string; -export type GraphQLGrammarRuleConstraint = - | GraphQLGrammarTokenConstraint - | GraphQLGrammarOfTypeConstraint - | GraphQLGrammarListOfTypeConstraint - | GraphQLGrammarPeekConstraint; -export type GraphQLGrammarConstraintsSet = Array< - GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint, ->; -export type GraphQLGrammarRule = - | GraphQLGrammarRuleName - | GraphQLGrammarRuleConstraint - | GraphQLGrammarConstraintsSet; -export interface GraphQLGrammarBaseRuleConstraint { - butNot?: - | ?GraphQLGrammarTokenConstraint - | ?Array; - optional?: boolean; - eatNextOnFail?: boolean; -} -export interface GraphQLGrammarTokenConstraint - extends GraphQLGrammarBaseRuleConstraint { - token: - | '!' - | '$' - | '&' - | '(' - | ')' - | '...' - | ':' - | '=' - | '@' - | '[' - | ']' - | '{' - | '}' - | '|' - | 'Name' - | 'Int' - | 'Float' - | 'String' - | 'BlockString' - | 'Comment'; - ofValue?: ?string; - oneOf?: ?Array; - tokenName?: string; - definitionName?: boolean; - typeName?: boolean; -} -export interface GraphQLGrammarOfTypeConstraint - extends GraphQLGrammarBaseRuleConstraint { - ofType: GraphQLGrammarRule; - tokenName?: string; -} -export interface GraphQLGrammarListOfTypeConstraint - extends GraphQLGrammarBaseRuleConstraint { - listOfType: GraphQLGrammarRuleName; -} -export interface GraphQLGrammarPeekConstraint - extends GraphQLGrammarBaseRuleConstraint { - peek: Array; -} -export interface GraphQLGrammarPeekConstraintCondition { - ifCondition: GraphQLGrammarTokenConstraint; - expect: GraphQLGrammarRule; - end?: boolean; -} diff --git a/src/language/experimentalOnlineParser/onlineParser.d.ts b/src/language/experimentalOnlineParser/onlineParser.d.ts index 798f011767..9570b9e589 100644 --- a/src/language/experimentalOnlineParser/onlineParser.d.ts +++ b/src/language/experimentalOnlineParser/onlineParser.d.ts @@ -6,7 +6,7 @@ import { GraphQLGrammarListOfTypeConstraint, GraphQLGrammarPeekConstraint, GraphQLGrammarConstraintsSet, -} from './grammarTypes'; +} from './grammar'; interface BaseOnlineParserRule { kind: string; diff --git a/src/language/experimentalOnlineParser/onlineParser.js b/src/language/experimentalOnlineParser/onlineParser.js index 1ee9f14b83..6298cbb045 100644 --- a/src/language/experimentalOnlineParser/onlineParser.js +++ b/src/language/experimentalOnlineParser/onlineParser.js @@ -1,7 +1,7 @@ import { Lexer } from '../lexer'; import { Source } from '../source'; -import GraphQLGrammar from './rules'; +import GraphQLGrammar from './grammar'; import type { GraphQLGrammarRule, GraphQLGrammarRuleName, @@ -11,7 +11,7 @@ import type { GraphQLGrammarListOfTypeConstraint, GraphQLGrammarPeekConstraint, GraphQLGrammarConstraintsSet, -} from './grammarTypes'; +} from './grammar'; export const TokenKind = { NAME: 'Name', diff --git a/src/language/experimentalOnlineParser/rules.json b/src/language/experimentalOnlineParser/rules.json deleted file mode 100644 index 3682caea3a..0000000000 --- a/src/language/experimentalOnlineParser/rules.json +++ /dev/null @@ -1,936 +0,0 @@ -{ - "Name": { "token": "Name" }, - "String": { "token": "String" }, - "BlockString": { "token": "BlockString" }, - - "Document": { "listOfType": "Definition" }, - "Definition": { - "peek": [ - { - "ifCondition": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"] - }, - "expect": "OperationDefinition" - }, - { - "ifCondition": { "token": "Name", "ofValue": "fragment" }, - "expect": "FragmentDefinition" - }, - { - "ifCondition": { - "token": "Name", - "oneOf": [ - "schema", - "scalar", - "type", - "interface", - "union", - "enum", - "input", - "directive" - ] - }, - "expect": "TypeSystemDefinition" - }, - { - "ifCondition": { "token": "Name", "ofValue": "extend" }, - "expect": "TypeSystemExtension" - }, - { - "ifCondition": { "token": "{" }, - "expect": "OperationDefinition" - }, - { - "ifCondition": "String", - "expect": "TypeSystemDefinition" - }, - { - "ifCondition": "BlockString", - "expect": "TypeSystemDefinition" - } - ] - }, - - "OperationDefinition": { - "peek": [ - { - "ifCondition": { "token": "{" }, - "expect": "SelectionSet" - }, - { - "ifCondition": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"] - }, - "expect": [ - "OperationType", - { - "token": "Name", - "optional": true, - "tokenName": "OperationName", - "definitionName": true - }, - { "ofType": "VariableDefinitions", "optional": true }, - { "ofType": "Directives", "optional": true }, - "SelectionSet" - ] - } - ] - }, - "OperationType": { - "ofType": "OperationTypeName" - }, - "OperationTypeName": { - "token": "Name", - "oneOf": ["query", "mutation", "subscription"], - "definitionName": true - }, - "SelectionSet": [ - { "token": "{" }, - { "listOfType": "Selection" }, - { "token": "}" } - ], - "Selection": { - "peek": [ - { - "ifCondition": { "token": "..." }, - "expect": "Fragment" - }, - { - "ifCondition": { "token": "Name" }, - "expect": "Field" - } - ] - }, - - "Field": [ - { - "ofType": "Alias", - "optional": true, - "eatNextOnFail": true, - "definitionName": true - }, - { "token": "Name", "tokenName": "FieldName", "definitionName": true }, - { "ofType": "Arguments", "optional": true }, - { "ofType": "Directives", "optional": true }, - { "ofType": "SelectionSet", "optional": true } - ], - - "Arguments": [ - { "token": "(" }, - { "listOfType": "Argument" }, - { "token": ")" } - ], - "Argument": [ - { "token": "Name", "tokenName": "ArgumentName", "definitionName": true }, - { "token": ":" }, - "Value" - ], - - "Alias": [ - { "token": "Name", "tokenName": "AliasName", "definitionName": true }, - { "token": ":" } - ], - - "Fragment": [ - { "token": "..." }, - { - "peek": [ - { - "ifCondition": "FragmentName", - "expect": "FragmentSpread" - }, - { - "ifCondition": { "token": "Name", "ofValue": "on" }, - "expect": "InlineFragment" - }, - { - "ifCondition": { "token": "@" }, - "expect": "InlineFragment" - }, - { - "ifCondition": { "token": "{" }, - "expect": "InlineFragment" - } - ] - } - ], - - "FragmentSpread": [ - "FragmentName", - { "ofType": "Directives", "optional": true } - ], - "FragmentDefinition": [ - { - "token": "Name", - "ofValue": "fragment", - "tokenName": "FragmentDefinitionKeyword" - }, - "FragmentName", - "TypeCondition", - { "ofType": "Directives", "optional": true }, - "SelectionSet" - ], - "FragmentName": { - "token": "Name", - "butNot": { "token": "Name", "ofValue": "on" }, - "definitionName": true - }, - - "TypeCondition": [ - { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, - "TypeName" - ], - - "InlineFragment": [ - { "ofType": "TypeCondition", "optional": true }, - { "ofType": "Directives", "optional": true }, - "SelectionSet" - ], - - "Value": { - "peek": [ - { - "ifCondition": { "token": "$" }, - "expect": "Variable" - }, - { - "ifCondition": "IntValue", - "expect": { "ofType": "IntValue", "tokenName": "NumberValue" } - }, - { - "ifCondition": "FloatValue", - "expect": { "ofType": "FloatValue", "tokenName": "NumberValue" } - }, - { - "ifCondition": "BooleanValue", - "expect": { "ofType": "BooleanValue", "tokenName": "BooleanValue" } - }, - { - "ifCondition": "EnumValue", - "expect": { "ofType": "EnumValue", "tokenName": "EnumValue" } - }, - { - "ifCondition": "String", - "expect": { "ofType": "String", "tokenName": "StringValue" } - }, - { - "ifCondition": "BlockString", - "expect": { "ofType": "BlockString", "tokenName": "StringValue" } - }, - { - "ifCondition": "NullValue", - "expect": { "ofType": "NullValue", "tokenName": "NullValue" } - }, - { - "ifCondition": { "token": "[" }, - "expect": "ListValue" - }, - { - "ifCondition": { "token": "{" }, - "expect": "ObjectValue" - } - ] - }, - - "ConstValue": { - "peek": [ - { - "ifCondition": "IntValue", - "expect": { "ofType": "IntValue" } - }, - { - "ifCondition": "FloatValue", - "expect": { "ofType": "FloatValue" } - }, - { - "ifCondition": "BooleanValue", - "expect": "BooleanValue" - }, - { - "ifCondition": "EnumValue", - "expect": "EnumValue" - }, - { - "ifCondition": "String", - "expect": { "ofType": "String", "tokenName": "StringValue" } - }, - { - "ifCondition": "BlockString", - "expect": { "token": "BlockString", "tokenName": "StringValue" } - }, - { - "ifCondition": "NullValue", - "expect": "NullValue" - }, - { - "ifCondition": { "token": "[" }, - "expect": "ConstListValue" - }, - { - "ifCondition": { "token": "{" }, - "expect": "ObjectValue" - } - ] - }, - - "IntValue": { "token": "Int" }, - - "FloatValue": { "token": "Float" }, - - "StringValue": { - "peek": [ - { - "ifCondition": { "token": "String" }, - "expect": { "token": "String", "tokenName": "StringValue" } - }, - { - "ifCondition": { "token": "BlockString" }, - "expect": { "token": "BlockString", "tokenName": "StringValue" } - } - ] - }, - - "BooleanValue": { - "token": "Name", - "oneOf": ["true", "false"], - "tokenName": "BooleanValue" - }, - - "NullValue": { - "token": "Name", - "ofValue": "null", - "tokenName": "NullValue" - }, - - "EnumValue": { - "token": "Name", - "butNot": { "token": "Name", "oneOf": ["null", "true", "false"] }, - "tokenName": "EnumValue" - }, - - "ListValue": [ - { "token": "[" }, - { "listOfType": "Value", "optional": true }, - { "token": "]" } - ], - - "ConstListValue": [ - { "token": "[" }, - { "listOfType": "ConstValue", "optional": true }, - { "token": "]" } - ], - - "ObjectValue": [ - { "token": "{" }, - { "listOfType": "ObjectField", "optional": true }, - { "token": "}" } - ], - "ObjectField": [ - { "token": "Name", "tokenName": "ObjectFieldName" }, - { "token": ":" }, - { "ofType": "ConstValue" } - ], - - "Variable": [ - { "token": "$", "tokenName": "VariableName" }, - { "token": "Name", "tokenName": "VariableName" } - ], - "VariableDefinitions": [ - { "token": "(" }, - { "listOfType": "VariableDefinition" }, - { "token": ")" } - ], - "VariableDefinition": [ - "Variable", - { "token": ":" }, - "Type", - { "ofType": "DefaultValue", "optional": true } - ], - "DefaultValue": [{ "token": "=" }, "ConstValue"], - - "TypeName": { "token": "Name", "tokenName": "TypeName", "typeName": true }, - - "Type": { - "peek": [ - { - "ifCondition": { "token": "Name" }, - "expect": ["TypeName", { "token": "!", "optional": true }] - }, - { - "ifCondition": { "token": "[" }, - "expect": "ListType" - } - ] - }, - "ListType": [ - { "token": "[" }, - { "listOfType": "Type" }, - { "token": "]" }, - { "token": "!", "optional": true } - ], - - "Directives": { "listOfType": "Directive" }, - "Directive": [ - { "token": "@", "tokenName": "DirectiveName" }, - { "token": "Name", "tokenName": "DirectiveName" }, - { "ofType": "Arguments", "optional": true } - ], - - "TypeSystemDefinition": [ - { "ofType": "Description", "optional": true }, - { - "peek": [ - { - "ifCondition": { - "target": "Name", - "ofValue": "schema" - }, - "expect": "SchemaDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "scalar" - }, - "expect": "ScalarTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "type" - }, - "expect": "ObjectTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "interface" - }, - "expect": "InterfaceTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "union" - }, - "expect": "UnionTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "enum" - }, - "expect": "EnumTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "input" - }, - "expect": "InputObjectTypeDefinition" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "directive" - }, - "expect": "DirectiveDefinition" - } - ] - } - ], - - "TypeSystemExtension": { - "peek": [ - { - "ifCondition": { - "target": "Name", - "ofValue": "schema" - }, - "expect": "SchemaExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "scalar" - }, - "expect": "ScalarTypeExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "type" - }, - "expect": "ObjectTypeExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "interface" - }, - "expect": "InterfaceTypeExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "union" - }, - "expect": "UnionTypeExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "enum" - }, - "expect": "EnumTypeExtension" - }, - { - "ifCondition": { - "target": "Name", - "ofValue": "input" - }, - "expect": "InputObjectTypeExtension" - } - ] - }, - - "SchemaDefinition": [ - { - "token": "Name", - "ofValue": "schema", - "tokenName": "SchemaDefinitionKeyword" - }, - { "ofType": "Directives", "optional": true }, - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ], - "RootOperationTypeDefinition": [ - "OperationType", - { "token": ":" }, - { "token": "Name", "tokenName": "OperationTypeDefinitionName" } - ], - - "SchemaExtension": [ - { "token": "Name", "ofValue": "extend" }, - { "token": "Name", "ofValue": "schema" }, - "Name", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { - "ofType": [ - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ], - "optional": true - } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": [ - { "token": "{" }, - { "listOfType": "RootOperationTypeDefinition" }, - { "token": "}" } - ] - } - ] - } - ], - - "Description": "StringValue", - - "ScalarTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "scalar", - "tokenName": "ScalarDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true } - ], - - "ScalarTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "scalar", - "tokenName": "ScalarDefinitionKeyword" - }, - "TypeName", - "Directives" - ], - - "ObjectTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "type", - "tokenName": "TypeDefinitionKeyword" - }, - "TypeName", - { "ofType": "ImplementsInterfaces", "optional": true }, - { "ofType": "Directives", "optional": true }, - { "ofType": "FieldsDefinition", "optional": true } - ], - "ImplementsInterfaces": [ - { - "token": "Name", - "ofValue": "implements", - "tokenName": "ImplementsKeyword" - }, - { "token": "&", "optional": true }, - "TypeName", - { - "listOfType": "ImplementsAdditionalInterfaceName", - "optional": true - } - ], - "ImplementsAdditionalInterfaceName": [{ "token": "&" }, "TypeName"], - "FieldsDefinition": [ - { "token": "{" }, - { "listOfType": "FieldDefinition" }, - { "token": "}" } - ], - "FieldDefinition": [ - { "ofType": "Description", "optional": true }, - { "token": "Name", "tokenName": "AliasName", "definitionName": true }, - { "ofType": "ArgumentsDefinition", "optional": true }, - { "token": ":" }, - "Type", - { "ofType": "Directives", "optional": true } - ], - - "ArgumentsDefinition": [ - { "token": "(" }, - { "listOfType": "InputValueDefinition" }, - { "token": ")" } - ], - "InputValueDefinition": [ - { "ofType": "Description", "optional": true }, - { "tokenName": "Name", "tokenName": "ArgumentName" }, - { "token": ":" }, - "Type", - { "ofType": "DefaultValue", "optional": true }, - { "ofType": "Directives", "optional": true } - ], - - "ObjectTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "type", - "tokenName": "TypeDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "Name", "ofValue": "interface" }, - "expect": [ - "ImplementsInterfaces", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ], - "optional": true - } - ] - }, - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ] - } - ], - - "InterfaceTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "interface", - "tokenName": "InterfaceDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "FieldsDefinition", "optional": true } - ], - - "InterfaceTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "interface", - "tokenName": "InterfaceDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "FieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "FieldsDefinition" - } - ] - } - ], - - "UnionTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "union", - "tokenName": "UnionDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "UnionMemberTypes", "optional": true } - ], - - "UnionMemberTypes": [ - { "token": "=" }, - { "token": "|", "optional": true }, - "Name", - { - "listOfType": "UnionMemberAdditionalTypeName", - "optional": true - } - ], - - "UnionMemberAdditionalTypeName": [{ "token": "|" }, "TypeName"], - - "UnionTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "union", - "tokenName": "UnionDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "UnionMemberTypes", "optional": true } - ] - }, - { - "ifCondition": { "token": "=" }, - "expect": "UnionMemberTypes" - } - ] - } - ], - - "EnumTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "enum", - "tokenName": "EnumDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "EnumValuesDefinition", "optional": true } - ], - "EnumValuesDefinition": [ - { "token": "{" }, - { "listOfType": "EnumValueDefinition" }, - { "token": "}" } - ], - "EnumValueDefinition": [ - { "ofType": "Description", "optional": true }, - "EnumValue", - { "ofType": "Directives", "optional": true } - ], - - "EnumTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "enum", - "tokenName": "EnumDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "EnumValuesDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "EnumValuesDefinition" - } - ] - } - ], - - "InputObjectTypeDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "input", - "tokenName": "InputDefinitionKeyword" - }, - "TypeName", - { "ofType": "Directives", "optional": true }, - { "ofType": "InputFieldsDefinition", "optional": true } - ], - "InputFieldsDefinition": [ - { "token": "{" }, - { "listOfType": "InputValueDefinition" }, - { "token": "}" } - ], - - "InputObjectTypeExtension": [ - { - "token": "Name", - "ofValue": "extend", - "tokenName": "ExtendDefinitionKeyword" - }, - { - "token": "Name", - "ofValue": "input", - "tokenName": "InputDefinitionKeyword" - }, - "TypeName", - { - "peek": [ - { - "ifCondition": { "token": "@" }, - "expect": [ - "Directives", - { "ofType": "InputFieldsDefinition", "optional": true } - ] - }, - { - "ifCondition": { "token": "{" }, - "expect": "InputFieldsDefinition" - } - ] - } - ], - - "DirectiveDefinition": [ - { "ofType": "Description", "optional": true }, - { - "token": "Name", - "ofValue": "directive", - "tokenName": "DirectiveDefinitionKeyword" - }, - { "token": "@", "tokenName": "DirectiveName" }, - { "token": "Name", "tokenName": "DirectiveName" }, - { "ofType": "ArgumentsDefinition", "optional": true }, - { "token": "Name", "ofValue": "on", "tokenName": "OnKeyword" }, - "DirectiveLocations" - ], - "DirectiveLocations": [ - { "token": "|", "optional": true }, - "DirectiveLocation", - { - "listOfType": "DirectiveLocationAdditionalName", - "optional": true - } - ], - "DirectiveLocationAdditionalName": [{ "token": "|" }, "DirectiveLocation"], - "DirectiveLocation": { - "peek": [ - { - "ifCondition": "ExecutableDirectiveLocation", - "expect": "ExecutableDirectiveLocation" - }, - { - "ifCondition": "TypeSystemDirectiveLocation", - "expect": "TypeSystemDirectiveLocation" - } - ] - }, - "ExecutableDirectiveLocation": { - "token": "Name", - "oneOf": [ - "QUERY", - "MUTATION", - "SUBSCRIPTION", - "FIELD", - "FRAGMENT_DEFINITION", - "FRAGMENT_SPREAD", - "INLINE_FRAGMENT" - ], - "tokenName": "EnumValue" - }, - "TypeSystemDirectiveLocation": { - "token": "Name", - "oneOf": [ - "SCHEMA", - "SCALAR", - "OBJECT", - "FIELD_DEFINITION", - "ARGUMENT_DEFINITION", - "INTERFACE", - "UNION", - "ENUM", - "ENUM_VALUE", - "INPUT_OBJECT", - "INPUT_FIELD_DEFINITION" - ], - "tokenName": "EnumValue" - } -} From 6b10dbe5b2120cb2fc32034e6b552241ffafe6ee Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Sun, 13 Sep 2020 13:13:11 +0300 Subject: [PATCH 5/5] Fix build --- resources/build-npm.js | 2 +- .../experimentalOnlineParser/grammar.js | 197 ++++++++++++++---- .../experimentalOnlineParser/onlineParser.js | 1 + 3 files changed, 156 insertions(+), 44 deletions(-) diff --git a/resources/build-npm.js b/resources/build-npm.js index 21f0b7c30a..fbc26c73e2 100644 --- a/resources/build-npm.js +++ b/resources/build-npm.js @@ -26,7 +26,7 @@ if (require.main === module) { const mjs = babelBuild(srcPath, { envName: 'mjs' }); fs.writeFileSync(destPath.replace(/\.js$/, '.mjs'), mjs); - } else if (filepath.endsWith('.d.ts') || filepath.endsWith('.json')) { + } else if (filepath.endsWith('.d.ts')) { fs.copyFileSync(srcPath, destPath); } } diff --git a/src/language/experimentalOnlineParser/grammar.js b/src/language/experimentalOnlineParser/grammar.js index a9200daf99..0ab7788534 100644 --- a/src/language/experimentalOnlineParser/grammar.js +++ b/src/language/experimentalOnlineParser/grammar.js @@ -1,20 +1,28 @@ -export type GraphQLGrammarType = { - [string]: GraphQLGrammarRule, -}; +export type GraphQLGrammarType = {| + [name: string]: GraphQLGrammarRule, +|}; export type GraphQLGrammarRuleName = string; export type GraphQLGrammarRuleConstraint = | GraphQLGrammarTokenConstraint | GraphQLGrammarOfTypeConstraint | GraphQLGrammarListOfTypeConstraint | GraphQLGrammarPeekConstraint; -export type GraphQLGrammarConstraintsSet = Array; -export type GraphQLGrammarRule = GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint | GraphQLGrammarConstraintsSet; +export type GraphQLGrammarConstraintsSet = Array< + GraphQLGrammarRuleName | GraphQLGrammarRuleConstraint, +>; +export type GraphQLGrammarRule = + | GraphQLGrammarRuleName + | GraphQLGrammarRuleConstraint + | GraphQLGrammarConstraintsSet; export interface GraphQLGrammarBaseRuleConstraint { - butNot?: ?GraphQLGrammarTokenConstraint | ?Array; + butNot?: + | ?GraphQLGrammarTokenConstraint + | ?Array; optional?: boolean; eatNextOnFail?: boolean; } -export interface GraphQLGrammarTokenConstraint extends GraphQLGrammarBaseRuleConstraint { +export interface GraphQLGrammarTokenConstraint + extends GraphQLGrammarBaseRuleConstraint { token: | '!' | '$' @@ -42,14 +50,17 @@ export interface GraphQLGrammarTokenConstraint extends GraphQLGrammarBaseRuleCon definitionName?: boolean; typeName?: boolean; } -export interface GraphQLGrammarOfTypeConstraint extends GraphQLGrammarBaseRuleConstraint { +export interface GraphQLGrammarOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { ofType: GraphQLGrammarRule; tokenName?: string; } -export interface GraphQLGrammarListOfTypeConstraint extends GraphQLGrammarBaseRuleConstraint { +export interface GraphQLGrammarListOfTypeConstraint + extends GraphQLGrammarBaseRuleConstraint { listOfType: GraphQLGrammarRuleName; } -export interface GraphQLGrammarPeekConstraint extends GraphQLGrammarBaseRuleConstraint { +export interface GraphQLGrammarPeekConstraint + extends GraphQLGrammarBaseRuleConstraint { peek: Array; } export interface GraphQLGrammarPeekConstraintCondition { @@ -58,10 +69,10 @@ export interface GraphQLGrammarPeekConstraintCondition { end?: boolean; } -const grammar: GraphQLGrammarType = { - Name: ({ token: 'Name' }: GraphQLGrammarTokenConstraint), - String: ({ token: 'String' }: GraphQLGrammarTokenConstraint), - BlockString: ({ token: 'BlockString' }: GraphQLGrammarTokenConstraint), +const grammar: GraphQLGrammarType = ({ + Name: { token: 'Name' }, + String: { token: 'String' }, + BlockString: { token: 'BlockString' }, Document: { listOfType: 'Definition' }, Definition: { @@ -80,7 +91,16 @@ const grammar: GraphQLGrammarType = { { ifCondition: { token: 'Name', - oneOf: ['schema', 'scalar', 'type', 'interface', 'union', 'enum', 'input', 'directive'], + oneOf: [ + 'schema', + 'scalar', + 'type', + 'interface', + 'union', + 'enum', + 'input', + 'directive', + ], }, expect: 'TypeSystemDefinition', }, @@ -103,7 +123,7 @@ const grammar: GraphQLGrammarType = { ], }, - OperationDefinition: ({ + OperationDefinition: { peek: [ { ifCondition: { token: '{' }, @@ -128,7 +148,7 @@ const grammar: GraphQLGrammarType = { ], }, ], - }: GraphQLGrammarPeekConstraint), + }, OperationType: { ofType: 'OperationTypeName', }, @@ -165,9 +185,16 @@ const grammar: GraphQLGrammarType = { ], Arguments: [{ token: '(' }, { listOfType: 'Argument' }, { token: ')' }], - Argument: [{ token: 'Name', tokenName: 'ArgumentName', definitionName: true }, { token: ':' }, 'Value'], + Argument: [ + { token: 'Name', tokenName: 'ArgumentName', definitionName: true }, + { token: ':' }, + 'Value', + ], - Alias: [{ token: 'Name', tokenName: 'AliasName', definitionName: true }, { token: ':' }], + Alias: [ + { token: 'Name', tokenName: 'AliasName', definitionName: true }, + { token: ':' }, + ], Fragment: [ { token: '...' }, @@ -211,7 +238,10 @@ const grammar: GraphQLGrammarType = { definitionName: true, }, - TypeCondition: [{ token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, 'TypeName'], + TypeCondition: [ + { token: 'Name', ofValue: 'on', tokenName: 'OnKeyword' }, + 'TypeName', + ], InlineFragment: [ { ofType: 'TypeCondition', optional: true }, @@ -340,19 +370,44 @@ const grammar: GraphQLGrammarType = { tokenName: 'EnumValue', }, - ListValue: [{ token: '[' }, { listOfType: 'Value', optional: true }, { token: ']' }], + ListValue: [ + { token: '[' }, + { listOfType: 'Value', optional: true }, + { token: ']' }, + ], - ConstListValue: [{ token: '[' }, { listOfType: 'ConstValue', optional: true }, { token: ']' }], + ConstListValue: [ + { token: '[' }, + { listOfType: 'ConstValue', optional: true }, + { token: ']' }, + ], - ObjectValue: [{ token: '{' }, { listOfType: 'ObjectField', optional: true }, { token: '}' }], - ObjectField: [{ token: 'Name', tokenName: 'ObjectFieldName' }, { token: ':' }, { ofType: 'ConstValue' }], + ObjectValue: [ + { token: '{' }, + { listOfType: 'ObjectField', optional: true }, + { token: '}' }, + ], + ObjectField: [ + { token: 'Name', tokenName: 'ObjectFieldName' }, + { token: ':' }, + { ofType: 'ConstValue' }, + ], Variable: [ { token: '$', tokenName: 'VariableName' }, { token: 'Name', tokenName: 'VariableName' }, ], - VariableDefinitions: [{ token: '(' }, { listOfType: 'VariableDefinition' }, { token: ')' }], - VariableDefinition: ['Variable', { token: ':' }, 'Type', { ofType: 'DefaultValue', optional: true }], + VariableDefinitions: [ + { token: '(' }, + { listOfType: 'VariableDefinition' }, + { token: ')' }, + ], + VariableDefinition: [ + 'Variable', + { token: ':' }, + 'Type', + { ofType: 'DefaultValue', optional: true }, + ], DefaultValue: [{ token: '=' }, 'ConstValue'], TypeName: { token: 'Name', tokenName: 'TypeName', typeName: true }, @@ -369,7 +424,12 @@ const grammar: GraphQLGrammarType = { }, ], }, - ListType: [{ token: '[' }, { listOfType: 'Type' }, { token: ']' }, { token: '!', optional: true }], + ListType: [ + { token: '[' }, + { listOfType: 'Type' }, + { token: ']' }, + { token: '!', optional: true }, + ], Directives: { listOfType: 'Directive' }, Directive: [ @@ -524,14 +584,22 @@ const grammar: GraphQLGrammarType = { expect: [ 'Directives', { - ofType: [{ token: '{' }, { listOfType: 'RootOperationTypeDefinition' }, { token: '}' }], + ofType: [ + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], optional: true, }, ], }, { ifCondition: { token: '{' }, - expect: [{ token: '{' }, { listOfType: 'RootOperationTypeDefinition' }, { token: '}' }], + expect: [ + { token: '{' }, + { listOfType: 'RootOperationTypeDefinition' }, + { token: '}' }, + ], }, ], }, @@ -591,7 +659,11 @@ const grammar: GraphQLGrammarType = { }, ], ImplementsAdditionalInterfaceName: [{ token: '&' }, 'TypeName'], - FieldsDefinition: [{ token: '{' }, { listOfType: 'FieldDefinition' }, { token: '}' }], + FieldsDefinition: [ + { token: '{' }, + { listOfType: 'FieldDefinition' }, + { token: '}' }, + ], FieldDefinition: [ { ofType: 'Description', optional: true }, { token: 'Name', tokenName: 'AliasName', definitionName: true }, @@ -601,7 +673,11 @@ const grammar: GraphQLGrammarType = { { ofType: 'Directives', optional: true }, ], - ArgumentsDefinition: [{ token: '(' }, { listOfType: 'InputValueDefinition' }, { token: ')' }], + ArgumentsDefinition: [ + { token: '(' }, + { listOfType: 'InputValueDefinition' }, + { token: ')' }, + ], InputValueDefinition: [ { ofType: 'Description', optional: true }, { token: 'Name', tokenName: 'ArgumentName' }, @@ -633,7 +709,10 @@ const grammar: GraphQLGrammarType = { peek: [ { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], }, { ifCondition: { token: '{' }, @@ -646,7 +725,10 @@ const grammar: GraphQLGrammarType = { }, { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], }, { ifCondition: { token: '{' }, @@ -684,7 +766,10 @@ const grammar: GraphQLGrammarType = { peek: [ { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'FieldsDefinition', optional: true }], + expect: [ + 'Directives', + { ofType: 'FieldsDefinition', optional: true }, + ], }, { ifCondition: { token: '{' }, @@ -734,7 +819,10 @@ const grammar: GraphQLGrammarType = { peek: [ { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'UnionMemberTypes', optional: true }], + expect: [ + 'Directives', + { ofType: 'UnionMemberTypes', optional: true }, + ], }, { ifCondition: { token: '=' }, @@ -755,7 +843,11 @@ const grammar: GraphQLGrammarType = { { ofType: 'Directives', optional: true }, { ofType: 'EnumValuesDefinition', optional: true }, ], - EnumValuesDefinition: [{ token: '{' }, { listOfType: 'EnumValueDefinition' }, { token: '}' }], + EnumValuesDefinition: [ + { token: '{' }, + { listOfType: 'EnumValueDefinition' }, + { token: '}' }, + ], EnumValueDefinition: [ { ofType: 'Description', optional: true }, 'EnumValue', @@ -778,7 +870,10 @@ const grammar: GraphQLGrammarType = { peek: [ { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'EnumValuesDefinition', optional: true }], + expect: [ + 'Directives', + { ofType: 'EnumValuesDefinition', optional: true }, + ], }, { ifCondition: { token: '{' }, @@ -799,7 +894,11 @@ const grammar: GraphQLGrammarType = { { ofType: 'Directives', optional: true }, { ofType: 'InputFieldsDefinition', optional: true }, ], - InputFieldsDefinition: [{ token: '{' }, { listOfType: 'InputValueDefinition' }, { token: '}' }], + InputFieldsDefinition: [ + { token: '{' }, + { listOfType: 'InputValueDefinition' }, + { token: '}' }, + ], InputObjectTypeExtension: [ { @@ -817,7 +916,10 @@ const grammar: GraphQLGrammarType = { peek: [ { ifCondition: { token: '@' }, - expect: ['Directives', { ofType: 'InputFieldsDefinition', optional: true }], + expect: [ + 'Directives', + { ofType: 'InputFieldsDefinition', optional: true }, + ], }, { ifCondition: { token: '{' }, @@ -863,10 +965,18 @@ const grammar: GraphQLGrammarType = { }, ExecutableDirectiveLocation: { token: 'Name', - oneOf: ['QUERY', 'MUTATION', 'SUBSCRIPTION', 'FIELD', 'FRAGMENT_DEFINITION', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'], + oneOf: [ + 'QUERY', + 'MUTATION', + 'SUBSCRIPTION', + 'FIELD', + 'FRAGMENT_DEFINITION', + 'FRAGMENT_SPREAD', + 'INLINE_FRAGMENT', + ], tokenName: 'EnumValue', }, - TypeSystemDirectiveLocation: ({ + TypeSystemDirectiveLocation: { token: 'Name', oneOf: [ 'SCHEMA', @@ -882,7 +992,8 @@ const grammar: GraphQLGrammarType = { 'INPUT_FIELD_DEFINITION', ], tokenName: 'EnumValue', - }: GraphQLGrammarTokenConstraint), -}; + }, + // FIXME: enforce proper typing +}: any); export default grammar; diff --git a/src/language/experimentalOnlineParser/onlineParser.js b/src/language/experimentalOnlineParser/onlineParser.js index 6298cbb045..f296d1c8e2 100644 --- a/src/language/experimentalOnlineParser/onlineParser.js +++ b/src/language/experimentalOnlineParser/onlineParser.js @@ -123,6 +123,7 @@ export class OnlineParser { static startState(): OnlineParserState { return { rules: [ + // $FlowFixMe[cannot-spread-interface] { name: 'Document', state: 'Document',