babylon
Advanced tools
Comparing version 5.8.29 to 6.0.2
@@ -0,9 +1,10 @@ | ||
/* @flow */ | ||
"use strict"; | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
exports.__esModule = true; | ||
exports.parse = parse; | ||
// istanbul ignore next | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _parser = require("./parser"); | ||
@@ -10,0 +11,0 @@ |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// A second optional argument can be given to further configure | ||
@@ -11,7 +13,2 @@ // the parser process. These options are recognized: | ||
sourceType: "script", | ||
// By default, reserved words are not enforced. Disable | ||
// `allowReserved` to enforce them. When this option has the | ||
// value "never", reserved words and keywords can also not be | ||
// used as property names. | ||
allowReserved: true, | ||
// When enabled, a return at the top level is not considered an | ||
@@ -23,5 +20,7 @@ // error. | ||
allowImportExportEverywhere: false, | ||
plugins: {}, | ||
// Babel-specific options | ||
features: {}, | ||
// TODO | ||
allowSuperOutsideMethod: false, | ||
// An array of plugins to enable | ||
plugins: [], | ||
// TODO | ||
strictMode: null | ||
@@ -33,3 +32,3 @@ }; | ||
function getOptions(opts) { | ||
function getOptions(opts /*:: ?: Object*/) /*: Object*/ { | ||
var options = {}; | ||
@@ -36,0 +35,0 @@ for (var key in defaultOptions) { |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
/** | ||
@@ -27,6 +29,4 @@ * Based on the comment attachment algorithm used in espree and estraverse. | ||
// istanbul ignore next | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _index = require("./index"); | ||
@@ -52,3 +52,5 @@ | ||
var lastChild, trailingComments, i; | ||
var lastChild = undefined, | ||
trailingComments = undefined, | ||
i = undefined; | ||
@@ -91,3 +93,3 @@ if (this.state.trailingComments.length > 0) { | ||
} else { | ||
// A leading comment for an anonymous class had been stolen by its first MethodDefinition, | ||
// A leading comment for an anonymous class had been stolen by its first ClassMethod, | ||
// so this takes back the leading comment. | ||
@@ -94,0 +96,0 @@ // See also: https://github.com/eslint/espree/issues/158 |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// A recursive descent parser operates by defining functions for all | ||
@@ -21,6 +23,8 @@ // syntactic elements, and recursively calling those, each function | ||
// istanbul ignore next | ||
var _Object$create = require("babel-runtime/core-js/object/create")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _getIterator = require("babel-runtime/core-js/get-iterator")["default"]; | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
var _tokenizerTypes = require("../tokenizer/types"); | ||
@@ -42,11 +46,16 @@ | ||
pp.checkPropClash = function (prop, propHash) { | ||
if (prop.computed || prop.method || prop.shorthand) return; | ||
if (prop.computed || prop.method) return; | ||
var key = prop.key, | ||
name = undefined; | ||
var key = prop.key; | ||
var name = undefined; | ||
switch (key.type) { | ||
case "Identifier": | ||
name = key.name;break; | ||
case "Literal": | ||
name = String(key.value);break; | ||
name = key.name; | ||
break; | ||
case "StringLiteral": | ||
case "NumberLiteral": | ||
name = String(key.value); | ||
break; | ||
default: | ||
@@ -56,4 +65,3 @@ return; | ||
var kind = prop.kind; | ||
if (name === "__proto__" && kind === "init") { | ||
if (name === "__proto__" && prop.kind === "init") { | ||
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property"); | ||
@@ -123,3 +131,3 @@ propHash.proto = true; | ||
this.checkLVal(left); | ||
if (left.parenthesizedExpression) { | ||
if (left.extra && left.extra.parenthesized) { | ||
var errorMsg = undefined; | ||
@@ -213,3 +221,3 @@ if (left.type === "ObjectPattern") { | ||
this.checkLVal(node.argument); | ||
} else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") { | ||
} else if (this.state.strict && node.operator === "delete" && node.argument.type === "Identifier") { | ||
this.raise(node.start, "Deleting local variable in strict mode"); | ||
@@ -259,3 +267,3 @@ } | ||
node.object = base; | ||
node.property = this.parseIdent(true); | ||
node.property = this.parseIdentifier(true); | ||
node.computed = false; | ||
@@ -276,7 +284,7 @@ base = this.finishNode(node, "MemberExpression"); | ||
node.callee = base; | ||
node.arguments = this.parseExprList(_tokenizerTypes.types.parenR, this.options.features["es7.trailingFunctionCommas"]); | ||
node.arguments = this.parseCallExpressionArguments(_tokenizerTypes.types.parenR, this.hasPlugin("trailingFunctionCommas"), possibleAsync); | ||
base = this.finishNode(node, "CallExpression"); | ||
if (possibleAsync && (this.match(_tokenizerTypes.types.colon) || this.match(_tokenizerTypes.types.arrow))) { | ||
base = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); | ||
if (possibleAsync && this.shouldParseAsyncArrow()) { | ||
return this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); | ||
} else { | ||
@@ -296,4 +304,37 @@ this.toReferencedList(node.arguments); | ||
pp.parseCallExpressionArguments = function (close, allowTrailingComma, possibleAsyncArrow) { | ||
var innerParenStart = undefined; | ||
var elts = [], | ||
first = true; | ||
while (!this.eat(close)) { | ||
if (first) { | ||
first = false; | ||
} else { | ||
this.expect(_tokenizerTypes.types.comma); | ||
if (allowTrailingComma && this.eat(close)) break; | ||
} | ||
// we need to make sure that if this is an async arrow functions, that we don't allow inner parens inside the params | ||
if (this.match(_tokenizerTypes.types.parenL) && !innerParenStart) { | ||
innerParenStart = this.state.start; | ||
} | ||
elts.push(this.parseExprListItem()); | ||
} | ||
// we found an async arrow function so let's not allow any inner parens | ||
if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) { | ||
this.unexpected(); | ||
} | ||
return elts; | ||
}; | ||
pp.shouldParseAsyncArrow = function () { | ||
return this.match(_tokenizerTypes.types.arrow); | ||
}; | ||
pp.parseAsyncArrowFromCallExpression = function (node, call) { | ||
if (!this.options.features["es7.asyncFunctions"]) this.unexpected(); | ||
if (!this.hasPlugin("asyncFunctions")) this.unexpected(); | ||
this.expect(_tokenizerTypes.types.arrow); | ||
@@ -321,8 +362,20 @@ return this.parseArrowExpression(node, call.arguments, true); | ||
case _tokenizerTypes.types._super: | ||
if (!this.state.inFunction) this.raise(this.state.start, "'super' outside of function or class"); | ||
if (!this.state.inMethod && !this.options.allowSuperOutsideMethod) { | ||
this.raise(this.state.start, "'super' outside of function or class"); | ||
} | ||
node = this.startNode(); | ||
this.next(); | ||
if (!this.match(_tokenizerTypes.types.parenL) && !this.match(_tokenizerTypes.types.bracketL) && !this.match(_tokenizerTypes.types.dot)) { | ||
this.unexpected(); | ||
} | ||
if (this.match(_tokenizerTypes.types.parenL) && this.state.inMethod !== "constructor" && !this.options.allowSuperOutsideMethod) { | ||
this.raise(node.start, "super() outside of class constructor"); | ||
} | ||
return this.finishNode(node, "Super"); | ||
case _tokenizerTypes.types._this: | ||
var type = this.match(_tokenizerTypes.types._this) ? "ThisExpression" : "Super"; | ||
node = this.startNode(); | ||
this.next(); | ||
return this.finishNode(node, type); | ||
return this.finishNode(node, "ThisExpression"); | ||
@@ -332,23 +385,13 @@ case _tokenizerTypes.types._yield: | ||
case _tokenizerTypes.types._do: | ||
if (this.options.features["es7.doExpressions"]) { | ||
var _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"); | ||
} | ||
case _tokenizerTypes.types.name: | ||
node = this.startNode(); | ||
var id = this.parseIdent(true); | ||
var allowAwait = this.hasPlugin("asyncFunctions") && this.state.value === "await" && this.state.inAsync; | ||
var allowYield = this.shouldAllowYieldIdentifier(); | ||
var id = this.parseIdentifier(allowAwait || allowYield); | ||
if (this.options.features["es7.asyncFunctions"]) { | ||
if (this.hasPlugin("asyncFunctions")) { | ||
if (id.name === "await") { | ||
if (this.inAsync) return this.parseAwait(node); | ||
if (this.state.inAsync || this.inModule) { | ||
return this.parseAwait(node); | ||
} | ||
} else if (id.name === "async" && this.match(_tokenizerTypes.types._function) && !this.canInsertSemicolon()) { | ||
@@ -358,5 +401,5 @@ this.next(); | ||
} else if (canBeArrow && id.name === "async" && this.match(_tokenizerTypes.types.name)) { | ||
var params = [this.parseIdent()]; | ||
var params = [this.parseIdentifier()]; | ||
this.expect(_tokenizerTypes.types.arrow); | ||
// var foo = bar => {}; | ||
// let foo = bar => {}; | ||
return this.parseArrowExpression(node, params, true); | ||
@@ -372,18 +415,40 @@ } | ||
case _tokenizerTypes.types._do: | ||
if (this.hasPlugin("doExpressions")) { | ||
var _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(false, true); | ||
this.state.inFunction = oldInFunction; | ||
this.state.labels = oldLabels; | ||
return this.finishNode(_node, "DoExpression"); | ||
} | ||
case _tokenizerTypes.types.regexp: | ||
var value = this.state.value; | ||
node = this.parseLiteral(value.value); | ||
node.regex = { pattern: value.pattern, flags: value.flags }; | ||
node = this.parseLiteral(value.value, "RegexLiteral"); | ||
node.pattern = value.pattern; | ||
node.flags = value.flags; | ||
return node; | ||
case _tokenizerTypes.types.num:case _tokenizerTypes.types.string: | ||
return this.parseLiteral(this.state.value); | ||
case _tokenizerTypes.types.num: | ||
return this.parseLiteral(this.state.value, "NumberLiteral"); | ||
case _tokenizerTypes.types._null:case _tokenizerTypes.types._true:case _tokenizerTypes.types._false: | ||
case _tokenizerTypes.types.string: | ||
return this.parseLiteral(this.state.value, "StringLiteral"); | ||
case _tokenizerTypes.types._null: | ||
node = this.startNode(); | ||
node.rawValue = node.value = this.match(_tokenizerTypes.types._null) ? null : this.match(_tokenizerTypes.types._true); | ||
node.raw = this.state.type.keyword; | ||
this.next(); | ||
return this.finishNode(node, "Literal"); | ||
return this.finishNode(node, "NullLiteral"); | ||
case _tokenizerTypes.types._true:case _tokenizerTypes.types._false: | ||
node = this.startNode(); | ||
node.value = this.match(_tokenizerTypes.types._true); | ||
this.next(); | ||
return this.finishNode(node, "BooleanLiteral"); | ||
case _tokenizerTypes.types.parenL: | ||
@@ -395,6 +460,2 @@ return this.parseParenAndDistinguishExpression(null, null, canBeArrow); | ||
this.next(); | ||
// check whether this is array comprehension or regular array | ||
if (this.options.features["es7.comprehensions"] && this.match(_tokenizerTypes.types._for)) { | ||
return this.parseComprehension(node, false); | ||
} | ||
node.elements = this.parseExprList(_tokenizerTypes.types.bracketR, true, true, refShorthandDefaultPos); | ||
@@ -442,8 +503,9 @@ this.toReferencedList(node.elements); | ||
pp.parseLiteral = function (value) { | ||
pp.parseLiteral = function (value, type) { | ||
var node = this.startNode(); | ||
node.rawValue = node.value = value; | ||
node.raw = this.input.slice(this.state.start, this.state.end); | ||
this.addExtra(node, "rawValue", value); | ||
this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); | ||
node.value = value; | ||
this.next(); | ||
return this.finishNode(node, "Literal"); | ||
return this.finishNode(node, type); | ||
}; | ||
@@ -464,6 +526,2 @@ | ||
if (this.options.features["es7.comprehensions"] && this.match(_tokenizerTypes.types._for)) { | ||
return this.parseComprehension(this.startNodeAt(startPos, startLoc), true); | ||
} | ||
var innerStartPos = this.state.start, | ||
@@ -482,3 +540,3 @@ innerStartLoc = this.state.startLoc; | ||
this.expect(_tokenizerTypes.types.comma); | ||
if (this.match(_tokenizerTypes.types.parenR) && this.options.features["es7.trailingFunctionCommas"]) { | ||
if (this.match(_tokenizerTypes.types.parenR) && this.hasPlugin("trailingFunctionCommas")) { | ||
optionalCommaStart = this.state.start; | ||
@@ -502,2 +560,3 @@ break; | ||
} | ||
var innerEndPos = this.state.start; | ||
@@ -531,4 +590,3 @@ var innerEndLoc = this.state.startLoc; | ||
} | ||
val.parenthesizedExpression = true; | ||
this.addExtra(val, "parenthesized", true); | ||
return val; | ||
@@ -547,7 +605,7 @@ }; | ||
var node = this.startNode(); | ||
var meta = this.parseIdent(true); | ||
var meta = this.parseIdentifier(true); | ||
if (this.eat(_tokenizerTypes.types.dot)) { | ||
node.meta = meta; | ||
node.property = this.parseIdent(true); | ||
node.property = this.parseIdentifier(true); | ||
@@ -564,3 +622,3 @@ if (node.property.name !== "target") { | ||
if (this.eat(_tokenizerTypes.types.parenL)) { | ||
node.arguments = this.parseExprList(_tokenizerTypes.types.parenR, this.options.features["es7.trailingFunctionCommas"]); | ||
node.arguments = this.parseExprList(_tokenizerTypes.types.parenR, this.hasPlugin("trailingFunctionCommas")); | ||
this.toReferencedList(node.arguments); | ||
@@ -606,8 +664,10 @@ } else { | ||
pp.parseObj = function (isPattern, refShorthandDefaultPos) { | ||
var node = this.startNode(), | ||
first = true, | ||
propHash = Object.create(null); | ||
var decorators = []; | ||
var propHash = _Object$create(null); | ||
var first = true; | ||
var node = this.startNode(); | ||
node.properties = []; | ||
var decorators = []; | ||
this.next(); | ||
while (!this.eat(_tokenizerTypes.types.braceR)) { | ||
@@ -634,10 +694,13 @@ if (first) { | ||
} | ||
if (this.options.features["es7.objectRestSpread"] && this.match(_tokenizerTypes.types.ellipsis)) { | ||
if (this.hasPlugin("objectRestSpread") && this.match(_tokenizerTypes.types.ellipsis)) { | ||
prop = this.parseSpread(); | ||
prop.type = "SpreadProperty"; | ||
prop.type = isPattern ? "RestProperty" : "SpreadProperty"; | ||
node.properties.push(prop); | ||
continue; | ||
} | ||
prop.method = false; | ||
prop.shorthand = false; | ||
if (isPattern || refShorthandDefaultPos) { | ||
@@ -647,8 +710,11 @@ startPos = this.state.start; | ||
} | ||
if (!isPattern) { | ||
isGenerator = this.eat(_tokenizerTypes.types.star); | ||
} | ||
if (!isPattern && this.options.features["es7.asyncFunctions"] && this.isContextual("async")) { | ||
if (!isPattern && this.hasPlugin("asyncFunctions") && this.isContextual("async")) { | ||
if (isGenerator) this.unexpected(); | ||
var asyncId = this.parseIdent(); | ||
var asyncId = this.parseIdentifier(); | ||
if (this.match(_tokenizerTypes.types.colon) || this.match(_tokenizerTypes.types.parenL) || this.match(_tokenizerTypes.types.braceR)) { | ||
@@ -663,9 +729,17 @@ prop.key = asyncId; | ||
} | ||
this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refShorthandDefaultPos); | ||
this.checkPropClash(prop, propHash); | ||
node.properties.push(this.finishNode(prop, "Property")); | ||
if (prop.shorthand) { | ||
this.addExtra(prop, "shorthand", true); | ||
} | ||
node.properties.push(prop); | ||
} | ||
if (decorators.length) { | ||
this.raise(this.state.start, "You have trailing decorators with no property"); | ||
} | ||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); | ||
@@ -677,25 +751,44 @@ }; | ||
prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos); | ||
prop.kind = "init"; | ||
} else if (this.match(_tokenizerTypes.types.parenL)) { | ||
return this.finishNode(prop, "ObjectProperty"); | ||
} | ||
if (this.match(_tokenizerTypes.types.parenL)) { | ||
if (isPattern) this.unexpected(); | ||
prop.kind = "init"; | ||
prop.kind = "method"; | ||
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.match(_tokenizerTypes.types.comma) && !this.match(_tokenizerTypes.types.braceR))) { | ||
this.parseMethod(prop, isGenerator, isAsync); | ||
return this.finishNode(prop, "ObjectMethod"); | ||
} | ||
if (!prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (!this.match(_tokenizerTypes.types.comma) && !this.match(_tokenizerTypes.types.braceR))) { | ||
if (isGenerator || isAsync || isPattern) this.unexpected(); | ||
prop.kind = prop.key.name; | ||
this.parsePropertyName(prop); | ||
prop.value = this.parseMethod(false); | ||
this.parseMethod(prop, false); | ||
var paramCount = prop.kind === "get" ? 0 : 1; | ||
if (prop.value.params.length !== paramCount) { | ||
var start = prop.value.start; | ||
if (prop.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param"); | ||
if (prop.params.length !== paramCount) { | ||
var start = prop.start; | ||
if (prop.kind === "get") { | ||
this.raise(start, "getter should have no params"); | ||
} else { | ||
this.raise(start, "setter should have exactly one param"); | ||
} | ||
} | ||
} else if (!prop.computed && prop.key.type === "Identifier") { | ||
prop.kind = "init"; | ||
return this.finishNode(prop, "ObjectMethod"); | ||
} | ||
if (!prop.computed && prop.key.type === "Identifier") { | ||
if (isPattern) { | ||
if (this.isKeyword(prop.key.name) || this.strict && (_utilIdentifier.reservedWords.strictBind(prop.key.name) || _utilIdentifier.reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name); | ||
var illegalBinding = this.isKeyword(prop.key.name); | ||
if (!illegalBinding && this.state.strict) { | ||
illegalBinding = _utilIdentifier.reservedWords.strictBind(prop.key.name) || _utilIdentifier.reservedWords.strict(prop.key.name); | ||
} | ||
if (illegalBinding) { | ||
this.raise(prop.key.start, "Binding " + prop.key.name); | ||
} | ||
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); | ||
} else if (this.match(_tokenizerTypes.types.eq) && refShorthandDefaultPos) { | ||
if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.state.start; | ||
if (!refShorthandDefaultPos.start) { | ||
refShorthandDefaultPos.start = this.state.start; | ||
} | ||
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); | ||
@@ -706,5 +799,6 @@ } else { | ||
prop.shorthand = true; | ||
} else { | ||
this.unexpected(); | ||
return this.finishNode(prop, "ObjectProperty"); | ||
} | ||
this.unexpected(); | ||
}; | ||
@@ -720,3 +814,3 @@ | ||
prop.computed = false; | ||
return prop.key = this.match(_tokenizerTypes.types.num) || this.match(_tokenizerTypes.types.string) ? this.parseExprAtom() : this.parseIdent(true); | ||
return prop.key = this.match(_tokenizerTypes.types.num) || this.match(_tokenizerTypes.types.string) ? this.parseExprAtom() : this.parseIdentifier(true); | ||
} | ||
@@ -731,3 +825,3 @@ }; | ||
node.expression = false; | ||
if (this.options.features["es7.asyncFunctions"]) { | ||
if (this.hasPlugin("asyncFunctions")) { | ||
node.async = !!isAsync; | ||
@@ -739,10 +833,12 @@ } | ||
pp.parseMethod = function (isGenerator, isAsync) { | ||
var node = this.startNode(); | ||
pp.parseMethod = function (node, isGenerator, isAsync) { | ||
var oldInMethod = this.state.inMethod; | ||
this.state.inMethod = node.kind || true; | ||
this.initFunction(node, isAsync); | ||
this.expect(_tokenizerTypes.types.parenL); | ||
node.params = this.parseBindingList(_tokenizerTypes.types.parenR, false, this.options.features["es7.trailingFunctionCommas"]); | ||
node.params = this.parseBindingList(_tokenizerTypes.types.parenR, false, this.hasPlugin("trailingFunctionCommas")); | ||
node.generator = isGenerator; | ||
this.parseFunctionBody(node); | ||
return this.finishNode(node, "FunctionExpression"); | ||
this.state.inMethod = oldInMethod; | ||
return node; | ||
}; | ||
@@ -764,4 +860,4 @@ | ||
var oldInAsync = this.inAsync; | ||
this.inAsync = node.async; | ||
var oldInAsync = this.state.inAsync; | ||
this.state.inAsync = node.async; | ||
if (isExpression) { | ||
@@ -781,3 +877,3 @@ node.body = this.parseMaybeAssign(); | ||
} | ||
this.inAsync = oldInAsync; | ||
this.state.inAsync = oldInAsync; | ||
@@ -787,15 +883,63 @@ // If this is a strict mode function, verify that argument names | ||
// or `arguments`. | ||
if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) { | ||
var nameHash = Object.create(null), | ||
oldStrict = this.strict; | ||
this.strict = true; | ||
var checkLVal = this.state.strict; | ||
var checkLValStrict = false; | ||
var isStrict = false; | ||
// arrow function | ||
if (allowExpression) checkLVal = true; | ||
// normal function | ||
if (!isExpression && node.body.directives.length) { | ||
for (var _iterator = (node.body.directives /*: Array<Object>*/), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _getIterator(_iterator);;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var directive = _ref; | ||
if (directive.value.value === "use strict") { | ||
isStrict = true; | ||
checkLVal = true; | ||
checkLValStrict = true; | ||
break; | ||
} | ||
} | ||
} | ||
// | ||
if (isStrict && node.id && node.id.type === "Identifier" && node.id.name === "yield") { | ||
this.raise(node.id.start, "Binding yield in strict mode"); | ||
} | ||
if (checkLVal) { | ||
var nameHash = _Object$create(null); | ||
var oldStrict = this.state.strict; | ||
if (checkLValStrict) this.state.strict = true; | ||
if (node.id) { | ||
this.checkLVal(node.id, true); | ||
} | ||
var _arr = node.params; | ||
for (var _i = 0; _i < _arr.length; _i++) { | ||
var param = _arr[_i]; | ||
for (var _iterator2 = (node.params /*: Array<Object>*/), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _getIterator(_iterator2);;) { | ||
var _ref2; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
} | ||
var param = _ref2; | ||
this.checkLVal(param, true, nameHash); | ||
} | ||
this.strict = oldStrict; | ||
this.state.strict = oldStrict; | ||
} | ||
@@ -842,6 +986,10 @@ }; | ||
pp.parseIdent = function (liberal) { | ||
pp.parseIdentifier = function (liberal) { | ||
var node = this.startNode(); | ||
if (this.match(_tokenizerTypes.types.name)) { | ||
if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.state.value) || this.strict && _utilIdentifier.reservedWords.strict(this.state.value))) this.raise(this.state.start, "The keyword '" + this.state.value + "' is reserved"); | ||
if (!liberal && this.state.strict && _utilIdentifier.reservedWords.strict(this.state.value)) { | ||
this.raise(this.state.start, "The keyword '" + this.state.value + "' is reserved"); | ||
} | ||
node.name = this.state.value; | ||
@@ -853,2 +1001,7 @@ } else if (liberal && this.state.type.keyword) { | ||
} | ||
if (!liberal && node.name === "await" && this.state.inAsync) { | ||
this.raise(node.start, "invalid use of await inside of an async function"); | ||
} | ||
this.next(); | ||
@@ -861,3 +1014,3 @@ return this.finishNode(node, "Identifier"); | ||
pp.parseAwait = function (node) { | ||
if (this.eat(_tokenizerTypes.types.semi) || this.canInsertSemicolon()) { | ||
if (this.isLineTerminator()) { | ||
this.unexpected(); | ||
@@ -883,24 +1036,2 @@ } | ||
return this.finishNode(node, "YieldExpression"); | ||
}; | ||
// Parses array and generator comprehensions. | ||
pp.parseComprehension = function (node, isGenerator) { | ||
node.blocks = []; | ||
while (this.match(_tokenizerTypes.types._for)) { | ||
var block = this.startNode(); | ||
this.next(); | ||
this.expect(_tokenizerTypes.types.parenL); | ||
block.left = this.parseBindingAtom(); | ||
this.checkLVal(block.left, true); | ||
this.expectContextual("of"); | ||
block.right = this.parseExpression(); | ||
this.expect(_tokenizerTypes.types.parenR); | ||
node.blocks.push(this.finishNode(block, "ComprehensionBlock")); | ||
} | ||
node.filter = this.eat(_tokenizerTypes.types._if) ? this.parseParenExpression() : null; | ||
node.body = this.parseExpression(); | ||
this.expect(isGenerator ? _tokenizerTypes.types.parenR : _tokenizerTypes.types.bracketR); | ||
node.generator = isGenerator; | ||
return this.finishNode(node, "ComprehensionExpression"); | ||
}; |
@@ -0,16 +1,15 @@ | ||
/* @flow */ | ||
"use strict"; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
var _inherits = require("babel-runtime/helpers/inherits")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
// istanbul ignore next | ||
var _getIterator = require("babel-runtime/core-js/get-iterator")["default"]; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
// istanbul ignore next | ||
exports.__esModule = true; | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var _utilIdentifier = require("../util/identifier"); | ||
@@ -24,4 +23,2 @@ | ||
// Registered plugins | ||
var plugins = {}; | ||
@@ -34,17 +31,14 @@ | ||
function Parser(options, input) { | ||
function Parser(options, input /*: string*/) { | ||
_classCallCheck(this, Parser); | ||
_Tokenizer.call(this, input); | ||
options = _options.getOptions(options); | ||
_Tokenizer.call(this, options, input); | ||
this.options = _options.getOptions(options); | ||
this.isKeyword = _utilIdentifier.isKeyword; | ||
this.options = options; | ||
this.inModule = this.options.sourceType === "module"; | ||
this.isReservedWord = _utilIdentifier.reservedWords[6]; | ||
this.input = input; | ||
this.loadPlugins(this.options.plugins); | ||
this.plugins = this.loadPlugins(this.options.plugins); | ||
// Figure out if it's a module code. | ||
this.inModule = this.options.sourceType === "module"; | ||
this.strict = this.options.strictMode === false ? false : this.inModule; | ||
// If enabled, skip leading hashbang line. | ||
@@ -56,15 +50,49 @@ if (this.state.pos === 0 && this.input[0] === "#" && this.input[1] === "!") { | ||
Parser.prototype.extend = function extend(name, f) { | ||
Parser.prototype.hasPlugin = function hasPlugin(name /*: string*/) /*: boolean*/ { | ||
return !!(this.plugins["*"] || this.plugins[name]); | ||
}; | ||
Parser.prototype.extend = function extend(name /*: string*/, f /*: Function*/) { | ||
this[name] = f(this[name]); | ||
}; | ||
Parser.prototype.loadPlugins = function loadPlugins(plugins) { | ||
for (var _name in plugins) { | ||
Parser.prototype.loadPlugins = function loadPlugins(plugins /*: Array<string>*/) { | ||
var pluginMap = {}; | ||
if (plugins.indexOf("flow") >= 0) { | ||
// ensure flow plugin loads last | ||
plugins.splice(plugins.indexOf("flow"), 1); | ||
plugins.push("flow"); | ||
} | ||
for (var _iterator = plugins, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _getIterator(_iterator);;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var _name = _ref; | ||
pluginMap[_name] = true; | ||
var plugin = exports.plugins[_name]; | ||
if (!plugin) throw new Error("Plugin '" + _name + "' not found"); | ||
plugin(this, plugins[_name]); | ||
if (plugin) plugin(this); | ||
} | ||
return pluginMap; | ||
}; | ||
Parser.prototype.parse = function parse() { | ||
Parser.prototype.parse = function parse() /*: { | ||
type: "File", | ||
program: { | ||
type: "Program", | ||
body: Array<Object> | ||
} | ||
}*/ { | ||
var file = this.startNode(); | ||
@@ -71,0 +99,0 @@ var program = this.startNode(); |
@@ -0,7 +1,7 @@ | ||
/* @flow */ | ||
"use strict"; | ||
// istanbul ignore next | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _utilLocation = require("../util/location"); | ||
@@ -8,0 +8,0 @@ |
@@ -0,6 +1,8 @@ | ||
/* @flow */ | ||
"use strict"; | ||
// istanbul ignore next | ||
var _getIterator = require("babel-runtime/core-js/get-iterator")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
@@ -31,8 +33,29 @@ var _tokenizerTypes = require("../tokenizer/types"); | ||
node.type = "ObjectPattern"; | ||
var _arr = node.properties; | ||
for (var _i = 0; _i < _arr.length; _i++) { | ||
var prop = _arr[_i]; | ||
for (var _iterator = (node.properties /*: Array<Object>*/), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _getIterator(_iterator);;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var prop = _ref; | ||
if (prop.type === "SpreadProperty") continue; | ||
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter"); | ||
this.toAssignable(prop.value, isBinding); | ||
if (prop.type === "ObjectMethod") { | ||
if (prop.kind === "get" || prop.kind === "set") { | ||
this.raise(prop.key.start, "Object pattern can't contain getter or setter"); | ||
} else { | ||
this.raise(prop.key.start, "Object pattern can't contain methods"); | ||
} | ||
} | ||
if (prop.type === "ObjectProperty") { | ||
this.toAssignable(prop.value, isBinding); | ||
} | ||
} | ||
@@ -108,6 +131,14 @@ break; | ||
this.next(); | ||
node.argument = this.match(_tokenizerTypes.types.name) || this.match(_tokenizerTypes.types.bracketL) ? this.parseBindingAtom() : this.unexpected(); | ||
node.argument = this.parseBindingIdentifier(); | ||
return this.finishNode(node, "RestElement"); | ||
}; | ||
pp.shouldAllowYieldIdentifier = function () { | ||
return this.match(_tokenizerTypes.types._yield) && !this.state.strict && !this.state.inGenerator; | ||
}; | ||
pp.parseBindingIdentifier = function () { | ||
return this.parseIdentifier(this.shouldAllowYieldIdentifier()); | ||
}; | ||
// Parses lvalue (assignable) atom. | ||
@@ -117,4 +148,7 @@ | ||
switch (this.state.type) { | ||
case _tokenizerTypes.types._yield: | ||
if (this.state.strict || this.state.inGenerator) this.unexpected(); | ||
case _tokenizerTypes.types.name: | ||
return this.parseIdent(); | ||
return this.parseIdentifier(true); | ||
@@ -136,6 +170,10 @@ case _tokenizerTypes.types.bracketL: | ||
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) { | ||
var elts = [], | ||
first = true; | ||
var elts = []; | ||
var first = true; | ||
while (!this.eat(close)) { | ||
if (first) first = false;else this.expect(_tokenizerTypes.types.comma); | ||
if (first) { | ||
first = false; | ||
} else { | ||
this.expect(_tokenizerTypes.types.comma); | ||
} | ||
if (allowEmpty && this.match(_tokenizerTypes.types.comma)) { | ||
@@ -182,3 +220,6 @@ elts.push(null); | ||
case "Identifier": | ||
if (this.strict && (_utilIdentifier.reservedWords.strictBind(expr.name) || _utilIdentifier.reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); | ||
if (this.state.strict && (_utilIdentifier.reservedWords.strictBind(expr.name) || _utilIdentifier.reservedWords.strict(expr.name))) { | ||
this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); | ||
} | ||
if (checkClashes) { | ||
@@ -198,7 +239,17 @@ if (checkClashes[expr.name]) { | ||
case "ObjectPattern": | ||
var _arr2 = expr.properties; | ||
for (var _iterator2 = (expr.properties /*: Array<Object>*/), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _getIterator(_iterator2);;) { | ||
var _ref2; | ||
for (var _i2 = 0; _i2 < _arr2.length; _i2++) { | ||
var prop = _arr2[_i2]; | ||
if (prop.type === "Property") prop = prop.value; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
} | ||
var prop = _ref2; | ||
if (prop.type === "ObjectProperty") prop = prop.value; | ||
this.checkLVal(prop, isBinding, checkClashes); | ||
@@ -209,6 +260,16 @@ } | ||
case "ArrayPattern": | ||
var _arr3 = expr.elements; | ||
for (var _iterator3 = (expr.elements /*: Array<Object>*/), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _getIterator(_iterator3);;) { | ||
var _ref3; | ||
for (var _i3 = 0; _i3 < _arr3.length; _i3++) { | ||
var elem = _arr3[_i3]; | ||
if (_isArray3) { | ||
if (_i3 >= _iterator3.length) break; | ||
_ref3 = _iterator3[_i3++]; | ||
} else { | ||
_i3 = _iterator3.next(); | ||
if (_i3.done) break; | ||
_ref3 = _i3.value; | ||
} | ||
var elem = _ref3; | ||
if (elem) this.checkLVal(elem, isBinding, checkClashes); | ||
@@ -222,3 +283,3 @@ } | ||
case "SpreadProperty": | ||
case "RestProperty": | ||
case "RestElement": | ||
@@ -225,0 +286,0 @@ this.checkLVal(expr.argument, isBinding, checkClashes); |
@@ -0,12 +1,9 @@ | ||
/* @flow */ | ||
"use strict"; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
// istanbul ignore next | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _index = require("./index"); | ||
@@ -23,3 +20,3 @@ | ||
var Node = (function () { | ||
function Node(parser, pos, loc) { | ||
function Node(pos /*:: ?: number*/, loc /*:: ?: SourceLocation*/) { | ||
_classCallCheck(this, Node); | ||
@@ -33,6 +30,7 @@ | ||
Node.prototype.__clone = function __clone() { | ||
Node.prototype.__clone = function __clone() /*: Node*/ { | ||
var node2 = new Node(); | ||
for (var key in this) node2[key] = this[key]; | ||
return node2; | ||
for (var key in this) { | ||
node2[key] = this[key]; | ||
}return node2; | ||
}; | ||
@@ -43,10 +41,8 @@ | ||
exports.Node = Node; | ||
pp.startNode = function () { | ||
return new Node(this, this.state.start, this.state.startLoc); | ||
return new Node(this.state.start, this.state.startLoc); | ||
}; | ||
pp.startNodeAt = function (pos, loc) { | ||
return new Node(this, pos, loc); | ||
return new Node(pos, loc); | ||
}; | ||
@@ -53,0 +49,0 @@ |
@@ -0,7 +1,11 @@ | ||
/* @flow */ | ||
"use strict"; | ||
// istanbul ignore next | ||
var _Object$create = require("babel-runtime/core-js/object/create")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _getIterator = require("babel-runtime/core-js/get-iterator")["default"]; | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
var _tokenizerTypes = require("../tokenizer/types"); | ||
@@ -26,14 +30,4 @@ | ||
program.sourceType = this.options.sourceType; | ||
program.body = []; | ||
var first = true; | ||
while (!this.match(_tokenizerTypes.types.eof)) { | ||
var stmt = this.parseStatement(true, true); | ||
program.body.push(stmt); | ||
if (first) { | ||
if (this.isUseStrict(stmt)) this.setStrict(true); | ||
first = false; | ||
} | ||
} | ||
this.next(); | ||
this.parseBlockBody(program, true, true, _tokenizerTypes.types.eof); | ||
@@ -50,2 +44,22 @@ file.program = this.finishNode(program, "Program"); | ||
// TODO | ||
pp.parseDirective = function () { | ||
var directiveLiteral = this.startNode(); | ||
var directive = this.startNode(); | ||
var raw = this.input.slice(this.state.start, this.state.end); | ||
var val = directiveLiteral.value = raw.slice(1, -1); // remove quotes | ||
this.addExtra(directiveLiteral, "raw", raw); | ||
this.addExtra(directiveLiteral, "rawValue", val); | ||
this.next(); | ||
directive.value = this.finishNode(directiveLiteral, "DirectiveLiteral"); | ||
this.semicolon(); | ||
return this.finishNode(directive, "Directive"); | ||
}; | ||
// Parse a single statement. | ||
@@ -98,6 +112,10 @@ // | ||
return this.parseTryStatement(node); | ||
case _tokenizerTypes.types._let:case _tokenizerTypes.types._const: | ||
case _tokenizerTypes.types._let: | ||
case _tokenizerTypes.types._const: | ||
if (!declaration) this.unexpected(); // NOTE: falls through to _var | ||
case _tokenizerTypes.types._var: | ||
return this.parseVarStatement(node, starttype); | ||
case _tokenizerTypes.types._while: | ||
@@ -114,5 +132,9 @@ return this.parseWhileStatement(node); | ||
if (!this.options.allowImportExportEverywhere) { | ||
if (!topLevel) this.raise(this.state.start, "'import' and 'export' may only appear at the top level"); | ||
if (!topLevel) { | ||
this.raise(this.state.start, "'import' and 'export' may only appear at the top level"); | ||
} | ||
if (!this.inModule) this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: module'"); | ||
if (!this.inModule) { | ||
this.raise(this.state.start, "'import' and 'export' may appear only with 'sourceType: module'"); | ||
} | ||
} | ||
@@ -122,3 +144,3 @@ return starttype === _tokenizerTypes.types._import ? this.parseImport(node) : this.parseExport(node); | ||
case _tokenizerTypes.types.name: | ||
if (this.options.features["es7.asyncFunctions"] && this.state.value === "async") { | ||
if (this.hasPlugin("asyncFunctions") && this.state.value === "async") { | ||
// peek ahead and see if next token is a function | ||
@@ -134,17 +156,16 @@ var state = this.state.clone(); | ||
} | ||
} | ||
// If the statement does not start with a statement keyword or a | ||
// brace, it's an ExpressionStatement or LabeledStatement. We | ||
// simply start parsing an expression, and afterwards, if the | ||
// next token is a colon and the expression was a simple | ||
// Identifier node, we switch to interpreting it as a label. | ||
default: | ||
var maybeName = this.state.value, | ||
expr = this.parseExpression(); | ||
// If the statement does not start with a statement keyword or a | ||
// brace, it's an ExpressionStatement or LabeledStatement. We | ||
// simply start parsing an expression, and afterwards, if the | ||
// next token is a colon and the expression was a simple | ||
// Identifier node, we switch to interpreting it as a label. | ||
var maybeName = this.state.value, | ||
expr = this.parseExpression(); | ||
if (starttype === _tokenizerTypes.types.name && expr.type === "Identifier" && this.eat(_tokenizerTypes.types.colon)) { | ||
return this.parseLabeledStatement(node, maybeName, expr); | ||
} else { | ||
return this.parseExpressionStatement(node, expr); | ||
} | ||
if (starttype === _tokenizerTypes.types.name && expr.type === "Identifier" && this.eat(_tokenizerTypes.types.colon)) { | ||
return this.parseLabeledStatement(node, maybeName, expr); | ||
} else { | ||
return this.parseExpressionStatement(node, expr); | ||
} | ||
@@ -175,3 +196,3 @@ }; | ||
pp.parseDecorator = function () { | ||
if (!this.options.features["es7.decorators"]) { | ||
if (!this.hasPlugin("decorators")) { | ||
this.unexpected(); | ||
@@ -189,3 +210,3 @@ } | ||
if (this.eat(_tokenizerTypes.types.semi) || this.canInsertSemicolon()) { | ||
if (this.isLineTerminator()) { | ||
node.label = null; | ||
@@ -195,3 +216,3 @@ } else if (!this.match(_tokenizerTypes.types.name)) { | ||
} else { | ||
node.label = this.parseIdent(); | ||
node.label = this.parseIdentifier(); | ||
this.semicolon(); | ||
@@ -202,3 +223,4 @@ } | ||
// continue to. | ||
for (var i = 0; i < this.state.labels.length; ++i) { | ||
var i = undefined; | ||
for (i = 0; i < this.state.labels.length; ++i) { | ||
var lab = this.state.labels[i]; | ||
@@ -254,3 +276,9 @@ if (node.label == null || lab.name === node.label.name) { | ||
this.finishNode(_init, "VariableDeclaration"); | ||
if ((this.match(_tokenizerTypes.types._in) || this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== _tokenizerTypes.types._var && _init.declarations[0].init)) return this.parseForIn(node, _init); | ||
if (this.match(_tokenizerTypes.types._in) || this.isContextual("of")) { | ||
if (_init.declarations.length === 1 && !_init.declarations[0].init) { | ||
return this.parseForIn(node, _init); | ||
} | ||
} | ||
return this.parseFor(node, _init); | ||
@@ -295,3 +323,3 @@ } | ||
if (this.eat(_tokenizerTypes.types.semi) || this.canInsertSemicolon()) { | ||
if (this.isLineTerminator()) { | ||
node.argument = null; | ||
@@ -317,3 +345,4 @@ } else { | ||
for (var cur, sawDefault; !this.match(_tokenizerTypes.types.braceR);) { | ||
var cur = undefined; | ||
for (var sawDefault = undefined; !this.match(_tokenizerTypes.types.braceR);) { | ||
if (this.match(_tokenizerTypes.types._case) || this.match(_tokenizerTypes.types._default)) { | ||
@@ -334,4 +363,7 @@ var isCase = this.match(_tokenizerTypes.types._case); | ||
} else { | ||
if (!cur) this.unexpected(); | ||
cur.consequent.push(this.parseStatement(true)); | ||
if (cur) { | ||
cur.consequent.push(this.parseStatement(true)); | ||
} else { | ||
this.unexpected(); | ||
} | ||
} | ||
@@ -359,11 +391,15 @@ } | ||
this.next(); | ||
node.block = this.parseBlock(); | ||
node.handler = null; | ||
if (this.match(_tokenizerTypes.types._catch)) { | ||
var clause = this.startNode(); | ||
this.next(); | ||
this.expect(_tokenizerTypes.types.parenL); | ||
clause.param = this.parseBindingAtom(); | ||
this.checkLVal(clause.param, true); | ||
this.checkLVal(clause.param, true, _Object$create(null)); | ||
this.expect(_tokenizerTypes.types.parenR); | ||
clause.body = this.parseBlock(); | ||
@@ -400,3 +436,3 @@ node.handler = this.finishNode(clause, "CatchClause"); | ||
pp.parseWithStatement = function (node) { | ||
if (this.strict) this.raise(this.state.start, "'with' in strict mode"); | ||
if (this.state.strict) this.raise(this.state.start, "'with' in strict mode"); | ||
this.next(); | ||
@@ -414,6 +450,16 @@ node.object = this.parseParenExpression(); | ||
pp.parseLabeledStatement = function (node, maybeName, expr) { | ||
var _arr = this.state.labels; | ||
for (var _iterator = (this.state.labels /*: Array<Object>*/), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _getIterator(_iterator);;) { | ||
var _ref; | ||
for (var _i = 0; _i < _arr.length; _i++) { | ||
var label = _arr[_i]; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var label = _ref; | ||
if (label.name === maybeName) { | ||
@@ -452,19 +498,56 @@ this.raise(expr.start, "Label '" + maybeName + "' is already declared"); | ||
pp.parseBlock = function (allowStrict) { | ||
var node = this.startNode(), | ||
first = true, | ||
oldStrict = undefined; | ||
pp.parseBlock = function (allowDirectives /*:: ?*/) { | ||
var node = this.startNode(); | ||
this.expect(_tokenizerTypes.types.braceL); | ||
this.parseBlockBody(node, allowDirectives, false, _tokenizerTypes.types.braceR); | ||
return this.finishNode(node, "BlockStatement"); | ||
}; | ||
// TODO | ||
pp.parseBlockBody = function (node, allowDirectives, topLevel, end) { | ||
node.body = []; | ||
this.expect(_tokenizerTypes.types.braceL); | ||
while (!this.eat(_tokenizerTypes.types.braceR)) { | ||
var stmt = this.parseStatement(true); | ||
node.body.push(stmt); | ||
if (first && allowStrict && this.isUseStrict(stmt)) { | ||
oldStrict = this.strict; | ||
this.setStrict(this.strict = true); | ||
node.directives = []; | ||
var parsedNonDirective = false; | ||
var oldStrict = undefined; | ||
var octalPosition = undefined; | ||
while (!this.eat(end)) { | ||
if (allowDirectives && !parsedNonDirective && this.match(_tokenizerTypes.types.string)) { | ||
var oldState = this.state; | ||
var lookahead = this.lookahead(); | ||
this.state = lookahead; | ||
var isDirective = this.isLineTerminator(); | ||
this.state = oldState; | ||
if (isDirective) { | ||
if (this.state.containsOctal && !octalPosition) { | ||
octalPosition = this.state.octalPosition; | ||
} | ||
var stmt = this.parseDirective(); | ||
node.directives.push(stmt); | ||
if (allowDirectives && stmt.value.value === "use strict") { | ||
oldStrict = this.state.strict; | ||
this.state.strict = true; | ||
this.setStrict(true); | ||
if (octalPosition) { | ||
this.raise(octalPosition, "Octal literal in strict mode"); | ||
} | ||
} | ||
continue; | ||
} | ||
} | ||
first = false; | ||
parsedNonDirective = true; | ||
node.body.push(this.parseStatement(true, topLevel)); | ||
} | ||
if (oldStrict === false) this.setStrict(false); | ||
return this.finishNode(node, "BlockStatement"); | ||
if (oldStrict === false) { | ||
this.setStrict(false); | ||
} | ||
}; | ||
@@ -533,12 +616,30 @@ | ||
pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync) { | ||
pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync, optionalId) { | ||
var oldInMethod = this.state.inMethod; | ||
this.state.inMethod = false; | ||
this.initFunction(node, isAsync); | ||
node.generator = this.eat(_tokenizerTypes.types.star); | ||
if (isStatement || this.match(_tokenizerTypes.types.name)) { | ||
node.id = this.parseIdent(); | ||
if (this.match(_tokenizerTypes.types.star)) { | ||
if (node.async && !this.hasPlugin("asyncGenerators")) { | ||
this.unexpected(); | ||
} else { | ||
node.generator = true; | ||
this.next(); | ||
} | ||
} | ||
if (isStatement && !optionalId && !this.match(_tokenizerTypes.types.name) && !this.match(_tokenizerTypes.types._yield)) { | ||
this.unexpected(); | ||
} | ||
if (this.match(_tokenizerTypes.types.name) || this.match(_tokenizerTypes.types._yield)) { | ||
node.id = this.parseBindingIdentifier(); | ||
} | ||
this.parseFunctionParams(node); | ||
this.parseFunctionBody(node, allowExpressionBody); | ||
this.state.inMethod = oldInMethod; | ||
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); | ||
@@ -549,3 +650,3 @@ }; | ||
this.expect(_tokenizerTypes.types.parenL); | ||
node.params = this.parseBindingList(_tokenizerTypes.types.parenR, false, this.options.features["es7.trailingFunctionCommas"]); | ||
node.params = this.parseBindingList(_tokenizerTypes.types.parenR, false, this.hasPlugin("trailingFunctionCommas")); | ||
}; | ||
@@ -556,13 +657,33 @@ | ||
pp.parseClass = function (node, isStatement) { | ||
pp.parseClass = function (node, isStatement, optionalId) { | ||
this.next(); | ||
this.parseClassId(node, isStatement); | ||
this.parseClassId(node, isStatement, optionalId); | ||
this.parseClassSuper(node); | ||
this.parseClassBody(node); | ||
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); | ||
}; | ||
pp.isClassProperty = function () { | ||
return this.match(_tokenizerTypes.types.eq) || this.isLineTerminator(); | ||
}; | ||
pp.parseClassBody = function (node) { | ||
// class bodies are implicitly strict | ||
var oldStrict = this.state.strict; | ||
this.state.strict = true; | ||
var hadConstructorCall = false; | ||
var hadConstructor = false; | ||
var decorators = []; | ||
var classBody = this.startNode(); | ||
var hadConstructor = false; | ||
classBody.body = []; | ||
this.expect(_tokenizerTypes.types.braceL); | ||
var decorators = []; | ||
while (!this.eat(_tokenizerTypes.types.braceR)) { | ||
if (this.eat(_tokenizerTypes.types.semi)) continue; | ||
if (this.eat(_tokenizerTypes.types.semi)) { | ||
continue; | ||
} | ||
if (this.match(_tokenizerTypes.types.at)) { | ||
@@ -572,3 +693,6 @@ decorators.push(this.parseDecorator()); | ||
} | ||
var method = this.startNode(); | ||
// steal the decorators if there are any | ||
if (decorators.length) { | ||
@@ -578,6 +702,11 @@ method.decorators = decorators; | ||
} | ||
var isConstructorCall = false; | ||
var isMaybeStatic = this.match(_tokenizerTypes.types.name) && this.state.value === "static"; | ||
var isGenerator = this.eat(_tokenizerTypes.types.star), | ||
isAsync = false; | ||
var isGenerator = this.eat(_tokenizerTypes.types.star); | ||
var isGetSet = false; | ||
var isAsync = false; | ||
this.parsePropertyName(method); | ||
method["static"] = isMaybeStatic && !this.match(_tokenizerTypes.types.parenL); | ||
@@ -589,15 +718,29 @@ if (method["static"]) { | ||
} | ||
if (!isGenerator && method.key.type === "Identifier" && !method.computed && this.isClassProperty()) { | ||
classBody.body.push(this.parseClassProperty(method)); | ||
continue; | ||
if (!isGenerator && method.key.type === "Identifier" && !method.computed) { | ||
if (this.isClassProperty()) { | ||
classBody.body.push(this.parseClassProperty(method)); | ||
continue; | ||
} | ||
if (this.hasPlugin("classConstructorCall") && method.key.name === "call" && this.match(_tokenizerTypes.types.name) && this.state.value === "constructor") { | ||
isConstructorCall = true; | ||
this.parsePropertyName(method); | ||
} | ||
} | ||
if (this.options.features["es7.asyncFunctions"] && !this.match(_tokenizerTypes.types.parenL) && !method.computed && method.key.type === "Identifier" && method.key.name === "async") { | ||
var isAsyncMethod = this.hasPlugin("asyncFunctions") && !this.match(_tokenizerTypes.types.parenL) && !method.computed && method.key.type === "Identifier" && method.key.name === "async"; | ||
if (isAsyncMethod) { | ||
if (this.hasPlugin("asyncGenerators") && this.eat(_tokenizerTypes.types.star)) isGenerator = true; | ||
isAsync = true; | ||
this.parsePropertyName(method); | ||
} | ||
var isGetSet = false; | ||
method.kind = "method"; | ||
if (!method.computed) { | ||
var key = method.key; | ||
// handle get/set methods | ||
// eg. class Foo { get bar() {} set bar() {} } | ||
if (!isAsync && !isGenerator && key.type === "Identifier" && !this.match(_tokenizerTypes.types.parenL) && (key.name === "get" || key.name === "set")) { | ||
@@ -608,3 +751,6 @@ isGetSet = true; | ||
} | ||
if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) { | ||
// disallow invalid constructors | ||
var isConstructor = !isConstructorCall && !method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "StringLiteral" && key.value === "constructor"); | ||
if (isConstructor) { | ||
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class"); | ||
@@ -617,11 +763,30 @@ if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier"); | ||
} | ||
// disallow static prototype method | ||
var isStaticPrototype = method["static"] && (key.type === "Identifier" && key.name === "prototype" || key.type === "StringLiteral" && key.value === "prototype"); | ||
if (isStaticPrototype) { | ||
this.raise(key.start, "Classes may not have static property named prototype"); | ||
} | ||
} | ||
if (method.kind === "constructor" && method.decorators) { | ||
// convert constructor to a constructor call | ||
if (isConstructorCall) { | ||
if (hadConstructorCall) this.raise(method.start, "Duplicate constructor call in the same class"); | ||
method.kind = "constructorCall"; | ||
hadConstructorCall = true; | ||
} | ||
// disallow decorators on class constructors | ||
if ((method.kind === "constructor" || method.kind === "constructorCall") && method.decorators) { | ||
this.raise(method.start, "You can't attach decorators to a class constructor"); | ||
} | ||
this.parseClassMethod(classBody, method, isGenerator, isAsync); | ||
// get methods aren't allowed to have any parameters | ||
// set methods must have exactly 1 parameter | ||
if (isGetSet) { | ||
var paramCount = method.kind === "get" ? 0 : 1; | ||
if (method.value.params.length !== paramCount) { | ||
var start = method.value.start; | ||
if (method.params.length !== paramCount) { | ||
var start = method.start; | ||
if (method.kind === "get") { | ||
@@ -641,7 +806,4 @@ this.raise(start, "getter should have no params"); | ||
node.body = this.finishNode(classBody, "ClassBody"); | ||
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); | ||
}; | ||
pp.isClassProperty = function () { | ||
return this.match(_tokenizerTypes.types.eq) || (this.match(_tokenizerTypes.types.semi) || this.canInsertSemicolon()); | ||
this.state.strict = oldStrict; | ||
}; | ||
@@ -651,3 +813,3 @@ | ||
if (this.match(_tokenizerTypes.types.eq)) { | ||
if (!this.options.features["es7.classProperties"]) this.unexpected(); | ||
if (!this.hasPlugin("classProperties")) this.unexpected(); | ||
this.next(); | ||
@@ -663,8 +825,16 @@ node.value = this.parseMaybeAssign(); | ||
pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) { | ||
method.value = this.parseMethod(isGenerator, isAsync); | ||
classBody.body.push(this.finishNode(method, "MethodDefinition")); | ||
this.parseMethod(method, isGenerator, isAsync); | ||
classBody.body.push(this.finishNode(method, "ClassMethod")); | ||
}; | ||
pp.parseClassId = function (node, isStatement) { | ||
node.id = this.match(_tokenizerTypes.types.name) ? this.parseIdent() : isStatement ? this.unexpected() : null; | ||
pp.parseClassId = function (node, isStatement, optionalId) { | ||
if (this.match(_tokenizerTypes.types.name)) { | ||
node.id = this.parseIdentifier(); | ||
} else { | ||
if (optionalId || !isStatement) { | ||
node.id = null; | ||
} else { | ||
this.unexpected(); | ||
} | ||
} | ||
}; | ||
@@ -684,4 +854,4 @@ | ||
this.next(); | ||
if (this.options.features["es7.exportExtensions"] && this.eatContextual("as")) { | ||
specifier.exported = this.parseIdent(); | ||
if (this.hasPlugin("exportExtensions") && this.eatContextual("as")) { | ||
specifier.exported = this.parseIdentifier(); | ||
node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")]; | ||
@@ -694,5 +864,5 @@ this.parseExportSpecifiersMaybe(node); | ||
} | ||
} else if (this.options.features["es7.exportExtensions"] && this.isExportDefaultSpecifier()) { | ||
} else if (this.hasPlugin("exportExtensions") && this.isExportDefaultSpecifier()) { | ||
var specifier = this.startNode(); | ||
specifier.exported = this.parseIdent(true); | ||
specifier.exported = this.parseIdentifier(true); | ||
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; | ||
@@ -704,3 +874,3 @@ if (this.match(_tokenizerTypes.types.comma) && this.lookahead().type === _tokenizerTypes.types.star) { | ||
this.expectContextual("as"); | ||
_specifier.exported = this.parseIdent(); | ||
_specifier.exported = this.parseIdentifier(); | ||
node.specifiers.push(this.finishNode(_specifier, "ExportNamespaceSpecifier")); | ||
@@ -713,10 +883,11 @@ } else { | ||
// export default ... | ||
var possibleDeclaration = this.match(_tokenizerTypes.types._function) || this.match(_tokenizerTypes.types._class); | ||
var expr = this.parseMaybeAssign(); | ||
var needsSemi = true; | ||
if (possibleDeclaration) { | ||
needsSemi = false; | ||
if (expr.id) { | ||
expr.type = expr.type === "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration"; | ||
} | ||
var expr = this.startNode(); | ||
var needsSemi = false; | ||
if (this.eat(_tokenizerTypes.types._function)) { | ||
expr = this.parseFunction(expr, true, false, false, true); | ||
} else if (this.match(_tokenizerTypes.types._class)) { | ||
expr = this.parseClass(expr, true, true); | ||
} else { | ||
needsSemi = true; | ||
expr = this.parseMaybeAssign(); | ||
} | ||
@@ -764,3 +935,3 @@ node.declaration = expr; | ||
pp.parseExportFrom = function (node, expect) { | ||
pp.parseExportFrom = function (node, expect /*:: ?*/) { | ||
if (this.eatContextual("from")) { | ||
@@ -781,3 +952,3 @@ node.source = this.match(_tokenizerTypes.types.string) ? this.parseExprAtom() : this.unexpected(); | ||
pp.shouldParseExportDeclaration = function () { | ||
return this.options.features["es7.asyncFunctions"] && this.isContextual("async"); | ||
return this.hasPlugin("asyncFunctions") && this.isContextual("async"); | ||
}; | ||
@@ -798,4 +969,6 @@ | ||
pp.parseExportSpecifiers = function () { | ||
var nodes = [], | ||
first = true; | ||
var nodes = []; | ||
var first = true; | ||
var needsFrom = undefined; | ||
// export { x, y as z } [from '...'] | ||
@@ -812,8 +985,16 @@ this.expect(_tokenizerTypes.types.braceL); | ||
var isDefault = this.match(_tokenizerTypes.types._default); | ||
if (isDefault && !needsFrom) needsFrom = true; | ||
var node = this.startNode(); | ||
node.local = this.parseIdent(this.match(_tokenizerTypes.types._default)); | ||
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local.__clone(); | ||
node.local = this.parseIdentifier(isDefault); | ||
node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone(); | ||
nodes.push(this.finishNode(node, "ExportSpecifier")); | ||
} | ||
// https://github.com/ember-cli/ember-cli/pull/3739 | ||
if (needsFrom && !this.isContextual("from")) { | ||
this.unexpected(); | ||
} | ||
return nodes; | ||
@@ -849,3 +1030,3 @@ }; | ||
startLoc = this.state.startLoc; | ||
node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdent(), startPos, startLoc)); | ||
node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdentifier(), startPos, startLoc)); | ||
if (!this.eat(_tokenizerTypes.types.comma)) return; | ||
@@ -858,3 +1039,3 @@ } | ||
this.expectContextual("as"); | ||
specifier.local = this.parseIdent(); | ||
specifier.local = this.parseIdentifier(); | ||
this.checkLVal(specifier.local, true); | ||
@@ -875,4 +1056,4 @@ node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier")); | ||
var specifier = this.startNode(); | ||
specifier.imported = this.parseIdent(true); | ||
specifier.local = this.eatContextual("as") ? this.parseIdent() : specifier.imported.__clone(); | ||
specifier.imported = this.parseIdentifier(true); | ||
specifier.local = this.eatContextual("as") ? this.parseIdentifier() : specifier.imported.__clone(); | ||
this.checkLVal(specifier.local, true); | ||
@@ -879,0 +1060,0 @@ node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); |
@@ -0,7 +1,7 @@ | ||
/* @flow */ | ||
"use strict"; | ||
// istanbul ignore next | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _tokenizerTypes = require("../tokenizer/types"); | ||
@@ -19,6 +19,9 @@ | ||
// Test whether a statement node is the string literal `"use strict"`. | ||
// TODO | ||
pp.isUseStrict = function (stmt) { | ||
return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.raw.slice(1, -1) === "use strict"; | ||
pp.addExtra = function (node, key, val) { | ||
if (!node) return; | ||
var extra = node.extra = node.extra || {}; | ||
extra[key] = val; | ||
}; | ||
@@ -66,2 +69,8 @@ | ||
// TODO | ||
pp.isLineTerminator = function () { | ||
return this.eat(_tokenizerTypes.types.semi) || this.canInsertSemicolon(); | ||
}; | ||
// Consume a semicolon, or, failing that, see if we are allowed to | ||
@@ -68,0 +77,0 @@ // pretend that there is a semicolon at this position. |
@@ -0,8 +1,9 @@ | ||
/* @flow */ | ||
"use strict"; | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _tokenizerTypes = require("../tokenizer/types"); | ||
@@ -34,3 +35,3 @@ | ||
var id = node.id = this.parseIdent(); | ||
var id = node.id = this.parseIdentifier(); | ||
@@ -90,3 +91,3 @@ var typeNode = this.startNode(); | ||
} else { | ||
node.id = this.parseIdent(); | ||
node.id = this.parseIdentifier(); | ||
} | ||
@@ -114,3 +115,3 @@ | ||
pp.flowParseInterfaceish = function (node, allowStatic) { | ||
node.id = this.parseIdent(); | ||
node.id = this.parseIdentifier(); | ||
@@ -137,3 +138,3 @@ if (this.isRelational("<")) { | ||
node.id = this.parseIdent(); | ||
node.id = this.parseIdentifier(); | ||
if (this.isRelational("<")) { | ||
@@ -156,3 +157,3 @@ node.typeParameters = this.flowParseTypeParameterInstantiation(); | ||
pp.flowParseTypeAlias = function (node) { | ||
node.id = this.parseIdent(); | ||
node.id = this.parseIdentifier(); | ||
@@ -211,3 +212,3 @@ if (this.isRelational("<")) { | ||
pp.flowParseObjectPropertyKey = function () { | ||
return this.match(_tokenizerTypes.types.num) || this.match(_tokenizerTypes.types.string) ? this.parseExprAtom() : this.parseIdent(true); | ||
return this.match(_tokenizerTypes.types.num) || this.match(_tokenizerTypes.types.string) ? this.parseExprAtom() : this.parseIdentifier(true); | ||
}; | ||
@@ -274,5 +275,5 @@ | ||
var nodeStart = this.startNode(); | ||
var node; | ||
var propertyKey; | ||
var isStatic; | ||
var node = undefined; | ||
var propertyKey = undefined; | ||
var isStatic = undefined; | ||
@@ -301,3 +302,3 @@ nodeStart.callProperties = []; | ||
if (isStatic && this.match(_tokenizerTypes.types.colon)) { | ||
propertyKey = this.parseIdent(); | ||
propertyKey = this.parseIdentifier(); | ||
} else { | ||
@@ -343,3 +344,3 @@ propertyKey = this.flowParseObjectPropertyKey(); | ||
node2.qualification = node.id; | ||
node2.id = this.parseIdent(); | ||
node2.id = this.parseIdentifier(); | ||
node.id = this.finishNode(node2, "QualifiedTypeIdentifier"); | ||
@@ -379,3 +380,3 @@ } | ||
var node = this.startNode(); | ||
node.name = this.parseIdent(); | ||
node.name = this.parseIdentifier(); | ||
if (this.eat(_tokenizerTypes.types.question)) { | ||
@@ -436,4 +437,4 @@ optional = true; | ||
var node = this.startNode(); | ||
var tmp; | ||
var type; | ||
var tmp = undefined; | ||
var type = undefined; | ||
var isGroupedType = false; | ||
@@ -443,3 +444,3 @@ | ||
case _tokenizerTypes.types.name: | ||
return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdent()); | ||
return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); | ||
@@ -508,4 +509,5 @@ case _tokenizerTypes.types.braceL: | ||
case _tokenizerTypes.types.string: | ||
node.rawValue = node.value = this.state.value; | ||
node.raw = this.input.slice(this.state.start, this.state.end); | ||
node.value = this.state.value; | ||
this.addExtra(node, "rawValue", node.value); | ||
this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); | ||
this.next(); | ||
@@ -520,4 +522,5 @@ return this.finishNode(node, "StringLiteralTypeAnnotation"); | ||
case _tokenizerTypes.types.num: | ||
node.rawValue = node.value = this.state.value; | ||
node.raw = this.input.slice(this.state.start, this.state.end); | ||
node.value = this.state.value; | ||
this.addExtra(node, "rawValue", node.value); | ||
this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end)); | ||
this.next(); | ||
@@ -592,3 +595,3 @@ return this.finishNode(node, "NumberLiteralTypeAnnotation"); | ||
pp.flowParseTypeAnnotatableIdentifier = function (requireTypeAnnotation, canBeOptionalParam) { | ||
var ident = this.parseIdent(); | ||
var ident = this.parseIdentifier(); | ||
var isOptionalParam = false; | ||
@@ -615,3 +618,3 @@ | ||
exports["default"] = function (instance) { | ||
// function name(): string {} | ||
// plain function return types: function name(): string {} | ||
instance.extend("parseFunctionBody", function (inner) { | ||
@@ -629,6 +632,7 @@ return function (node, allowExpression) { | ||
// interfaces | ||
instance.extend("parseStatement", function (inner) { | ||
return function (declaration, topLevel) { | ||
// strict mode handling of `interface` since it's a reserved word | ||
if (this.strict && this.match(_tokenizerTypes.types.name) && this.state.value === "interface") { | ||
if (this.state.strict && this.match(_tokenizerTypes.types.name) && this.state.value === "interface") { | ||
var node = this.startNode(); | ||
@@ -643,2 +647,3 @@ this.next(); | ||
// declares, interfaces and type aliases | ||
instance.extend("parseExpressionStatement", function (inner) { | ||
@@ -664,2 +669,3 @@ return function (node, expr) { | ||
// export type | ||
instance.extend("shouldParseExportDeclaration", function (inner) { | ||
@@ -672,3 +678,3 @@ return function () { | ||
instance.extend("parseParenItem", function () { | ||
return function (node, startLoc, startPos, forceArrow) { | ||
return function (node, startLoc, startPos, forceArrow /*:: ?*/) { | ||
if (this.match(_tokenizerTypes.types.colon)) { | ||
@@ -731,4 +737,4 @@ var typeCastNode = this.startNodeAt(startLoc, startPos); | ||
instance.extend("parseClassId", function (inner) { | ||
return function (node, isStatement) { | ||
inner.call(this, node, isStatement); | ||
return function (node) { | ||
inner.apply(this, arguments); | ||
if (this.isRelational("<")) { | ||
@@ -752,2 +758,3 @@ node.typeParameters = this.flowParseTypeParameterDeclaration(); | ||
// ensure that inside flow types, we bypass the jsx parser plugin | ||
instance.extend("readToken", function (inner) { | ||
@@ -763,2 +770,3 @@ return function (code) { | ||
// don't lex any token as a jsx one inside a flow type | ||
instance.extend("jsx_readToken", function (inner) { | ||
@@ -775,2 +783,3 @@ return function () { | ||
// turn type casts that we found in function parameter head into type annotated params | ||
instance.extend("toAssignableList", function (inner) { | ||
@@ -788,2 +797,4 @@ return function (exprList, isBinding) { | ||
// this is a list of nodes, from something like a call expression, we need to filter the | ||
// type casts that we've found that are illegal in this context | ||
instance.extend("toReferencedList", function () { | ||
@@ -802,2 +813,4 @@ return function (exprList) { | ||
// parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents | ||
// the position where this function is cal;ed | ||
instance.extend("parseExprListItem", function (inner) { | ||
@@ -818,2 +831,3 @@ return function (allowEmpty, refShorthandDefaultPos) { | ||
// parse class property type annotations | ||
instance.extend("parseClassProperty", function (inner) { | ||
@@ -828,2 +842,3 @@ return function (node) { | ||
// determine whether or not we're currently in the position where a class property would appear | ||
instance.extend("isClassProperty", function (inner) { | ||
@@ -835,14 +850,14 @@ return function () { | ||
// parse type parameters for class methods | ||
instance.extend("parseClassMethod", function () { | ||
return function (classBody, method, isGenerator, isAsync) { | ||
var typeParameters; | ||
if (this.isRelational("<")) { | ||
typeParameters = this.flowParseTypeParameterDeclaration(); | ||
method.typeParameters = this.flowParseTypeParameterDeclaration(); | ||
} | ||
method.value = this.parseMethod(isGenerator, isAsync); | ||
method.value.typeParameters = typeParameters; | ||
classBody.body.push(this.finishNode(method, "MethodDefinition")); | ||
this.parseMethod(method, isGenerator, isAsync); | ||
classBody.body.push(this.finishNode(method, "ClassMethod")); | ||
}; | ||
}); | ||
// parse a the super class type parameters and implements | ||
instance.extend("parseClassSuper", function (inner) { | ||
@@ -859,3 +874,3 @@ return function (node, isStatement) { | ||
var _node = this.startNode(); | ||
_node.id = this.parseIdent(); | ||
_node.id = this.parseIdentifier(); | ||
if (this.isRelational("<")) { | ||
@@ -872,5 +887,6 @@ _node.typeParameters = this.flowParseTypeParameterInstantiation(); | ||
// parse type parameters for object method shorthand | ||
instance.extend("parseObjPropValue", function (inner) { | ||
return function (prop) { | ||
var typeParameters; | ||
var typeParameters = undefined; | ||
@@ -887,3 +903,3 @@ // method shorthand | ||
if (typeParameters) { | ||
prop.value.typeParameters = typeParameters; | ||
(prop.value || prop).typeParameters = typeParameters; | ||
} | ||
@@ -906,2 +922,3 @@ }; | ||
// parse typeof and type imports | ||
instance.extend("parseImportSpecifiers", function (inner) { | ||
@@ -911,3 +928,8 @@ return function (node) { | ||
var kind = this.match(_tokenizerTypes.types._typeof) ? "typeof" : this.isContextual("type") ? "type" : null; | ||
var kind = null; | ||
if (this.match(_tokenizerTypes.types._typeof)) { | ||
kind = "typeof"; | ||
} else if (this.isContextual("type")) { | ||
kind = "type"; | ||
} | ||
if (kind) { | ||
@@ -925,3 +947,3 @@ var lh = this.lookahead(); | ||
// function foo<T>() {} | ||
// parse function type parameters - function foo<T>() {} | ||
instance.extend("parseFunctionParams", function (inner) { | ||
@@ -936,3 +958,3 @@ return function (node) { | ||
// var foo: string = bar | ||
// parse flow type annotations on variable declarator heads - let foo: string = bar | ||
instance.extend("parseVarHead", function (inner) { | ||
@@ -948,3 +970,3 @@ return function (decl) { | ||
// var foo = (async (): number => {}); | ||
// parse the return type of an async arrow function - let foo = (async (): number => {}); | ||
instance.extend("parseAsyncArrowFromCallExpression", function (inner) { | ||
@@ -960,2 +982,10 @@ return function (node, call) { | ||
// todo description | ||
instance.extend("shouldParseAsyncArrow", function (inner) { | ||
return function () { | ||
return this.match(_tokenizerTypes.types.colon) || inner.call(this); | ||
}; | ||
}); | ||
// handle return types for arrow functions | ||
instance.extend("parseParenAndDistinguishExpression", function (inner) { | ||
@@ -967,3 +997,3 @@ return function (startPos, startLoc, canBeArrow, isAsync) { | ||
if (this.lookahead().type === _tokenizerTypes.types.parenR) { | ||
// var foo = (): number => {}; | ||
// let foo = (): number => {}; | ||
this.expect(_tokenizerTypes.types.parenL); | ||
@@ -977,3 +1007,3 @@ this.expect(_tokenizerTypes.types.parenR); | ||
} else { | ||
// var foo = (foo): number => {}; | ||
// let foo = (foo): number => {}; | ||
var node = inner.call(this, startPos, startLoc, canBeArrow, isAsync); | ||
@@ -980,0 +1010,0 @@ |
@@ -0,8 +1,9 @@ | ||
/* @flow */ | ||
"use strict"; | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _xhtml = require("./xhtml"); | ||
@@ -57,4 +58,4 @@ | ||
pp.jsxReadToken = function () { | ||
var out = "", | ||
chunkStart = this.state.pos; | ||
var out = ""; | ||
var chunkStart = this.state.pos; | ||
for (;;) { | ||
@@ -102,3 +103,3 @@ if (this.state.pos >= this.input.length) { | ||
var ch = this.input.charCodeAt(this.state.pos); | ||
var out; | ||
var out = undefined; | ||
++this.state.pos; | ||
@@ -118,4 +119,4 @@ if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { | ||
pp.jsxReadString = function (quote) { | ||
var out = "", | ||
chunkStart = ++this.state.pos; | ||
var out = ""; | ||
var chunkStart = ++this.state.pos; | ||
for (;;) { | ||
@@ -146,5 +147,5 @@ if (this.state.pos >= this.input.length) { | ||
pp.jsxReadEntity = function () { | ||
var str = "", | ||
count = 0, | ||
entity; | ||
var str = ""; | ||
var count = 0; | ||
var entity = undefined; | ||
var ch = this.input[this.state.pos]; | ||
@@ -186,4 +187,4 @@ | ||
pp.jsxReadWord = function () { | ||
var ch, | ||
start = this.state.pos; | ||
var ch = undefined; | ||
var start = this.state.pos; | ||
do { | ||
@@ -259,3 +260,3 @@ ch = this.input.charCodeAt(++this.state.pos); | ||
pp.jsxParseAttributeValue = function () { | ||
var node; | ||
var node = undefined; | ||
switch (this.state.type) { | ||
@@ -273,3 +274,3 @@ case _tokenizerTypes.types.braceL: | ||
node = this.parseExprAtom(); | ||
node.rawValue = null; | ||
node.extra = null; | ||
return node; | ||
@@ -282,3 +283,3 @@ | ||
// JSXEmptyExpression is unique type since it doesn"t actually parse anything, | ||
// JSXEmptyExpression is unique type since it doesn't actually parse anything, | ||
// and so it should start at the end of last read token (left brace) and finish | ||
@@ -288,11 +289,4 @@ // at the beginning of the next one (right brace). | ||
pp.jsxParseEmptyExpression = function () { | ||
var tmp = this.state.start; | ||
this.state.start = this.state.lastTokEnd; | ||
this.state.lastTokEnd = tmp; | ||
tmp = this.state.startLoc; | ||
this.state.startLoc = this.state.lastTokEndLoc; | ||
this.state.lastTokEndLoc = tmp; | ||
return this.finishNode(this.startNode(), "JSXEmptyExpression"); | ||
var node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); | ||
return this.finishNodeAt(node, "JSXEmptyExpression", this.start, this.startLoc); | ||
}; | ||
@@ -414,5 +408,5 @@ | ||
if (this.match(_tokenizerTypes.types.jsxText)) { | ||
var node = this.parseLiteral(this.state.value); | ||
var node = this.parseLiteral(this.state.value, "JSXText"); | ||
// https://github.com/babel/babel/issues/2078 | ||
node.rawValue = null; | ||
node.extra = null; | ||
return node; | ||
@@ -419,0 +413,0 @@ } else if (this.match(_tokenizerTypes.types.jsxTagStart)) { |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// The algorithm used to determine whether a regexp can appear at a | ||
@@ -7,10 +9,9 @@ // given point in the program is loosely based on sweet.js' approach. | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _types = require("./types"); | ||
var TokContext = function TokContext(token, isExpr, preserveSpace, override) { | ||
var TokContext = function TokContext(token /*: string*/, isExpr /*:: ?: boolean*/, preserveSpace /*:: ?: boolean*/, override /*:: ?: Function*/) { | ||
_classCallCheck(this, TokContext); | ||
@@ -17,0 +18,0 @@ |
@@ -0,12 +1,11 @@ | ||
/* @flow */ | ||
"use strict"; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; | ||
// istanbul ignore next | ||
exports.__esModule = true; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _utilIdentifier = require("../util/identifier"); | ||
@@ -30,2 +29,3 @@ | ||
/*:: import type { TokenType } from "./types";*/ | ||
var Token = function Token(state) { | ||
@@ -43,37 +43,20 @@ _classCallCheck(this, Token); | ||
// Are we running under Rhino? | ||
/* global Packages */ | ||
; | ||
exports.Token = Token; | ||
var isRhino = typeof Packages === "object" && Object.prototype.toString.call(Packages) === "[object JavaPackage]"; | ||
// Parse a regular expression. Some context-awareness is necessary, | ||
// since a '/' inside a '[]' set does not end the expression. | ||
function tryCreateRegexp(src, flags, throwErrorStart) { | ||
try { | ||
return new RegExp(src, flags); | ||
} catch (e) { | ||
if (throwErrorStart !== undefined) { | ||
if (e instanceof SyntaxError) this.raise(throwErrorStart, "Error parsing regular expression: " + e.message); | ||
this.raise(e); | ||
} | ||
} | ||
} | ||
var regexpUnicodeSupport = !!tryCreateRegexp("", "u"); | ||
function codePointToString(code) { | ||
// UTF-16 Decoding | ||
if (code <= 0xFFFF) return String.fromCharCode(code); | ||
return String.fromCharCode((code - 0x10000 >> 10) + 0xD800, (code - 0x10000 & 1023) + 0xDC00); | ||
if (code <= 0xFFFF) { | ||
return String.fromCharCode(code); | ||
} else { | ||
return String.fromCharCode((code - 0x10000 >> 10) + 0xD800, (code - 0x10000 & 1023) + 0xDC00); | ||
} | ||
} | ||
var Tokenizer = (function () { | ||
function Tokenizer(input) { | ||
function Tokenizer(options, input) { | ||
_classCallCheck(this, Tokenizer); | ||
this.state = new _state2["default"](); | ||
this.state.init(input); | ||
this.state.init(options, input); | ||
} | ||
@@ -84,3 +67,5 @@ | ||
Tokenizer.prototype.next = function next() { | ||
this.state.tokens.push(new Token(this.state)); | ||
if (!this.isLookahead) { | ||
this.state.tokens.push(new Token(this.state)); | ||
} | ||
@@ -113,7 +98,17 @@ this.state.lastTokEnd = this.state.end; | ||
Tokenizer.prototype.isKeyword = function isKeyword(word) { | ||
return _utilIdentifier.isKeyword(word); | ||
}; | ||
// TODO | ||
Tokenizer.prototype.lookahead = function lookahead() { | ||
var old = this.state; | ||
this.state = old.clone(); | ||
this.state = old.clone(true); | ||
this.isLookahead = true; | ||
this.next(); | ||
var curr = this.state.clone(); | ||
this.isLookahead = false; | ||
var curr = this.state.clone(true); | ||
this.state = old; | ||
@@ -127,3 +122,3 @@ return curr; | ||
Tokenizer.prototype.setStrict = function setStrict(strict) { | ||
this.strict = strict; | ||
this.state.strict = strict; | ||
if (!this.match(_types.types.num) && !this.match(_types.types.string)) return; | ||
@@ -149,2 +144,4 @@ this.state.pos = this.state.start; | ||
this.state.containsOctal = false; | ||
this.state.octalPosition = null; | ||
this.state.start = this.state.pos; | ||
@@ -164,5 +161,7 @@ this.state.startLoc = this.state.curPosition(); | ||
// identifiers, so '\' also dispatches to that. | ||
if (_utilIdentifier.isIdentifierStart(code, true) || code === 92 /* '\' */) return this.readWord(); | ||
return this.getTokenFromCode(code); | ||
if (_utilIdentifier.isIdentifierStart(code, true) || code === 92 /* '\' */) { | ||
return this.readWord(); | ||
} else { | ||
return this.getTokenFromCode(code); | ||
} | ||
}; | ||
@@ -184,8 +183,10 @@ | ||
end: end, | ||
loc: new _utilLocation.SourceLocation(startLoc, endLoc), | ||
range: [start, end] | ||
loc: new _utilLocation.SourceLocation(startLoc, endLoc) | ||
}; | ||
this.state.tokens.push(comment); | ||
this.state.comments.push(comment); | ||
if (!this.isLookahead) { | ||
this.state.tokens.push(comment); | ||
this.state.comments.push(comment); | ||
} | ||
this.addComment(comment); | ||
@@ -336,3 +337,3 @@ }; | ||
if (next === 42 && this.options.features["es7.exponentiationOperator"]) { | ||
if (next === 42 && this.hasPlugin("exponentiationOperator")) { | ||
// '*' | ||
@@ -456,3 +457,3 @@ width++; | ||
case 58: | ||
if (this.options.features["es7.functionBind"] && this.input.charCodeAt(this.state.pos + 1) === 58) { | ||
if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) { | ||
return this.finishOp(_types.types.doubleColon, 2); | ||
@@ -539,6 +540,2 @@ } else { | ||
Tokenizer.prototype.readRegexp = function readRegexp() { | ||
// istanbul ignore next | ||
var _this = this; | ||
var escaped = undefined, | ||
@@ -572,37 +569,9 @@ inClass = undefined, | ||
var mods = this.readWord1(); | ||
var tmp = content; | ||
if (mods) { | ||
var validFlags = /^[gmsiyu]*$/; | ||
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag"); | ||
if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) { | ||
// Replace each astral symbol and every Unicode escape sequence that | ||
// possibly represents an astral symbol or a paired surrogate with a | ||
// single ASCII symbol to avoid throwing on regular expressions that | ||
// are only valid in combination with the `/u` flag. | ||
// Note: replacing with the ASCII symbol `x` might cause false | ||
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a | ||
// perfectly valid pattern that is equivalent to `[a-b]`, but it would | ||
// be replaced by `[x-b]` which throws an error. | ||
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, function (match, code, offset) { | ||
code = Number("0x" + code); | ||
if (code > 0x10FFFF) _this.raise(start + offset + 3, "Code point out of bounds"); | ||
return "x"; | ||
}); | ||
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x"); | ||
} | ||
} | ||
// Detect invalid regular expressions. | ||
var value = null; | ||
// Rhino's regular expression parser is flaky and throws uncatchable exceptions, | ||
// so don't do detection if we are running under Rhino | ||
if (!isRhino) { | ||
tryCreateRegexp.call(this, tmp, undefined, start); | ||
// Get a regular expression object for this pattern-flag pair, or `null` in | ||
// case the current environment doesn't support the flags it uses. | ||
value = tryCreateRegexp.call(this, content, mods); | ||
} | ||
return this.finishToken(_types.types.regexp, { | ||
pattern: content, | ||
flags: mods, | ||
value: value | ||
flags: mods | ||
}); | ||
@@ -677,3 +646,3 @@ }; | ||
val = parseInt(str, 10); | ||
} else if (/[89]/.test(str) || this.strict) { | ||
} else if (/[89]/.test(str) || this.state.strict) { | ||
this.raise(start, "Invalid number"); | ||
@@ -810,4 +779,10 @@ } else { | ||
} | ||
if (octal > 0 && (this.strict || inTemplate)) { | ||
this.raise(this.state.pos - 2, "Octal literal in strict mode"); | ||
if (octal > 0) { | ||
if (!this.state.containsOctal) { | ||
this.state.containsOctal = true; | ||
this.state.octalPosition = this.state.pos - 2; | ||
} | ||
if (this.state.strict || inTemplate) { | ||
this.raise(this.state.pos - 2, "Octal literal in strict mode"); | ||
} | ||
} | ||
@@ -879,3 +854,5 @@ this.state.pos += octalStr.length - 1; | ||
var type = _types.types.name; | ||
if (!this.state.containsEsc && this.isKeyword(word)) type = _types.keywords[word]; | ||
if (!this.state.containsEsc && this.isKeyword(word)) { | ||
type = _types.keywords[word]; | ||
} | ||
return this.finishToken(type, word); | ||
@@ -882,0 +859,0 @@ }; |
@@ -0,8 +1,9 @@ | ||
/* @flow */ | ||
"use strict"; | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _utilLocation = require("../util/location"); | ||
@@ -14,2 +15,4 @@ | ||
/*:: import type { TokContext } from "./context";*/ | ||
/*:: import type { Token } from "./index";*/ | ||
var State = (function () { | ||
@@ -20,24 +23,19 @@ function State() { | ||
State.prototype.init = function init(input) { | ||
State.prototype.init = function init(options /*: Object*/, input /*: string*/) { | ||
this.strict = options.strictMode === false ? false : options.sourceType === "module"; | ||
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.inFunction = this.inGenerator = false; | ||
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 = []; | ||
@@ -47,36 +45,24 @@ this.leadingComments = []; | ||
// 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 = _types.types.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 = [_context.types.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 = this.containsOctal = false; | ||
this.octalPosition = null; | ||
this.containsEsc = false; | ||
return this; | ||
}; | ||
// TODO | ||
State.prototype.curPosition = function curPosition() { | ||
@@ -86,7 +72,11 @@ return new _utilLocation.Position(this.curLine, this.pos - this.lineStart); | ||
State.prototype.clone = function clone() { | ||
State.prototype.clone = function clone(skipArrays /*:: ?*/) { | ||
var state = new State(); | ||
for (var key in this) { | ||
var val = this[key]; | ||
if (Array.isArray(val)) val = val.slice(); | ||
if ((!skipArrays || key === "context") && Array.isArray(val)) { | ||
val = val.slice(); | ||
} | ||
state[key] = val; | ||
@@ -101,2 +91,42 @@ } | ||
exports["default"] = State; | ||
module.exports = exports["default"]; | ||
module.exports = exports["default"]; | ||
// TODO | ||
// Used to signify the start of a potential arrow function | ||
// Flags to track whether we are in a function, a generator. | ||
// Labels in scope. | ||
// Leading decorators. | ||
// Token store. | ||
// Comment store. | ||
// Comment attachment store | ||
// The current position of the tokenizer in the input. | ||
// Properties of the current token: | ||
// Its type | ||
// For tokens that include more information than their type, the value | ||
// Its start and end offset | ||
// And, if locations are used, the {line, column} object | ||
// corresponding to those offsets | ||
// Position information for the previous token | ||
// The context stack is used to superficially track syntactic | ||
// context to predict whether a regular expression is allowed in a | ||
// given position. | ||
// 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. | ||
// TODO |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// ## Token types | ||
@@ -21,7 +23,6 @@ | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
exports.__esModule = true; | ||
// istanbul ignore next | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var TokenType = function TokenType(label) { | ||
@@ -133,3 +134,3 @@ var conf = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
kw("default", beforeExpr); | ||
kw("do", { isLoop: true }); | ||
kw("do", { isLoop: true, beforeExpr: true }); | ||
kw("else", beforeExpr); | ||
@@ -136,0 +137,0 @@ kw("finally"); |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// This is a trick taken from Esprima. It turns out that, on | ||
@@ -2,0 +4,0 @@ // non-Chrome browsers, to check whether a string is in a set, a |
@@ -0,9 +1,10 @@ | ||
/* @flow */ | ||
"use strict"; | ||
var _classCallCheck = require("babel-runtime/helpers/class-call-check")["default"]; | ||
exports.__esModule = true; | ||
exports.getLineInfo = getLineInfo; | ||
// istanbul ignore next | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _whitespace = require("./whitespace"); | ||
@@ -10,0 +11,0 @@ |
@@ -0,1 +1,3 @@ | ||
/* @flow */ | ||
// Matches a whole line break (where CRLF is considered a single | ||
@@ -2,0 +4,0 @@ // line break). Used to count lines. |
{ | ||
"name": "babylon", | ||
"version": "5.8.29", | ||
"description": "", | ||
"version": "6.0.2", | ||
"description": "A JavaScript parser", | ||
"author": "Sebastian McKenzie <sebmck@gmail.com>", | ||
@@ -9,3 +9,9 @@ "homepage": "https://babeljs.io/", | ||
"repository": "babel/babel", | ||
"main": "lib/index.js" | ||
"main": "lib/index.js", | ||
"dependencies": { | ||
"babel-runtime": "^6.0.2" | ||
}, | ||
"bin": { | ||
"babylon": "./bin/babylon.js" | ||
} | ||
} |
@@ -9,2 +9,7 @@ <p align="center"> | ||
- ES6 enabled by default. | ||
- Comment attachment. | ||
- Support for JSX and Flow. | ||
- Support for experimental language proposals. | ||
## Credits | ||
@@ -15,3 +20,56 @@ | ||
Significant diversions are expected to occur in the future such as streaming, EBNF definitions, sweet.js integration, | ||
interspacial parsing, comment attachment and more. | ||
Significant diversions are expected to occur in the future such as streaming, EBNF definitions, sweet.js integration, interspacial parsing and more. | ||
## API | ||
### `babylon.parse(code, [options])` | ||
## Options | ||
- **allowImportExportEverywhere**: By default, `import` and `export` | ||
declarations can only appear at a program's top level. Setting this | ||
option to `true` allows them anywhere where a statement is allowed. | ||
- **allowReturnOutsideFunction**: By default, a return statement at | ||
the top level raises an error. Set this to `true` to accept such | ||
code. | ||
- **allowSuperOutsideMethod** TODO | ||
- **sourceType**: Indicate the mode the code should be parsed in. Can be | ||
either `"script"` or `"module"`. | ||
- **plugins**: Array containing the plugins that you want to enable. | ||
### Example | ||
```javascript | ||
require("babylon").parse("code", { | ||
// parse in strict mode and allow module declarations | ||
sourceType: "module", | ||
features: [ | ||
// enable experimental async functions | ||
"asyncFunctions", | ||
// enable jsx and flow syntax | ||
"jsx", | ||
"flow" | ||
] | ||
}); | ||
``` | ||
### Plugins | ||
- `jsx` | ||
- `flow` | ||
- `asyncFunctions` | ||
- `classConstructorCall` | ||
- `doExpressions` | ||
- `trailingFunctionCommas` | ||
- `objectRestSpread` | ||
- `decorators` | ||
- `classProperties` | ||
- `exportExtensions` | ||
- `exponentiationOperator` | ||
- `asyncGenerators` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
195999
26
4988
74
1
2
+ Addedbabel-runtime@^6.0.2
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)