kopia lustrzana https://github.com/c9/core
update treehugger
rodzic
0618e5c08c
commit
3645173678
|
@ -47,7 +47,7 @@ pp.checkPropClash = function (prop, propHash) {
|
|||
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
if (name === "__proto__" && kind === "init") {
|
||||
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
|
||||
if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
|
||||
propHash.proto = true;
|
||||
}
|
||||
return;
|
||||
|
@ -56,7 +56,7 @@ pp.checkPropClash = function (prop, propHash) {
|
|||
var other = propHash[name];
|
||||
if (other) {
|
||||
var isGetSet = kind !== "init";
|
||||
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
|
||||
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raiseRecoverable(key.start, "Redefinition of property");
|
||||
} else {
|
||||
other = propHash[name] = {
|
||||
init: false,
|
||||
|
@ -99,7 +99,7 @@ pp.parseExpression = function (noIn, refDestructuringErrors) {
|
|||
// operators like `+=`.
|
||||
|
||||
pp.parseMaybeAssign = function (noIn, refDestructuringErrors, afterLeftParse) {
|
||||
if (this.type == _tokentype.types._yield && this.inGenerator) return this.parseYield();
|
||||
if (this.inGenerator && this.isContextual("yield")) return this.parseYield();
|
||||
|
||||
var validateDestructuring = false;
|
||||
if (!refDestructuringErrors) {
|
||||
|
@ -191,7 +191,7 @@ pp.parseMaybeUnary = function (refDestructuringErrors) {
|
|||
this.next();
|
||||
node.argument = this.parseMaybeUnary();
|
||||
this.checkExpressionErrors(refDestructuringErrors, true);
|
||||
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
|
||||
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raiseRecoverable(node.start, "Deleting local variable in strict mode");
|
||||
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
|
||||
}
|
||||
var startPos = this.start,
|
||||
|
@ -263,18 +263,16 @@ pp.parseExprAtom = function (refDestructuringErrors) {
|
|||
switch (this.type) {
|
||||
case _tokentype.types._super:
|
||||
if (!this.inFunction) this.raise(this.start, "'super' outside of function or class");
|
||||
|
||||
case _tokentype.types._this:
|
||||
var type = this.type === _tokentype.types._this ? "ThisExpression" : "Super";
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.finishNode(node, type);
|
||||
|
||||
case _tokentype.types._yield:
|
||||
if (this.inGenerator) this.unexpected();
|
||||
|
||||
case _tokentype.types.name:
|
||||
// quick hack to allow async and await
|
||||
if (this.value == "async" && /^[ \t]+function\b/.test(this.input.slice(this.end))) {
|
||||
if (this.value == "async" && /^[ \t]*(function\b|\(|\w+[ \t]*=>)/.test(this.input.slice(this.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom(refDestructuringErrors);
|
||||
|
@ -313,10 +311,6 @@ pp.parseExprAtom = function (refDestructuringErrors) {
|
|||
case _tokentype.types.bracketL:
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
// check whether this is array comprehension or regular array
|
||||
if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
|
||||
return this.parseComprehension(node, false);
|
||||
}
|
||||
node.elements = this.parseExprList(_tokentype.types.bracketR, true, true, refDestructuringErrors);
|
||||
return this.finishNode(node, "ArrayExpression");
|
||||
|
||||
|
@ -364,10 +358,6 @@ pp.parseParenAndDistinguishExpression = function (canBeArrow) {
|
|||
if (this.options.ecmaVersion >= 6) {
|
||||
this.next();
|
||||
|
||||
if (this.options.ecmaVersion >= 7 && this.type === _tokentype.types._for) {
|
||||
return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
|
||||
}
|
||||
|
||||
var innerStartPos = this.start,
|
||||
innerStartLoc = this.startLoc;
|
||||
var exprList = [],
|
||||
|
@ -444,8 +434,8 @@ pp.parseNew = function () {
|
|||
if (this.options.ecmaVersion >= 6 && this.eat(_tokentype.types.dot)) {
|
||||
node.meta = meta;
|
||||
node.property = this.parseIdent(true);
|
||||
if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
|
||||
if (!this.inFunction) this.raise(node.start, "new.target can only be used in functions");
|
||||
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");
|
||||
return this.finishNode(node, "MetaProperty");
|
||||
}
|
||||
var startPos = this.start,
|
||||
|
@ -536,13 +526,13 @@ pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startL
|
|||
var paramCount = prop.kind === "get" ? 0 : 1;
|
||||
if (prop.value.params.length !== paramCount) {
|
||||
var start = prop.value.start;
|
||||
if (prop.kind === "get") this.raise(start, "getter should have no params");else this.raise(start, "setter should have exactly one param");
|
||||
if (prop.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.raise(prop.value.params[0].start, "Setter cannot use rest params");
|
||||
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.raise(prop.key.start, "Binding " + prop.key.name);
|
||||
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 === _tokentype.types.eq && refDestructuringErrors) {
|
||||
if (!refDestructuringErrors.shorthandAssign) refDestructuringErrors.shorthandAssign = this.start;
|
||||
|
@ -581,21 +571,27 @@ pp.initFunction = function (node) {
|
|||
// Parse object or class method.
|
||||
|
||||
pp.parseMethod = function (isGenerator) {
|
||||
var node = this.startNode();
|
||||
var node = this.startNode(),
|
||||
oldInGen = this.inGenerator;
|
||||
this.inGenerator = isGenerator;
|
||||
this.initFunction(node);
|
||||
this.expect(_tokentype.types.parenL);
|
||||
node.params = this.parseBindingList(_tokentype.types.parenR, false, false);
|
||||
if (this.options.ecmaVersion >= 6) node.generator = isGenerator;
|
||||
this.parseFunctionBody(node, false);
|
||||
this.inGenerator = oldInGen;
|
||||
return this.finishNode(node, "FunctionExpression");
|
||||
};
|
||||
|
||||
// Parse arrow function expression with given parameters.
|
||||
|
||||
pp.parseArrowExpression = function (node, params) {
|
||||
var oldInGen = this.inGenerator;
|
||||
this.inGenerator = false;
|
||||
this.initFunction(node);
|
||||
node.params = this.toAssignableList(params, true);
|
||||
this.parseFunctionBody(node, true);
|
||||
this.inGenerator = oldInGen;
|
||||
return this.finishNode(node, "ArrowFunctionExpression");
|
||||
};
|
||||
|
||||
|
@ -611,12 +607,11 @@ pp.parseFunctionBody = function (node, isArrowFunction) {
|
|||
// Start a new scope with regard to labels and the `inFunction`
|
||||
// flag (restore them to their old value afterwards).
|
||||
var oldInFunc = this.inFunction,
|
||||
oldInGen = this.inGenerator,
|
||||
oldLabels = this.labels;
|
||||
this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
|
||||
this.inFunction = true;this.labels = [];
|
||||
node.body = this.parseBlock(true);
|
||||
node.expression = false;
|
||||
this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
|
||||
this.inFunction = oldInFunc;this.labels = oldLabels;
|
||||
}
|
||||
|
||||
// If this is a strict mode function, verify that argument names
|
||||
|
@ -676,7 +671,8 @@ pp.parseIdent = function (liberal) {
|
|||
var node = this.startNode();
|
||||
if (liberal && this.options.allowReserved == "never") liberal = false;
|
||||
if (this.type === _tokentype.types.name) {
|
||||
if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1)) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1)) this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved");
|
||||
if (!liberal && this.inGenerator && this.value === "yield") this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator");
|
||||
node.name = this.value;
|
||||
} else if (liberal && this.type.keyword) {
|
||||
node.name = this.type.keyword;
|
||||
|
@ -702,38 +698,7 @@ pp.parseYield = function () {
|
|||
return this.finishNode(node, "YieldExpression");
|
||||
};
|
||||
|
||||
// Parses array and generator comprehensions.
|
||||
|
||||
pp.parseComprehension = function (node, isGenerator) {
|
||||
node.blocks = [];
|
||||
while (this.type === _tokentype.types._for) {
|
||||
var block = this.startNode();
|
||||
this.next();
|
||||
this.expect(_tokentype.types.parenL);
|
||||
block.left = this.parseBindingAtom();
|
||||
this.checkLVal(block.left, true);
|
||||
this.expectContextual("of");
|
||||
block.right = this.parseExpression();
|
||||
this.expect(_tokentype.types.parenR);
|
||||
node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
|
||||
}
|
||||
node.filter = this.eat(_tokentype.types._if) ? this.parseParenExpression() : null;
|
||||
node.body = this.parseExpression();
|
||||
this.expect(isGenerator ? _tokentype.types.parenR : _tokentype.types.bracketR);
|
||||
node.generator = isGenerator;
|
||||
return this.finishNode(node, "ComprehensionExpression");
|
||||
};
|
||||
|
||||
},{"./state":"/src\\state.js","./tokentype":"/src\\tokentype.js"}],"/src\\identifier.js":[function(_dereq_,module,exports){
|
||||
// This is a trick taken from Esprima. It turns out that, on
|
||||
// non-Chrome browsers, to check whether a string is in a set, a
|
||||
// predicate containing a big ugly `switch` statement is faster than
|
||||
// a regular expression, and on Chrome the two are about on par.
|
||||
// This function uses `eval` (non-lexical) to produce such a
|
||||
// predicate from a space-separated string of words.
|
||||
//
|
||||
// It starts by sorting the words by length.
|
||||
|
||||
// Reserved word lists for various dialects of the language
|
||||
|
||||
"use strict";
|
||||
|
@ -756,7 +721,7 @@ var ecma5AndLessKeywords = "break case catch continue debugger default do else f
|
|||
|
||||
var keywords = {
|
||||
5: ecma5AndLessKeywords,
|
||||
6: ecma5AndLessKeywords + " let const class extends export import yield super"
|
||||
6: ecma5AndLessKeywords + " const class extends export import super"
|
||||
};
|
||||
|
||||
exports.keywords = keywords;
|
||||
|
@ -866,7 +831,7 @@ var _whitespace = _dereq_("./whitespace");
|
|||
exports.isNewLine = _whitespace.isNewLine;
|
||||
exports.lineBreak = _whitespace.lineBreak;
|
||||
exports.lineBreakG = _whitespace.lineBreakG;
|
||||
var version = "2.7.0";
|
||||
var version = "2.7.1";
|
||||
|
||||
exports.version = version;
|
||||
// The main exported interface (under `self.acorn` when in the
|
||||
|
@ -920,6 +885,8 @@ pp.raise = function (pos, message) {
|
|||
throw err;
|
||||
};
|
||||
|
||||
pp.raiseRecoverable = pp.raise;
|
||||
|
||||
pp.curPosition = function () {
|
||||
if (this.options.locations) {
|
||||
return new _locutil.Position(this.curLine, this.pos - this.lineStart);
|
||||
|
@ -1161,15 +1128,15 @@ pp.parseMaybeDefault = function (startPos, startLoc, left) {
|
|||
pp.checkLVal = function (expr, isBinding, checkClashes) {
|
||||
switch (expr.type) {
|
||||
case "Identifier":
|
||||
if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
|
||||
if (this.strict && this.reservedWordsStrictBind.test(expr.name)) this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
|
||||
if (checkClashes) {
|
||||
if (_util.has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash");
|
||||
if (_util.has(checkClashes, expr.name)) this.raiseRecoverable(expr.start, "Argument name clash");
|
||||
checkClashes[expr.name] = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case "MemberExpression":
|
||||
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
|
||||
if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
|
||||
break;
|
||||
|
||||
case "ObjectPattern":
|
||||
|
@ -1274,8 +1241,8 @@ var defaultOptions = {
|
|||
// `ecmaVersion` indicates the ECMAScript version to parse. Must
|
||||
// be either 3, or 5, or 6. This influences support for strict
|
||||
// mode, the set of reserved words, support for getters and
|
||||
// setters and other features.
|
||||
ecmaVersion: 5,
|
||||
// setters and other features. The default is 6.
|
||||
ecmaVersion: 6,
|
||||
// Source type ("script" or "module") for different semantics
|
||||
sourceType: "script",
|
||||
// `onInsertedSemicolon` can be a callback that will be called
|
||||
|
@ -1623,6 +1590,8 @@ var _state = _dereq_("./state");
|
|||
|
||||
var _whitespace = _dereq_("./whitespace");
|
||||
|
||||
var _identifier = _dereq_("./identifier");
|
||||
|
||||
var pp = _state.Parser.prototype;
|
||||
|
||||
// ### Statement parsing
|
||||
|
@ -1653,6 +1622,21 @@ pp.parseTopLevel = function (node) {
|
|||
var loopLabel = { kind: "loop" },
|
||||
switchLabel = { kind: "switch" };
|
||||
|
||||
pp.isLet = function () {
|
||||
if (this.type !== _tokentype.types.name || this.options.ecmaVersion < 6 || this.value != "let") return false;
|
||||
_whitespace.skipWhiteSpace.lastIndex = this.pos;
|
||||
var skip = _whitespace.skipWhiteSpace.exec(this.input);
|
||||
var next = this.pos + skip[0].length,
|
||||
nextCh = this.input.charCodeAt(next);
|
||||
if (nextCh === 91 || nextCh == 123) return true; // '{' and '['
|
||||
if (_identifier.isIdentifierStart(nextCh, true)) {
|
||||
for (var pos = next + 1; _identifier.isIdentifierChar(this.input.charCodeAt(pos, true)); ++pos) {}
|
||||
var ident = this.input.slice(next, pos);
|
||||
if (!this.isKeyword(ident)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Parse a single statement.
|
||||
//
|
||||
// If expecting a statement and finding a slash operator, parse a
|
||||
|
@ -1662,7 +1646,13 @@ var loopLabel = { kind: "loop" },
|
|||
|
||||
pp.parseStatement = function (declaration, topLevel) {
|
||||
var starttype = this.type,
|
||||
node = this.startNode();
|
||||
node = this.startNode(),
|
||||
kind = undefined;
|
||||
|
||||
if (this.isLet()) {
|
||||
starttype = _tokentype.types._var;
|
||||
kind = "let";
|
||||
}
|
||||
|
||||
// Most types of statements are recognized by the keyword they
|
||||
// start with. Many are trivial to parse, some require a bit of
|
||||
|
@ -1693,10 +1683,10 @@ pp.parseStatement = function (declaration, topLevel) {
|
|||
return this.parseThrowStatement(node);
|
||||
case _tokentype.types._try:
|
||||
return this.parseTryStatement(node);
|
||||
case _tokentype.types._let:case _tokentype.types._const:
|
||||
if (!declaration) this.unexpected(); // NOTE: falls through to _var
|
||||
case _tokentype.types._var:
|
||||
return this.parseVarStatement(node, starttype);
|
||||
case _tokentype.types._const:case _tokentype.types._var:
|
||||
kind = kind || this.value;
|
||||
if (!declaration && kind != "var") this.unexpected();
|
||||
return this.parseVarStatement(node, kind);
|
||||
case _tokentype.types._while:
|
||||
return this.parseWhileStatement(node);
|
||||
case _tokentype.types._with:
|
||||
|
@ -1709,7 +1699,7 @@ pp.parseStatement = function (declaration, topLevel) {
|
|||
case _tokentype.types._import:
|
||||
if (!this.options.allowImportExportEverywhere) {
|
||||
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
|
||||
// if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
||||
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
|
||||
}
|
||||
return starttype === _tokentype.types._import ? this.parseImport(node) : this.parseExport(node);
|
||||
|
||||
|
@ -1776,13 +1766,14 @@ pp.parseForStatement = function (node) {
|
|||
this.labels.push(loopLabel);
|
||||
this.expect(_tokentype.types.parenL);
|
||||
if (this.type === _tokentype.types.semi) return this.parseFor(node, null);
|
||||
if (this.type === _tokentype.types._var || this.type === _tokentype.types._let || this.type === _tokentype.types._const) {
|
||||
var isLet = this.isLet();
|
||||
if (this.type === _tokentype.types._var || this.type === _tokentype.types._const || isLet) {
|
||||
var _init = this.startNode(),
|
||||
varKind = this.type;
|
||||
kind = isLet ? "let" : this.value;
|
||||
this.next();
|
||||
this.parseVar(_init, true, varKind);
|
||||
this.parseVar(_init, true, kind);
|
||||
this.finishNode(_init, "VariableDeclaration");
|
||||
if ((this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== _tokentype.types._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)) return this.parseForIn(node, _init);
|
||||
return this.parseFor(node, _init);
|
||||
}
|
||||
var refDestructuringErrors = { shorthandAssign: 0, trailingComma: 0 };
|
||||
|
@ -1846,7 +1837,7 @@ pp.parseSwitchStatement = function (node) {
|
|||
if (isCase) {
|
||||
cur.test = this.parseExpression();
|
||||
} else {
|
||||
if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
|
||||
if (sawDefault) this.raiseRecoverable(this.lastTokStart, "Multiple default clauses");
|
||||
sawDefault = true;
|
||||
cur.test = null;
|
||||
}
|
||||
|
@ -2003,13 +1994,13 @@ pp.parseForIn = function (node, init) {
|
|||
|
||||
pp.parseVar = function (node, isFor, kind) {
|
||||
node.declarations = [];
|
||||
node.kind = kind.keyword;
|
||||
node.kind = kind;
|
||||
for (;;) {
|
||||
var decl = this.startNode();
|
||||
this.parseVarId(decl);
|
||||
if (this.eat(_tokentype.types.eq)) {
|
||||
decl.init = this.parseMaybeAssign(isFor);
|
||||
} else if (kind === _tokentype.types._const && !(this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
|
||||
} else if (kind === "const" && !(this.type === _tokentype.types._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
|
||||
this.unexpected();
|
||||
} 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");
|
||||
|
@ -2033,9 +2024,12 @@ pp.parseVarId = function (decl) {
|
|||
pp.parseFunction = function (node, isStatement, allowExpressionBody) {
|
||||
this.initFunction(node);
|
||||
if (this.options.ecmaVersion >= 6) node.generator = this.eat(_tokentype.types.star);
|
||||
var oldInGen = this.inGenerator;
|
||||
this.inGenerator = node.generator;
|
||||
if (isStatement || this.type === _tokentype.types.name) node.id = this.parseIdent();
|
||||
this.parseFunctionParams(node);
|
||||
this.parseFunctionBody(node, allowExpressionBody);
|
||||
this.inGenerator = oldInGen;
|
||||
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
|
||||
};
|
||||
|
||||
|
@ -2090,7 +2084,7 @@ pp.parseClass = function (node, isStatement) {
|
|||
var paramCount = method.kind === "get" ? 0 : 1;
|
||||
if (method.value.params.length !== paramCount) {
|
||||
var 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 (method.kind === "get") this.raiseRecoverable(start, "getter should have no params");else this.raiseRecoverable(start, "setter should have exactly one param");
|
||||
}
|
||||
if (method.kind === "set" && method.value.params[0].type === "RestElement") this.raise(method.value.params[0].start, "Setter cannot use rest params");
|
||||
}
|
||||
|
@ -2125,9 +2119,10 @@ pp.parseExport = function (node) {
|
|||
}
|
||||
if (this.eat(_tokentype.types._default)) {
|
||||
// export default ...
|
||||
var parens = this.type == _tokentype.types.parenL;
|
||||
var expr = this.parseMaybeAssign();
|
||||
var needsSemi = true;
|
||||
if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
|
||||
if (!parens && (expr.type == "FunctionExpression" || expr.type == "ClassExpression")) {
|
||||
needsSemi = false;
|
||||
if (expr.id) {
|
||||
expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
|
||||
|
@ -2164,7 +2159,7 @@ pp.parseExport = function (node) {
|
|||
};
|
||||
|
||||
pp.shouldParseExportStatement = function () {
|
||||
return this.type.keyword;
|
||||
return this.type.keyword || this.isLet();
|
||||
};
|
||||
|
||||
// Parses a comma-separated list of module exports.
|
||||
|
@ -2249,7 +2244,7 @@ pp.parseImportSpecifiers = function () {
|
|||
return nodes;
|
||||
};
|
||||
|
||||
},{"./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./whitespace":"/src\\whitespace.js"}],"/src\\tokencontext.js":[function(_dereq_,module,exports){
|
||||
},{"./identifier":"/src\\identifier.js","./state":"/src\\state.js","./tokentype":"/src\\tokentype.js","./whitespace":"/src\\whitespace.js"}],"/src\\tokencontext.js":[function(_dereq_,module,exports){
|
||||
// The algorithm used to determine whether a regexp can appear at a
|
||||
// given point in the program is loosely based on sweet.js' approach.
|
||||
// See https://github.com/mozilla/sweet.js/wiki/design
|
||||
|
@ -2601,11 +2596,21 @@ pp.readToken_slash = function () {
|
|||
return this.finishOp(_tokentype.types.slash, 1);
|
||||
};
|
||||
|
||||
pp.readToken_mult_modulo = function (code) {
|
||||
pp.readToken_mult_modulo_exp = function (code) {
|
||||
// '%*'
|
||||
var next = this.input.charCodeAt(this.pos + 1);
|
||||
if (next === 61) return this.finishOp(_tokentype.types.assign, 2);
|
||||
return this.finishOp(code === 42 ? _tokentype.types.star : _tokentype.types.modulo, 1);
|
||||
var size = 1;
|
||||
var tokentype = code === 42 ? _tokentype.types.star : _tokentype.types.modulo;
|
||||
|
||||
// exponentiation operator ** and **=
|
||||
if (this.options.ecmaVersion >= 7 && next === 42) {
|
||||
++size;
|
||||
tokentype = _tokentype.types.starstar;
|
||||
next = this.input.charCodeAt(this.pos + 2);
|
||||
}
|
||||
|
||||
if (next === 61) return this.finishOp(_tokentype.types.assign, size + 1);
|
||||
return this.finishOp(tokentype, size);
|
||||
};
|
||||
|
||||
pp.readToken_pipe_amp = function (code) {
|
||||
|
@ -2713,7 +2718,8 @@ pp.getTokenFromCode = function (code) {
|
|||
if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
|
||||
if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
|
||||
if (next === 98 || next === 66) return this.readRadixNumber(2) // '0b', '0B' - binary number
|
||||
;
|
||||
}
|
||||
// Anything else beginning with a digit is an integer, octal
|
||||
// number, or float.
|
||||
|
@ -2737,7 +2743,7 @@ pp.getTokenFromCode = function (code) {
|
|||
|
||||
case 37:case 42:
|
||||
// '%*'
|
||||
return this.readToken_mult_modulo(code);
|
||||
return this.readToken_mult_modulo_exp(code);
|
||||
|
||||
case 124:case 38:
|
||||
// '|&'
|
||||
|
@ -2855,10 +2861,10 @@ pp.readInt = function (radix, len) {
|
|||
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
|
||||
var code = this.input.charCodeAt(this.pos),
|
||||
val = undefined;
|
||||
if (code >= 97) val = code - 97 + 10; // a
|
||||
else if (code >= 65) val = code - 65 + 10; // A
|
||||
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
|
||||
else val = Infinity;
|
||||
if (code >= 97) val = code - 97 + 10 // a
|
||||
;else if (code >= 65) val = code - 65 + 10 // A
|
||||
;else if (code >= 48 && code <= 57) val = code - 48 // 0-9
|
||||
;else val = Infinity;
|
||||
if (val >= radix) break;
|
||||
++this.pos;
|
||||
total = total * radix + val;
|
||||
|
@ -3214,7 +3220,8 @@ var types = {
|
|||
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
|
||||
modulo: binop("%", 10),
|
||||
star: binop("*", 10),
|
||||
slash: binop("/", 10)
|
||||
slash: binop("/", 10),
|
||||
starstar: binop("**", 11)
|
||||
};
|
||||
|
||||
exports.types = types;
|
||||
|
@ -3248,7 +3255,6 @@ kw("switch");
|
|||
kw("throw", beforeExpr);
|
||||
kw("try");
|
||||
kw("var");
|
||||
kw("let");
|
||||
kw("const");
|
||||
kw("while", { isLoop: true });
|
||||
kw("with");
|
||||
|
@ -3259,7 +3265,6 @@ kw("class");
|
|||
kw("extends", beforeExpr);
|
||||
kw("export");
|
||||
kw("import");
|
||||
kw("yield", { beforeExpr: true, startsExpr: true });
|
||||
kw("null", startsExpr);
|
||||
kw("true", startsExpr);
|
||||
kw("false", startsExpr);
|
||||
|
@ -3305,7 +3310,10 @@ function isNewLine(code) {
|
|||
}
|
||||
|
||||
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
|
||||
|
||||
exports.nonASCIIwhitespace = nonASCIIwhitespace;
|
||||
var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
|
||||
exports.skipWhiteSpace = skipWhiteSpace;
|
||||
|
||||
},{}]},{},["/src\\index.js"])("/src\\index.js")
|
||||
});
|
||||
|
|
|
@ -54,6 +54,19 @@ lp.parseParenExpression = function () {
|
|||
};
|
||||
|
||||
lp.parseMaybeAssign = function (noIn) {
|
||||
if (this.toks.isContextual("yield")) {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
if (this.semicolon() || this.canInsertSemicolon() || this.tok.type != _.tokTypes.star && !this.tok.type.startsExpr) {
|
||||
node.delegate = false;
|
||||
node.argument = null;
|
||||
} else {
|
||||
node.delegate = this.eat(_.tokTypes.star);
|
||||
node.argument = this.parseMaybeAssign();
|
||||
}
|
||||
return this.finishNode(node, "YieldExpression");
|
||||
}
|
||||
|
||||
var start = this.storeCurrentPos();
|
||||
var left = this.parseMaybeConditional(noIn);
|
||||
if (this.tok.type.isAssign) {
|
||||
|
@ -193,7 +206,7 @@ lp.parseExprAtom = function () {
|
|||
|
||||
case _.tokTypes.name:
|
||||
// quick hack to allow async and await
|
||||
if (this.tok.value == "async" && /^[ \t]+function\b/.test(this.input.slice(this.tok.end))) {
|
||||
if (this.value == "async" && /^[ \t]*(function\b|\(|\w+[ \t]*=>)/.test(this.input.slice(this.tok.end))) {
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
return this.parseExprAtom();
|
||||
|
@ -264,18 +277,6 @@ lp.parseExprAtom = function () {
|
|||
case _.tokTypes._new:
|
||||
return this.parseNew();
|
||||
|
||||
case _.tokTypes._yield:
|
||||
node = this.startNode();
|
||||
this.next();
|
||||
if (this.semicolon() || this.canInsertSemicolon() || this.tok.type != _.tokTypes.star && !this.tok.type.startsExpr) {
|
||||
node.delegate = false;
|
||||
node.argument = null;
|
||||
} else {
|
||||
node.delegate = this.eat(_.tokTypes.star);
|
||||
node.argument = this.parseMaybeAssign();
|
||||
}
|
||||
return this.finishNode(node, "YieldExpression");
|
||||
|
||||
case _.tokTypes.backQuote:
|
||||
return this.parseTemplate();
|
||||
|
||||
|
@ -801,7 +802,13 @@ lp.parseTopLevel = function () {
|
|||
|
||||
lp.parseStatement = function () {
|
||||
var starttype = this.tok.type,
|
||||
node = this.startNode();
|
||||
node = this.startNode(),
|
||||
kind = undefined;
|
||||
|
||||
if (this.toks.isLet()) {
|
||||
starttype = _.tokTypes._var;
|
||||
kind = "let";
|
||||
}
|
||||
|
||||
switch (starttype) {
|
||||
case _.tokTypes._break:case _.tokTypes._continue:
|
||||
|
@ -832,8 +839,9 @@ lp.parseStatement = function () {
|
|||
this.pushCx();
|
||||
this.expect(_.tokTypes.parenL);
|
||||
if (this.tok.type === _.tokTypes.semi) return this.parseFor(node, null);
|
||||
if (this.tok.type === _.tokTypes._var || this.tok.type === _.tokTypes._let || this.tok.type === _.tokTypes._const) {
|
||||
var _init = this.parseVar(true);
|
||||
var isLet = this.toks.isLet();
|
||||
if (isLet || this.tok.type === _.tokTypes._var || this.tok.type === _.tokTypes._const) {
|
||||
var _init = this.parseVar(true, isLet ? "let" : this.tok.value);
|
||||
if (_init.declarations.length === 1 && (this.tok.type === _.tokTypes._in || this.isContextual("of"))) {
|
||||
return this.parseForIn(node, _init);
|
||||
}
|
||||
|
@ -918,9 +926,8 @@ lp.parseStatement = function () {
|
|||
return this.finishNode(node, "TryStatement");
|
||||
|
||||
case _.tokTypes._var:
|
||||
case _.tokTypes._let:
|
||||
case _.tokTypes._const:
|
||||
return this.parseVar();
|
||||
return this.parseVar(false, kind || this.tok.value);
|
||||
|
||||
case _.tokTypes._while:
|
||||
this.next();
|
||||
|
@ -1003,9 +1010,9 @@ lp.parseForIn = function (node, init) {
|
|||
return this.finishNode(node, type);
|
||||
};
|
||||
|
||||
lp.parseVar = function (noIn) {
|
||||
lp.parseVar = function (noIn, kind) {
|
||||
var node = this.startNode();
|
||||
node.kind = this.tok.type.keyword;
|
||||
node.kind = kind;
|
||||
this.next();
|
||||
node.declarations = [];
|
||||
do {
|
||||
|
@ -1114,7 +1121,7 @@ lp.parseExport = function () {
|
|||
this.semicolon();
|
||||
return this.finishNode(node, "ExportDefaultDeclaration");
|
||||
}
|
||||
if (this.tok.type.keyword) {
|
||||
if (this.tok.type.keyword || this.toks.isLet()) {
|
||||
node.declaration = this.parseStatement();
|
||||
node.specifiers = [];
|
||||
node.source = null;
|
||||
|
@ -1298,7 +1305,7 @@ lp.resetTo = function (pos) {
|
|||
this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) || /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos));
|
||||
|
||||
if (this.options.locations) {
|
||||
this.toks.curLine = 1;
|
||||
this.toks.curLine = 0;
|
||||
this.toks.lineStart = _.lineBreakG.lastIndex = 0;
|
||||
var match = undefined;
|
||||
while ((match = _.lineBreakG.exec(this.input)) && match.index < pos) {
|
||||
|
|
|
@ -1,38 +1,48 @@
|
|||
require({
|
||||
baseUrl: "lib"
|
||||
}, ["treehugger/tree", "treehugger/traverse", "treehugger/js/parse", "jquery",
|
||||
}, ["treehugger/tree", "treehugger/traverse", "treehugger/js/parse",
|
||||
"acorn/dist/acorn", "acorn/dist/acorn_loose", "acorn/dist/walk"
|
||||
], function(tree, traverse, parsejs, jq, acorn, acorn_loose) {
|
||||
], function(tree, traverse, parsejs, acorn, acorn_loose) {
|
||||
var $ = document.querySelector.bind(document);
|
||||
window.acorn_loose = acorn_loose;
|
||||
|
||||
window.acorn_loose = acorn_loose
|
||||
if (localStorage.trehuggerJsVal)
|
||||
$("#code").value = localStorage.trehuggerJsVal;
|
||||
if (localStorage.trehuggerAnalysisVal)
|
||||
$("#analysis").value = localStorage.trehuggerAnalysisVal;
|
||||
window.onbeforeunload = function() {
|
||||
localStorage.trehuggerJsVal = $("#code").value;
|
||||
localStorage.trehuggerAnalysisVal = $("#analysis").value;
|
||||
};
|
||||
|
||||
function log(message) {
|
||||
$("#output").val($("#output").val() + message + "\n");
|
||||
$("#output").value = $("#output").value + message + "\n";
|
||||
}
|
||||
|
||||
function exec() {
|
||||
var js = $("#code").val();
|
||||
var analysisJs = $("#analysis").val();
|
||||
$("#output").val("");
|
||||
var js = $("#code").value;
|
||||
var analysisJs = $("#analysis").value;
|
||||
$("#output").value = "";
|
||||
|
||||
var t = performance.now();
|
||||
var ast = parsejs.parse(js);
|
||||
t -= performance.now();
|
||||
$("#ast").val(t + "\n" + ast.toPrettyString());
|
||||
try {
|
||||
var t = performance.now();
|
||||
var ast = parsejs.parse(js);
|
||||
t -= performance.now();
|
||||
$("#ast").value = t + "\n" + ast.toPrettyString();
|
||||
eval(analysisJs);
|
||||
} catch(e) {
|
||||
$("#output").val("JS Error");
|
||||
console.log(e.message)
|
||||
$("#output").value = "JS Error \n\t" + (e.stack || e.message);
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
tree.Node.prototype.log = function() {
|
||||
$("#output").val(this.toPrettyString());
|
||||
$("#output").value = this.toPrettyString();
|
||||
}
|
||||
|
||||
|
||||
$("#code").keyup(exec);
|
||||
$("#runbutton").click(exec);
|
||||
$("#code").addEventListener("input", exec);
|
||||
$("#runbutton").addEventListener("click", exec);
|
||||
exec();
|
||||
|
||||
});
|
||||
|
|
|
@ -216,7 +216,7 @@ exports.transform = function transform(n) {
|
|||
case "ArrowFunctionExpression":
|
||||
resultNode = tree.cons("Arrow", [tree.list(n.params.map(function(arg) {
|
||||
return setIdPos(arg, tree.cons("FArg", [id(arg)]));
|
||||
})), tree.list(n.body.body.map(transform))]);
|
||||
})), tree.list(n.body.body ? n.body.body.map(transform) : transform(n.body))]);
|
||||
break;
|
||||
case "YieldExpression":
|
||||
resultNode = tree.cons("Yield", [transform(n.argument)]);
|
||||
|
|
Ładowanie…
Reference in New Issue