From 9a180797c073b9644b0cdfa51e1c4f3ce3d672d3 Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Thu, 3 Mar 2016 14:49:20 -0800 Subject: [PATCH] Revert "Remove flow" This reverts commit 2827ff6b01dcce69e9d3c0402e96b52b3a2a47ee. --- src/parser/expression.js | 4 +- src/parser/lval.js | 6 +-- src/parser/node.js | 9 +++- src/parser/statement.js | 6 +-- src/plugins/flow.js | 2 +- src/tokenizer/state.js | 110 +++++++++++++++++++++++++++------------ 6 files changed, 94 insertions(+), 43 deletions(-) diff --git a/src/parser/expression.js b/src/parser/expression.js index 78dc6e97ac..bc89b4bdf5 100644 --- a/src/parser/expression.js +++ b/src/parser/expression.js @@ -873,7 +873,7 @@ pp.parseFunctionBody = function (node, allowExpression) { // normal function if (!isExpression && node.body.directives.length) { - for (let directive of node.body.directives) { + for (let directive of (node.body.directives: Array)) { if (directive.value.value === "use strict") { isStrict = true; checkLVal = true; @@ -895,7 +895,7 @@ pp.parseFunctionBody = function (node, allowExpression) { if (node.id) { this.checkLVal(node.id, true); } - for (let param of node.params) { + for (let param of (node.params: Array)) { this.checkLVal(param, true, nameHash); } this.state.strict = oldStrict; diff --git a/src/parser/lval.js b/src/parser/lval.js index 96811030d8..fe3e6bb34e 100644 --- a/src/parser/lval.js +++ b/src/parser/lval.js @@ -20,7 +20,7 @@ pp.toAssignable = function (node, isBinding) { case "ObjectExpression": node.type = "ObjectPattern"; - for (let prop of node.properties) { + for (let prop of (node.properties: Array)) { if (prop.type === "ObjectMethod") { if (prop.kind === "get" || prop.kind === "set") { this.raise(prop.key.start, "Object pattern can't contain getter or setter"); @@ -225,14 +225,14 @@ pp.checkLVal = function (expr, isBinding, checkClashes) { break; case "ObjectPattern": - for (let prop of expr.properties) { + for (let prop of (expr.properties: Array)) { if (prop.type === "ObjectProperty") prop = prop.value; this.checkLVal(prop, isBinding, checkClashes); } break; case "ArrayPattern": - for (let elem of expr.elements) { + for (let elem of (expr.elements: Array)) { if (elem) this.checkLVal(elem, isBinding, checkClashes); } break; diff --git a/src/parser/node.js b/src/parser/node.js index 3d219278e8..d9e07ae329 100644 --- a/src/parser/node.js +++ b/src/parser/node.js @@ -6,14 +6,19 @@ import { SourceLocation } from "../util/location"; const pp = Parser.prototype; class Node { - constructor(pos, loc) { + constructor(pos?: number, loc?: SourceLocation) { this.type = ""; this.start = pos; this.end = 0; this.loc = new SourceLocation(loc); } - __clone() { + type: string; + start: ?number; + end: number; + loc: SourceLocation; + + __clone(): Node { let node2 = new Node; for (let key in this) node2[key] = this[key]; return node2; diff --git a/src/parser/statement.js b/src/parser/statement.js index 16c4cb5a70..5a9c2ae9df 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -404,7 +404,7 @@ pp.parseEmptyStatement = function (node) { }; pp.parseLabeledStatement = function (node, maybeName, expr) { - for (let label of this.state.labels) { + for (let label of (this.state.labels: Array)){ if (label.name === maybeName) { this.raise(expr.start, `Label '${maybeName}' is already declared`); } @@ -438,7 +438,7 @@ pp.parseExpressionStatement = function (node, expr) { // strict"` declarations when `allowStrict` is true (used for // function bodies). -pp.parseBlock = function (allowDirectives) { +pp.parseBlock = function (allowDirectives?) { let node = this.startNode(); this.expect(tt.braceL); this.parseBlockBody(node, allowDirectives, false, tt.braceR); @@ -860,7 +860,7 @@ pp.parseExportSpecifiersMaybe = function (node) { } }; -pp.parseExportFrom = function (node, expect) { +pp.parseExportFrom = function (node, expect?) { if (this.eatContextual("from")) { node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); this.checkExport(node); diff --git a/src/plugins/flow.js b/src/plugins/flow.js index a12487e660..f856955176 100644 --- a/src/plugins/flow.js +++ b/src/plugins/flow.js @@ -704,7 +704,7 @@ export default function (instance) { }); instance.extend("parseParenItem", function () { - return function (node, startLoc, startPos, forceArrow) { + return function (node, startLoc, startPos, forceArrow?) { let canBeArrow = this.state.potentialArrowAt = startPos; if (this.match(tt.colon)) { let typeCastNode = this.startNodeAt(startLoc, startPos); diff --git a/src/tokenizer/state.js b/src/tokenizer/state.js index a932b1618a..68104ae947 100644 --- a/src/tokenizer/state.js +++ b/src/tokenizer/state.js @@ -1,83 +1,129 @@ +import type { TokContext } from "./context"; +import type { Token } from "./index"; import { Position } from "../util/location"; import { types as ct } from "./context"; import { types as tt } from "./types"; export default class State { - init(options, input) { - // TODO + init(options: Object, input: string) { this.strict = options.strictMode === false ? false : options.sourceType === "module"; - // TODO this.input = input; - // Used to signify the start of a potential arrow function this.potentialArrowAt = -1; - // Flags to track whether we are in a function, a generator. this.inMethod = this.inFunction = this.inGenerator = this.inAsync = false; - // Labels in scope. this.labels = []; - // Leading decorators. this.decorators = []; - // Token store. this.tokens = []; - // Comment store. this.comments = []; - // Comment attachment store this.trailingComments = []; this.leadingComments = []; this.commentStack = []; - // The current position of the tokenizer in the input. this.pos = this.lineStart = 0; this.curLine = 1; - // Properties of the current token: - // Its type this.type = tt.eof; - - // For tokens that include more information than their type, the value this.value = null; - - // Its start and end offset this.start = this.end = this.pos; - - // And, if locations are used, the {line, column} object - // corresponding to those offsets this.startLoc = this.endLoc = this.curPosition(); - // Position information for the previous token this.lastTokEndLoc = this.lastTokStartLoc = null; this.lastTokStart = this.lastTokEnd = this.pos; - // The context stack is used to superficially track syntactic - // context to predict whether a regular expression is allowed in a - // given position. this.context = [ct.b_stat]; this.exprAllowed = true; - // Used to signal to callers of `readWord1` whether the word - // contained any escape sequences. This is needed because words with - // escape sequences must not be interpreted as keywords. - this.containsEsc = false; - - // TODO - this.containsOctal = false; + this.containsEsc = this.containsOctal = false; this.octalPosition = null; return this; } + // TODO + strict: boolean; + + // TODO + input: string; + + // Used to signify the start of a potential arrow function + potentialArrowAt: number; + + // Flags to track whether we are in a function, a generator. + inFunction: boolean; + inGenerator: boolean; + inMethod: boolean; + + // Labels in scope. + labels: Array; + + // Leading decorators. + decorators: Array; + + // Token store. + tokens: Array; + + // Comment store. + comments: Array; + + // Comment attachment store + trailingComments: Array; + leadingComments: Array; + commentStack: Array; + + // The current position of the tokenizer in the input. + pos: number; + lineStart: number; + curLine: number; + + // Properties of the current token: + // Its type + type: Token; + + // For tokens that include more information than their type, the value + value: any; + + // Its start and end offset + start: number; + end: number; + + // And, if locations are used, the {line, column} object + // corresponding to those offsets + startLoc: Position; + endLoc: Position; + + // Position information for the previous token + lastTokEndLoc: ?Position; + lastTokStartLoc: ?Position; + lastTokStart: number; + lastTokEnd: number; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + context: Array; + exprAllowed: boolean; + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + containsEsc: boolean; + + // TODO + containsOctal: boolean; + octalPosition: ?number; + curPosition() { return new Position(this.curLine, this.pos - this.lineStart); } - clone(skipArrays) { + clone(skipArrays?) { let state = new State; for (let key in this) { let val = this[key];