aboutsummaryrefslogtreecommitdiff
path: root/node_modules/uglify-js/lib/parse.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/uglify-js/lib/parse.js')
-rw-r--r--node_modules/uglify-js/lib/parse.js152
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) {