Merge branch 'master' into harmony-v3.0.0

This commit is contained in:
alexlamsl
2017-05-07 07:18:15 +08:00
83 changed files with 9768 additions and 8722 deletions

View File

@@ -118,7 +118,7 @@ var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
@@ -785,8 +785,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
next_token.has_directive = function(directive) {
return S.directives[directive] !== undefined &&
S.directives[directive] > 0;
return S.directives[directive] > 0;
}
return next_token;
@@ -846,7 +845,6 @@ function parse($TEXT, options) {
options = defaults(options, {
bare_returns : false,
cli : false,
expression : false,
filename : null,
html5_comments : true,
@@ -1268,7 +1266,7 @@ function parse($TEXT, options) {
unexpected();
var args = parameters();
var body = _function_body(true, is_generator || is_generator_property);
var body = _function_body(true, is_generator || is_generator_property, name, args);
return new ctor({
start : args.start,
end : body.end,
@@ -1601,7 +1599,7 @@ function parse($TEXT, options) {
});
}
function _function_body(block, generator) {
function _function_body(block, generator, name, args) {
var loop = S.in_loop;
var labels = S.labels;
var current_generator = S.in_generator;
@@ -1615,6 +1613,10 @@ function parse($TEXT, options) {
if (block) {
S.input.push_directives_stack();
var a = block_();
if (S.input.has_directive("use strict")) {
if (name) strict_verify_symbol(name);
if (args) args.forEach(strict_verify_symbol);
}
S.input.pop_directives_stack();
} else {
var a = expression(false);
@@ -1772,7 +1774,10 @@ function parse($TEXT, options) {
def = new AST_VarDef({
start : S.token,
name : as_symbol(sym_type),
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
value : is("operator", "=")
? (next(), expression(false, no_in))
: kind === "const" && S.input.has_directive("use strict")
? croak("Missing initializer in const declaration") : null,
end : prev()
})
}
@@ -2346,16 +2351,17 @@ function parse($TEXT, options) {
function as_property_name() {
var tmp = S.token;
next();
switch (tmp.type) {
case "punc":
if (tmp.value === "[") {
next();
var ex = expression(false);
expect("]");
return ex;
} else unexpected(tmp);
case "operator":
if (tmp.value === "*") {
next();
return null;
}
if (["delete", "in", "instanceof", "new", "typeof", "void"].indexOf(tmp.value) === -1) {
@@ -2369,6 +2375,7 @@ function parse($TEXT, options) {
case "num":
case "keyword":
case "atom":
next();
return tmp.value;
default:
unexpected(tmp);
@@ -2377,16 +2384,9 @@ function parse($TEXT, options) {
function as_name() {
var tmp = S.token;
if (tmp.type != "name") unexpected();
next();
switch (tmp.type) {
case "name":
case "operator":
case "keyword":
case "atom":
return tmp.value;
default:
unexpected();
}
return tmp.value;
};
function _make_symbol(type) {
@@ -2400,6 +2400,11 @@ function parse($TEXT, options) {
});
};
function strict_verify_symbol(sym) {
if (sym.name == "arguments" || sym.name == "eval")
croak("Unexpected " + sym.name + " in strict mode", sym.start.line, sym.start.col, sym.start.pos);
}
function as_symbol(type, noerror) {
if (!is("name")) {
if (!noerror) croak("Name expected");
@@ -2409,6 +2414,9 @@ function parse($TEXT, options) {
token_error(S.prev, "Unexpected yield identifier inside strict mode");
}
var sym = _make_symbol(type);
if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) {
strict_verify_symbol(sym);
}
next();
return sym;
};
@@ -2478,14 +2486,14 @@ function parse($TEXT, options) {
if (is("operator") && UNARY_PREFIX(start.value)) {
next();
handle_regexp();
var ex = make_unary(AST_UnaryPrefix, start.value, maybe_unary(allow_calls));
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
ex.start = start;
ex.end = prev();
return ex;
}
var val = expr_atom(allow_calls);
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
val = make_unary(AST_UnaryPostfix, S.token.value, val);
val = make_unary(AST_UnaryPostfix, S.token, val);
val.start = start;
val.end = S.token;
next();
@@ -2493,9 +2501,19 @@ function parse($TEXT, options) {
return val;
};
function make_unary(ctor, op, expr) {
if ((op == "++" || op == "--") && !is_assignable(expr))
croak("Invalid use of " + op + " operator", null, ctor === AST_UnaryPrefix ? expr.start.col - 1 : null);
function make_unary(ctor, token, expr) {
var op = token.value;
switch (op) {
case "++":
case "--":
if (!is_assignable(expr))
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
break;
case "delete":
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
break;
}
return new ctor({ operator: op, expression: expr });
};
@@ -2544,7 +2562,6 @@ function parse($TEXT, options) {
};
function is_assignable(expr) {
if (options.cli) return true;
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
};
@@ -2641,25 +2658,27 @@ function parse($TEXT, options) {
var expression = function(commas, no_in) {
var start = S.token;
var expr = maybe_assign(no_in);
if (expr instanceof AST_SymbolRef && is("arrow", "=>")) {
expr = new AST_ArrowParametersOrSeq({
var exprs = [];
while (true) {
exprs.push(maybe_assign(no_in));
if (!commas || !is("punc", ",")) break;
next();
commas = true;
}
if (exprs.length == 1) {
var expr = exprs[0];
if (!(expr instanceof AST_SymbolRef) || !is("arrow", "=>")) return expr;
return arrow_function(new AST_ArrowParametersOrSeq({
start: expr.start,
end: expr.end,
expressions: [expr]
});
return arrow_function(expr);
}));
}
if (commas && is("punc", ",")) {
next();
return new AST_Seq({
start : start,
car : expr,
cdr : expression(true, no_in),
end : peek()
});
}
return expr;
return new AST_Sequence({
start : start,
expressions : exprs,
end : peek()
});
};
function in_loop(cont) {