diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:01:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:02:09 +0200 |
commit | 363723fc84f7b8477592e0105aeb331ec9a017af (patch) | |
tree | 29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/uglify-js/lib/parse.js | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) |
node_modules
Diffstat (limited to 'node_modules/uglify-js/lib/parse.js')
-rw-r--r-- | node_modules/uglify-js/lib/parse.js | 152 |
1 files changed, 75 insertions, 77 deletions
diff --git a/node_modules/uglify-js/lib/parse.js b/node_modules/uglify-js/lib/parse.js index 014822ad9..e2dd04b6c 100644 --- a/node_modules/uglify-js/lib/parse.js +++ b/node_modules/uglify-js/lib/parse.js @@ -115,8 +115,6 @@ var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:")); var PUNC_CHARS = makePredicate(characters("[]{}(),;:")); -var REGEXP_MODIFIERS = makePredicate(characters("gmsiy")); - /* -----[ Tokenizer ]----- */ // regexps adapted from http://xregexp.com/plugins/#unicode @@ -477,31 +475,33 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { return name; }; - var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){ + var read_regexp = with_eof_error("Unterminated regular expression", function(source) { var prev_backslash = false, ch, in_class = false; while ((ch = next(true))) if (NEWLINE_CHARS(ch)) { parse_error("Unexpected line terminator"); } else if (prev_backslash) { - regexp += "\\" + ch; + source += "\\" + ch; prev_backslash = false; } else if (ch == "[") { in_class = true; - regexp += ch; + source += ch; } else if (ch == "]" && in_class) { in_class = false; - regexp += ch; + source += ch; } else if (ch == "/" && !in_class) { break; } else if (ch == "\\") { prev_backslash = true; } else { - regexp += ch; + source += ch; } var mods = read_name(); try { - return token("regexp", new RegExp(regexp, mods)); + var regexp = new RegExp(source, mods); + regexp.raw_source = source; + return token("regexp", regexp); } catch(e) { - parse_error(e.message); + parse_error(e.message); } }); @@ -633,8 +633,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; @@ -683,9 +682,7 @@ var PRECEDENCE = (function(a, ret){ {} ); -var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]); - -var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]); +var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]); /* -----[ Parser ]----- */ @@ -693,14 +690,13 @@ function parse($TEXT, options) { options = defaults(options, { bare_returns : false, - cli : false, expression : false, filename : null, html5_comments : true, shebang : true, strict : false, toplevel : null, - }); + }, true); var S = { input : (typeof $TEXT == "string" @@ -941,12 +937,6 @@ function parse($TEXT, options) { semicolon(); return node; - case "const": - next(); - var node = const_(); - semicolon(); - return node; - case "with": if (S.input.has_directive("use strict")) { croak("Strict mode may not include a with statement"); @@ -1020,8 +1010,12 @@ function parse($TEXT, options) { ? (next(), var_(true)) : expression(true, true); if (is("operator", "in")) { - if (init instanceof AST_Var && init.definitions.length > 1) - croak("Only one variable declaration allowed in for..in loop"); + if (init instanceof AST_Var) { + if (init.definitions.length > 1) + croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos); + } else if (!is_assignable(init)) { + croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos); + } next(); return for_in(init); } @@ -1061,29 +1055,32 @@ function parse($TEXT, options) { if (in_statement && !name) unexpected(); expect("("); + var argnames = []; + for (var first = true; !is("punc", ")");) { + if (first) first = false; else expect(","); + argnames.push(as_symbol(AST_SymbolFunarg)); + } + next(); + var loop = S.in_loop; + var labels = S.labels; + ++S.in_function; + S.in_directives = true; + S.input.push_directives_stack(); + S.in_loop = 0; + S.labels = []; + var body = block_(); + if (S.input.has_directive("use strict")) { + if (name) strict_verify_symbol(name); + argnames.forEach(strict_verify_symbol); + } + S.input.pop_directives_stack(); + --S.in_function; + S.in_loop = loop; + S.labels = labels; return new ctor({ name: name, - argnames: (function(first, a){ - while (!is("punc", ")")) { - if (first) first = false; else expect(","); - a.push(as_symbol(AST_SymbolFunarg)); - } - next(); - return a; - })(true, []), - body: (function(loop, labels){ - ++S.in_function; - S.in_directives = true; - S.input.push_directives_stack(); - S.in_loop = 0; - S.labels = []; - var a = block_(); - S.input.pop_directives_stack(); - --S.in_function; - S.in_loop = loop; - S.labels = labels; - return a; - })(S.in_loop, S.labels) + argnames: argnames, + body: body }); }; @@ -1179,12 +1176,12 @@ function parse($TEXT, options) { }); }; - function vardefs(no_in, in_const) { + function vardefs(no_in) { var a = []; for (;;) { a.push(new AST_VarDef({ start : S.token, - name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar), + name : as_symbol(AST_SymbolVar), value : is("operator", "=") ? (next(), expression(false, no_in)) : null, end : prev() })); @@ -1198,15 +1195,7 @@ function parse($TEXT, options) { var var_ = function(no_in) { return new AST_Var({ start : prev(), - definitions : vardefs(no_in, false), - end : prev() - }); - }; - - var const_ = function() { - return new AST_Const({ - start : prev(), - definitions : vardefs(false, true), + definitions : vardefs(no_in), end : prev() }); }; @@ -1233,7 +1222,6 @@ function parse($TEXT, options) { var tok = S.token, ret; switch (tok.type) { case "name": - case "keyword": ret = _make_symbol(AST_SymbolRef); break; case "num": @@ -1263,13 +1251,6 @@ function parse($TEXT, options) { break; } break; - case "operator": - if (!is_identifier_string(tok.value)) { - croak("Invalid getter/setter name: " + tok.value, - tok.line, tok.col, tok.pos); - } - ret = _make_symbol(AST_SymbolRef); - break; } next(); return ret; @@ -1303,7 +1284,7 @@ function parse($TEXT, options) { func.end = prev(); return subscripts(func, allow_calls); } - if (ATOMIC_START_TOKEN[S.token.type]) { + if (ATOMIC_START_TOKEN(S.token.type)) { return subscripts(as_atom_node(), allow_calls); } unexpected(); @@ -1417,12 +1398,20 @@ 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"); return null; } var sym = _make_symbol(type); + if (S.input.has_directive("use strict") && sym instanceof AST_SymbolDeclaration) { + strict_verify_symbol(sym); + } next(); return sym; }; @@ -1483,8 +1472,17 @@ function parse($TEXT, options) { function make_unary(ctor, token, expr) { var op = token.value; - if ((op == "++" || op == "--") && !is_assignable(expr)) - croak("Invalid use of " + op + " operator", token.line, token.col, token.pos); + 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 }); }; @@ -1529,7 +1527,6 @@ function parse($TEXT, options) { }; function is_assignable(expr) { - if (options.cli) return true; return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef; }; @@ -1554,17 +1551,18 @@ function parse($TEXT, options) { var expression = function(commas, no_in) { var start = S.token; - var expr = maybe_assign(no_in); - if (commas && is("punc", ",")) { + var exprs = []; + while (true) { + exprs.push(maybe_assign(no_in)); + if (!commas || !is("punc", ",")) break; next(); - return new AST_Seq({ - start : start, - car : expr, - cdr : expression(true, no_in), - end : peek() - }); + commas = true; } - return expr; + return exprs.length == 1 ? exprs[0] : new AST_Sequence({ + start : start, + expressions : exprs, + end : peek() + }); }; function in_loop(cont) { |