Skip to content

Commit

Permalink
Update acorn to 3.0.4 (close #591) (#606)
Browse files Browse the repository at this point in the history
  • Loading branch information
LavrovArtem authored and churkin committed May 27, 2016
1 parent c100fd0 commit ad9bedc
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 94 deletions.
108 changes: 53 additions & 55 deletions src/processing/script/tools/acorn/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import {types as tt} from "./tokentype"
import {Parser} from "./state"
import {DestructuringErrors} from "./parseutil"

const pp = Parser.prototype

Expand Down Expand Up @@ -93,19 +92,18 @@ pp.parseExpression = function(noIn, refDestructuringErrors) {
pp.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
if (this.inGenerator && this.isContextual("yield")) return this.parseYield()

let ownDestructuringErrors = false
let validateDestructuring = false
if (!refDestructuringErrors) {
refDestructuringErrors = new DestructuringErrors
ownDestructuringErrors = true
refDestructuringErrors = {shorthandAssign: 0, trailingComma: 0}
validateDestructuring = true
}
let startPos = this.start, startLoc = this.startLoc
if (this.type == tt.parenL || this.type == tt.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) DestructuringErrors.call(refDestructuringErrors)
if (validateDestructuring) this.checkPatternErrors(refDestructuringErrors, true)
let node = this.startNodeAt(startPos, startLoc)
node.operator = this.value
node.left = this.type === tt.eq ? this.toAssignable(left) : left
Expand All @@ -115,7 +113,7 @@ pp.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
node.right = this.parseMaybeAssign(noIn)
return this.finishNode(node, "AssignmentExpression")
} else {
if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true)
if (validateDestructuring) this.checkExpressionErrors(refDestructuringErrors, true)
}
return left
}
Expand Down Expand Up @@ -348,7 +346,7 @@ pp.parseParenAndDistinguishExpression = function(canBeArrow) {

let innerStartPos = this.start, innerStartLoc = this.startLoc
let exprList = [], first = true
let refDestructuringErrors = new DestructuringErrors, spreadStart, innerParenStart
let refDestructuringErrors = {shorthandAssign: 0, trailingComma: 0}, spreadStart, innerParenStart
while (this.type !== tt.parenR) {
first ? first = false : this.expect(tt.comma)
if (this.type === tt.ellipsis) {
Expand Down Expand Up @@ -492,47 +490,47 @@ pp.parseObj = function(isPattern, refDestructuringErrors) {

pp.parsePropertyValue = function(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) {
if (this.eat(tt.colon)) {
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors)
prop.kind = "init"
} else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
if (isPattern) this.unexpected()
prop.kind = "init"
prop.method = true
prop.value = this.parseMethod(isGenerator)
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
(prop.key.name === "get" || prop.key.name === "set") &&
(this.type != tt.comma && this.type != tt.braceR)) {
if (isGenerator || isPattern) this.unexpected()
prop.kind = prop.key.name
this.parsePropertyName(prop)
prop.value = this.parseMethod(false)
let paramCount = prop.kind === "get" ? 0 : 1
if (prop.value.params.length !== paramCount) {
let start = prop.value.start
if (prop.kind === "get")
this.raiseRecoverable(start, "getter should have no params")
else
this.raiseRecoverable(start, "setter should have exactly one param")
}
if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params")
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
if (this.keywords.test(prop.key.name) ||
(this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name) ||
(this.inGenerator && prop.key.name == "yield"))
this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property")
prop.kind = "init"
if (isPattern) {
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
} else if (this.type === tt.eq && refDestructuringErrors) {
if (!refDestructuringErrors.shorthandAssign)
refDestructuringErrors.shorthandAssign = this.start
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
} else {
prop.value = prop.key
}
prop.shorthand = true
} else this.unexpected()
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors)
prop.kind = "init"
} else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
if (isPattern) this.unexpected()
prop.kind = "init"
prop.method = true
prop.value = this.parseMethod(isGenerator)
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
(prop.key.name === "get" || prop.key.name === "set") &&
(this.type != tt.comma && this.type != tt.braceR)) {
if (isGenerator || isPattern) this.unexpected()
prop.kind = prop.key.name
this.parsePropertyName(prop)
prop.value = this.parseMethod(false)
let paramCount = prop.kind === "get" ? 0 : 1
if (prop.value.params.length !== paramCount) {
let start = prop.value.start
if (prop.kind === "get")
this.raiseRecoverable(start, "getter should have no params")
else
this.raiseRecoverable(start, "setter should have exactly one param")
}
if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params")
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
prop.kind = "init"
if (isPattern) {
if (this.keywords.test(prop.key.name) ||
(this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name) ||
(this.inGenerator && prop.key.name == "yield"))
this.raiseRecoverable(prop.key.start, "Binding " + prop.key.name)
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
} else if (this.type === tt.eq && refDestructuringErrors) {
if (!refDestructuringErrors.shorthandAssign)
refDestructuringErrors.shorthandAssign = this.start
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
} else {
prop.value = prop.key
}
prop.shorthand = true
} else this.unexpected()
}

pp.parsePropertyName = function(prop) {
Expand All @@ -546,7 +544,7 @@ pp.parsePropertyName = function(prop) {
prop.computed = false
}
}
return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true)
return prop.key = (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true)
}

