resync with upstream acorn
This commit is contained in:
parent
4ac33d62af
commit
4f08a77230
@ -29,14 +29,23 @@ const pp = Parser.prototype
|
||||
// strict mode, init properties are also not allowed to be repeated.
|
||||
|
||||
pp.checkPropClash = function(prop, propHash) {
|
||||
if (this.options.ecmaVersion >= 6) return
|
||||
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
|
||||
return
|
||||
let key = prop.key, name
|
||||
switch (key.type) {
|
||||
case "Identifier": name = key.name; break
|
||||
case "Literal": name = String(key.value); break
|
||||
default: return
|
||||
}
|
||||
let kind = prop.kind || "init", other
|
||||
let kind = prop.kind
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
if (name === "__proto__" && kind === "init") {
|
||||
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
|
||||
propHash.proto = true
|
||||
}
|
||||
return
|
||||
}
|
||||
let other
|
||||
if (has(propHash, name)) {
|
||||
other = propHash[name]
|
||||
let isGetSet = kind !== "init"
|
||||
@ -260,8 +269,10 @@ pp.parseNoCallExpr = function() {
|
||||
pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
let node, canBeArrow = this.potentialArrowAt == this.start
|
||||
switch (this.type) {
|
||||
case tt._this:
|
||||
case tt._super:
|
||||
if (!this.inFunction)
|
||||
this.raise(this.start, "'super' outside of function or class")
|
||||
case tt._this:
|
||||
let type = this.type === tt._this ? "ThisExpression" : "Super"
|
||||
node = this.startNode()
|
||||
this.next()
|
||||
@ -609,6 +620,14 @@ pp.parseObjPropValue = function (prop, start, isGenerator, isAsync, isPattern, r
|
||||
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.raise(start, "getter should have no params");
|
||||
else
|
||||
this.raise(start, "setter should have exactly one param")
|
||||
}
|
||||
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
|
||||
prop.kind = "init"
|
||||
if (isPattern) {
|
||||
@ -634,12 +653,12 @@ pp.parsePropertyName = function(prop) {
|
||||
prop.computed = true
|
||||
prop.key = this.parseMaybeAssign()
|
||||
this.expect(tt.bracketR)
|
||||
return
|
||||
return prop.key
|
||||
} else {
|
||||
prop.computed = false
|
||||
}
|
||||
}
|
||||
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.
|
||||
|
||||
@ -35,6 +35,7 @@ pp.toAssignable = function(node, isBinding) {
|
||||
case "AssignmentExpression":
|
||||
if (node.operator === "=") {
|
||||
node.type = "AssignmentPattern"
|
||||
delete node.operator
|
||||
} else {
|
||||
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
|
||||
}
|
||||
@ -171,7 +172,7 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
|
||||
break
|
||||
|
||||
case "ObjectPattern":
|
||||
for (let i = 0; i < expr.properties.length; i++) {
|
||||
for (let i = 0; i < expr.properties.length; i++) {
|
||||
var prop = expr.properties[i];
|
||||
if (prop.type === "Property") prop = prop.value;
|
||||
this.checkLVal(prop, isBinding, checkClashes)
|
||||
@ -194,6 +195,10 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
|
||||
this.checkLVal(expr.argument, isBinding, checkClashes)
|
||||
break
|
||||
|
||||
case "ParenthesizedExpression":
|
||||
this.checkLVal(expr.expression, isBinding, checkClashes)
|
||||
break
|
||||
|
||||
default:
|
||||
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {reservedWords, keywords} from "./identifier"
|
||||
import {types as tt, lineBreak} from "./tokentype"
|
||||
import {types as tt} from "./tokentype"
|
||||
import {lineBreak} from "./whitespace"
|
||||
|
||||
export function Parser(options, input, startPos) {
|
||||
this.options = options
|
||||
|
||||
@ -347,7 +347,14 @@ pp.parseLabeledStatement = function(node, maybeName, expr) {
|
||||
for (let i = 0; i < this.labels.length; ++i)
|
||||
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared")
|
||||
let kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null
|
||||
this.labels.push({name: maybeName, kind: kind})
|
||||
for (let i = this.labels.length - 1; i >= 0; i--) {
|
||||
let label = this.labels[i]
|
||||
if (label.statementStart == node.start) {
|
||||
label.statementStart = this.start;
|
||||
label.kind = kind;
|
||||
} else break;
|
||||
}
|
||||
this.labels.push({name: maybeName, kind: kind, statementStart: this.start})
|
||||
node.body = this.parseStatement(true)
|
||||
this.labels.pop()
|
||||
node.label = expr
|
||||
@ -466,6 +473,7 @@ pp.parseClass = function(node, isStatement) {
|
||||
this.parseClassId(node, isStatement)
|
||||
this.parseClassSuper(node)
|
||||
var classBody = this.startNode()
|
||||
let hadConstructor = false
|
||||
classBody.body = []
|
||||
this.expect(tt.braceL)
|
||||
let decorators = []
|
||||
@ -480,16 +488,14 @@ pp.parseClass = function(node, isStatement) {
|
||||
method.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
let isMaybeStatic = this.type === tt.name && this.value === "static"
|
||||
var isGenerator = this.eat(tt.star), isAsync = false
|
||||
this.parsePropertyName(method)
|
||||
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" &&
|
||||
method.key.name === "static") {
|
||||
method.static = isMaybeStatic && this.type !== tt.parenL
|
||||
if (method.static) {
|
||||
if (isGenerator) this.unexpected()
|
||||
method['static'] = true
|
||||
isGenerator = this.eat(tt.star)
|
||||
this.parsePropertyName(method)
|
||||
} else {
|
||||
method['static'] = false
|
||||
}
|
||||
if (!isGenerator && method.key.type === "Identifier" && !method.computed && this.isClassProperty()) {
|
||||
classBody.body.push(this.parseClassProperty(method))
|
||||
@ -500,23 +506,39 @@ pp.parseClass = function(node, isStatement) {
|
||||
isAsync = true
|
||||
this.parsePropertyName(method)
|
||||
}
|
||||
let isGetSet = false
|
||||
method.kind = "method"
|
||||
if (!method.computed && !isGenerator && !isAsync) {
|
||||
if (method.key.type === "Identifier") {
|
||||
if (this.type !== tt.parenL && (method.key.name === "get" || method.key.name === "set")) {
|
||||
method.kind = method.key.name
|
||||
this.parsePropertyName(method)
|
||||
} else if (!method['static'] && method.key.name === "constructor") {
|
||||
method.kind = "constructor"
|
||||
}
|
||||
} else if (!method['static'] && method.key.type === "Literal" && method.key.value === "constructor") {
|
||||
if (!method.computed) {
|
||||
let {key} = method
|
||||
if (!isAsync && !isGenerator && key.type === "Identifier" && this.type !== tt.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 function")
|
||||
method.kind = "constructor"
|
||||
hadConstructor = true
|
||||
}
|
||||
}
|
||||
if (method.kind === "constructor" && method.decorators) {
|
||||
this.raise(method.start, "You can't attach decorators to a class constructor")
|
||||
}
|
||||
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.raise(start, "getter should have no params");
|
||||
else
|
||||
this.raise(start, "setter should have exactly one param")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no method");
|
||||
|
||||
@ -25,6 +25,9 @@ export class Token {
|
||||
|
||||
const pp = Parser.prototype
|
||||
|
||||
// Are we running under Rhino?
|
||||
const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"
|
||||
|
||||
// Move to the next token
|
||||
|
||||
pp.next = function() {
|
||||
@ -430,23 +433,30 @@ pp.readRegexp = function() {
|
||||
// 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([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
|
||||
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.
|
||||
try {
|
||||
new RegExp(tmp)
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
|
||||
this.raise(e)
|
||||
}
|
||||
// Get a regular expression object for this pattern-flag pair, or `null` in
|
||||
// case the current environment doesn't support the flags it uses.
|
||||
let value
|
||||
try {
|
||||
value = new RegExp(content, mods)
|
||||
} catch (err) {
|
||||
value = null
|
||||
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) {
|
||||
try {
|
||||
new RegExp(tmp)
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
|
||||
this.raise(e)
|
||||
}
|
||||
// Get a regular expression object for this pattern-flag pair, or `null` in
|
||||
// case the current environment doesn't support the flags it uses.
|
||||
try {
|
||||
value = new RegExp(content, mods)
|
||||
} catch (err) {}
|
||||
}
|
||||
return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value})
|
||||
}
|
||||
@ -514,10 +524,10 @@ pp.readCodePoint = function() {
|
||||
|
||||
if (ch === 123) {
|
||||
if (this.options.ecmaVersion < 6) this.unexpected()
|
||||
++this.pos
|
||||
let codePos = ++this.pos
|
||||
code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos)
|
||||
++this.pos
|
||||
if (code > 0x10FFFF) this.unexpected()
|
||||
if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds")
|
||||
} else {
|
||||
code = this.readHexChar(4)
|
||||
}
|
||||
@ -539,7 +549,7 @@ pp.readString = function(quote) {
|
||||
if (ch === quote) break
|
||||
if (ch === 92) { // '\'
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
out += this.readEscapedChar()
|
||||
out += this.readEscapedChar(false)
|
||||
chunkStart = this.pos
|
||||
} else {
|
||||
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant")
|
||||
@ -572,7 +582,7 @@ pp.readTmplToken = function() {
|
||||
}
|
||||
if (ch === 92) { // '\'
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
out += this.readEscapedChar()
|
||||
out += this.readEscapedChar(true)
|
||||
chunkStart = this.pos
|
||||
} else if (isNewLine(ch)) {
|
||||
out += this.input.slice(chunkStart, this.pos)
|
||||
@ -600,42 +610,46 @@ pp.readTmplToken = function() {
|
||||
|
||||
// Used to read escaped characters
|
||||
|
||||
pp.readEscapedChar = function() {
|
||||
pp.readEscapedChar = function(inTemplate) {
|
||||
let ch = this.input.charCodeAt(++this.pos)
|
||||
let octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3))
|
||||
if (octal) octal = octal[0]
|
||||
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1)
|
||||
if (octal === "0") octal = null
|
||||
++this.pos
|
||||
if (octal) {
|
||||
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode")
|
||||
this.pos += octal.length - 1
|
||||
return String.fromCharCode(parseInt(octal, 8))
|
||||
} else {
|
||||
switch (ch) {
|
||||
case 110: return "\n"; // 'n' -> '\n'
|
||||
case 114: return "\r"; // 'r' -> '\r'
|
||||
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
|
||||
case 117: return codePointToString(this.readCodePoint()); // 'u'
|
||||
case 116: return "\t"; // 't' -> '\t'
|
||||
case 98: return "\b"; // 'b' -> '\b'
|
||||
case 118: return "\u000b"; // 'v' -> '\u000b'
|
||||
case 102: return "\f"; // 'f' -> '\f'
|
||||
case 48: return "\0"; // 0 -> '\0'
|
||||
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
|
||||
case 10: // ' \n'
|
||||
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
|
||||
return ""
|
||||
default: return String.fromCharCode(ch)
|
||||
switch (ch) {
|
||||
case 110: return "\n"; // 'n' -> '\n'
|
||||
case 114: return "\r"; // 'r' -> '\r'
|
||||
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
|
||||
case 117: return codePointToString(this.readCodePoint()); // 'u'
|
||||
case 116: return "\t"; // 't' -> '\t'
|
||||
case 98: return "\b"; // 'b' -> '\b'
|
||||
case 118: return "\u000b"; // 'v' -> '\u000b'
|
||||
case 102: return "\f"; // 'f' -> '\f'
|
||||
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
|
||||
case 10: // ' \n'
|
||||
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
|
||||
return ""
|
||||
default:
|
||||
if (ch >= 48 && ch <= 55) {
|
||||
let octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]
|
||||
let octal = parseInt(octalStr, 8)
|
||||
if (octal > 255) {
|
||||
octalStr = octalStr.slice(0, -1)
|
||||
octal = parseInt(octalStr, 8)
|
||||
}
|
||||
if (octal > 0 && (this.strict || inTemplate)) {
|
||||
this.raise(this.pos - 2, "Octal literal in strict mode")
|
||||
}
|
||||
this.pos += octalStr.length - 1
|
||||
return String.fromCharCode(octal)
|
||||
}
|
||||
return String.fromCharCode(ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Used to read character escape sequences ('\x', '\u', '\U').
|
||||
|
||||
pp.readHexChar = function(len) {
|
||||
let codePos = this.pos
|
||||
let n = this.readInt(16, len)
|
||||
if (n === null) this.raise(this.start, "Bad character escape sequence")
|
||||
if (n === null) this.raise(codePos, "Bad character escape sequence")
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
@ -5,9 +5,7 @@ export const MESSAGES = {
|
||||
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
|
||||
classesIllegalBareSuper: "Illegal use of bare super",
|
||||
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||
classesIllegalConstructorKind: "Illegal kind for constructor method",
|
||||
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
||||
settersInvalidParamLength: "Setters must have exactly one parameter",
|
||||
settersNoRest: "Setters aren't allowed to have a rest",
|
||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemberExpression or Identifier",
|
||||
|
||||
@ -14,28 +14,8 @@ export var visitor = {
|
||||
}
|
||||
},
|
||||
|
||||
MethodDefinition(node) {
|
||||
if (node.kind !== "constructor") {
|
||||
// get constructor() {}
|
||||
var isConstructor = !node.computed && t.isIdentifier(node.key, { name: "constructor" });
|
||||
|
||||
// get ["constructor"]() {}
|
||||
isConstructor = isConstructor || t.isLiteral(node.key, { value: "constructor" });
|
||||
|
||||
if (isConstructor) {
|
||||
throw this.errorWithNode(messages.get("classesIllegalConstructorKind"));
|
||||
}
|
||||
}
|
||||
|
||||
visitor.Property.apply(this, arguments);
|
||||
},
|
||||
|
||||
Property(node, parent, scope, file) {
|
||||
if (node.kind === "set") {
|
||||
if (node.value.params.length !== 1) {
|
||||
throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength"));
|
||||
}
|
||||
|
||||
var first = node.value.params[0];
|
||||
if (t.isRestElement(first)) {
|
||||
throw file.errorWithNode(first, messages.get("settersNoRest"));
|
||||
|
||||
@ -2299,7 +2299,7 @@ test("class Foo { @foo bar() {} }", {
|
||||
features: { "es7.decorators": true }
|
||||
});
|
||||
|
||||
test("class Foo { @foo set bar() {} }", {
|
||||
test("class Foo { @foo set bar(f) {} }", {
|
||||
"start": 0,
|
||||
"body": [
|
||||
{
|
||||
@ -2343,29 +2343,32 @@ test("class Foo { @foo set bar() {} }", {
|
||||
"id": null,
|
||||
"generator": false,
|
||||
"expression": false,
|
||||
"params": [],
|
||||
"params": [{
|
||||
"type": "Identifier",
|
||||
"name": "f"
|
||||
}],
|
||||
"body": {
|
||||
"start": 27,
|
||||
"start": 28,
|
||||
"body": [],
|
||||
"type": "BlockStatement",
|
||||
"end": 29
|
||||
"end": 30
|
||||
},
|
||||
"type": "FunctionExpression",
|
||||
"end": 29
|
||||
"end": 30
|
||||
},
|
||||
"type": "MethodDefinition",
|
||||
"end": 29
|
||||
"end": 30
|
||||
}
|
||||
],
|
||||
"type": "ClassBody",
|
||||
"end": 31
|
||||
"end": 32
|
||||
},
|
||||
"type": "ClassDeclaration",
|
||||
"end": 31
|
||||
"end": 32
|
||||
}
|
||||
],
|
||||
"type": "Program",
|
||||
"end": 31
|
||||
"end": 32
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
features: { "es7.decorators": true }
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2015 Ingvar Stepanyan <me@rreverser.com>
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
|
||||
Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
@ -6,7 +7,6 @@
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Copyright (C) 2011 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
Copyright (C) 2011 Arpad Borsos <arpad.borsos@googlemail.com>
|
||||
Copyright (C) 2014 Ingvar Stepanyan <me@rreverser.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@ -877,7 +877,7 @@ test("`\n\r\n\r`", {
|
||||
locations: true
|
||||
});
|
||||
|
||||
test("`\\u{000042}\\u0042\\x42u0\\102\\A`", {
|
||||
test("`\\u{000042}\\u0042\\x42u0\\A`", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
type: "ExpressionStatement",
|
||||
@ -885,27 +885,27 @@ test("`\\u{000042}\\u0042\\x42u0\\102\\A`", {
|
||||
type: "TemplateLiteral",
|
||||
quasis: [{
|
||||
type: "TemplateElement",
|
||||
value: {raw: "\\u{000042}\\u0042\\x42u0\\102\\A", cooked: "BBBu0BA"},
|
||||
value: {raw: "\\u{000042}\\u0042\\x42u0\\A", cooked: "BBBu0A"},
|
||||
tail: true,
|
||||
loc: {
|
||||
start: {line: 1, column: 1},
|
||||
end: {line: 1, column: 29}
|
||||
end: {line: 1, column: 25}
|
||||
}
|
||||
}],
|
||||
expressions: [],
|
||||
loc: {
|
||||
start: {line: 1, column: 0},
|
||||
end: {line: 1, column: 30}
|
||||
end: {line: 1, column: 26}
|
||||
}
|
||||
},
|
||||
loc: {
|
||||
start: {line: 1, column: 0},
|
||||
end: {line: 1, column: 30}
|
||||
end: {line: 1, column: 26}
|
||||
}
|
||||
}],
|
||||
loc: {
|
||||
start: {line: 1, column: 0},
|
||||
end: {line: 1, column: 30}
|
||||
end: {line: 1, column: 26}
|
||||
}
|
||||
}, {
|
||||
ecmaVersion: 6,
|
||||
@ -1714,7 +1714,7 @@ test("([a, , b]) => 42", {
|
||||
|
||||
testFail("([a.a]) => 42", "Assigning to rvalue (1:2)", {ecmaVersion: 6});
|
||||
|
||||
testFail("console.log(typeof () => {});", "Unexpected token (1:20)", {ecmaVersion: 6});
|
||||
testFail("console.log(typeof () => {});", "Unexpected token (1:20)", {ecmaVersion: 6})
|
||||
|
||||
test("(x=1) => x * x", {
|
||||
type: "Program",
|
||||
@ -7223,6 +7223,12 @@ test("class A {'constructor'() {}}", {
|
||||
}]
|
||||
}, {ecmaVersion: 6});
|
||||
|
||||
testFail("class A { constructor() {} 'constructor'() }", "Duplicate constructor in the same class (1:27)", {ecmaVersion: 6});
|
||||
|
||||
testFail("class A { get constructor() {} }", "Constructor can't have get/set modifier (1:14)", {ecmaVersion: 6});
|
||||
|
||||
testFail("class A { *constructor() {} }", "Constructor can't be a generator (1:11)", {ecmaVersion: 6});
|
||||
|
||||
test("class A {static foo() {}}", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
@ -13641,21 +13647,21 @@ testFail("0B18", "Unexpected token (1:3)", {ecmaVersion: 6});
|
||||
|
||||
testFail("0B12", "Unexpected token (1:3)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"\\u{110000}\"", "Unexpected token (1:0)", {ecmaVersion: 6});
|
||||
testFail("\"\\u{110000}\"", "Code point out of bounds (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"\\u{}\"", "Bad character escape sequence (1:0)", {ecmaVersion: 6});
|
||||
testFail("\"\\u{}\"", "Bad character escape sequence (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"\\u{FFFF\"", "Bad character escape sequence (1:0)", {ecmaVersion: 6});
|
||||
testFail("\"\\u{FFFF\"", "Bad character escape sequence (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"\\u{FFZ}\"", "Bad character escape sequence (1:0)", {ecmaVersion: 6});
|
||||
testFail("\"\\u{FFZ}\"", "Bad character escape sequence (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("[v] += ary", "Assigning to rvalue (1:0)", {ecmaVersion: 6});
|
||||
|
||||
testFail("[2] = 42", "Assigning to rvalue (1:1)", {ecmaVersion: 6});
|
||||
|
||||
testFail("({ obj:20 } = 42)", "Assigning to rvalue (1:7)", {ecmaVersion: 6});
|
||||
testFail("({ obj:20 }) = 42", "Assigning to rvalue (1:7)", {ecmaVersion: 6});
|
||||
|
||||
testFail("( { get x() {} } = 0 )", "Object pattern can't contain getter or setter (1:8)", {ecmaVersion: 6});
|
||||
testFail("( { get x() {} } ) = 0", "Object pattern can't contain getter or setter (1:8)", {ecmaVersion: 6});
|
||||
|
||||
testFail("x \n is y", "Unexpected token (2:4)", {ecmaVersion: 6});
|
||||
|
||||
@ -13675,9 +13681,9 @@ testFail("let default", "Unexpected token (1:4)", {ecmaVersion: 6});
|
||||
|
||||
testFail("const default", "Unexpected token (1:6)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"use strict\"; ({ v: eval } = obj)", "Assigning to eval in strict mode (1:20)", {ecmaVersion: 6});
|
||||
testFail("\"use strict\"; ({ v: eval }) = obj", "Assigning to eval in strict mode (1:20)", {ecmaVersion: 6});
|
||||
|
||||
testFail("\"use strict\"; ({ v: arguments } = obj)", "Assigning to arguments in strict mode (1:20)", {ecmaVersion: 6});
|
||||
testFail("\"use strict\"; ({ v: arguments }) = obj", "Assigning to arguments in strict mode (1:20)", {ecmaVersion: 6});
|
||||
|
||||
testFail("for (let x = 42 in list) process(x);", "Unexpected token (1:16)", {ecmaVersion: 6});
|
||||
|
||||
@ -14288,7 +14294,6 @@ test("var {propName: localVar = defaultValue} = obj", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [15, 38],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [15, 23],
|
||||
@ -14344,7 +14349,6 @@ test("var {propName = defaultValue} = obj", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [5, 28],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [5, 13],
|
||||
@ -14387,7 +14391,6 @@ test("var [localVar = defaultValue] = obj", {
|
||||
elements: [{
|
||||
type: "AssignmentPattern",
|
||||
range: [5, 28],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [5, 13],
|
||||
@ -14442,7 +14445,6 @@ test("({x = 0} = obj)", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [2, 7],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [2, 3],
|
||||
@ -14498,7 +14500,6 @@ test("({x = 0}) => x", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [2, 7],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [2, 3],
|
||||
@ -14575,7 +14576,6 @@ test("[a, {b: {c = 1}}] = arr", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [9, 14],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [9, 10],
|
||||
@ -14630,7 +14630,6 @@ test("for ({x = 0} in arr);", {
|
||||
value: {
|
||||
type: "AssignmentPattern",
|
||||
range: [6, 11],
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
range: [6, 7],
|
||||
@ -15262,3 +15261,70 @@ test("new.target", {
|
||||
}, {ecmaVersion: 6});
|
||||
|
||||
testFail("new.prop", "The only valid meta property for new is new.target (1:4)", {ecmaVersion: 6});
|
||||
|
||||
test("export default function foo() {} false", {
|
||||
body: [
|
||||
{
|
||||
declaration: {
|
||||
id: {
|
||||
name: "foo",
|
||||
type: "Identifier"
|
||||
},
|
||||
generator: false,
|
||||
expression: false,
|
||||
params: [],
|
||||
body: {
|
||||
body: [],
|
||||
type: "BlockStatement"
|
||||
},
|
||||
type: "FunctionDeclaration"
|
||||
},
|
||||
type: "ExportDefaultDeclaration"
|
||||
},
|
||||
{
|
||||
expression: {
|
||||
value: false,
|
||||
raw: "false",
|
||||
type: "Literal"
|
||||
},
|
||||
type: "ExpressionStatement"
|
||||
}
|
||||
],
|
||||
sourceType: "module",
|
||||
type: "Program"
|
||||
}, {ecmaVersion: 6, sourceType: "module"})
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/274
|
||||
|
||||
testFail("`\\07`", "Octal literal in strict mode (1:1)", {ecmaVersion: 6});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/277
|
||||
|
||||
testFail("x = { method() 42 }", "Unexpected token (1:15)", {ecmaVersion: 6});
|
||||
|
||||
testFail("x = { get method() 42 }", "Unexpected token (1:19)", {ecmaVersion: 6});
|
||||
|
||||
testFail("x = { set method(val) v = val }", "Unexpected token (1:22)", {ecmaVersion: 6});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/278
|
||||
|
||||
testFail("/\\u{110000}/u", "Code point out of bounds (1:4)", {ecmaVersion: 6});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/279
|
||||
|
||||
testFail("super", "'super' outside of function or class (1:0)", {ecmaVersion: 6});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/275
|
||||
|
||||
testFail("class A { get prop(x) {} }", "getter should have no params (1:18)", {ecmaVersion: 6});
|
||||
testFail("class A { set prop() {} }", "setter should have exactly one param (1:18)", {ecmaVersion: 6});
|
||||
testFail("class A { set prop(x, y) {} }", "setter should have exactly one param (1:18)", {ecmaVersion: 6});
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/276
|
||||
|
||||
testFail("({ __proto__: 1, __proto__: 2 })", "Redefinition of __proto__ property (1:17)", {ecmaVersion: 6});
|
||||
testFail("({ '__proto__': 1, __proto__: 2 })", "Redefinition of __proto__ property (1:19)", {ecmaVersion: 6});
|
||||
test("({ ['__proto__']: 1, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ __proto__() { return 1 }, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ get __proto__() { return 1 }, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
test("({ __proto__, __proto__: 2 })", {}, {ecmaVersion: 6});
|
||||
|
||||
@ -403,7 +403,30 @@ test("(1 + 2 ) * 3", {
|
||||
preserveParens: true
|
||||
});
|
||||
|
||||
testFail("(x) = 23", "Assigning to rvalue (1:0)", { preserveParens: true });
|
||||
test("(x) = 23", {
|
||||
body: [
|
||||
{
|
||||
expression: {
|
||||
operator: "=",
|
||||
left: {
|
||||
expression: {
|
||||
name: "x",
|
||||
type: "Identifier",
|
||||
},
|
||||
type: "ParenthesizedExpression",
|
||||
},
|
||||
right: {
|
||||
value: 23,
|
||||
raw: "23",
|
||||
type: "Literal",
|
||||
},
|
||||
type: "AssignmentExpression",
|
||||
},
|
||||
type: "ExpressionStatement",
|
||||
}
|
||||
],
|
||||
type: "Program",
|
||||
}, {preserveParens: true});
|
||||
|
||||
test("x = []", {
|
||||
type: "Program",
|
||||
@ -20637,6 +20660,9 @@ test("done: while (true) { break done; }", {
|
||||
}
|
||||
});
|
||||
|
||||
test("target1: target2: while (true) { continue target1; }", {});
|
||||
test("target1: target2: target3: while (true) { continue target1; }", {});
|
||||
|
||||
test("(function(){ return })", {
|
||||
type: "Program",
|
||||
body: [
|
||||
@ -26881,7 +26907,7 @@ testFail("/test",
|
||||
"Unterminated regular expression (1:1)");
|
||||
|
||||
testFail("var x = /[a-z]/\\ux",
|
||||
"Bad character escape sequence (1:8)");
|
||||
"Bad character escape sequence (1:17)");
|
||||
|
||||
testFail("3 = 4",
|
||||
"Assigning to rvalue (1:0)");
|
||||
@ -27168,7 +27194,7 @@ testFail("\"\\",
|
||||
"Unterminated string constant (1:0)");
|
||||
|
||||
testFail("\"\\u",
|
||||
"Bad character escape sequence (1:0)");
|
||||
"Bad character escape sequence (1:3)");
|
||||
|
||||
testFail("return",
|
||||
"'return' outside of function (1:0)");
|
||||
@ -28720,6 +28746,39 @@ testFail("for(x of a);", "Unexpected token (1:6)");
|
||||
|
||||
testFail("for(var x of a);", "Unexpected token (1:10)");
|
||||
|
||||
// Assertion Tests
|
||||
test(function TestComments() {
|
||||
// Bear class
|
||||
function Bear(x,y,z) {
|
||||
this.position = [x||0,y||0,z||0]
|
||||
}
|
||||
|
||||
Bear.prototype.roar = function(message) {
|
||||
return 'RAWWW: ' + message; // Whatever
|
||||
};
|
||||
|
||||
function Cat() {
|
||||
/* 1
|
||||
2
|
||||
3*/
|
||||
}
|
||||
|
||||
Cat.prototype.roar = function(message) {
|
||||
return 'MEOOWW: ' + /*stuff*/ message;
|
||||
};
|
||||
}.toString().replace(/\r\n/g, '\n'), {}, {
|
||||
onComment: [
|
||||
{type: "Line", value: " Bear class"},
|
||||
{type: "Line", value: " Whatever"},
|
||||
{type: "Block", value: [
|
||||
" 1",
|
||||
" 2",
|
||||
" 3"
|
||||
].join('\n')},
|
||||
{type: "Block", value: "stuff"}
|
||||
]
|
||||
});
|
||||
|
||||
test("<!--\n;", {
|
||||
type: "Program",
|
||||
body: [{
|
||||
@ -28932,3 +28991,9 @@ testAssert("[1,2,] + {foo: 1,}", function() {
|
||||
return "Unexpected result for onTrailingComma: " + result;
|
||||
}, {onTrailingComma: function(pos) { trailingCommas.push(pos); },
|
||||
loose: false})
|
||||
|
||||
// https://github.com/marijnh/acorn/issues/275
|
||||
|
||||
testFail("({ get prop(x) {} })", "getter should have no params (1:11)");
|
||||
testFail("({ set prop() {} })", "setter should have exactly one param (1:11)");
|
||||
testFail("({ set prop(x, y) {} })", "setter should have exactly one param (1:11)");
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
class Test {
|
||||
get constructor() {
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"throws": "Illegal kind for constructor method"
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
class Foo {
|
||||
set bar() {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
class Foo {
|
||||
set bar(foo, bar) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
var obj = {
|
||||
set foo(...args) {
|
||||
|
||||
}
|
||||
};
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"throws": "Setters aren't allowed to have a rest"
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
var obj = {
|
||||
set bar() {
|
||||
|
||||
}
|
||||
};
|
||||
@ -1,5 +0,0 @@
|
||||
var obj = {
|
||||
set bar(foo, bar) {
|
||||
|
||||
}
|
||||
};
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"throws": "Setters must have exactly one parameter"
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
class X { async constructor() {} }
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"throws": "Illegal kind for constructor method",
|
||||
"optional": ["es7.asyncFunctions"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user