From 69721b930ae3dbdb992fa966918c3c2990003ca1 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sun, 26 Jul 2015 04:48:42 +0100 Subject: [PATCH] add token match method and remove more dead code --- packages/babylon/src/parser/comments.js | 6 +- packages/babylon/src/parser/expression.js | 252 +++++++++++----------- packages/babylon/src/parser/lval.js | 8 +- packages/babylon/src/parser/statement.js | 90 ++++---- packages/babylon/src/parser/util.js | 35 +-- packages/babylon/src/plugins/flow.js | 76 +++---- packages/babylon/src/plugins/jsx/index.js | 16 +- packages/babylon/src/tokenizer/index.js | 23 +- packages/babylon/src/tokenizer/state.js | 2 +- 9 files changed, 251 insertions(+), 257 deletions(-) diff --git a/packages/babylon/src/parser/comments.js b/packages/babylon/src/parser/comments.js index 53a4fc3f73..65de15b5c6 100644 --- a/packages/babylon/src/parser/comments.js +++ b/packages/babylon/src/parser/comments.js @@ -38,7 +38,7 @@ pp.addComment = function (comment) { pp.processComment = function (node) { if (node.type === "Program" && node.body.length > 0) return; - var stack = this.state.bottomRightStack; + var stack = this.state.commentStack; var lastChild, trailingComments, i; @@ -80,7 +80,7 @@ pp.processComment = function (node) { } else { // A leading comment for an anonymous class had been stolen by its first MethodDefinition, // so this takes back the leading comment. - // See Also: https://github.com/eslint/espree/issues/158 + // See also: https://github.com/eslint/espree/issues/158 for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { if (lastChild.leadingComments[i].end <= node.start) { node.leadingComments = lastChild.leadingComments.splice(0, i + 1); @@ -99,7 +99,7 @@ pp.processComment = function (node) { // In special cases, such as return (without a value) and // debugger, all comments will end up as leadingComments and // will otherwise be eliminated. This this step runs when the - // bottomRightStack is empty and there are comments left + // commentStack is empty and there are comments left // in leadingComments. // // This loop figures out the stopping point between the actual diff --git a/packages/babylon/src/parser/expression.js b/packages/babylon/src/parser/expression.js index 38f52cde4a..56d7e0b342 100644 --- a/packages/babylon/src/parser/expression.js +++ b/packages/babylon/src/parser/expression.js @@ -62,7 +62,7 @@ pp.checkPropClash = function (prop, propHash) { pp.parseExpression = function (noIn, refShorthandDefaultPos) { let startPos = this.state.start, startLoc = this.state.startLoc; let expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos); - if (this.state.type === tt.comma) { + if (this.match(tt.comma)) { let node = this.startNodeAt(startPos, startLoc); node.expressions = [expr]; while (this.eat(tt.comma)) { @@ -78,7 +78,7 @@ pp.parseExpression = function (noIn, refShorthandDefaultPos) { // operators like `+=`. pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) { - if (this.state.type === tt._yield && this.state.inGenerator) { + if (this.match(tt._yield) && this.state.inGenerator) { return this.parseYield(); } @@ -90,7 +90,7 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) { failOnShorthandAssign = false; } let startPos = this.state.start, startLoc = this.state.startLoc; - if (this.state.type === tt.parenL || this.state.type === tt.name) { + if (this.match(tt.parenL) || this.match(tt.name)) { this.state.potentialArrowAt = this.state.start; } let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos); @@ -98,7 +98,7 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) { if (this.state.type.isAssign) { let node = this.startNodeAt(startPos, startLoc); node.operator = this.state.value; - node.left = this.state.type === tt.eq ? this.toAssignable(left) : left; + node.left = this.match(tt.eq) ? this.toAssignable(left) : left; refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly this.checkLVal(left); if (left.parenthesizedExpression) { @@ -155,7 +155,7 @@ pp.parseExprOps = function (noIn, refShorthandDefaultPos) { pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { let prec = this.state.type.binop; - if (prec != null && (!noIn || this.state.type !== tt._in)) { + if (prec != null && (!noIn || !this.match(tt._in))) { if (prec > minPrec) { let node = this.startNodeAt(leftStartPos, leftStartLoc); node.left = left; @@ -175,7 +175,7 @@ pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { pp.parseMaybeUnary = function (refShorthandDefaultPos) { if (this.state.type.prefix) { - let node = this.startNode(), update = this.state.type === tt.incDec; + let node = this.startNode(), update = this.match(tt.incDec); node.operator = this.state.value; node.prefix = true; this.next(); @@ -235,7 +235,7 @@ pp.parseSubscripts = function(base, startPos, startLoc, noCalls) { node.computed = true; this.expect(tt.bracketR); base = this.finishNode(node, "MemberExpression"); - } else if (!noCalls && this.state.type === tt.parenL) { + } else if (!noCalls && this.match(tt.parenL)) { let possibleAsync = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon(); this.next(); @@ -244,12 +244,12 @@ pp.parseSubscripts = function(base, startPos, startLoc, noCalls) { node.arguments = this.parseExprList(tt.parenR, this.options.features["es7.trailingFunctionCommas"]); base = this.finishNode(node, "CallExpression"); - if (possibleAsync && (this.state.type === tt.colon || this.state.type === tt.arrow)) { + if (possibleAsync && (this.match(tt.colon) || this.match(tt.arrow))) { base = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); } else { this.toReferencedList(node.arguments); } - } else if (this.state.type === tt.backQuote) { + } else if (this.match(tt.backQuote)) { let node = this.startNodeAt(startPos, startLoc); node.tag = base; node.quasi = this.parseTemplate(); @@ -281,122 +281,122 @@ pp.parseNoCallExpr = function () { pp.parseExprAtom = function (refShorthandDefaultPos) { let node, canBeArrow = this.state.potentialArrowAt === this.state.start; switch (this.state.type) { - case tt._super: - if (!this.state.inFunction) - this.raise(this.state.start, "'super' outside of function or class"); - case tt._this: - let type = this.state.type === tt._this ? "ThisExpression" : "Super"; - node = this.startNode(); - this.next(); - return this.finishNode(node, type); - - case tt._yield: - if (this.state.inGenerator) this.unexpected(); - - case tt._do: - if (this.options.features["es7.doExpressions"]) { - let node = this.startNode(); + case tt._super: + if (!this.state.inFunction) + this.raise(this.state.start, "'super' outside of function or class"); + case tt._this: + let type = this.match(tt._this) ? "ThisExpression" : "Super"; + node = this.startNode(); this.next(); - var oldInFunction = this.state.inFunction; - var oldLabels = this.state.labels; - this.state.labels = []; - this.state.inFunction = false; - node.body = this.parseBlock(); - this.state.inFunction = oldInFunction; - this.state.labels = oldLabels; - return this.finishNode(node, "DoExpression"); - } + return this.finishNode(node, type); - case tt.name: - node = this.startNode(); - let id = this.parseIdent(true); + case tt._yield: + if (this.state.inGenerator) this.unexpected(); - // - if (this.options.features["es7.asyncFunctions"]) { - if (id.name === "await") { - if (this.inAsync) return this.parseAwait(node); - } else if (id.name === "async" && this.state.type === tt._function && !this.canInsertSemicolon()) { + case tt._do: + if (this.options.features["es7.doExpressions"]) { + let node = this.startNode(); this.next(); - return this.parseFunction(node, false, false, true); - } else if (canBeArrow && id.name === "async" && this.state.type === tt.name) { - var params = [this.parseIdent()]; - this.expect(tt.arrow); - // var foo = bar => {}; - return this.parseArrowExpression(node, params, true); + var oldInFunction = this.state.inFunction; + var oldLabels = this.state.labels; + this.state.labels = []; + this.state.inFunction = false; + node.body = this.parseBlock(); + this.state.inFunction = oldInFunction; + this.state.labels = oldLabels; + return this.finishNode(node, "DoExpression"); } - } - if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { - return this.parseArrowExpression(node, [id]); - } + case tt.name: + node = this.startNode(); + let id = this.parseIdent(true); - return id; + // + if (this.options.features["es7.asyncFunctions"]) { + if (id.name === "await") { + if (this.inAsync) return this.parseAwait(node); + } else if (id.name === "async" && this.match(tt._function) && !this.canInsertSemicolon()) { + this.next(); + return this.parseFunction(node, false, false, true); + } else if (canBeArrow && id.name === "async" && this.match(tt.name)) { + var params = [this.parseIdent()]; + this.expect(tt.arrow); + // var foo = bar => {}; + return this.parseArrowExpression(node, params, true); + } + } - case tt.regexp: - let value = this.state.value; - node = this.parseLiteral(value.value); - node.regex = {pattern: value.pattern, flags: value.flags}; - return node; + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + return this.parseArrowExpression(node, [id]); + } - case tt.num: case tt.string: - return this.parseLiteral(this.state.value); + return id; - case tt._null: case tt._true: case tt._false: - node = this.startNode(); - node.rawValue = node.value = this.state.type === tt._null ? null : this.state.type === tt._true; - node.raw = this.state.type.keyword; - this.next(); - return this.finishNode(node, "Literal"); + case tt.regexp: + let value = this.state.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node; - case tt.parenL: - return this.parseParenAndDistinguishExpression(null, null, canBeArrow); + case tt.num: case tt.string: + return this.parseLiteral(this.state.value); - case tt.bracketL: - node = this.startNode(); - this.next(); - // check whether this is array comprehension or regular array - if (this.options.features["es7.comprehensions"] && this.state.type === tt._for) { - return this.parseComprehension(node, false); - } - node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos); - this.toReferencedList(node.elements); - return this.finishNode(node, "ArrayExpression"); + case tt._null: case tt._true: case tt._false: + node = this.startNode(); + node.rawValue = node.value = this.match(tt._null) ? null : this.match(tt._true); + node.raw = this.state.type.keyword; + this.next(); + return this.finishNode(node, "Literal"); - case tt.braceL: - return this.parseObj(false, refShorthandDefaultPos); + case tt.parenL: + return this.parseParenAndDistinguishExpression(null, null, canBeArrow); - case tt._function: - node = this.startNode(); - this.next(); - return this.parseFunction(node, false); + case tt.bracketL: + node = this.startNode(); + this.next(); + // check whether this is array comprehension or regular array + if (this.options.features["es7.comprehensions"] && this.match(tt._for)) { + return this.parseComprehension(node, false); + } + node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos); + this.toReferencedList(node.elements); + return this.finishNode(node, "ArrayExpression"); - case tt.at: - this.parseDecorators(); + case tt.braceL: + return this.parseObj(false, refShorthandDefaultPos); - case tt._class: - node = this.startNode(); - this.takeDecorators(node); - return this.parseClass(node, false); + case tt._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false); - case tt._new: - return this.parseNew(); + case tt.at: + this.parseDecorators(); - case tt.backQuote: - return this.parseTemplate(); + case tt._class: + node = this.startNode(); + this.takeDecorators(node); + return this.parseClass(node, false); - case tt.doubleColon: - node = this.startNode(); - this.next(); - node.object = null; - let callee = node.callee = this.parseNoCallExpr(); - if (callee.type === "MemberExpression") { - return this.finishNode(node, "BindExpression"); - } else { - this.raise(callee.start, "Binding should be performed on object property."); - } + case tt._new: + return this.parseNew(); - default: - this.unexpected(); + case tt.backQuote: + return this.parseTemplate(); + + case tt.doubleColon: + node = this.startNode(); + this.next(); + node.object = null; + let callee = node.callee = this.parseNoCallExpr(); + if (callee.type === "MemberExpression") { + return this.finishNode(node, "BindExpression"); + } else { + this.raise(callee.start, "Binding should be performed on object property."); + } + + default: + this.unexpected(); } }; @@ -421,31 +421,31 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow let val; this.next(); - if (this.options.features["es7.comprehensions"] && this.state.type === tt._for) { + if (this.options.features["es7.comprehensions"] && this.match(tt._for)) { return this.parseComprehension(this.startNodeAt(startPos, startLoc), true); } let innerStartPos = this.state.start, innerStartLoc = this.state.startLoc; let exprList = [], first = true; let refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart, optionalCommaStart; - while (this.state.type !== tt.parenR) { + while (!this.match(tt.parenR)) { if (first) { first = false; } else { this.expect(tt.comma); - if (this.state.type === tt.parenR && this.options.features["es7.trailingFunctionCommas"]) { + if (this.match(tt.parenR) && this.options.features["es7.trailingFunctionCommas"]) { optionalCommaStart = this.state.start; break; } } - if (this.state.type === tt.ellipsis) { + if (this.match(tt.ellipsis)) { let spreadNodeStartPos = this.state.start, spreadNodeStartLoc = this.state.startLoc; spreadStart = this.state.start; exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartLoc, spreadNodeStartPos)); break; } else { - if (this.state.type === tt.parenL && !innerParenStart) { + if (this.match(tt.parenL) && !innerParenStart) { innerParenStart = this.state.start; } exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem)); @@ -528,7 +528,7 @@ pp.parseTemplateElement = function () { cooked: this.state.value }; this.next(); - elem.tail = this.state.type === tt.backQuote; + elem.tail = this.match(tt.backQuote); return this.finishNode(elem, "TemplateElement"); }; @@ -560,10 +560,10 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) { first = false; } else { this.expect(tt.comma); - if (this.afterTrailingComma(tt.braceR)) break; + if (this.eat(tt.braceR)) break; } - while (this.state.type === tt.at) { + while (this.match(tt.at)) { decorators.push(this.parseDecorator()); } @@ -572,7 +572,7 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) { prop.decorators = decorators; decorators = []; } - if (this.options.features["es7.objectRestSpread"] && this.state.type === tt.ellipsis) { + if (this.options.features["es7.objectRestSpread"] && this.match(tt.ellipsis)) { prop = this.parseSpread(); prop.type = "SpreadProperty"; node.properties.push(prop); @@ -589,7 +589,7 @@ pp.parseObj = function (isPattern, refShorthandDefaultPos) { if (this.options.features["es7.asyncFunctions"] && this.isContextual("async")) { if (isGenerator || isPattern) this.unexpected(); var asyncId = this.parseIdent(); - if (this.state.type === tt.colon || this.state.type === tt.parenL) { + if (this.match(tt.colon) || this.match(tt.parenL)) { prop.key = asyncId; } else { isAsync = true; @@ -612,12 +612,12 @@ pp.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, if (this.eat(tt.colon)) { prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); prop.kind = "init"; - } else if (this.state.type === tt.parenL) { + } else if (this.match(tt.parenL)) { if (isPattern) this.unexpected(); prop.kind = "init"; prop.method = true; prop.value = this.parseMethod(isGenerator, isAsync); - } else if (!prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.state.type !== tt.comma && this.state.type !== tt.braceR)) { + } else if (!prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (!this.match(tt.comma) && !this.match(tt.braceR))) { if (isGenerator || isAsync || isPattern) this.unexpected(); prop.kind = prop.key.name; this.parsePropertyName(prop); @@ -638,7 +638,7 @@ pp.parseObjPropValue = function (prop, startPos, startLoc, isGenerator, isAsync, (!this.options.allowReserved && this.isReservedWord(prop.key.name))) this.raise(prop.key.start, "Binding " + prop.key.name); prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); - } else if (this.state.type === tt.eq && refShorthandDefaultPos) { + } else if (this.match(tt.eq) && refShorthandDefaultPos) { if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.state.start; prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); @@ -659,7 +659,7 @@ pp.parsePropertyName = function (prop) { return prop.key; } else { prop.computed = false; - return prop.key = (this.state.type === tt.num || this.state.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true); + return prop.key = (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdent(true); } }; @@ -698,7 +698,7 @@ pp.parseArrowExpression = function (node, params, isAsync) { // Parse function body and check parameters. pp.parseFunctionBody = function (node, allowExpression) { - let isExpression = allowExpression && this.state.type !== tt.braceL; + let isExpression = allowExpression && !this.match(tt.braceL); var oldInAsync = this.inAsync; this.inAsync = node.async; @@ -745,7 +745,7 @@ pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthand first = false; } else { this.expect(tt.comma); - if (allowTrailingComma && this.afterTrailingComma(close)) break; + if (allowTrailingComma && this.eat(close)) break; } elts.push(this.parseExprListItem(allowEmpty, refShorthandDefaultPos)); @@ -755,9 +755,9 @@ pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthand pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) { let elt; - if (allowEmpty && this.state.type === tt.comma) { + if (allowEmpty && this.match(tt.comma)) { elt = null; - } else if (this.state.type === tt.ellipsis) { + } else if (this.match(tt.ellipsis)) { elt = this.parseSpread(refShorthandDefaultPos); } else { elt = this.parseMaybeAssign(false, refShorthandDefaultPos); @@ -771,7 +771,7 @@ pp.parseExprListItem = function (allowEmpty, refShorthandDefaultPos) { pp.parseIdent = function (liberal) { let node = this.startNode(); - if (this.state.type === tt.name) { + if (this.match(tt.name)) { if (!liberal && ((!this.options.allowReserved && this.isReservedWord(this.state.value)) || (this.strict && reservedWords.strict(this.state.value)))) @@ -802,7 +802,7 @@ pp.parseAwait = function (node) { pp.parseYield = function () { let node = this.startNode(); this.next(); - if (this.state.type === tt.semi || this.canInsertSemicolon() || (this.state.type !== tt.star && !this.state.type.startsExpr)) { + if (this.match(tt.semi) || this.canInsertSemicolon() || (!this.match(tt.star) && !this.state.type.startsExpr)) { node.delegate = false; node.argument = null; } else { @@ -816,7 +816,7 @@ pp.parseYield = function () { pp.parseComprehension = function (node, isGenerator) { node.blocks = []; - while (this.state.type === tt._for) { + while (this.match(tt._for)) { let block = this.startNode(); this.next(); this.expect(tt.parenL); diff --git a/packages/babylon/src/parser/lval.js b/packages/babylon/src/parser/lval.js index 68fd6c1252..265aa90cf0 100644 --- a/packages/babylon/src/parser/lval.js +++ b/packages/babylon/src/parser/lval.js @@ -92,7 +92,7 @@ pp.parseSpread = function (refShorthandDefaultPos) { pp.parseRest = function () { let node = this.startNode(); this.next(); - node.argument = this.state.type === tt.name || this.state.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected(); + node.argument = this.match(tt.name) || this.match(tt.bracketL) ? this.parseBindingAtom() : this.unexpected(); return this.finishNode(node, "RestElement"); }; @@ -122,11 +122,11 @@ pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) { while (!this.eat(close)) { if (first) first = false; else this.expect(tt.comma); - if (allowEmpty && this.state.type === tt.comma) { + if (allowEmpty && this.match(tt.comma)) { elts.push(null); - } else if (allowTrailingComma && this.afterTrailingComma(close)) { + } else if (allowTrailingComma && this.eat(close)) { break; - } else if (this.state.type === tt.ellipsis) { + } else if (this.match(tt.ellipsis)) { elts.push(this.parseAssignableListItemTypes(this.parseRest())); this.expect(close); break; diff --git a/packages/babylon/src/parser/statement.js b/packages/babylon/src/parser/statement.js index 4d63b2a0f2..730cf0c2a4 100644 --- a/packages/babylon/src/parser/statement.js +++ b/packages/babylon/src/parser/statement.js @@ -16,7 +16,7 @@ pp.parseTopLevel = function (file, program) { program.body = []; let first = true; - while (this.state.type !== tt.eof) { + while (!this.match(tt.eof)) { let stmt = this.parseStatement(true, true); program.body.push(stmt); if (first) { @@ -43,7 +43,7 @@ const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; // does not help. pp.parseStatement = function (declaration, topLevel) { - if (this.state.type === tt.at) { + if (this.match(tt.at)) { this.parseDecorators(true); } @@ -94,7 +94,7 @@ pp.parseStatement = function (declaration, topLevel) { // peek ahead and see if next token is a function var state = this.state.clone(); this.next(); - if (this.state.type === tt._function && !this.canInsertSemicolon()) { + if (this.match(tt._function) && !this.canInsertSemicolon()) { this.expect(tt._function); return this.parseFunction(node, true, false, true); } else { @@ -126,15 +126,15 @@ pp.takeDecorators = function (node) { }; pp.parseDecorators = function (allowExport) { - while (this.state.type === tt.at) { + while (this.match(tt.at)) { this.state.decorators.push(this.parseDecorator()); } - if (allowExport && this.state.type === tt._export) { + if (allowExport && this.match(tt._export)) { return; } - if (this.state.type !== tt._class) { + if (!this.match(tt._class)) { this.raise(this.state.start, "Leading decorators must be attached to a class declaration"); } }; @@ -153,9 +153,9 @@ pp.parseBreakContinueStatement = function (node, keyword) { let isBreak = keyword === "break"; this.next(); - if (this.eat(tt.semi) || this.insertSemicolon()) { + if (this.eat(tt.semi) || this.canInsertSemicolon()) { node.label = null; - } else if (this.state.type !== tt.name) { + } else if (!this.match(tt.name)) { this.unexpected(); } else { node.label = this.parseIdent(); @@ -205,16 +205,16 @@ pp.parseForStatement = function (node) { this.state.labels.push(loopLabel); this.expect(tt.parenL); - if (this.state.type === tt.semi) { + if (this.match(tt.semi)) { return this.parseFor(node, null); } - if (this.state.type === tt._var || this.state.type === tt._let || this.state.type === tt._const) { + if (this.match(tt._var) || this.match(tt._let) || this.match(tt._const)) { let init = this.startNode(), varKind = this.state.type; this.next(); this.parseVar(init, true, varKind); this.finishNode(init, "VariableDeclaration"); - if ((this.state.type === tt._in || this.isContextual("of")) && init.declarations.length === 1 && + if ((this.match(tt._in) || this.isContextual("of")) && init.declarations.length === 1 && !(varKind !== tt._var && init.declarations[0].init)) return this.parseForIn(node, init); return this.parseFor(node, init); @@ -222,7 +222,7 @@ pp.parseForStatement = function (node) { let refShorthandDefaultPos = {start: 0}; let init = this.parseExpression(true, refShorthandDefaultPos); - if (this.state.type === tt._in || this.isContextual("of")) { + if (this.match(tt._in) || this.isContextual("of")) { this.toAssignable(init); this.checkLVal(init); return this.parseForIn(node, init); @@ -256,7 +256,7 @@ pp.parseReturnStatement = function (node) { // optional arguments, we eagerly look for a semicolon or the // possibility to insert one. - if (this.eat(tt.semi) || this.insertSemicolon()) { + if (this.eat(tt.semi) || this.canInsertSemicolon()) { node.argument = null; } else { node.argument = this.parseExpression(); @@ -277,9 +277,9 @@ pp.parseSwitchStatement = function (node) { // nodes. `cur` is used to keep the node that we are currently // adding statements to. - for (var cur, sawDefault; this.state.type !== tt.braceR; ) { - if (this.state.type === tt._case || this.state.type === tt._default) { - let isCase = this.state.type === tt._case; + for (var cur, sawDefault; !this.match(tt.braceR); ) { + if (this.match(tt._case) || this.match(tt._default)) { + let isCase = this.match(tt._case); if (cur) this.finishNode(cur, "SwitchCase"); node.cases.push(cur = this.startNode()); cur.consequent = []; @@ -320,7 +320,7 @@ pp.parseTryStatement = function (node) { this.next(); node.block = this.parseBlock(); node.handler = null; - if (this.state.type === tt._catch) { + if (this.match(tt._catch)) { let clause = this.startNode(); this.next(); this.expect(tt.parenL); @@ -377,7 +377,7 @@ pp.parseLabeledStatement = function (node, maybeName, expr) { } } - let kind = this.state.type.isLoop ? "loop" : this.state.type === tt._switch ? "switch" : null; + let kind = this.state.type.isLoop ? "loop" : this.match(tt._switch) ? "switch" : null; for (let i = this.state.labels.length - 1; i >= 0; i--) { let label = this.state.labels[i]; if (label.statementStart === node.start) { @@ -429,9 +429,9 @@ pp.parseBlock = function (allowStrict) { pp.parseFor = function (node, init) { node.init = init; this.expect(tt.semi); - node.test = this.state.type === tt.semi ? null : this.parseExpression(); + node.test = this.match(tt.semi) ? null : this.parseExpression(); this.expect(tt.semi); - node.update = this.state.type === tt.parenR ? null : this.parseExpression(); + node.update = this.match(tt.parenR) ? null : this.parseExpression(); this.expect(tt.parenR); node.body = this.parseStatement(false); this.state.labels.pop(); @@ -442,7 +442,7 @@ pp.parseFor = function (node, init) { // same from parser's perspective. pp.parseForIn = function (node, init) { - let type = this.state.type === tt._in ? "ForInStatement" : "ForOfStatement"; + let type = this.match(tt._in) ? "ForInStatement" : "ForOfStatement"; this.next(); node.left = init; node.right = this.parseExpression(); @@ -462,9 +462,9 @@ pp.parseVar = function (node, isFor, kind) { this.parseVarHead(decl); if (this.eat(tt.eq)) { decl.init = this.parseMaybeAssign(isFor); - } else if (kind === tt._const && !(this.state.type === tt._in || this.isContextual("of"))) { + } else if (kind === tt._const && !(this.match(tt._in) || this.isContextual("of"))) { this.unexpected(); - } else if (decl.id.type !== "Identifier" && !(isFor && (this.state.type === tt._in || this.isContextual("of")))) { + } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(tt._in) || this.isContextual("of")))) { this.raise(this.state.lastTokEnd, "Complex binding patterns require an initialization value"); } else { decl.init = null; @@ -487,7 +487,7 @@ pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync) { this.initFunction(node, isAsync); node.generator = this.eat(tt.star); - if (isStatement || this.state.type === tt.name) { + if (isStatement || this.match(tt.name)) { node.id = this.parseIdent(); } @@ -515,7 +515,7 @@ pp.parseClass = function (node, isStatement) { let decorators = []; while (!this.eat(tt.braceR)) { if (this.eat(tt.semi)) continue; - if (this.state.type === tt.at) { + if (this.match(tt.at)) { decorators.push(this.parseDecorator()); continue; } @@ -524,10 +524,10 @@ pp.parseClass = function (node, isStatement) { method.decorators = decorators; decorators = []; } - let isMaybeStatic = this.state.type === tt.name && this.state.value === "static"; + let isMaybeStatic = this.match(tt.name) && this.state.value === "static"; var isGenerator = this.eat(tt.star), isAsync = false; this.parsePropertyName(method); - method.static = isMaybeStatic && this.state.type !== tt.parenL; + method.static = isMaybeStatic && !this.match(tt.parenL); if (method.static) { if (isGenerator) this.unexpected(); isGenerator = this.eat(tt.star); @@ -537,7 +537,7 @@ pp.parseClass = function (node, isStatement) { classBody.body.push(this.parseClassProperty(method)); continue; } - if (this.options.features["es7.asyncFunctions"] && this.state.type !== tt.parenL && + if (this.options.features["es7.asyncFunctions"] && !this.match(tt.parenL) && !method.computed && method.key.type === "Identifier" && method.key.name === "async") { isAsync = true; this.parsePropertyName(method); @@ -546,7 +546,7 @@ pp.parseClass = function (node, isStatement) { method.kind = "method"; if (!method.computed) { let {key} = method; - if (!isAsync && !isGenerator && key.type === "Identifier" && this.state.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + if (!isAsync && !isGenerator && key.type === "Identifier" && !this.match(tt.parenL) && (key.name === "get" || key.name === "set")) { isGetSet = true; method.kind = key.name; key = this.parsePropertyName(method); @@ -587,11 +587,11 @@ pp.parseClass = function (node, isStatement) { }; pp.isClassProperty = function () { - return this.state.type === tt.eq || (this.state.type === tt.semi || this.canInsertSemicolon()); + return this.match(tt.eq) || (this.match(tt.semi) || this.canInsertSemicolon()); }; pp.parseClassProperty = function (node) { - if (this.state.type === tt.eq) { + if (this.match(tt.eq)) { if (!this.options.features["es7.classProperties"]) this.unexpected(); this.next(); node.value = this.parseMaybeAssign(); @@ -608,7 +608,7 @@ pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) { }; pp.parseClassId = function (node, isStatement) { - node.id = this.state.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null; + node.id = this.match(tt.name) ? this.parseIdent() : isStatement ? this.unexpected() : null; }; pp.parseClassSuper = function (node) { @@ -620,7 +620,7 @@ pp.parseClassSuper = function (node) { pp.parseExport = function (node) { this.next(); // export * from '...' - if (this.state.type === tt.star) { + if (this.match(tt.star)) { let specifier = this.startNode(); this.next(); if (this.options.features["es7.exportExtensions"] && this.eatContextual("as")) { @@ -636,7 +636,7 @@ pp.parseExport = function (node) { let specifier = this.startNode(); specifier.exported = this.parseIdent(true); node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; - if (this.state.type === tt.comma && this.lookahead().type === tt.star) { + if (this.match(tt.comma) && this.lookahead().type === tt.star) { this.expect(tt.comma); let specifier = this.startNode(); this.expect(tt.star); @@ -668,7 +668,7 @@ pp.parseExport = function (node) { node.declaration = null; node.specifiers = this.parseExportSpecifiers(); if (this.eatContextual("from")) { - node.source = this.state.type === tt.string ? this.parseExprAtom() : this.unexpected(); + node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); } else { node.source = null; } @@ -679,11 +679,11 @@ pp.parseExport = function (node) { }; pp.isExportDefaultSpecifier = function () { - if (this.state.type === tt.name) { + if (this.match(tt.name)) { return this.state.value !== "type" && this.state.value !== "async"; } - if (this.state.type !== tt._default) { + if (!this.match(tt._default)) { return false; } @@ -699,7 +699,7 @@ pp.parseExportSpecifiersMaybe = function (node) { pp.parseExportFrom = function (node) { this.expectContextual("from"); - node.source = this.state.type === tt.string ? this.parseExprAtom() : this.unexpected(); + node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); this.semicolon(); this.checkExport(node); }; @@ -730,11 +730,11 @@ pp.parseExportSpecifiers = function () { first = false; } else { this.expect(tt.comma); - if (this.afterTrailingComma(tt.braceR)) break; + if (this.eat(tt.braceR)) break; } let node = this.startNode(); - node.local = this.parseIdent(this.state.type === tt._default); + node.local = this.parseIdent(this.match(tt._default)); node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local.__clone(); nodes.push(this.finishNode(node, "ExportSpecifier")); } @@ -748,14 +748,14 @@ pp.parseImport = function (node) { this.next(); // import '...' - if (this.state.type === tt.string) { + if (this.match(tt.string)) { node.specifiers = []; node.source = this.parseExprAtom(); } else { node.specifiers = []; this.parseImportSpecifiers(node); this.expectContextual("from"); - node.source = this.state.type === tt.string ? this.parseExprAtom() : this.unexpected(); + node.source = this.match(tt.string) ? this.parseExprAtom() : this.unexpected(); } this.semicolon(); return this.finishNode(node, "ImportDeclaration"); @@ -765,14 +765,14 @@ pp.parseImport = function (node) { pp.parseImportSpecifiers = function (node) { var first = true; - if (this.state.type === tt.name) { + if (this.match(tt.name)) { // import defaultObj, { x, y as z } from '...' var startPos = this.state.start, startLoc = this.state.startLoc; node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdent(), startPos, startLoc)); if (!this.eat(tt.comma)) return; } - if (this.state.type === tt.star) { + if (this.match(tt.star)) { let specifier = this.startNode(); this.next(); this.expectContextual("as"); @@ -788,7 +788,7 @@ pp.parseImportSpecifiers = function (node) { first = false; } else { this.expect(tt.comma); - if (this.afterTrailingComma(tt.braceR)) break; + if (this.eat(tt.braceR)) break; } let specifier = this.startNode(); diff --git a/packages/babylon/src/parser/util.js b/packages/babylon/src/parser/util.js index 8c6c09017d..51ca0bdc6f 100644 --- a/packages/babylon/src/parser/util.js +++ b/packages/babylon/src/parser/util.js @@ -12,22 +12,10 @@ pp.isUseStrict = function (stmt) { return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.raw.slice(1, -1) === "use strict"; }; -// Predicate that tests whether the next token is of the given -// type, and if yes, consumes it as a side effect. - -pp.eat = function (type) { - if (this.state.type === type) { - this.next(); - return true; - } else { - return false; - } -}; - // TODO pp.isRelational = function (op) { - return this.state.type === tt.relational && this.state.value === op; + return this.match(tt.relational) && this.state.value === op; }; // TODO @@ -43,7 +31,7 @@ pp.expectRelational = function (op) { // Tests whether parsed token is a contextual keyword. pp.isContextual = function (name) { - return this.state.type === tt.name && this.state.value === name; + return this.match(tt.name) && this.state.value === name; }; // Consumes contextual keyword if possible. @@ -61,29 +49,16 @@ pp.expectContextual = function (name) { // Test whether a semicolon can be inserted at the current position. pp.canInsertSemicolon = function () { - return this.state.type === tt.eof || - this.state.type === tt.braceR || + return this.match(tt.eof) || + this.match(tt.braceR) || lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); }; -pp.insertSemicolon = function () { - if (this.canInsertSemicolon()) { - return true; - } -}; - // Consume a semicolon, or, failing that, see if we are allowed to // pretend that there is a semicolon at this position. pp.semicolon = function () { - if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected(); -}; - -pp.afterTrailingComma = function (tokType) { - if (this.state.type === tokType) { - this.next(); - return true; - } + if (!this.eat(tt.semi) && !this.canInsertSemicolon()) this.unexpected(); }; // Expect a token of a given type. If found, consume it, otherwise, diff --git a/packages/babylon/src/plugins/flow.js b/packages/babylon/src/plugins/flow.js index 7b45b70880..2f1c190ae5 100644 --- a/packages/babylon/src/plugins/flow.js +++ b/packages/babylon/src/plugins/flow.js @@ -50,11 +50,11 @@ pp.flowParseDeclareFunction = function (node) { }; pp.flowParseDeclare = function (node) { - if (this.state.type === tt._class) { + if (this.match(tt._class)) { return this.flowParseDeclareClass(node); - } else if (this.state.type === tt._function) { + } else if (this.match(tt._function)) { return this.flowParseDeclareFunction(node); - } else if (this.state.type === tt._var) { + } else if (this.match(tt._var)) { return this.flowParseDeclareVariable(node); } else if (this.isContextual("module")) { return this.flowParseDeclareModule(node); @@ -73,7 +73,7 @@ pp.flowParseDeclareVariable = function (node) { pp.flowParseDeclareModule = function (node) { this.next(); - if (this.state.type === tt.string) { + if (this.match(tt.string)) { node.id = this.parseExprAtom(); } else { node.id = this.parseIdent(); @@ -82,7 +82,7 @@ pp.flowParseDeclareModule = function (node) { var bodyNode = node.body = this.startNode(); var body = bodyNode.body = []; this.expect(tt.braceL); - while (this.state.type !== tt.braceR) { + while (!this.match(tt.braceR)) { var node2 = this.startNode(); // todo: declare check @@ -193,7 +193,7 @@ pp.flowParseTypeParameterInstantiation = function () { }; pp.flowParseObjectPropertyKey = function () { - return (this.state.type === tt.num || this.state.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true); + return (this.match(tt.num) || this.match(tt.string)) ? this.parseExprAtom() : this.parseIdent(true); }; pp.flowParseObjectTypeIndexer = function (node, isStatic) { @@ -219,9 +219,9 @@ pp.flowParseObjectTypeMethodish = function (node) { } this.expect(tt.parenL); - while (this.state.type === tt.name) { + while (this.match(tt.name)) { node.params.push(this.flowParseFunctionTypeParam()); - if (this.state.type !== tt.parenR) { + if (!this.match(tt.parenR)) { this.expect(tt.comma); } } @@ -266,7 +266,7 @@ pp.flowParseObjectType = function (allowStatic) { this.expect(tt.braceL); - while (this.state.type !== tt.braceR) { + while (!this.match(tt.braceR)) { var startPos = this.state.start, startLoc = this.state.startLoc; node = this.startNode(); if (allowStatic && this.isContextual("static")) { @@ -274,17 +274,17 @@ pp.flowParseObjectType = function (allowStatic) { isStatic = true; } - if (this.state.type === tt.bracketL) { + if (this.match(tt.bracketL)) { nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic)); - } else if (this.state.type === tt.parenL || this.isRelational("<")) { + } else if (this.match(tt.parenL) || this.isRelational("<")) { nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, allowStatic)); } else { - if (isStatic && this.state.type === tt.colon) { + if (isStatic && this.match(tt.colon)) { propertyKey = this.parseIdent(); } else { propertyKey = this.flowParseObjectPropertyKey(); } - if (this.isRelational("<") || this.state.type === tt.parenL) { + if (this.isRelational("<") || this.match(tt.parenL)) { // This is a method property nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey)); } else { @@ -307,7 +307,7 @@ pp.flowParseObjectType = function (allowStatic) { }; pp.flowObjectTypeSemicolon = function () { - if (!this.eat(tt.semi) && !this.eat(tt.comma) && this.state.type !== tt.braceR) { + if (!this.eat(tt.semi) && !this.eat(tt.comma) && !this.match(tt.braceR)) { this.unexpected(); } }; @@ -344,9 +344,9 @@ pp.flowParseTupleType = function () { node.types = []; this.expect(tt.bracketL); // We allow trailing commas - while (this.state.pos < this.input.length && this.state.type !== tt.bracketR) { + while (this.state.pos < this.input.length && !this.match(tt.bracketR)) { node.types.push(this.flowParseType()); - if (this.state.type === tt.bracketR) break; + if (this.match(tt.bracketR)) break; this.expect(tt.comma); } this.expect(tt.bracketR); @@ -367,9 +367,9 @@ pp.flowParseFunctionTypeParam = function () { pp.flowParseFunctionTypeParams = function () { var ret = { params: [], rest: null }; - while (this.state.type === tt.name) { + while (this.match(tt.name)) { ret.params.push(this.flowParseFunctionTypeParam()); - if (this.state.type !== tt.parenR) { + if (!this.match(tt.parenR)) { this.expect(tt.comma); } } @@ -445,8 +445,8 @@ pp.flowParsePrimaryType = function () { this.next(); // Check to see if this is actually a grouped type - if (this.state.type !== tt.parenR && this.state.type !== tt.ellipsis) { - if (this.state.type === tt.name) { + if (!this.match(tt.parenR) && !this.match(tt.ellipsis)) { + if (this.match(tt.name)) { var token = this.lookahead().type; isGroupedType = token !== tt.question && token !== tt.colon; } else { @@ -511,7 +511,7 @@ pp.flowParsePrimaryType = function () { pp.flowParsePostfixType = function () { var node = this.startNode(); var type = node.elementType = this.flowParsePrimaryType(); - if (this.state.type === tt.bracketL) { + if (this.match(tt.bracketL)) { this.expect(tt.bracketL); this.expect(tt.bracketR); return this.finishNode(node, "ArrayTypeAnnotation"); @@ -573,7 +573,7 @@ pp.flowParseTypeAnnotatableIdentifier = function (requireTypeAnnotation, canBeOp isOptionalParam = true; } - if (requireTypeAnnotation || this.state.type === tt.colon) { + if (requireTypeAnnotation || this.match(tt.colon)) { ident.typeAnnotation = this.flowParseTypeAnnotation(); this.finishNode(ident, ident.type); } @@ -590,7 +590,7 @@ export default function (instance) { // function name(): string {} instance.extend("parseFunctionBody", function (inner) { return function (node, allowExpression) { - if (this.state.type === tt.colon && !allowExpression) { + if (this.match(tt.colon) && !allowExpression) { // if allowExpression is true then we're parsing an arrow function and if // there's a return type then it's been handled elsewhere node.returnType = this.flowParseTypeAnnotation(); @@ -603,7 +603,7 @@ export default function (instance) { instance.extend("parseStatement", function (inner) { return function (declaration, topLevel) { // strict mode handling of `interface` since it's a reserved word - if (this.strict && this.state.type === tt.name && this.state.value === "interface") { + if (this.strict && this.match(tt.name) && this.state.value === "interface") { var node = this.startNode(); this.next(); return this.flowParseInterface(node); @@ -617,10 +617,10 @@ export default function (instance) { return function (node, expr) { if (expr.type === "Identifier") { if (expr.name === "declare") { - if (this.state.type === tt._class || this.state.type === tt.name || this.state.type === tt._function || this.state.type === tt._var) { + if (this.match(tt._class) || this.match(tt.name) || this.match(tt._function) || this.match(tt._var)) { return this.flowParseDeclare(node); } - } else if (this.state.type === tt.name) { + } else if (this.match(tt.name)) { if (expr.name === "interface") { return this.flowParseInterface(node); } else if (expr.name === "type") { @@ -641,12 +641,12 @@ export default function (instance) { instance.extend("parseParenItem", function () { return function (node, startLoc, startPos, forceArrow?) { - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { var typeCastNode = this.startNodeAt(startLoc, startPos); typeCastNode.expression = node; typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); - if (forceArrow && this.state.type !== tt.arrow) { + if (forceArrow && !this.match(tt.arrow)) { this.unexpected(); } @@ -735,7 +735,7 @@ export default function (instance) { return function (allowEmpty, refShorthandDefaultPos) { var container = this.startNode(); var node = inner.call(this, allowEmpty, refShorthandDefaultPos); - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { container._exprListItem = true; container.expression = node; container.typeAnnotation = this.flowParseTypeAnnotation(); @@ -748,7 +748,7 @@ export default function (instance) { instance.extend("parseClassProperty", function (inner) { return function (node) { - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { node.typeAnnotation = this.flowParseTypeAnnotation(); } return inner.call(this, node); @@ -757,7 +757,7 @@ export default function (instance) { instance.extend("isClassProperty", function (inner) { return function () { - return this.state.type === tt.colon || inner.call(this); + return this.match(tt.colon) || inner.call(this); }; }); @@ -801,7 +801,7 @@ export default function (instance) { var typeParameters; if (this.isRelational("<")) { typeParameters = this.flowParseTypeParameterDeclaration(); - if (this.state.type !== tt.parenL) this.unexpected(); + if (!this.match(tt.parenL)) this.unexpected(); } inner.apply(this, arguments); prop.value.typeParameters = typeParameters; @@ -813,7 +813,7 @@ export default function (instance) { if (this.eat(tt.question)) { param.optional = true; } - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { param.typeAnnotation = this.flowParseTypeAnnotation(); } this.finishNode(param, param.type); @@ -825,7 +825,7 @@ export default function (instance) { return function (node) { node.importKind = "value"; - var kind = (this.state.type === tt._typeof ? "typeof" : (this.isContextual("type") ? "type" : null)); + var kind = (this.match(tt._typeof) ? "typeof" : (this.isContextual("type") ? "type" : null)); if (kind) { var lh = this.lookahead(); if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) { @@ -852,7 +852,7 @@ export default function (instance) { instance.extend("parseVarHead", function (inner) { return function (decl) { inner.call(this, decl); - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { decl.id.typeAnnotation = this.flowParseTypeAnnotation(); this.finishNode(decl.id, decl.id.type); } @@ -862,7 +862,7 @@ export default function (instance) { // var foo = (async (): number => {}); instance.extend("parseAsyncArrowFromCallExpression", function (inner) { return function (node, call) { - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { node.returnType = this.flowParseTypeAnnotation(); } @@ -881,7 +881,7 @@ export default function (instance) { this.expect(tt.parenR); let node = this.startNodeAt(startPos, startLoc); - if (this.state.type === tt.colon) node.returnType = this.flowParseTypeAnnotation(); + if (this.match(tt.colon)) node.returnType = this.flowParseTypeAnnotation(); this.expect(tt.arrow); return this.parseArrowExpression(node, [], isAsync); } else { @@ -890,7 +890,7 @@ export default function (instance) { var state = this.state.clone(); - if (this.state.type === tt.colon) { + if (this.match(tt.colon)) { try { return this.parseParenItem(node, startPos, startLoc, true); } catch (err) { diff --git a/packages/babylon/src/plugins/jsx/index.js b/packages/babylon/src/plugins/jsx/index.js index b07e60fe3b..3ff0cc0c7c 100644 --- a/packages/babylon/src/plugins/jsx/index.js +++ b/packages/babylon/src/plugins/jsx/index.js @@ -186,7 +186,7 @@ function getQualifiedJSXName(object) { pp.jsxParseIdentifier = function() { var node = this.startNode(); - if (this.state.type === tt.jsxName) { + if (this.match(tt.jsxName)) { node.name = this.state.value; } else if (this.state.type.keyword) { node.name = this.state.type.keyword; @@ -268,7 +268,7 @@ pp.jsxParseEmptyExpression = function() { pp.jsxParseExpressionContainer = function() { var node = this.startNode(); this.next(); - if (this.state.type === tt.braceR) { + if (this.match(tt.braceR)) { node.expression = this.jsxParseEmptyExpression(); } else { node.expression = this.parseExpression(); @@ -298,7 +298,7 @@ pp.jsxParseOpeningElementAt = function(startPos, startLoc) { var node = this.startNodeAt(startPos, startLoc); node.attributes = []; node.name = this.jsxParseElementName(); - while (this.state.type !== tt.slash && this.state.type !== tt.jsxTagEnd) { + while (!this.match(tt.slash) && !this.match(tt.jsxTagEnd)) { node.attributes.push(this.jsxParseAttribute()); } node.selfClosing = this.eat(tt.slash); @@ -360,7 +360,7 @@ pp.jsxParseElementAt = function(startPos, startLoc) { node.openingElement = openingElement; node.closingElement = closingElement; node.children = children; - if (this.state.type === tt.relational && this.state.value === "<") { + if (this.match(tt.relational) && this.state.value === "<") { this.raise(this.state.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); } return this.finishNode(node, "JSXElement"); @@ -377,9 +377,9 @@ pp.jsxParseElement = function() { export default function(instance) { instance.extend("parseExprAtom", function(inner) { return function(refShortHandDefaultPos) { - if (this.state.type === tt.jsxText) + if (this.match(tt.jsxText)) return this.parseLiteral(this.state.value); - else if (this.state.type === tt.jsxTagStart) + else if (this.match(tt.jsxTagStart)) return this.jsxParseElement(); else return inner.call(this, refShortHandDefaultPos); @@ -414,13 +414,13 @@ export default function(instance) { instance.extend("updateContext", function(inner) { return function(prevType) { - if (this.state.type === tt.braceL) { + if (this.match(tt.braceL)) { var curContext = this.curContext(); if (curContext === tc.j_oTag) this.state.context.push(tc.b_expr); else if (curContext === tc.j_expr) this.state.context.push(tc.b_tmpl); else inner.call(this, prevType); this.state.exprAllowed = true; - } else if (this.state.type === tt.slash && prevType === tt.jsxTagStart) { + } else if (this.match(tt.slash) && prevType === tt.jsxTagStart) { this.state.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore this.state.context.push(tc.j_cTag); // reconsider as closing tag context this.state.exprAllowed = false; diff --git a/packages/babylon/src/tokenizer/index.js b/packages/babylon/src/tokenizer/index.js index 5d2a210f4e..f75f720a7f 100644 --- a/packages/babylon/src/tokenizer/index.js +++ b/packages/babylon/src/tokenizer/index.js @@ -71,6 +71,25 @@ export default class Tokenizer { this.nextToken(); } + // TODO + + eat(type) { + if (this.match(type)) { + this.next(); + return true; + } else { + return false; + } + } + + // TODO + + match(type) { + return this.state.type === type; + } + + // TODO + lookahead() { var old = this.state.clone(); this.next(); @@ -84,7 +103,7 @@ export default class Tokenizer { setStrict(strict) { this.strict = strict; - if (this.state.type !== tt.num && this.state.type !== tt.string) return; + if (!this.match(tt.num) && !this.match(tt.string)) return; this.state.pos = this.state.start; while (this.state.pos < this.state.lineStart) { this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1; @@ -610,7 +629,7 @@ export default class Tokenizer { if (this.state.pos >= this.input.length) this.raise(this.state.start, "Unterminated template"); let ch = this.input.charCodeAt(this.state.pos); if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { // '`', '${' - if (this.state.pos === this.state.start && this.state.type === tt.template) { + if (this.state.pos === this.state.start && this.match(tt.template)) { if (ch === 36) { this.state.pos += 2; return this.finishToken(tt.dollarBraceL); diff --git a/packages/babylon/src/tokenizer/state.js b/packages/babylon/src/tokenizer/state.js index 61204ad329..d73fbbc568 100644 --- a/packages/babylon/src/tokenizer/state.js +++ b/packages/babylon/src/tokenizer/state.js @@ -25,9 +25,9 @@ export default class State { this.comments = []; // Comment attachment store - this.bottomRightStack = []; this.trailingComments = []; this.leadingComments = []; + this.commentStack = []; // The current position of the tokenizer in the input. this.pos = this.lineStart = 0;