acorn-hammerhead
Advanced tools
Comparing version 0.1.2 to 0.2.0
@@ -11,2 +11,11 @@ "use strict"; | ||
var _scopeflags = require("./scopeflags"); | ||
const pp = _state.Parser.prototype; | ||
// Check if property name clashes with already added. | ||
// Object/class getters and setters are not allowed to clash — | ||
// either with each other or with an init property — and in | ||
// strict mode, init properties are also not allowed to be repeated. | ||
// A recursive descent parser operates by defining functions for all | ||
@@ -30,10 +39,4 @@ // syntactic elements, and recursively calling those, each function | ||
const pp = _state.Parser.prototype; | ||
// Check if property name clashes with already added. | ||
// Object/class getters and setters are not allowed to clash — | ||
// either with each other or with an init property — and in | ||
// strict mode, init properties are also not allowed to be repeated. | ||
pp.checkPropClash = function (prop, propHash) { | ||
pp.checkPropClash = function (prop, propHash, refDestructuringErrors) { | ||
if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") return; | ||
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) return; | ||
@@ -54,3 +57,7 @@ let key = prop.key, | ||
if (name === "__proto__" && kind === "init") { | ||
if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); | ||
if (propHash.proto) { | ||
if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) refDestructuringErrors.doubleProto = key.start; | ||
// Backwards-compat kludge. Can be removed in version 6.0 | ||
else this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); | ||
} | ||
propHash.proto = true; | ||
@@ -112,11 +119,18 @@ } | ||
pp.parseMaybeAssign = function (noIn, refDestructuringErrors, afterLeftParse) { | ||
if (this.inGenerator && this.isContextual("yield")) return this.parseYield(); | ||
if (this.isContextual("yield")) { | ||
if (this.inGenerator) return this.parseYield(noIn); | ||
// The tokenizer will assume an expression is allowed after | ||
// `yield`, but this isn't that kind of yield | ||
else this.exprAllowed = false; | ||
} | ||
let ownDestructuringErrors = false, | ||
oldParenAssign = -1, | ||
oldTrailingComma = -1; | ||
oldTrailingComma = -1, | ||
oldShorthandAssign = -1; | ||
if (refDestructuringErrors) { | ||
oldParenAssign = refDestructuringErrors.parenthesizedAssign; | ||
oldTrailingComma = refDestructuringErrors.trailingComma; | ||
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; | ||
oldShorthandAssign = refDestructuringErrors.shorthandAssign; | ||
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.shorthandAssign = -1; | ||
} else { | ||
@@ -129,11 +143,10 @@ refDestructuringErrors = new _parseutil.DestructuringErrors(); | ||
startLoc = this.startLoc; | ||
if (this.type == _tokentype.types.parenL || this.type == _tokentype.types.name) this.potentialArrowAt = this.start; | ||
if (this.type === _tokentype.types.parenL || this.type === _tokentype.types.name) this.potentialArrowAt = this.start; | ||
let left = this.parseMaybeConditional(noIn, refDestructuringErrors); | ||
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc); | ||
if (this.type.isAssign) { | ||
this.checkPatternErrors(refDestructuringErrors, true); | ||
if (!ownDestructuringErrors) _parseutil.DestructuringErrors.call(refDestructuringErrors); | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.operator = this.value; | ||
node.left = this.type === _tokentype.types.eq ? this.toAssignable(left) : left; | ||
node.left = this.type === _tokentype.types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; | ||
if (!ownDestructuringErrors) _parseutil.DestructuringErrors.call(refDestructuringErrors); | ||
refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly | ||
@@ -149,2 +162,3 @@ this.checkLVal(left); | ||
if (oldTrailingComma > -1) refDestructuringErrors.trailingComma = oldTrailingComma; | ||
if (oldShorthandAssign > -1) refDestructuringErrors.shorthandAssign = oldShorthandAssign; | ||
return left; | ||
@@ -178,3 +192,3 @@ }; | ||
if (this.checkExpressionErrors(refDestructuringErrors)) return expr; | ||
return expr.start == startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn); | ||
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn); | ||
}; | ||
@@ -219,4 +233,4 @@ | ||
expr; | ||
if (this.inAsync && this.isContextual("await")) { | ||
expr = this.parseAwait(refDestructuringErrors); | ||
if (this.isContextual("await") && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction)) { | ||
expr = this.parseAwait(); | ||
sawUnary = true; | ||
@@ -267,41 +281,52 @@ } else if (this.type.prefix) { | ||
pp.parseSubscripts = function (base, startPos, startLoc, noCalls) { | ||
let maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && this.lastTokEnd == base.end && !this.canInsertSemicolon(); | ||
for (let computed;;) { | ||
if ((computed = this.eat(_tokentype.types.bracketL)) || this.eat(_tokentype.types.dot)) { | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.object = base; | ||
node.property = computed ? this.parseExpression() : this.parseIdent(true); | ||
node.computed = !!computed; | ||
if (computed) this.expect(_tokentype.types.bracketR); | ||
base = this.finishNode(node, "MemberExpression"); | ||
} else if (!noCalls && this.eat(_tokentype.types.parenL)) { | ||
let refDestructuringErrors = new _parseutil.DestructuringErrors(), | ||
oldYieldPos = this.yieldPos, | ||
oldAwaitPos = this.awaitPos; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
let exprList = this.parseExprList(_tokentype.types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); | ||
if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) { | ||
this.checkPatternErrors(refDestructuringErrors, false); | ||
this.checkYieldAwaitInDefaultParams(); | ||
this.yieldPos = oldYieldPos; | ||
this.awaitPos = oldAwaitPos; | ||
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true); | ||
} | ||
this.checkExpressionErrors(refDestructuringErrors, true); | ||
this.yieldPos = oldYieldPos || this.yieldPos; | ||
this.awaitPos = oldAwaitPos || this.awaitPos; | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.callee = base; | ||
node.arguments = exprList; | ||
base = this.finishNode(node, "CallExpression"); | ||
} else if (this.type === _tokentype.types.backQuote) { | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.tag = base; | ||
node.quasi = this.parseTemplate({ isTagged: true }); | ||
base = this.finishNode(node, "TaggedTemplateExpression"); | ||
} else { | ||
return base; | ||
let maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; | ||
while (true) { | ||
let element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow); | ||
if (element === base || element.type === "ArrowFunctionExpression") return element; | ||
base = element; | ||
} | ||
}; | ||
pp.parseSubscript = function (base, startPos, startLoc, noCalls, maybeAsyncArrow) { | ||
let computed = this.eat(_tokentype.types.bracketL); | ||
if (computed || this.eat(_tokentype.types.dot)) { | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.object = base; | ||
node.property = computed ? this.parseExpression() : this.parseIdent(true); | ||
node.computed = !!computed; | ||
if (computed) this.expect(_tokentype.types.bracketR); | ||
base = this.finishNode(node, "MemberExpression"); | ||
} else if (!noCalls && this.eat(_tokentype.types.parenL)) { | ||
let refDestructuringErrors = new _parseutil.DestructuringErrors(), | ||
oldYieldPos = this.yieldPos, | ||
oldAwaitPos = this.awaitPos, | ||
oldAwaitIdentPos = this.awaitIdentPos; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
this.awaitIdentPos = 0; | ||
let exprList = this.parseExprList(_tokentype.types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); | ||
if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(_tokentype.types.arrow)) { | ||
this.checkPatternErrors(refDestructuringErrors, false); | ||
this.checkYieldAwaitInDefaultParams(); | ||
if (this.awaitIdentPos > 0) this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); | ||
this.yieldPos = oldYieldPos; | ||
this.awaitPos = oldAwaitPos; | ||
this.awaitIdentPos = oldAwaitIdentPos; | ||
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true); | ||
} | ||
this.checkExpressionErrors(refDestructuringErrors, true); | ||
this.yieldPos = oldYieldPos || this.yieldPos; | ||
this.awaitPos = oldAwaitPos || this.awaitPos; | ||
this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.callee = base; | ||
node.arguments = exprList; | ||
base = this.finishNode(node, "CallExpression"); | ||
} else if (this.type === _tokentype.types.backQuote) { | ||
let node = this.startNodeAt(startPos, startLoc); | ||
node.tag = base; | ||
node.quasi = this.parseTemplate({ isTagged: true }); | ||
base = this.finishNode(node, "TaggedTemplateExpression"); | ||
} | ||
return base; | ||
}; | ||
@@ -315,23 +340,38 @@ | ||
pp.parseExprAtom = function (refDestructuringErrors) { | ||
// If a division operator appears in an expression position, the | ||
// tokenizer got confused, and we force it to read a regexp instead. | ||
if (this.type === _tokentype.types.slash) this.readRegexp(); | ||
let node, | ||
canBeArrow = this.potentialArrowAt == this.start; | ||
canBeArrow = this.potentialArrowAt === this.start; | ||
switch (this.type) { | ||
case _tokentype.types._super: | ||
if (!this.inFunction) this.raise(this.start, "'super' outside of function or class"); | ||
if (!this.allowSuper) this.raise(this.start, "'super' keyword outside a method"); | ||
node = this.startNode(); | ||
this.next(); | ||
if (this.type === _tokentype.types.parenL && !this.allowDirectSuper) this.raise(node.start, "super() call outside constructor of a subclass"); | ||
// The `super` keyword can appear at below: | ||
// SuperProperty: | ||
// super [ Expression ] | ||
// super . IdentifierName | ||
// SuperCall: | ||
// super Arguments | ||
if (this.type !== _tokentype.types.dot && this.type !== _tokentype.types.bracketL && this.type !== _tokentype.types.parenL) this.unexpected(); | ||
return this.finishNode(node, "Super"); | ||
case _tokentype.types._this: | ||
let type = this.type === _tokentype.types._this ? "ThisExpression" : "Super"; | ||
node = this.startNode(); | ||
this.next(); | ||
return this.finishNode(node, type); | ||
return this.finishNode(node, "ThisExpression"); | ||
case _tokentype.types.name: | ||
let startPos = this.start, | ||
startLoc = this.startLoc; | ||
let id = this.parseIdent(this.type !== _tokentype.types.name); | ||
if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(_tokentype.types._function)) return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true); | ||
startLoc = this.startLoc, | ||
containsEsc = this.containsEsc; | ||
let id = this.parseIdent(false); | ||
if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(_tokentype.types._function)) return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true); | ||
if (canBeArrow && !this.canInsertSemicolon()) { | ||
if (this.eat(_tokentype.types.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false); | ||
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === _tokentype.types.name) { | ||
id = this.parseIdent(); | ||
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === _tokentype.types.name && !containsEsc) { | ||
id = this.parseIdent(false); | ||
if (this.canInsertSemicolon() || !this.eat(_tokentype.types.arrow)) this.unexpected(); | ||
@@ -380,3 +420,3 @@ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true); | ||
this.next(); | ||
return this.parseFunction(node, false); | ||
return this.parseFunction(node, 0); | ||
@@ -428,6 +468,6 @@ case _tokentype.types._class: | ||
oldAwaitPos = this.awaitPos, | ||
spreadStart, | ||
innerParenStart; | ||
spreadStart; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
// Do not save awaitIdentPos to allow checking awaits nested in parameters | ||
while (this.type !== _tokentype.types.parenR) { | ||
@@ -444,5 +484,2 @@ first ? first = false : this.expect(_tokentype.types.comma); | ||
} else { | ||
if (this.type === _tokentype.types.parenL && !innerParenStart) { | ||
innerParenStart = this.start; | ||
} | ||
exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); | ||
@@ -458,3 +495,2 @@ } | ||
this.checkYieldAwaitInDefaultParams(); | ||
if (innerParenStart) this.unexpected(innerParenStart); | ||
this.yieldPos = oldYieldPos; | ||
@@ -512,5 +548,6 @@ this.awaitPos = oldAwaitPos; | ||
node.meta = meta; | ||
let containsEsc = this.containsEsc; | ||
node.property = this.parseIdent(true); | ||
if (node.property.name !== "target") this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); | ||
if (!this.inFunction) this.raiseRecoverable(node.start, "new.target can only be used in functions"); | ||
if (node.property.name !== "target" || containsEsc) this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); | ||
if (!this.inNonArrowFunction()) this.raiseRecoverable(node.start, "new.target can only be used in functions"); | ||
return this.finishNode(node, "MetaProperty"); | ||
@@ -555,2 +592,3 @@ } | ||
while (!curElt.tail) { | ||
if (this.type === _tokentype.types.eof) this.raise(this.pos, "Unterminated template literal"); | ||
this.expect(_tokentype.types.dollarBraceL); | ||
@@ -565,8 +603,8 @@ node.expressions.push(this.parseExpression()); | ||
// Parse an object literal or binding pattern. | ||
pp.isAsyncProp = function (prop) { | ||
return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && (this.type === _tokentype.types.name || this.type === _tokentype.types.num || this.type === _tokentype.types.string || this.type === _tokentype.types.bracketL) && !_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); | ||
return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && (this.type === _tokentype.types.name || this.type === _tokentype.types.num || this.type === _tokentype.types.string || this.type === _tokentype.types.bracketL || this.type.keyword || this.options.ecmaVersion >= 9 && this.type === _tokentype.types.star) && !_whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); | ||
}; | ||
// Parse an object literal or binding pattern. | ||
pp.parseObj = function (isPattern, refDestructuringErrors) { | ||
@@ -584,31 +622,64 @@ let node = this.startNode(), | ||
let prop = this.startNode(), | ||
isGenerator, | ||
isAsync, | ||
startPos, | ||
startLoc; | ||
if (this.options.ecmaVersion >= 6) { | ||
prop.method = false; | ||
prop.shorthand = false; | ||
if (isPattern || refDestructuringErrors) { | ||
startPos = this.start; | ||
startLoc = this.startLoc; | ||
const prop = this.parseProperty(isPattern, refDestructuringErrors); | ||
if (!isPattern) this.checkPropClash(prop, propHash, refDestructuringErrors); | ||
node.properties.push(prop); | ||
} | ||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); | ||
}; | ||
pp.parseProperty = function (isPattern, refDestructuringErrors) { | ||
let prop = this.startNode(), | ||
isGenerator, | ||
isAsync, | ||
startPos, | ||
startLoc; | ||
if (this.options.ecmaVersion >= 9 && this.eat(_tokentype.types.ellipsis)) { | ||
if (isPattern) { | ||
prop.argument = this.parseIdent(false); | ||
if (this.type === _tokentype.types.comma) { | ||
this.raise(this.start, "Comma is not permitted after the rest element"); | ||
} | ||
if (!isPattern) isGenerator = this.eat(_tokentype.types.star); | ||
return this.finishNode(prop, "RestElement"); | ||
} | ||
this.parsePropertyName(prop); | ||
if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { | ||
isAsync = true; | ||
this.parsePropertyName(prop, refDestructuringErrors); | ||
} else { | ||
isAsync = false; | ||
// To disallow parenthesized identifier via `this.toAssignable()`. | ||
if (this.type === _tokentype.types.parenL && refDestructuringErrors) { | ||
if (refDestructuringErrors.parenthesizedAssign < 0) { | ||
refDestructuringErrors.parenthesizedAssign = this.start; | ||
} | ||
if (refDestructuringErrors.parenthesizedBind < 0) { | ||
refDestructuringErrors.parenthesizedBind = this.start; | ||
} | ||
} | ||
this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors); | ||
this.checkPropClash(prop, propHash); | ||
node.properties.push(this.finishNode(prop, "Property")); | ||
// Parse argument. | ||
prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); | ||
// To disallow trailing comma via `this.toAssignable()`. | ||
if (this.type === _tokentype.types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { | ||
refDestructuringErrors.trailingComma = this.start; | ||
} | ||
// Finish | ||
return this.finishNode(prop, "SpreadElement"); | ||
} | ||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); | ||
if (this.options.ecmaVersion >= 6) { | ||
prop.method = false; | ||
prop.shorthand = false; | ||
if (isPattern || refDestructuringErrors) { | ||
startPos = this.start; | ||
startLoc = this.startLoc; | ||
} | ||
if (!isPattern) isGenerator = this.eat(_tokentype.types.star); | ||
} | ||
let containsEsc = this.containsEsc; | ||
this.parsePropertyName(prop); | ||
if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { | ||
isAsync = true; | ||
isGenerator = this.options.ecmaVersion >= 9 && this.eat(_tokentype.types.star); | ||
this.parsePropertyName(prop, refDestructuringErrors); | ||
} else { | ||
isAsync = false; | ||
} | ||
this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); | ||
return this.finishNode(prop, "Property"); | ||
}; | ||
pp.parsePropertyValue = function (prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) { | ||
pp.parsePropertyValue = function (prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { | ||
if ((isGenerator || isAsync) && this.type === _tokentype.types.colon) this.unexpected(); | ||
@@ -624,4 +695,4 @@ | ||
prop.value = this.parseMethod(isGenerator, isAsync); | ||
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && this.type != _tokentype.types.comma && this.type != _tokentype.types.braceR) { | ||
if (isGenerator || isAsync || isPattern) this.unexpected(); | ||
} else if (!isPattern && !containsEsc && this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && this.type !== _tokentype.types.comma && this.type !== _tokentype.types.braceR) { | ||
if (isGenerator || isAsync) this.unexpected(); | ||
prop.kind = prop.key.name; | ||
@@ -638,3 +709,5 @@ this.parsePropertyName(prop); | ||
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { | ||
if (isGenerator || isAsync) this.unexpected(); | ||
this.checkUnreserved(prop.key); | ||
if (prop.key.name === "await" && !this.awaitIdentPos) this.awaitIdentPos = startPos; | ||
prop.kind = "init"; | ||
@@ -671,6 +744,3 @@ if (isPattern) { | ||
node.id = null; | ||
if (this.options.ecmaVersion >= 6) { | ||
node.generator = false; | ||
node.expression = false; | ||
} | ||
if (this.options.ecmaVersion >= 6) node.generator = node.expression = false; | ||
if (this.options.ecmaVersion >= 8) node.async = false; | ||
@@ -681,9 +751,7 @@ }; | ||
pp.parseMethod = function (isGenerator, isAsync) { | ||
pp.parseMethod = function (isGenerator, isAsync, allowDirectSuper) { | ||
let node = this.startNode(), | ||
oldInGen = this.inGenerator, | ||
oldInAsync = this.inAsync, | ||
oldYieldPos = this.yieldPos, | ||
oldAwaitPos = this.awaitPos, | ||
oldInFunc = this.inFunction; | ||
oldAwaitIdentPos = this.awaitIdentPos; | ||
@@ -694,8 +762,6 @@ this.initFunction(node); | ||
this.inGenerator = node.generator; | ||
this.inAsync = node.async; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
this.inFunction = true; | ||
this.enterFunctionScope(); | ||
this.awaitIdentPos = 0; | ||
this.enterScope((0, _scopeflags.functionFlags)(isAsync, node.generator) | _scopeflags.SCOPE_SUPER | (allowDirectSuper ? _scopeflags.SCOPE_DIRECT_SUPER : 0)); | ||
@@ -705,9 +771,7 @@ this.expect(_tokentype.types.parenL); | ||
this.checkYieldAwaitInDefaultParams(); | ||
this.parseFunctionBody(node, false); | ||
this.parseFunctionBody(node, false, true); | ||
this.inGenerator = oldInGen; | ||
this.inAsync = oldInAsync; | ||
this.yieldPos = oldYieldPos; | ||
this.awaitPos = oldAwaitPos; | ||
this.inFunction = oldInFunc; | ||
this.awaitIdentPos = oldAwaitIdentPos; | ||
return this.finishNode(node, "FunctionExpression"); | ||
@@ -719,26 +783,20 @@ }; | ||
pp.parseArrowExpression = function (node, params, isAsync) { | ||
let oldInGen = this.inGenerator, | ||
oldInAsync = this.inAsync, | ||
oldYieldPos = this.yieldPos, | ||
let oldYieldPos = this.yieldPos, | ||
oldAwaitPos = this.awaitPos, | ||
oldInFunc = this.inFunction; | ||
oldAwaitIdentPos = this.awaitIdentPos; | ||
this.enterFunctionScope(); | ||
this.enterScope((0, _scopeflags.functionFlags)(isAsync, false) | _scopeflags.SCOPE_ARROW); | ||
this.initFunction(node); | ||
if (this.options.ecmaVersion >= 8) node.async = !!isAsync; | ||
this.inGenerator = false; | ||
this.inAsync = node.async; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
this.inFunction = true; | ||
this.awaitIdentPos = 0; | ||
node.params = this.toAssignableList(params, true); | ||
this.parseFunctionBody(node, true); | ||
this.parseFunctionBody(node, true, false); | ||
this.inGenerator = oldInGen; | ||
this.inAsync = oldInAsync; | ||
this.yieldPos = oldYieldPos; | ||
this.awaitPos = oldAwaitPos; | ||
this.inFunction = oldInFunc; | ||
this.awaitIdentPos = oldAwaitIdentPos; | ||
return this.finishNode(node, "ArrowFunctionExpression"); | ||
@@ -749,3 +807,3 @@ }; | ||
pp.parseFunctionBody = function (node, isArrowFunction) { | ||
pp.parseFunctionBody = function (node, isArrowFunction, isMethod) { | ||
let isExpression = isArrowFunction && this.type !== _tokentype.types.braceL; | ||
@@ -776,13 +834,12 @@ let oldStrict = this.strict, | ||
// if a let/const declaration in the function clashes with one of the params. | ||
this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); | ||
this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); | ||
node.body = this.parseBlock(false); | ||
node.expression = false; | ||
this.adaptDirectivePrologue(node.body.body); | ||
this.labels = oldLabels; | ||
} | ||
this.exitFunctionScope(); | ||
this.exitScope(); | ||
if (this.strict && node.id) { | ||
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' | ||
this.checkLVal(node.id, "none"); | ||
} | ||
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' | ||
if (this.strict && node.id) this.checkLVal(node.id, _scopeflags.BIND_OUTSIDE); | ||
this.strict = oldStrict; | ||
@@ -829,3 +886,3 @@ }; | ||
this.checkLVal(param, "var", allowDuplicates ? null : nameHash); | ||
this.checkLVal(param, _scopeflags.BIND_VAR, allowDuplicates ? null : nameHash); | ||
} | ||
@@ -861,2 +918,14 @@ }; | ||
pp.checkUnreserved = function ({ start, end, name }) { | ||
if (this.inGenerator && name === "yield") this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); | ||
if (this.inAsync && name === "await") this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); | ||
if (this.keywords.test(name)) this.raise(start, `Unexpected keyword '${name}'`); | ||
if (this.options.ecmaVersion < 6 && this.input.slice(start, end).indexOf("\\") !== -1) return; | ||
const re = this.strict ? this.reservedWordsStrict : this.reservedWords; | ||
if (re.test(name)) { | ||
if (!this.inAsync && name === "await") this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); | ||
this.raiseRecoverable(start, `The keyword '${name}' is reserved`); | ||
} | ||
}; | ||
// Parse the next token as an identifier. If `liberal` is true (used | ||
@@ -866,14 +935,5 @@ // when parsing properties), it will also convert keywords into | ||
pp.checkUnreserved = function ({ start, end, name }) { | ||
if (this.inGenerator && name === "yield") this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); | ||
if (this.inAsync && name === "await") this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); | ||
if (this.isKeyword(name)) this.raise(start, `Unexpected keyword '${name}'`); | ||
if (this.options.ecmaVersion < 6 && this.input.slice(start, end).indexOf("\\") != -1) return; | ||
const re = this.strict ? this.reservedWordsStrict : this.reservedWords; | ||
if (re.test(name)) this.raiseRecoverable(start, `The keyword '${name}' is reserved`); | ||
}; | ||
pp.parseIdent = function (liberal, isBinding) { | ||
let node = this.startNode(); | ||
if (liberal && this.options.allowReserved == "never") liberal = false; | ||
if (liberal && this.options.allowReserved === "never") liberal = false; | ||
if (this.type === _tokentype.types.name) { | ||
@@ -883,2 +943,10 @@ node.name = this.value; | ||
node.name = this.type.keyword; | ||
// To fix https://github.com/acornjs/acorn/issues/575 | ||
// `class` and `function` keywords push new context into this.context. | ||
// But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. | ||
// If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword | ||
if ((node.name === "class" || node.name === "function") && (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { | ||
this.context.pop(); | ||
} | ||
} else { | ||
@@ -889,3 +957,6 @@ this.unexpected(); | ||
this.finishNode(node, "Identifier"); | ||
if (!liberal) this.checkUnreserved(node); | ||
if (!liberal) { | ||
this.checkUnreserved(node); | ||
if (node.name === "await" && !this.awaitIdentPos) this.awaitIdentPos = node.start; | ||
} | ||
return node; | ||
@@ -896,3 +967,3 @@ }; | ||
pp.parseYield = function () { | ||
pp.parseYield = function (noIn) { | ||
if (!this.yieldPos) this.yieldPos = this.start; | ||
@@ -902,3 +973,3 @@ | ||
this.next(); | ||
if (this.type == _tokentype.types.semi || this.canInsertSemicolon() || this.type != _tokentype.types.star && !this.type.startsExpr) { | ||
if (this.type === _tokentype.types.semi || this.canInsertSemicolon() || this.type !== _tokentype.types.star && !this.type.startsExpr) { | ||
node.delegate = false; | ||
@@ -908,3 +979,3 @@ node.argument = null; | ||
node.delegate = this.eat(_tokentype.types.star); | ||
node.argument = this.parseMaybeAssign(); | ||
node.argument = this.parseMaybeAssign(noIn); | ||
} | ||
@@ -911,0 +982,0 @@ return this.finishNode(node, "YieldExpression"); |
@@ -22,14 +22,17 @@ "use strict"; | ||
6: ecma5AndLessKeywords + " const class extends export import super" | ||
}; | ||
// ## Character categories | ||
const keywordRelationalOperator = exports.keywordRelationalOperator = /^in(stanceof)?$/; | ||
// Big ugly regular expressions that match characters in the | ||
// whitespace, identifier, and identifier-start categories. These | ||
// are only applied when a character is found to actually have a | ||
// code point above 128. | ||
// Generated by `bin/generate-identifier-regex.js`. | ||
// ## Character categories | ||
};let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; | ||
let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; | ||
// Big ugly regular expressions that match characters in the | ||
// whitespace, identifier, and identifier-start categories. These | ||
// are only applied when a character is found to actually have a | ||
// code point above 128. | ||
// Generated by `bin/generate-identifier-regex.js`. | ||
let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; | ||
let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; | ||
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); | ||
@@ -47,6 +50,6 @@ const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); | ||
// eslint-disable-next-line comma-spacing | ||
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 785, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 54, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 86, 25, 391, 63, 32, 0, 449, 56, 264, 8, 2, 36, 18, 0, 50, 29, 881, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 65, 0, 32, 6124, 20, 754, 9486, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 60, 67, 1213, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 10591, 541]; | ||
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 477, 28, 11, 0, 9, 21, 190, 52, 76, 44, 33, 24, 27, 35, 30, 0, 12, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 54, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 86, 26, 230, 43, 117, 63, 32, 0, 257, 0, 11, 39, 8, 0, 22, 0, 12, 39, 3, 3, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 270, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 68, 12, 0, 67, 12, 65, 1, 31, 6129, 15, 754, 9486, 286, 82, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 60, 67, 1213, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541]; | ||
// eslint-disable-next-line comma-spacing | ||
const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 10, 2, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 87, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 423, 9, 838, 7, 2, 7, 17, 9, 57, 21, 2, 13, 19882, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 2214, 6, 110, 6, 6, 9, 792487, 239]; | ||
const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 525, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 4, 9, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 280, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 2214, 6, 110, 6, 6, 9, 792487, 239]; | ||
@@ -53,0 +56,0 @@ // This has a complexity linear to the value of the code. The |
"use strict"; | ||
exports.__esModule = true; | ||
exports.pluginsLoose = exports.LooseParser = exports.parse_dammit = exports.version = exports.nonASCIIwhitespace = exports.lineBreakG = exports.lineBreak = exports.isNewLine = exports.Token = exports.isIdentifierStart = exports.isIdentifierChar = exports.tokContexts = exports.TokContext = exports.keywordTypes = exports.tokTypes = exports.TokenType = exports.Node = exports.getLineInfo = exports.SourceLocation = exports.Position = exports.defaultOptions = exports.plugins = exports.Parser = undefined; | ||
exports.version = exports.nonASCIIwhitespace = exports.lineBreakG = exports.lineBreak = exports.isNewLine = exports.Token = exports.isIdentifierStart = exports.isIdentifierChar = exports.tokContexts = exports.TokContext = exports.keywordTypes = exports.tokTypes = exports.TokenType = exports.Node = exports.getLineInfo = exports.SourceLocation = exports.Position = exports.defaultOptions = exports.Parser = undefined; | ||
@@ -14,8 +14,2 @@ var _state = require("./state"); | ||
}); | ||
Object.defineProperty(exports, "plugins", { | ||
enumerable: true, | ||
get: function get() { | ||
return _state.plugins; | ||
} | ||
}); | ||
@@ -150,3 +144,2 @@ var _options = require("./options"); | ||
exports.tokenizer = tokenizer; | ||
exports.addLooseExports = addLooseExports; | ||
@@ -165,3 +158,3 @@ require("./parseutil"); | ||
const version = exports.version = "5.1.1"; | ||
const version = exports.version = "6.1.0"; | ||
@@ -176,3 +169,3 @@ // The main exported interface (under `self.acorn` when in the | ||
function parse(input, options) { | ||
return new _state.Parser(options, input).parse(); | ||
return _state.Parser.parse(input, options); | ||
} | ||
@@ -185,5 +178,3 @@ | ||
function parseExpressionAt(input, pos, options) { | ||
let p = new _state.Parser(options, input, pos); | ||
p.nextToken(); | ||
return p.parseExpression(); | ||
return _state.Parser.parseExpressionAt(input, pos, options); | ||
} | ||
@@ -195,15 +186,3 @@ | ||
function tokenizer(input, options) { | ||
return new _state.Parser(options, input); | ||
} | ||
// This is a terrible kludge to support the existing, pre-ES6 | ||
// interface where the loose parser module retroactively adds exports | ||
// to this module. | ||
let parse_dammit = exports.parse_dammit = undefined, | ||
LooseParser = exports.LooseParser = undefined, | ||
pluginsLoose = exports.pluginsLoose = undefined; // eslint-disable-line camelcase | ||
function addLooseExports(parse, Parser, plugins) { | ||
exports.parse_dammit = parse_dammit = parse; // eslint-disable-line camelcase | ||
exports.LooseParser = LooseParser = Parser; | ||
exports.pluginsLoose = pluginsLoose = plugins; | ||
return _state.Parser.tokenizer(input, options); | ||
} |
115
lib/lval.js
@@ -9,2 +9,4 @@ "use strict"; | ||
var _scopeflags = require("./scopeflags"); | ||
const pp = _state.Parser.prototype; | ||
@@ -15,7 +17,7 @@ | ||
pp.toAssignable = function (node, isBinding) { | ||
pp.toAssignable = function (node, isBinding, refDestructuringErrors) { | ||
if (this.options.ecmaVersion >= 6 && node) { | ||
switch (node.type) { | ||
case "Identifier": | ||
if (this.inAsync && node.name === "await") this.raise(node.start, "Can not use 'await' as identifier inside an async function"); | ||
if (this.inAsync && node.name === "await") this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); | ||
break; | ||
@@ -25,2 +27,3 @@ | ||
case "ArrayPattern": | ||
case "RestElement": | ||
break; | ||
@@ -30,2 +33,3 @@ | ||
node.type = "ObjectPattern"; | ||
if (refDestructuringErrors) this.checkPatternErrors(refDestructuringErrors, true); | ||
for (var _iterator = node.properties, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
@@ -45,22 +49,38 @@ var _ref; | ||
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter"); | ||
this.toAssignable(prop.value, isBinding); | ||
this.toAssignable(prop, isBinding); | ||
// Early error: | ||
// AssignmentRestProperty[Yield, Await] : | ||
// `...` DestructuringAssignmentTarget[Yield, Await] | ||
// | ||
// It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. | ||
if (prop.type === "RestElement" && (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")) { | ||
this.raise(prop.argument.start, "Unexpected token"); | ||
} | ||
} | ||
break; | ||
case "Property": | ||
// AssignmentProperty has type === "Property" | ||
if (node.kind !== "init") this.raise(node.key.start, "Object pattern can't contain getter or setter"); | ||
this.toAssignable(node.value, isBinding); | ||
break; | ||
case "ArrayExpression": | ||
node.type = "ArrayPattern"; | ||
if (refDestructuringErrors) this.checkPatternErrors(refDestructuringErrors, true); | ||
this.toAssignableList(node.elements, isBinding); | ||
break; | ||
case "SpreadElement": | ||
node.type = "RestElement"; | ||
this.toAssignable(node.argument, isBinding); | ||
if (node.argument.type === "AssignmentPattern") this.raise(node.argument.start, "Rest elements cannot have a default value"); | ||
break; | ||
case "AssignmentExpression": | ||
if (node.operator === "=") { | ||
node.type = "AssignmentPattern"; | ||
delete node.operator; | ||
this.toAssignable(node.left, isBinding); | ||
// falls through to AssignmentPattern | ||
} else { | ||
this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); | ||
break; | ||
} | ||
if (node.operator !== "=") this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); | ||
node.type = "AssignmentPattern"; | ||
delete node.operator; | ||
this.toAssignable(node.left, isBinding); | ||
// falls through to AssignmentPattern | ||
@@ -71,3 +91,3 @@ case "AssignmentPattern": | ||
case "ParenthesizedExpression": | ||
this.toAssignable(node.expression, isBinding); | ||
this.toAssignable(node.expression, isBinding, refDestructuringErrors); | ||
break; | ||
@@ -81,3 +101,3 @@ | ||
} | ||
} | ||
} else if (refDestructuringErrors) this.checkPatternErrors(refDestructuringErrors, true); | ||
return node; | ||
@@ -90,19 +110,10 @@ }; | ||
let end = exprList.length; | ||
for (let i = 0; i < end; i++) { | ||
let elt = exprList[i]; | ||
if (elt) this.toAssignable(elt, isBinding); | ||
} | ||
if (end) { | ||
let last = exprList[end - 1]; | ||
if (last && last.type == "RestElement") { | ||
--end; | ||
} else if (last && last.type == "SpreadElement") { | ||
last.type = "RestElement"; | ||
let arg = last.argument; | ||
this.toAssignable(arg, isBinding); | ||
--end; | ||
} | ||
if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") this.unexpected(last.argument.start); | ||
} | ||
for (let i = 0; i < end; i++) { | ||
let elt = exprList[i]; | ||
if (elt) this.toAssignable(elt, isBinding); | ||
} | ||
return exprList; | ||
@@ -135,19 +146,15 @@ }; | ||
pp.parseBindingAtom = function () { | ||
if (this.options.ecmaVersion < 6) return this.parseIdent(); | ||
switch (this.type) { | ||
case _tokentype.types.name: | ||
return this.parseIdent(); | ||
if (this.options.ecmaVersion >= 6) { | ||
switch (this.type) { | ||
case _tokentype.types.bracketL: | ||
let node = this.startNode(); | ||
this.next(); | ||
node.elements = this.parseBindingList(_tokentype.types.bracketR, true, true); | ||
return this.finishNode(node, "ArrayPattern"); | ||
case _tokentype.types.bracketL: | ||
let node = this.startNode(); | ||
this.next(); | ||
node.elements = this.parseBindingList(_tokentype.types.bracketR, true, true); | ||
return this.finishNode(node, "ArrayPattern"); | ||
case _tokentype.types.braceL: | ||
return this.parseObj(true); | ||
default: | ||
this.unexpected(); | ||
case _tokentype.types.braceL: | ||
return this.parseObj(true); | ||
} | ||
} | ||
return this.parseIdent(); | ||
}; | ||
@@ -202,3 +209,3 @@ | ||
pp.checkLVal = function (expr, bindingType, checkClashes) { | ||
pp.checkLVal = function (expr, bindingType = _scopeflags.BIND_NONE, checkClashes) { | ||
switch (expr.type) { | ||
@@ -211,16 +218,7 @@ case "Identifier": | ||
} | ||
if (bindingType && bindingType !== "none") { | ||
if (bindingType === "var" && !this.canDeclareVarName(expr.name) || bindingType !== "var" && !this.canDeclareLexicalName(expr.name)) { | ||
this.raiseRecoverable(expr.start, `Identifier '${expr.name}' has already been declared`); | ||
} | ||
if (bindingType === "var") { | ||
this.declareVarName(expr.name); | ||
} else { | ||
this.declareLexicalName(expr.name); | ||
} | ||
} | ||
if (bindingType !== _scopeflags.BIND_NONE && bindingType !== _scopeflags.BIND_OUTSIDE) this.declareName(expr.name, bindingType, expr.start); | ||
break; | ||
case "MemberExpression": | ||
if (bindingType) this.raiseRecoverable(expr.start, (bindingType ? "Binding" : "Assigning to") + " member expression"); | ||
if (bindingType) this.raiseRecoverable(expr.start, "Binding member expression"); | ||
break; | ||
@@ -243,5 +241,10 @@ | ||
this.checkLVal(prop.value, bindingType, checkClashes); | ||
this.checkLVal(prop, bindingType, checkClashes); | ||
}break; | ||
case "Property": | ||
// AssignmentProperty has type === "Property" | ||
this.checkLVal(expr.value, bindingType, checkClashes); | ||
break; | ||
case "ArrayPattern": | ||
@@ -248,0 +251,0 @@ for (var _iterator3 = expr.elements, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { |
@@ -15,7 +15,8 @@ "use strict"; | ||
const defaultOptions = exports.defaultOptions = { | ||
// `ecmaVersion` indicates the ECMAScript version to parse. Must | ||
// be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support | ||
// for strict mode, the set of reserved words, and support for | ||
// new syntax features. The default is 7. | ||
ecmaVersion: 7, | ||
// `ecmaVersion` indicates the ECMAScript version to parse. Must be | ||
// either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 | ||
// (2019). This influences support for strict mode, the set of | ||
// reserved words, and support for new syntax features. The default | ||
// is 9. | ||
ecmaVersion: 9, | ||
// `sourceType` indicates the mode the code should be parsed in. | ||
@@ -27,3 +28,3 @@ // Can be either `"script"` or `"module"`. This influences global | ||
// when a semicolon is automatically inserted. It will be passed | ||
// th position of the comma as an offset, and if `locations` is | ||
// the position of the comma as an offset, and if `locations` is | ||
// enabled, it is given the location as a `{line, column}` object | ||
@@ -46,2 +47,5 @@ // as second argument. | ||
allowImportExportEverywhere: false, | ||
// When enabled, await identifiers are allowed to appear at the top-level scope, | ||
// but they are still not allowed in non-async functions. | ||
allowAwaitOutsideFunction: false, | ||
// When enabled, hashbang directive in the beginning of file | ||
@@ -95,4 +99,3 @@ // is allowed and treated as a line comment. | ||
// (non-standard) ParenthesizedExpression nodes | ||
preserveParens: false, | ||
plugins: {} | ||
preserveParens: false | ||
@@ -99,0 +102,0 @@ // Interpret and default an options object |
@@ -16,5 +16,6 @@ "use strict"; | ||
const literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; | ||
const literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/; | ||
pp.strictDirective = function (start) { | ||
for (;;) { | ||
// Try to find string literal. | ||
_whitespace.skipWhiteSpace.lastIndex = start; | ||
@@ -24,4 +25,9 @@ start += _whitespace.skipWhiteSpace.exec(this.input)[0].length; | ||
if (!match) return false; | ||
if ((match[1] || match[2]) == "use strict") return false; | ||
if ((match[1] || match[2]) === "use strict") return false; | ||
start += match[0].length; | ||
// Skip semicolon, if any. | ||
_whitespace.skipWhiteSpace.lastIndex = start; | ||
start += _whitespace.skipWhiteSpace.exec(this.input)[0].length; | ||
if (this.input[start] === ";") start++; | ||
} | ||
@@ -45,3 +51,3 @@ }; | ||
pp.isContextual = function (name) { | ||
return this.type === _tokentype.types.name && this.value === name; | ||
return this.type === _tokentype.types.name && this.value === name && !this.containsEsc; | ||
}; | ||
@@ -52,3 +58,5 @@ | ||
pp.eatContextual = function (name) { | ||
return this.value === name && this.eat(_tokentype.types.name); | ||
if (!this.isContextual(name)) return false; | ||
this.next(); | ||
return true; | ||
}; | ||
@@ -83,3 +91,3 @@ | ||
pp.afterTrailingComma = function (tokType, notNext) { | ||
if (this.type == tokType) { | ||
if (this.type === tokType) { | ||
if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); | ||
@@ -105,3 +113,3 @@ if (!notNext) this.next(); | ||
function DestructuringErrors() { | ||
this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1; | ||
this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = this.doubleProto = -1; | ||
} | ||
@@ -117,5 +125,9 @@ | ||
pp.checkExpressionErrors = function (refDestructuringErrors, andThrow) { | ||
let pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1; | ||
if (!andThrow) return pos >= 0; | ||
if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns"); | ||
if (!refDestructuringErrors) return false; | ||
let shorthandAssign = refDestructuringErrors.shorthandAssign, | ||
doubleProto = refDestructuringErrors.doubleProto; | ||
if (!andThrow) return shorthandAssign >= 0 || doubleProto >= 0; | ||
if (shorthandAssign >= 0) this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); | ||
if (doubleProto >= 0) this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); | ||
}; | ||
@@ -122,0 +134,0 @@ |
127
lib/scope.js
@@ -5,87 +5,88 @@ "use strict"; | ||
var _util = require("./util"); | ||
var _scopeflags = require("./scopeflags"); | ||
const pp = _state.Parser.prototype; | ||
// Object.assign polyfill | ||
const assign = Object.assign || function (target, ...sources) { | ||
for (var _iterator = sources, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
let source = _ref; | ||
for (const key in source) { | ||
if ((0, _util.has)(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
class Scope { | ||
constructor(flags) { | ||
this.flags = flags; | ||
// A list of var-declared names in the current lexical scope | ||
this.var = []; | ||
// A list of lexically-declared names in the current lexical scope | ||
this.lexical = []; | ||
// A list of lexically-declared FunctionDeclaration names in the current lexical scope | ||
this.functions = []; | ||
} | ||
return target; | ||
}; | ||
} | ||
// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. | ||
pp.enterFunctionScope = function () { | ||
// var: a hash of var-declared names in the current lexical scope | ||
// lexical: a hash of lexically-declared names in the current lexical scope | ||
// childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope) | ||
// parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope) | ||
this.scopeStack.push({ var: {}, lexical: {}, childVar: {}, parentLexical: {} }); | ||
pp.enterScope = function (flags) { | ||
this.scopeStack.push(new Scope(flags)); | ||
}; | ||
pp.exitFunctionScope = function () { | ||
pp.exitScope = function () { | ||
this.scopeStack.pop(); | ||
}; | ||
pp.enterLexicalScope = function () { | ||
const parentScope = this.scopeStack[this.scopeStack.length - 1]; | ||
const childScope = { var: {}, lexical: {}, childVar: {}, parentLexical: {} }; | ||
this.scopeStack.push(childScope); | ||
assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); | ||
// The spec says: | ||
// > At the top level of a function, or script, function declarations are | ||
// > treated like var declarations rather than like lexical declarations. | ||
pp.treatFunctionsAsVarInScope = function (scope) { | ||
return scope.flags & _scopeflags.SCOPE_FUNCTION || !this.inModule && scope.flags & _scopeflags.SCOPE_TOP; | ||
}; | ||
pp.exitLexicalScope = function () { | ||
const childScope = this.scopeStack.pop(); | ||
const parentScope = this.scopeStack[this.scopeStack.length - 1]; | ||
assign(parentScope.childVar, childScope.var, childScope.childVar); | ||
pp.declareName = function (name, bindingType, pos) { | ||
let redeclared = false; | ||
if (bindingType === _scopeflags.BIND_LEXICAL) { | ||
const scope = this.currentScope(); | ||
redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; | ||
scope.lexical.push(name); | ||
if (this.inModule && scope.flags & _scopeflags.SCOPE_TOP) delete this.undefinedExports[name]; | ||
} else if (bindingType === _scopeflags.BIND_SIMPLE_CATCH) { | ||
const scope = this.currentScope(); | ||
scope.lexical.push(name); | ||
} else if (bindingType === _scopeflags.BIND_FUNCTION) { | ||
const scope = this.currentScope(); | ||
if (this.treatFunctionsAsVar) redeclared = scope.lexical.indexOf(name) > -1;else redeclared = scope.lexical.indexOf(name) > -1 || scope.var.indexOf(name) > -1; | ||
scope.functions.push(name); | ||
} else { | ||
for (let i = this.scopeStack.length - 1; i >= 0; --i) { | ||
const scope = this.scopeStack[i]; | ||
if (scope.lexical.indexOf(name) > -1 && !(scope.flags & _scopeflags.SCOPE_SIMPLE_CATCH && scope.lexical[0] === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.indexOf(name) > -1) { | ||
redeclared = true; | ||
break; | ||
} | ||
scope.var.push(name); | ||
if (this.inModule && scope.flags & _scopeflags.SCOPE_TOP) delete this.undefinedExports[name]; | ||
if (scope.flags & _scopeflags.SCOPE_VAR) break; | ||
} | ||
} | ||
if (redeclared) this.raiseRecoverable(pos, `Identifier '${name}' has already been declared`); | ||
}; | ||
/** | ||
* A name can be declared with `var` if there are no variables with the same name declared with `let`/`const` | ||
* in the current lexical scope or any of the parent lexical scopes in this function. | ||
*/ | ||
pp.canDeclareVarName = function (name) { | ||
const currentScope = this.scopeStack[this.scopeStack.length - 1]; | ||
return !(0, _util.has)(currentScope.lexical, name) && !(0, _util.has)(currentScope.parentLexical, name); | ||
pp.checkLocalExport = function (id) { | ||
// scope.functions must be empty as Module code is always strict. | ||
if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && this.scopeStack[0].var.indexOf(id.name) === -1) { | ||
this.undefinedExports[id.name] = id; | ||
} | ||
}; | ||
/** | ||
* A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const` | ||
* in the current scope, and there are no variables with the same name declared with `var` in the current scope or in | ||
* any child lexical scopes in this function. | ||
*/ | ||
pp.canDeclareLexicalName = function (name) { | ||
const currentScope = this.scopeStack[this.scopeStack.length - 1]; | ||
return !(0, _util.has)(currentScope.lexical, name) && !(0, _util.has)(currentScope.var, name) && !(0, _util.has)(currentScope.childVar, name); | ||
pp.currentScope = function () { | ||
return this.scopeStack[this.scopeStack.length - 1]; | ||
}; | ||
pp.declareVarName = function (name) { | ||
this.scopeStack[this.scopeStack.length - 1].var[name] = true; | ||
pp.currentVarScope = function () { | ||
for (let i = this.scopeStack.length - 1;; i--) { | ||
let scope = this.scopeStack[i]; | ||
if (scope.flags & _scopeflags.SCOPE_VAR) return scope; | ||
} | ||
}; | ||
pp.declareLexicalName = function (name) { | ||
this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; | ||
// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. | ||
pp.currentThisScope = function () { | ||
for (let i = this.scopeStack.length - 1;; i--) { | ||
let scope = this.scopeStack[i]; | ||
if (scope.flags & _scopeflags.SCOPE_VAR && !(scope.flags & _scopeflags.SCOPE_ARROW)) return scope; | ||
} | ||
}; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.Parser = exports.plugins = undefined; | ||
exports.Parser = undefined; | ||
@@ -14,8 +14,5 @@ var _identifier = require("./identifier"); | ||
// Registered plugins | ||
const plugins = exports.plugins = {}; | ||
var _util = require("./util"); | ||
function keywordRegexp(words) { | ||
return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"); | ||
} | ||
var _scopeflags = require("./scopeflags"); | ||
@@ -26,12 +23,12 @@ class Parser { | ||
this.sourceFile = options.sourceFile; | ||
this.keywords = keywordRegexp(_identifier.keywords[options.ecmaVersion >= 6 ? 6 : 5]); | ||
this.keywords = (0, _util.wordsRegexp)(_identifier.keywords[options.ecmaVersion >= 6 ? 6 : 5]); | ||
let reserved = ""; | ||
if (!options.allowReserved) { | ||
for (let v = options.ecmaVersion;; v--) if (reserved = _identifier.reservedWords[v]) break; | ||
if (options.sourceType == "module") reserved += " await"; | ||
if (options.sourceType === "module") reserved += " await"; | ||
} | ||
this.reservedWords = keywordRegexp(reserved); | ||
this.reservedWords = (0, _util.wordsRegexp)(reserved); | ||
let reservedStrict = (reserved ? reserved + " " : "") + _identifier.reservedWords.strict; | ||
this.reservedWordsStrict = keywordRegexp(reservedStrict); | ||
this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + _identifier.reservedWords.strictBind); | ||
this.reservedWordsStrict = (0, _util.wordsRegexp)(reservedStrict); | ||
this.reservedWordsStrictBind = (0, _util.wordsRegexp)(reservedStrict + " " + _identifier.reservedWords.strictBind); | ||
this.input = String(input); | ||
@@ -44,5 +41,2 @@ | ||
// Load plugins | ||
this.loadPlugins(options.plugins); | ||
// Set up token state | ||
@@ -88,8 +82,8 @@ | ||
// Flags to track whether we are in a function, a generator, an async function. | ||
this.inFunction = this.inGenerator = this.inAsync = false; | ||
// Positions to delayed-check that yield/await does not exist in default parameters. | ||
this.yieldPos = this.awaitPos = 0; | ||
this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; | ||
// Labels in scope. | ||
this.labels = []; | ||
// Thus-far undefined exports. | ||
this.undefinedExports = {}; | ||
@@ -101,31 +95,58 @@ // If enabled, skip leading hashbang line. | ||
this.scopeStack = []; | ||
this.enterFunctionScope(); | ||
this.enterScope(_scopeflags.SCOPE_TOP); | ||
// For RegExp validation | ||
this.regexpState = null; | ||
} | ||
// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them | ||
isKeyword(word) { | ||
return this.keywords.test(word); | ||
parse() { | ||
let node = this.options.program || this.startNode(); | ||
this.nextToken(); | ||
return this.parseTopLevel(node); | ||
} | ||
isReservedWord(word) { | ||
return this.reservedWords.test(word); | ||
get inFunction() { | ||
return (this.currentVarScope().flags & _scopeflags.SCOPE_FUNCTION) > 0; | ||
} | ||
get inGenerator() { | ||
return (this.currentVarScope().flags & _scopeflags.SCOPE_GENERATOR) > 0; | ||
} | ||
get inAsync() { | ||
return (this.currentVarScope().flags & _scopeflags.SCOPE_ASYNC) > 0; | ||
} | ||
get allowSuper() { | ||
return (this.currentThisScope().flags & _scopeflags.SCOPE_SUPER) > 0; | ||
} | ||
get allowDirectSuper() { | ||
return (this.currentThisScope().flags & _scopeflags.SCOPE_DIRECT_SUPER) > 0; | ||
} | ||
get treatFunctionsAsVar() { | ||
return this.treatFunctionsAsVarInScope(this.currentScope()); | ||
} | ||
extend(name, f) { | ||
this[name] = f(this[name]); | ||
// Switch to a getter for 7.0.0. | ||
inNonArrowFunction() { | ||
return (this.currentThisScope().flags & _scopeflags.SCOPE_FUNCTION) > 0; | ||
} | ||
loadPlugins(pluginConfigs) { | ||
for (let name in pluginConfigs) { | ||
let plugin = plugins[name]; | ||
if (!plugin) throw new Error("Plugin '" + name + "' not found"); | ||
plugin(this, pluginConfigs[name]); | ||
} | ||
static extend(...plugins) { | ||
let cls = this; | ||
for (let i = 0; i < plugins.length; i++) cls = plugins[i](cls); | ||
return cls; | ||
} | ||
parse() { | ||
let node = this.options.program || this.startNode(); | ||
this.nextToken(); | ||
return this.parseTopLevel(node); | ||
static parse(input, options) { | ||
return new this(options, input).parse(); | ||
} | ||
static parseExpressionAt(input, pos, options) { | ||
let parser = new this(options, input, pos); | ||
parser.nextToken(); | ||
return parser.parseExpression(); | ||
} | ||
static tokenizer(input, options) { | ||
return new this(options, input); | ||
} | ||
} | ||
exports.Parser = Parser; |
@@ -15,2 +15,4 @@ "use strict"; | ||
var _scopeflags = require("./scopeflags"); | ||
const pp = _state.Parser.prototype; | ||
@@ -29,5 +31,23 @@ | ||
while (this.type !== _tokentype.types.eof) { | ||
let stmt = this.parseStatement(true, true, exports); | ||
let stmt = this.parseStatement(null, true, exports); | ||
node.body.push(stmt); | ||
} | ||
if (this.inModule) { | ||
for (var _iterator = Object.keys(this.undefinedExports), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
let name = _ref; | ||
this.raiseRecoverable(this.undefinedExports[name].start, `Export '${name}' is not defined`); | ||
} | ||
}this.adaptDirectivePrologue(node.body); | ||
this.next(); | ||
@@ -43,4 +63,4 @@ if (this.options.ecmaVersion >= 6) { | ||
pp.isLet = function () { | ||
if (this.type !== _tokentype.types.name || this.options.ecmaVersion < 6 || this.value != "let") return false; | ||
pp.isLet = function (context) { | ||
if (this.options.ecmaVersion < 6 || !this.isContextual("let")) return false; | ||
_whitespace.skipWhiteSpace.lastIndex = this.pos; | ||
@@ -50,3 +70,10 @@ let skip = _whitespace.skipWhiteSpace.exec(this.input); | ||
nextCh = this.input.charCodeAt(next); | ||
if (nextCh === 91 || nextCh == 123) return true; // '{' and '[' | ||
// For ambiguous cases, determine if a LexicalDeclaration (or only a | ||
// Statement) is allowed here. If context is not empty then only a Statement | ||
// is allowed. However, `let [` is an explicit negative lookahead for | ||
// ExpressionStatement, so special-case it first. | ||
if (nextCh === 91) return true; // '[' | ||
if (context) return false; | ||
if (nextCh === 123) return true; // '{' | ||
if ((0, _identifier.isIdentifierStart)(nextCh, true)) { | ||
@@ -56,3 +83,3 @@ let pos = next + 1; | ||
let ident = this.input.slice(next, pos); | ||
if (!this.isKeyword(ident)) return true; | ||
if (!_identifier.keywordRelationalOperator.test(ident)) return true; | ||
} | ||
@@ -66,3 +93,3 @@ return false; | ||
pp.isAsyncFunction = function () { | ||
if (this.type !== _tokentype.types.name || this.options.ecmaVersion < 8 || this.value != "async") return false; | ||
if (this.options.ecmaVersion < 8 || !this.isContextual("async")) return false; | ||
@@ -72,3 +99,3 @@ _whitespace.skipWhiteSpace.lastIndex = this.pos; | ||
let next = this.pos + skip[0].length; | ||
return !_whitespace.lineBreak.test(this.input.slice(this.pos, next)) && this.input.slice(next, next + 8) === "function" && (next + 8 == this.input.length || !(0, _identifier.isIdentifierChar)(this.input.charAt(next + 8))); | ||
return !_whitespace.lineBreak.test(this.input.slice(this.pos, next)) && this.input.slice(next, next + 8) === "function" && (next + 8 === this.input.length || !(0, _identifier.isIdentifierChar)(this.input.charAt(next + 8))); | ||
}; | ||
@@ -83,3 +110,3 @@ | ||
pp.parseStatement = function (declaration, topLevel, exports) { | ||
pp.parseStatement = function (context, topLevel, exports) { | ||
let starttype = this.type, | ||
@@ -89,3 +116,3 @@ node = this.startNode(), | ||
if (this.isLet()) { | ||
if (this.isLet(context)) { | ||
starttype = _tokentype.types._var; | ||
@@ -109,6 +136,9 @@ kind = "let"; | ||
case _tokentype.types._function: | ||
if (!declaration && this.options.ecmaVersion >= 6) this.unexpected(); | ||
return this.parseFunctionStatement(node, false); | ||
// Function as sole body of either an if statement or a labeled statement | ||
// works, but not when it is part of a labeled statement that is the sole | ||
// body of an if statement. | ||
if (context && (this.strict || context !== "if" && context !== "label") && this.options.ecmaVersion >= 6) this.unexpected(); | ||
return this.parseFunctionStatement(node, false, !context); | ||
case _tokentype.types._class: | ||
if (!declaration) this.unexpected(); | ||
if (context) this.unexpected(); | ||
return this.parseClass(node, true); | ||
@@ -127,3 +157,3 @@ case _tokentype.types._if: | ||
kind = kind || this.value; | ||
if (!declaration && kind != "var") this.unexpected(); | ||
if (context && kind !== "var") this.unexpected(); | ||
return this.parseVarStatement(node, kind); | ||
@@ -135,3 +165,3 @@ case _tokentype.types._while: | ||
case _tokentype.types.braceL: | ||
return this.parseBlock(); | ||
return this.parseBlock(true, node); | ||
case _tokentype.types.semi: | ||
@@ -153,5 +183,6 @@ return this.parseEmptyStatement(node); | ||
default: | ||
if (this.isAsyncFunction() && declaration) { | ||
if (this.isAsyncFunction()) { | ||
if (context) this.unexpected(); | ||
this.next(); | ||
return this.parseFunctionStatement(node, true); | ||
return this.parseFunctionStatement(node, true, !context); | ||
} | ||
@@ -161,3 +192,3 @@ | ||
expr = this.parseExpression(); | ||
if (starttype === _tokentype.types.name && expr.type === "Identifier" && this.eat(_tokentype.types.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr); | ||
if (starttype === _tokentype.types.name && expr.type === "Identifier" && this.eat(_tokentype.types.colon)) return this.parseLabeledStatement(node, maybeName, expr, context);else return this.parseExpressionStatement(node, expr); | ||
} | ||
@@ -167,3 +198,3 @@ }; | ||
pp.parseBreakContinueStatement = function (node, keyword) { | ||
let isBreak = keyword == "break"; | ||
let isBreak = keyword === "break"; | ||
this.next(); | ||
@@ -198,3 +229,3 @@ if (this.eat(_tokentype.types.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== _tokentype.types.name) this.unexpected();else { | ||
this.labels.push(loopLabel); | ||
node.body = this.parseStatement(false); | ||
node.body = this.parseStatement("do"); | ||
this.labels.pop(); | ||
@@ -217,6 +248,10 @@ this.expect(_tokentype.types._while); | ||
this.next(); | ||
let awaitAt = this.options.ecmaVersion >= 9 && (this.inAsync || !this.inFunction && this.options.allowAwaitOutsideFunction) && this.eatContextual("await") ? this.lastTokStart : -1; | ||
this.labels.push(loopLabel); | ||
this.enterLexicalScope(); | ||
this.enterScope(0); | ||
this.expect(_tokentype.types.parenL); | ||
if (this.type === _tokentype.types.semi) return this.parseFor(node, null); | ||
if (this.type === _tokentype.types.semi) { | ||
if (awaitAt > -1) this.unexpected(awaitAt); | ||
return this.parseFor(node, null); | ||
} | ||
let isLet = this.isLet(); | ||
@@ -229,3 +264,11 @@ if (this.type === _tokentype.types._var || this.type === _tokentype.types._const || isLet) { | ||
this.finishNode(init, "VariableDeclaration"); | ||
if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && init.declarations.length === 1 && !(kind !== "var" && init.declarations[0].init)) return this.parseForIn(node, init); | ||
if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && init.declarations.length === 1 && !(kind !== "var" && init.declarations[0].init)) { | ||
if (this.options.ecmaVersion >= 9) { | ||
if (this.type === _tokentype.types._in) { | ||
if (awaitAt > -1) this.unexpected(awaitAt); | ||
} else node.await = awaitAt > -1; | ||
} | ||
return this.parseForIn(node, init); | ||
} | ||
if (awaitAt > -1) this.unexpected(awaitAt); | ||
return this.parseFor(node, init); | ||
@@ -236,5 +279,9 @@ } | ||
if (this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) { | ||
this.toAssignable(init); | ||
if (this.options.ecmaVersion >= 9) { | ||
if (this.type === _tokentype.types._in) { | ||
if (awaitAt > -1) this.unexpected(awaitAt); | ||
} else node.await = awaitAt > -1; | ||
} | ||
this.toAssignable(init, false, refDestructuringErrors); | ||
this.checkLVal(init); | ||
this.checkPatternErrors(refDestructuringErrors, true); | ||
return this.parseForIn(node, init); | ||
@@ -244,14 +291,11 @@ } else { | ||
} | ||
if (awaitAt > -1) this.unexpected(awaitAt); | ||
return this.parseFor(node, init); | ||
}; | ||
pp.parseFunctionStatement = function (node, isAsync) { | ||
pp.parseFunctionStatement = function (node, isAsync, declarationPosition) { | ||
this.next(); | ||
return this.parseFunction(node, true, false, isAsync); | ||
return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync); | ||
}; | ||
pp.isFunction = function () { | ||
return this.type === _tokentype.types._function || this.isAsyncFunction(); | ||
}; | ||
pp.parseIfStatement = function (node) { | ||
@@ -261,4 +305,4 @@ this.next(); | ||
// allow function declarations in branches, but only in non-strict mode | ||
node.consequent = this.parseStatement(!this.strict && this.isFunction()); | ||
node.alternate = this.eat(_tokentype.types._else) ? this.parseStatement(!this.strict && this.isFunction()) : null; | ||
node.consequent = this.parseStatement("if"); | ||
node.alternate = this.eat(_tokentype.types._else) ? this.parseStatement("if") : null; | ||
return this.finishNode(node, "IfStatement"); | ||
@@ -287,3 +331,3 @@ }; | ||
this.labels.push(switchLabel); | ||
this.enterLexicalScope(); | ||
this.enterScope(0); | ||
@@ -295,3 +339,3 @@ // Statements under must be grouped (by label) in SwitchCase | ||
let cur; | ||
for (let sawDefault = false; this.type != _tokentype.types.braceR;) { | ||
for (let sawDefault = false; this.type !== _tokentype.types.braceR;) { | ||
if (this.type === _tokentype.types._case || this.type === _tokentype.types._default) { | ||
@@ -313,6 +357,6 @@ let isCase = this.type === _tokentype.types._case; | ||
if (!cur) this.unexpected(); | ||
cur.consequent.push(this.parseStatement(true)); | ||
cur.consequent.push(this.parseStatement(null)); | ||
} | ||
} | ||
this.exitLexicalScope(); | ||
this.exitScope(); | ||
if (cur) this.finishNode(cur, "SwitchCase"); | ||
@@ -343,9 +387,15 @@ this.next(); // Closing brace | ||
this.next(); | ||
this.expect(_tokentype.types.parenL); | ||
clause.param = this.parseBindingAtom(); | ||
this.enterLexicalScope(); | ||
this.checkLVal(clause.param, "let"); | ||
this.expect(_tokentype.types.parenR); | ||
if (this.eat(_tokentype.types.parenL)) { | ||
clause.param = this.parseBindingAtom(); | ||
let simple = clause.param.type === "Identifier"; | ||
this.enterScope(simple ? _scopeflags.SCOPE_SIMPLE_CATCH : 0); | ||
this.checkLVal(clause.param, simple ? _scopeflags.BIND_SIMPLE_CATCH : _scopeflags.BIND_LEXICAL); | ||
this.expect(_tokentype.types.parenR); | ||
} else { | ||
if (this.options.ecmaVersion < 10) this.unexpected(); | ||
clause.param = null; | ||
this.enterScope(0); | ||
} | ||
clause.body = this.parseBlock(false); | ||
this.exitLexicalScope(); | ||
this.exitScope(); | ||
node.handler = this.finishNode(clause, "CatchClause"); | ||
@@ -369,3 +419,3 @@ } | ||
this.labels.push(loopLabel); | ||
node.body = this.parseStatement(false); | ||
node.body = this.parseStatement("while"); | ||
this.labels.pop(); | ||
@@ -379,3 +429,3 @@ return this.finishNode(node, "WhileStatement"); | ||
node.object = this.parseParenExpression(); | ||
node.body = this.parseStatement(false); | ||
node.body = this.parseStatement("with"); | ||
return this.finishNode(node, "WithStatement"); | ||
@@ -389,16 +439,16 @@ }; | ||
pp.parseLabeledStatement = function (node, maybeName, expr) { | ||
for (var _iterator = this.labels, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
var _ref; | ||
pp.parseLabeledStatement = function (node, maybeName, expr, context) { | ||
for (var _iterator2 = this.labels, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { | ||
var _ref2; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
} | ||
let label = _ref; | ||
let label = _ref2; | ||
@@ -409,3 +459,4 @@ if (label.name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared"); | ||
let label = this.labels[i]; | ||
if (label.statementStart == node.start) { | ||
if (label.statementStart === node.start) { | ||
// Update information about previous labels on this node | ||
label.statementStart = this.start; | ||
@@ -415,5 +466,4 @@ label.kind = kind; | ||
} | ||
this.labels.push({ name: maybeName, kind: kind, statementStart: this.start }); | ||
node.body = this.parseStatement(true); | ||
if (node.body.type == "ClassDeclaration" || node.body.type == "VariableDeclaration" && node.body.kind != "var" || node.body.type == "FunctionDeclaration" && (this.strict || node.body.generator)) this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); | ||
this.labels.push({ name: maybeName, kind, statementStart: this.start }); | ||
node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); | ||
this.labels.pop(); | ||
@@ -434,16 +484,11 @@ node.label = expr; | ||
pp.parseBlock = function (createNewLexicalScope = true) { | ||
let node = this.startNode(); | ||
pp.parseBlock = function (createNewLexicalScope = true, node = this.startNode()) { | ||
node.body = []; | ||
this.expect(_tokentype.types.braceL); | ||
if (createNewLexicalScope) { | ||
this.enterLexicalScope(); | ||
} | ||
if (createNewLexicalScope) this.enterScope(0); | ||
while (!this.eat(_tokentype.types.braceR)) { | ||
let stmt = this.parseStatement(true); | ||
let stmt = this.parseStatement(null); | ||
node.body.push(stmt); | ||
} | ||
if (createNewLexicalScope) { | ||
this.exitLexicalScope(); | ||
} | ||
if (createNewLexicalScope) this.exitScope(); | ||
return this.finishNode(node, "BlockStatement"); | ||
@@ -463,4 +508,4 @@ }; | ||
this.expect(_tokentype.types.parenR); | ||
this.exitLexicalScope(); | ||
node.body = this.parseStatement(false); | ||
node.body = this.parseStatement("for"); | ||
this.exitScope(); | ||
this.labels.pop(); | ||
@@ -476,7 +521,10 @@ return this.finishNode(node, "ForStatement"); | ||
this.next(); | ||
if (type === "ForInStatement") { | ||
if (init.type === "AssignmentPattern" || init.type === "VariableDeclaration" && init.declarations[0].init != null && (this.strict || init.declarations[0].id.type !== "Identifier")) this.raise(init.start, "Invalid assignment in for-in loop head"); | ||
} | ||
node.left = init; | ||
node.right = this.parseExpression(); | ||
node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); | ||
this.expect(_tokentype.types.parenR); | ||
this.exitLexicalScope(); | ||
node.body = this.parseStatement(false); | ||
node.body = this.parseStatement("for"); | ||
this.exitScope(); | ||
this.labels.pop(); | ||
@@ -498,3 +546,3 @@ return this.finishNode(node, type); | ||
this.unexpected(); | ||
} else if (decl.id.type != "Identifier" && !(isFor && (this.type === _tokentype.types._in || this.isContextual("of")))) { | ||
} else if (decl.id.type !== "Identifier" && !(isFor && (this.type === _tokentype.types._in || this.isContextual("of")))) { | ||
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); | ||
@@ -511,44 +559,52 @@ } else { | ||
pp.parseVarId = function (decl, kind) { | ||
decl.id = this.parseBindingAtom(kind); | ||
this.checkLVal(decl.id, kind, false); | ||
if ((kind === "const" || kind === "let") && this.isContextual("let")) { | ||
this.raiseRecoverable(this.start, "let is disallowed as a lexically bound name"); | ||
} | ||
decl.id = this.parseBindingAtom(); | ||
this.checkLVal(decl.id, kind === "var" ? _scopeflags.BIND_VAR : _scopeflags.BIND_LEXICAL, false); | ||
}; | ||
const FUNC_STATEMENT = 1, | ||
FUNC_HANGING_STATEMENT = 2, | ||
FUNC_NULLABLE_ID = 4; | ||
// Parse a function declaration or literal (depending on the | ||
// `isStatement` parameter). | ||
// `statement & FUNC_STATEMENT`). | ||
pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync) { | ||
// Remove `allowExpressionBody` for 7.0.0, as it is only called with false | ||
pp.parseFunction = function (node, statement, allowExpressionBody, isAsync) { | ||
this.initFunction(node); | ||
if (this.options.ecmaVersion >= 6 && !isAsync) node.generator = this.eat(_tokentype.types.star); | ||
if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { | ||
if (this.type === _tokentype.types.star && statement & FUNC_HANGING_STATEMENT) this.unexpected(); | ||
node.generator = this.eat(_tokentype.types.star); | ||
} | ||
if (this.options.ecmaVersion >= 8) node.async = !!isAsync; | ||
if (isStatement) { | ||
node.id = isStatement === "nullableID" && this.type != _tokentype.types.name ? null : this.parseIdent(); | ||
if (node.id) { | ||
this.checkLVal(node.id, "var"); | ||
} | ||
if (statement & FUNC_STATEMENT) { | ||
node.id = statement & FUNC_NULLABLE_ID && this.type !== _tokentype.types.name ? null : this.parseIdent(); | ||
if (node.id && !(statement & FUNC_HANGING_STATEMENT)) | ||
// If it is a regular function declaration in sloppy mode, then it is | ||
// subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding | ||
// mode depends on properties of the current scope (see | ||
// treatFunctionsAsVar). | ||
this.checkLVal(node.id, this.strict || node.generator || node.async ? this.treatFunctionsAsVar ? _scopeflags.BIND_VAR : _scopeflags.BIND_LEXICAL : _scopeflags.BIND_FUNCTION); | ||
} | ||
let oldInGen = this.inGenerator, | ||
oldInAsync = this.inAsync, | ||
oldYieldPos = this.yieldPos, | ||
let oldYieldPos = this.yieldPos, | ||
oldAwaitPos = this.awaitPos, | ||
oldInFunc = this.inFunction; | ||
this.inGenerator = node.generator; | ||
this.inAsync = node.async; | ||
oldAwaitIdentPos = this.awaitIdentPos; | ||
this.yieldPos = 0; | ||
this.awaitPos = 0; | ||
this.inFunction = true; | ||
this.enterFunctionScope(); | ||
this.awaitIdentPos = 0; | ||
this.enterScope((0, _scopeflags.functionFlags)(node.async, node.generator)); | ||
if (!isStatement) node.id = this.type == _tokentype.types.name ? this.parseIdent() : null; | ||
if (!(statement & FUNC_STATEMENT)) node.id = this.type === _tokentype.types.name ? this.parseIdent() : null; | ||
this.parseFunctionParams(node); | ||
this.parseFunctionBody(node, allowExpressionBody); | ||
this.parseFunctionBody(node, allowExpressionBody, false); | ||
this.inGenerator = oldInGen; | ||
this.inAsync = oldInAsync; | ||
this.yieldPos = oldYieldPos; | ||
this.awaitPos = oldAwaitPos; | ||
this.inFunction = oldInFunc; | ||
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); | ||
this.awaitIdentPos = oldAwaitIdentPos; | ||
return this.finishNode(node, statement & FUNC_STATEMENT ? "FunctionDeclaration" : "FunctionExpression"); | ||
}; | ||
@@ -568,2 +624,7 @@ | ||
// ecma-262 14.6 Class Definitions | ||
// A class definition is always strict mode code. | ||
const oldStrict = this.strict; | ||
this.strict = true; | ||
this.parseClassId(node, isStatement); | ||
@@ -576,59 +637,80 @@ this.parseClassSuper(node); | ||
while (!this.eat(_tokentype.types.braceR)) { | ||
if (this.eat(_tokentype.types.semi)) continue; | ||
let method = this.startNode(); | ||
let isGenerator = this.eat(_tokentype.types.star); | ||
let isAsync = false; | ||
let isMaybeStatic = this.type === _tokentype.types.name && this.value === "static"; | ||
this.parsePropertyName(method); | ||
method.static = isMaybeStatic && this.type !== _tokentype.types.parenL; | ||
if (method.static) { | ||
if (isGenerator) this.unexpected(); | ||
isGenerator = this.eat(_tokentype.types.star); | ||
this.parsePropertyName(method); | ||
} | ||
if (this.options.ecmaVersion >= 8 && !isGenerator && !method.computed && method.key.type === "Identifier" && method.key.name === "async" && this.type !== _tokentype.types.parenL && !this.canInsertSemicolon()) { | ||
isAsync = true; | ||
this.parsePropertyName(method); | ||
} | ||
method.kind = "method"; | ||
let isGetSet = false; | ||
if (!method.computed) { | ||
let key = method.key; | ||
if (!isGenerator && !isAsync && key.type === "Identifier" && this.type !== _tokentype.types.parenL && (key.name === "get" || key.name === "set")) { | ||
isGetSet = true; | ||
method.kind = key.name; | ||
key = this.parsePropertyName(method); | ||
} | ||
if (!method.static && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) { | ||
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class"); | ||
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier"); | ||
if (isGenerator) this.raise(key.start, "Constructor can't be a generator"); | ||
if (isAsync) this.raise(key.start, "Constructor can't be an async method"); | ||
method.kind = "constructor"; | ||
const element = this.parseClassElement(node.superClass !== null); | ||
if (element) { | ||
classBody.body.push(element); | ||
if (element.type === "MethodDefinition" && element.kind === "constructor") { | ||
if (hadConstructor) this.raise(element.start, "Duplicate constructor in the same class"); | ||
hadConstructor = true; | ||
} | ||
} | ||
this.parseClassMethod(classBody, method, isGenerator, isAsync); | ||
if (isGetSet) { | ||
let paramCount = method.kind === "get" ? 0 : 1; | ||
if (method.value.params.length !== paramCount) { | ||
let start = method.value.start; | ||
if (method.kind === "get") this.raiseRecoverable(start, "getter should have no params");else this.raiseRecoverable(start, "setter should have exactly one param"); | ||
} else { | ||
if (method.kind === "set" && method.value.params[0].type === "RestElement") this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); | ||
} | ||
} | ||
} | ||
node.body = this.finishNode(classBody, "ClassBody"); | ||
this.strict = oldStrict; | ||
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); | ||
}; | ||
pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) { | ||
method.value = this.parseMethod(isGenerator, isAsync); | ||
classBody.body.push(this.finishNode(method, "MethodDefinition")); | ||
pp.parseClassElement = function (constructorAllowsSuper) { | ||
if (this.eat(_tokentype.types.semi)) return null; | ||
let method = this.startNode(); | ||
const tryContextual = (k, noLineBreak = false) => { | ||
const start = this.start, | ||
startLoc = this.startLoc; | ||
if (!this.eatContextual(k)) return false; | ||
if (this.type !== _tokentype.types.parenL && (!noLineBreak || !this.canInsertSemicolon())) return true; | ||
if (method.key) this.unexpected(); | ||
method.computed = false; | ||
method.key = this.startNodeAt(start, startLoc); | ||
method.key.name = k; | ||
this.finishNode(method.key, "Identifier"); | ||
return false; | ||
}; | ||
method.kind = "method"; | ||
method.static = tryContextual("static"); | ||
let isGenerator = this.eat(_tokentype.types.star); | ||
let isAsync = false; | ||
if (!isGenerator) { | ||
if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { | ||
isAsync = true; | ||
isGenerator = this.options.ecmaVersion >= 9 && this.eat(_tokentype.types.star); | ||
} else if (tryContextual("get")) { | ||
method.kind = "get"; | ||
} else if (tryContextual("set")) { | ||
method.kind = "set"; | ||
} | ||
} | ||
if (!method.key) this.parsePropertyName(method); | ||
let key = method.key; | ||
let allowsDirectSuper = false; | ||
if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) { | ||
if (method.kind !== "method") this.raise(key.start, "Constructor can't have get/set modifier"); | ||
if (isGenerator) this.raise(key.start, "Constructor can't be a generator"); | ||
if (isAsync) this.raise(key.start, "Constructor can't be an async method"); | ||
method.kind = "constructor"; | ||
allowsDirectSuper = constructorAllowsSuper; | ||
} else if (method.static && key.type === "Identifier" && key.name === "prototype") { | ||
this.raise(key.start, "Classes may not have a static property named prototype"); | ||
} | ||
this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper); | ||
if (method.kind === "get" && method.value.params.length !== 0) this.raiseRecoverable(method.value.start, "getter should have no params"); | ||
if (method.kind === "set" && method.value.params.length !== 1) this.raiseRecoverable(method.value.start, "setter should have exactly one param"); | ||
if (method.kind === "set" && method.value.params[0].type === "RestElement") this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); | ||
return method; | ||
}; | ||
pp.parseClassMethod = function (method, isGenerator, isAsync, allowsDirectSuper) { | ||
method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); | ||
return this.finishNode(method, "MethodDefinition"); | ||
}; | ||
pp.parseClassId = function (node, isStatement) { | ||
node.id = this.type === _tokentype.types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; | ||
if (this.type === _tokentype.types.name) { | ||
node.id = this.parseIdent(); | ||
if (isStatement === true) this.checkLVal(node.id, _scopeflags.BIND_LEXICAL, false); | ||
} else { | ||
if (isStatement === true) this.unexpected(); | ||
node.id = null; | ||
} | ||
}; | ||
@@ -647,3 +729,4 @@ | ||
this.expectContextual("from"); | ||
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected(); | ||
if (this.type !== _tokentype.types.string) this.unexpected(); | ||
node.source = this.parseExprAtom(); | ||
this.semicolon(); | ||
@@ -660,3 +743,3 @@ return this.finishNode(node, "ExportAllDeclaration"); | ||
if (isAsync) this.next(); | ||
node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); | ||
node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync); | ||
} else if (this.type === _tokentype.types._class) { | ||
@@ -673,3 +756,3 @@ let cNode = this.startNode(); | ||
if (this.shouldParseExportStatement()) { | ||
node.declaration = this.parseStatement(true); | ||
node.declaration = this.parseStatement(null); | ||
if (node.declaration.type === "VariableDeclaration") this.checkVariableExport(exports, node.declaration.declarations);else this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); | ||
@@ -683,20 +766,23 @@ node.specifiers = []; | ||
if (this.eatContextual("from")) { | ||
node.source = this.type === _tokentype.types.string ? this.parseExprAtom() : this.unexpected(); | ||
if (this.type !== _tokentype.types.string) this.unexpected(); | ||
node.source = this.parseExprAtom(); | ||
} else { | ||
// check for keywords used as local names | ||
for (var _iterator2 = node.specifiers, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { | ||
var _ref2; | ||
for (var _iterator3 = node.specifiers, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { | ||
var _ref3; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
if (_isArray3) { | ||
if (_i3 >= _iterator3.length) break; | ||
_ref3 = _iterator3[_i3++]; | ||
} else { | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
_i3 = _iterator3.next(); | ||
if (_i3.done) break; | ||
_ref3 = _i3.value; | ||
} | ||
let spec = _ref2; | ||
let spec = _ref3; | ||
// check for keywords used as local names | ||
this.checkUnreserved(spec.local); | ||
// check if export is defined | ||
this.checkLocalExport(spec.local); | ||
} | ||
@@ -719,21 +805,4 @@ | ||
let type = pat.type; | ||
if (type == "Identifier") this.checkExport(exports, pat.name, pat.start);else if (type == "ObjectPattern") { | ||
for (var _iterator3 = pat.properties, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { | ||
var _ref3; | ||
if (_isArray3) { | ||
if (_i3 >= _iterator3.length) break; | ||
_ref3 = _iterator3[_i3++]; | ||
} else { | ||
_i3 = _iterator3.next(); | ||
if (_i3.done) break; | ||
_ref3 = _i3.value; | ||
} | ||
let prop = _ref3; | ||
this.checkPatternExport(exports, prop.value); | ||
} | ||
} else if (type == "ArrayPattern") { | ||
for (var _iterator4 = pat.elements, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { | ||
if (type === "Identifier") this.checkExport(exports, pat.name, pat.start);else if (type === "ObjectPattern") { | ||
for (var _iterator4 = pat.properties, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { | ||
var _ref4; | ||
@@ -750,7 +819,24 @@ | ||
let elt = _ref4; | ||
let prop = _ref4; | ||
this.checkPatternExport(exports, prop); | ||
} | ||
} else if (type === "ArrayPattern") { | ||
for (var _iterator5 = pat.elements, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { | ||
var _ref5; | ||
if (_isArray5) { | ||
if (_i5 >= _iterator5.length) break; | ||
_ref5 = _iterator5[_i5++]; | ||
} else { | ||
_i5 = _iterator5.next(); | ||
if (_i5.done) break; | ||
_ref5 = _i5.value; | ||
} | ||
let elt = _ref5; | ||
if (elt) this.checkPatternExport(exports, elt); | ||
} | ||
} else if (type == "AssignmentPattern") this.checkPatternExport(exports, pat.left);else if (type == "ParenthesizedExpression") this.checkPatternExport(exports, pat.expression); | ||
} else if (type === "Property") this.checkPatternExport(exports, pat.value);else if (type === "AssignmentPattern") this.checkPatternExport(exports, pat.left);else if (type === "RestElement") this.checkPatternExport(exports, pat.argument);else if (type === "ParenthesizedExpression") this.checkPatternExport(exports, pat.expression); | ||
}; | ||
@@ -760,15 +846,15 @@ | ||
if (!exports) return; | ||
for (var _iterator5 = decls, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { | ||
var _ref5; | ||
for (var _iterator6 = decls, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { | ||
var _ref6; | ||
if (_isArray5) { | ||
if (_i5 >= _iterator5.length) break; | ||
_ref5 = _iterator5[_i5++]; | ||
if (_isArray6) { | ||
if (_i6 >= _iterator6.length) break; | ||
_ref6 = _iterator6[_i6++]; | ||
} else { | ||
_i5 = _iterator5.next(); | ||
if (_i5.done) break; | ||
_ref5 = _i5.value; | ||
_i6 = _iterator6.next(); | ||
if (_i6.done) break; | ||
_ref6 = _i6.value; | ||
} | ||
let decl = _ref5; | ||
let decl = _ref6; | ||
@@ -831,3 +917,3 @@ this.checkPatternExport(exports, decl.id); | ||
node.local = this.parseIdent(); | ||
this.checkLVal(node.local, "let"); | ||
this.checkLVal(node.local, _scopeflags.BIND_LEXICAL); | ||
nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); | ||
@@ -841,3 +927,3 @@ if (!this.eat(_tokentype.types.comma)) return nodes; | ||
node.local = this.parseIdent(); | ||
this.checkLVal(node.local, "let"); | ||
this.checkLVal(node.local, _scopeflags.BIND_LEXICAL); | ||
nodes.push(this.finishNode(node, "ImportNamespaceSpecifier")); | ||
@@ -861,6 +947,18 @@ return nodes; | ||
} | ||
this.checkLVal(node.local, "let"); | ||
this.checkLVal(node.local, _scopeflags.BIND_LEXICAL); | ||
nodes.push(this.finishNode(node, "ImportSpecifier")); | ||
} | ||
return nodes; | ||
}; | ||
// Set `ExpressionStatement#directive` property for directive prologues. | ||
pp.adaptDirectivePrologue = function (statements) { | ||
for (let i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { | ||
statements[i].directive = statements[i].expression.raw.slice(1, -1); | ||
} | ||
}; | ||
pp.isDirectiveCandidate = function (statement) { | ||
return statement.type === "ExpressionStatement" && statement.expression.type === "Literal" && typeof statement.expression.value === "string" && ( | ||
// Reject parenthesized strings. | ||
this.input[statement.start] === "\"" || this.input[statement.start] === "'"); | ||
}; |
@@ -53,6 +53,6 @@ "use strict"; | ||
// `tt.name`. | ||
if (prevType === _tokentype.types._return || prevType == _tokentype.types.name && this.exprAllowed) return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); | ||
if (prevType === _tokentype.types._else || prevType === _tokentype.types.semi || prevType === _tokentype.types.eof || prevType === _tokentype.types.parenR || prevType == _tokentype.types.arrow) return true; | ||
if (prevType == _tokentype.types.braceL) return parent === types.b_stat; | ||
if (prevType == _tokentype.types._var || prevType == _tokentype.types.name) return false; | ||
if (prevType === _tokentype.types._return || prevType === _tokentype.types.name && this.exprAllowed) return _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start)); | ||
if (prevType === _tokentype.types._else || prevType === _tokentype.types.semi || prevType === _tokentype.types.eof || prevType === _tokentype.types.parenR || prevType === _tokentype.types.arrow) return true; | ||
if (prevType === _tokentype.types.braceL) return parent === types.b_stat; | ||
if (prevType === _tokentype.types._var || prevType === _tokentype.types._const || prevType === _tokentype.types.name) return false; | ||
return !this.exprAllowed; | ||
@@ -72,3 +72,3 @@ }; | ||
type = this.type; | ||
if (type.keyword && prevType == _tokentype.types.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr; | ||
if (type.keyword && prevType === _tokentype.types.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr; | ||
}; | ||
@@ -79,3 +79,3 @@ | ||
_tokentype.types.parenR.updateContext = _tokentype.types.braceR.updateContext = function () { | ||
if (this.context.length == 1) { | ||
if (this.context.length === 1) { | ||
this.exprAllowed = true; | ||
@@ -112,3 +112,3 @@ return; | ||
_tokentype.types._function.updateContext = _tokentype.types._class.updateContext = function (prevType) { | ||
if (prevType.beforeExpr && prevType !== _tokentype.types.semi && prevType !== _tokentype.types._else && !((prevType === _tokentype.types.colon || prevType === _tokentype.types.braceL) && this.curContext() === types.b_stat)) this.context.push(types.f_expr);else this.context.push(types.f_stat); | ||
if (prevType.beforeExpr && prevType !== _tokentype.types.semi && prevType !== _tokentype.types._else && !(prevType === _tokentype.types._return && _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && !((prevType === _tokentype.types.colon || prevType === _tokentype.types.braceL) && this.curContext() === types.b_stat)) this.context.push(types.f_expr);else this.context.push(types.f_stat); | ||
this.exprAllowed = false; | ||
@@ -123,3 +123,3 @@ }; | ||
_tokentype.types.star.updateContext = function (prevType) { | ||
if (prevType == _tokentype.types._function) { | ||
if (prevType === _tokentype.types._function) { | ||
let index = this.context.length - 1; | ||
@@ -133,6 +133,6 @@ if (this.context[index] === types.f_expr) this.context[index] = types.f_expr_gen;else this.context[index] = types.f_gen; | ||
let allowed = false; | ||
if (this.options.ecmaVersion >= 6) { | ||
if (this.value == "of" && !this.exprAllowed || this.value == "yield" && this.inGeneratorContext()) allowed = true; | ||
if (this.options.ecmaVersion >= 6 && prevType !== _tokentype.types.dot) { | ||
if (this.value === "of" && !this.exprAllowed || this.value === "yield" && this.inGeneratorContext()) allowed = true; | ||
} | ||
this.exprAllowed = allowed; | ||
}; |
@@ -14,2 +14,4 @@ "use strict"; | ||
var _regexp = require("./regexp"); | ||
var _whitespace = require("./whitespace"); | ||
@@ -36,5 +38,2 @@ | ||
// Are we running under Rhino? | ||
const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"; | ||
// Move to the next token | ||
@@ -234,3 +233,3 @@ | ||
// exponentiation operator ** and **= | ||
if (this.options.ecmaVersion >= 7 && next === 42) { | ||
if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { | ||
++size; | ||
@@ -264,3 +263,3 @@ tokentype = _tokentype.types.starstar; | ||
if (next === code) { | ||
if (next == 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 62 && (this.lastTokEnd === 0 || _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { | ||
if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && (this.lastTokEnd === 0 || _whitespace.lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { | ||
// A `-->` line comment | ||
@@ -286,3 +285,3 @@ this.skipLineComment(3); | ||
} | ||
if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) { | ||
if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && this.input.charCodeAt(this.pos + 3) === 45) { | ||
// `<!--`, an XML-style comment that should be interpreted as a line comment | ||
@@ -353,2 +352,3 @@ this.skipLineComment(4); | ||
} | ||
// Anything else beginning with a digit is an integer, octal | ||
@@ -412,18 +412,2 @@ // number, or float. | ||
// Parse a regular expression. Some context-awareness is necessary, | ||
// since a '/' inside a '[]' set does not end the expression. | ||
function tryCreateRegexp(src, flags, throwErrorAt, parser) { | ||
try { | ||
return new RegExp(src, flags); | ||
} catch (e) { | ||
if (throwErrorAt !== undefined) { | ||
if (e instanceof SyntaxError) parser.raise(throwErrorAt, "Error parsing regular expression: " + e.message); | ||
throw e; | ||
} | ||
} | ||
} | ||
const regexpUnicodeSupport = !!tryCreateRegexp("\uffff", "u"); | ||
pp.readRegexp = function () { | ||
@@ -443,46 +427,24 @@ let escaped, | ||
} | ||
let content = this.input.slice(start, this.pos); | ||
let pattern = this.input.slice(start, this.pos); | ||
++this.pos; | ||
// Need to use `readWord1` because '\uXXXX' sequences are allowed | ||
// here (don't ask). | ||
let mods = this.readWord1(); | ||
let tmp = content, | ||
tmpFlags = ""; | ||
if (mods) { | ||
let validFlags = /^[gim]*$/; | ||
if (this.options.ecmaVersion >= 6) validFlags = /^[gimuy]*$/; | ||
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag"); | ||
if (mods.indexOf("u") >= 0) { | ||
if (regexpUnicodeSupport) { | ||
tmpFlags = "u"; | ||
} else { | ||
// 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, (_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"); | ||
tmpFlags = tmpFlags.replace("u", ""); | ||
} | ||
} | ||
} | ||
// Detect invalid regular expressions. | ||
let flagsStart = this.pos; | ||
let flags = this.readWord1(); | ||
if (this.containsEsc) this.unexpected(flagsStart); | ||
// Validate pattern | ||
const state = this.regexpState || (this.regexpState = new _regexp.RegExpValidationState(this)); | ||
state.reset(start, pattern, flags); | ||
this.validateRegExpFlags(state); | ||
this.validateRegExpPattern(state); | ||
// Create Literal#value property value. | ||
let 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(tmp, tmpFlags, start, this); | ||
// 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(content, mods); | ||
try { | ||
value = new RegExp(pattern, flags); | ||
} catch (e) { | ||
// ESTree requires null if it failed to instantiate RegExp object. | ||
// https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral | ||
} | ||
return this.finishToken(_tokentype.types.regexp, { pattern: content, flags: mods, value: value }); | ||
return this.finishToken(_tokentype.types.regexp, { pattern, flags, value }); | ||
}; | ||
@@ -524,7 +486,7 @@ | ||
pp.readNumber = function (startsWithDot) { | ||
let start = this.pos, | ||
isFloat = false, | ||
octal = this.input.charCodeAt(this.pos) === 48; | ||
let start = this.pos; | ||
if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number"); | ||
if (octal && this.pos == start + 1) octal = false; | ||
let octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48; | ||
if (octal && this.strict) this.raise(start, "Invalid number"); | ||
if (octal && /[89]/.test(this.input.slice(start, this.pos))) octal = false; | ||
let next = this.input.charCodeAt(this.pos); | ||
@@ -535,3 +497,2 @@ if (next === 46 && !octal) { | ||
this.readInt(10); | ||
isFloat = true; | ||
next = this.input.charCodeAt(this.pos); | ||
@@ -544,9 +505,7 @@ } | ||
if (this.readInt(10) === null) this.raise(start, "Invalid number"); | ||
isFloat = true; | ||
} | ||
if ((0, _identifier.isIdentifierStart)(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number"); | ||
let str = this.input.slice(start, this.pos), | ||
val; | ||
if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (this.strict) this.raise(start, "Invalid number");else if (/[89]/.test(str)) val = parseInt(str, 10);else val = parseInt(str, 8); | ||
let str = this.input.slice(start, this.pos); | ||
let val = octal ? parseInt(str, 8) : parseFloat(str); | ||
return this.finishToken(_tokentype.types.num, val); | ||
@@ -594,3 +553,3 @@ }; | ||
} else { | ||
if ((0, _whitespace.isNewLine)(ch)) this.raise(this.start, "Unterminated string constant"); | ||
if ((0, _whitespace.isNewLine)(ch, this.options.ecmaVersion >= 10)) this.raise(this.start, "Unterminated string constant"); | ||
++this.pos; | ||
@@ -740,8 +699,14 @@ } | ||
} | ||
if (octalStr !== "0" && (this.strict || inTemplate)) { | ||
this.invalidStringToken(this.pos - 2, "Octal literal in strict mode"); | ||
this.pos += octalStr.length - 1; | ||
ch = this.input.charCodeAt(this.pos); | ||
if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) { | ||
this.invalidStringToken(this.pos - 1 - octalStr.length, inTemplate ? "Octal literal in template string" : "Octal literal in strict mode"); | ||
} | ||
this.pos += octalStr.length - 1; | ||
return String.fromCharCode(octal); | ||
} | ||
if ((0, _whitespace.isNewLine)(ch)) { | ||
// Unicode new line characters after \ get removed from output in both | ||
// template literals and strings | ||
return ""; | ||
} | ||
return String.fromCharCode(ch); | ||
@@ -781,3 +746,3 @@ } | ||
let escStart = this.pos; | ||
if (this.input.charCodeAt(++this.pos) != 117) // "u" | ||
if (this.input.charCodeAt(++this.pos) !== 117) // "u" | ||
this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); | ||
@@ -784,0 +749,0 @@ ++this.pos; |
@@ -102,3 +102,3 @@ "use strict"; | ||
incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }), | ||
prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }), | ||
prefix: new TokenType("!/~", { beforeExpr: true, prefix: true, startsExpr: true }), | ||
logicalOR: binop("||", 1), | ||
@@ -109,5 +109,5 @@ logicalAND: binop("&&", 2), | ||
bitwiseAND: binop("&", 5), | ||
equality: binop("==/!=", 6), | ||
relational: binop("</>", 7), | ||
bitShift: binop("<</>>", 8), | ||
equality: binop("==/!=/===/!==", 6), | ||
relational: binop("</>/<=/>=", 7), | ||
bitShift: binop("<</>>/>>>", 8), | ||
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }), | ||
@@ -114,0 +114,0 @@ modulo: binop("%", 10), |
@@ -5,2 +5,3 @@ "use strict"; | ||
exports.has = has; | ||
exports.wordsRegexp = wordsRegexp; | ||
var _Object$prototype = Object.prototype; | ||
@@ -16,2 +17,6 @@ const hasOwnProperty = _Object$prototype.hasOwnProperty, | ||
const isArray = exports.isArray = Array.isArray || (obj => toString.call(obj) === "[object Array]"); | ||
const isArray = exports.isArray = Array.isArray || (obj => toString.call(obj) === "[object Array]"); | ||
function wordsRegexp(words) { | ||
return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"); | ||
} |
@@ -11,8 +11,8 @@ "use strict"; | ||
function isNewLine(code) { | ||
return code === 10 || code === 13 || code === 0x2028 || code === 0x2029; | ||
function isNewLine(code, ecma2019String) { | ||
return code === 10 || code === 13 || !ecma2019String && (code === 0x2028 || code === 0x2029); | ||
} | ||
const nonASCIIwhitespace = exports.nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; | ||
const nonASCIIwhitespace = exports.nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; | ||
const skipWhiteSpace = exports.skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; |
{ | ||
"name": "acorn-hammerhead", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "", | ||
"main": "lib/index.js", | ||
"files": [ | ||
"lib" | ||
"lib", | ||
"ts-defs" | ||
], | ||
"dependencies": { | ||
"@types/estree": "^0.0.39" | ||
}, | ||
"devDependencies": { | ||
@@ -32,3 +36,4 @@ "babel-plugin-add-module-exports": "^0.1.2", | ||
}, | ||
"homepage": "https://github.com/miherlosev/acorn-hammerhead#readme" | ||
"homepage": "https://github.com/miherlosev/acorn-hammerhead#readme", | ||
"types": "./ts-defs/index.d.ts" | ||
} |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
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
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
197229
23
4562
0
15
1
1
1
+ Added@types/estree@^0.0.39
+ Added@types/estree@0.0.39(transitive)