// Initialize empty function node.
Expand Down Expand Up @@ -639,18 +637,18 @@ pp.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructur
while (!this.eat(close)) {
if (!first) {
this.expect(tt.comma)
if (this.type === close && refDestructuringErrors && !refDestructuringErrors.trailingComma) {
refDestructuringErrors.trailingComma = this.lastTokStart
}
if (allowTrailingComma && this.afterTrailingComma(close)) break
} else first = false

let elt
if (allowEmpty && this.type === tt.comma)
elt = null
else if (this.type === tt.ellipsis) {
else if (this.type === tt.ellipsis)
elt = this.parseSpread(refDestructuringErrors)
if (this.type === tt.comma && refDestructuringErrors && !refDestructuringErrors.trailingComma) {
refDestructuringErrors.trailingComma = this.lastTokStart
}
} else
else
elt = this.parseMaybeAssign(false, refDestructuringErrors)
elts.push(elt)
}
Expand Down
2 changes: 1 addition & 1 deletion src/processing/script/tools/acorn/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// [dammit]: acorn_loose.js
// [walk]: util/walk.js
//
// version 3.1.0
// version 3.0.4

import {Parser} from "./state"
import "./parseutil"
Expand Down
1 change: 0 additions & 1 deletion src/processing/script/tools/acorn/lval.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ pp.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonId
let rest = this.parseRest(allowNonIdent)
this.parseBindingListItem(rest)
elts.push(rest)
if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element")
this.expect(close)
break
} else {
Expand Down
13 changes: 3 additions & 10 deletions src/processing/script/tools/acorn/parseutil.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,10 @@ pp.unexpected = function(pos) {
this.raise(pos != null ? pos : this.start, "Unexpected token")
}

export class DestructuringErrors {
constructor() {
this.shorthandAssign = 0
this.trailingComma = 0
}
}

pp.checkPatternErrors = function(refDestructuringErrors, andThrow) {
let trailing = refDestructuringErrors && refDestructuringErrors.trailingComma
if (!andThrow) return !!trailing
if (trailing) this.raise(trailing, "Comma is not permitted after the rest element")
let pos = refDestructuringErrors && refDestructuringErrors.trailingComma
if (!andThrow) return !!pos
if (pos) this.raise(pos, "Trailing comma is not permitted in destructuring patterns")
}

pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
Expand Down
3 changes: 1 addition & 2 deletions src/processing/script/tools/acorn/statement.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {types as tt} from "./tokentype"
import {Parser} from "./state"
import {lineBreak, skipWhiteSpace} from "./whitespace"
import {isIdentifierStart, isIdentifierChar} from "./identifier"
import {DestructuringErrors} from "./parseutil"

const pp = Parser.prototype

Expand Down Expand Up @@ -180,7 +179,7 @@ pp.parseForStatement = function(node) {
return this.parseForIn(node, init)
return this.parseFor(node, init)
}
let refDestructuringErrors = new DestructuringErrors
let refDestructuringErrors = {shorthandAssign: 0, trailingComma: 0}
let init = this.parseExpression(true, refDestructuringErrors)
if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
this.checkPatternErrors(refDestructuringErrors, true)
Expand Down
5 changes: 2 additions & 3 deletions src/processing/script/tools/acorn/tokencontext.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,8 @@ tt.incDec.updateContext = function() {
// tokExprAllowed stays unchanged
}

tt._function.updateContext = function(prevType) {
if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else &&
(prevType !== tt.colon || this.curContext() !== types.b_stat))
tt._function.updateContext = function() {
if (this.curContext() !== types.b_stat)
this.context.push(types.f_expr)
this.exprAllowed = false
}
Expand Down
39 changes: 17 additions & 22 deletions src/processing/script/tools/acorn/tokenize.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,39 +417,34 @@ pp.readRegexp = function() {
// Need to use `readWord1` because '\uXXXX' sequences are allowed
// here (don't ask).
let mods = this.readWord1()
let tmp = content, tmpFlags = ""
let tmp = content
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", "")
}
if (mods.indexOf('u') >= 0 && !regexpUnicodeSupport) {
// Replace each astral symbol and every Unicode escape sequence that
// possibly represents an astral symbol or a paired surrogate with a
// single ASCII symbol to avoid throwing on regular expressions that
// are only valid in combination with the `/u` flag.
// Note: replacing with the ASCII symbol `x` might cause false
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
// be replaced by `[x-b]` which throws an error.
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, (_match, code, offset) => {
code = Number("0x" + code)
if (code > 0x10FFFF) this.raise(start + offset + 3, "Code point out of bounds")
return "x"
})
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
}
}
// Detect invalid regular expressions.
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)
tryCreateRegexp(tmp, undefined, 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)
Expand Down
11 changes: 11 additions & 0 deletions test/server/script-processor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,5 +652,16 @@ describe('Script processor', function () {
'//-->'
});
});

it('Should not throw parser exceptions', function () {
var testParser = function (scriptStr) {
scriptStr += '\nx.src';

expect(processScript(scriptStr, false).indexOf('x.src') === -1).equal(true);
};

testParser('function a(){function b(){}/k/;}'); // GH-591
testParser('function s(){do var x = 9; while(false)return}'); // GH-567
});
});
});

0 comments on commit ad9bedc

Please sign in to comment.