aboutsummaryrefslogtreecommitdiff
path: root/node_modules/uglify-js/lib/parse.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2018-09-20 02:56:13 +0200
committerFlorian Dold <florian.dold@gmail.com>2018-09-20 02:56:13 +0200
commitbbff7403fbf46f9ad92240ac213df8d30ef31b64 (patch)
treec58400ec5124da1c7d56b01aea83309f80a56c3b /node_modules/uglify-js/lib/parse.js
parent003fb34971cf63466184351b4db5f7c67df4f444 (diff)
update packages
Diffstat (limited to 'node_modules/uglify-js/lib/parse.js')
-rw-r--r--node_modules/uglify-js/lib/parse.js359
1 files changed, 204 insertions, 155 deletions
diff --git a/node_modules/uglify-js/lib/parse.js b/node_modules/uglify-js/lib/parse.js
index 099fc49a8..29df370c7 100644
--- a/node_modules/uglify-js/lib/parse.js
+++ b/node_modules/uglify-js/lib/parse.js
@@ -130,15 +130,27 @@ function is_letter(code) {
return (code >= 97 && code <= 122)
|| (code >= 65 && code <= 90)
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
-};
+}
+
+function is_surrogate_pair_head(code) {
+ if (typeof code == "string")
+ code = code.charCodeAt(0);
+ return code >= 0xd800 && code <= 0xdbff;
+}
+
+function is_surrogate_pair_tail(code) {
+ if (typeof code == "string")
+ code = code.charCodeAt(0);
+ return code >= 0xdc00 && code <= 0xdfff;
+}
function is_digit(code) {
return code >= 48 && code <= 57;
-};
+}
function is_alphanumeric_char(code) {
return is_digit(code) || is_letter(code);
-};
+}
function is_unicode_digit(code) {
return UNICODE.digit.test(String.fromCharCode(code));
@@ -146,19 +158,19 @@ function is_unicode_digit(code) {
function is_unicode_combining_mark(ch) {
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
-};
+}
function is_unicode_connector_punctuation(ch) {
return UNICODE.connector_punctuation.test(ch);
-};
+}
function is_identifier(name) {
- return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name);
-};
+ return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
+}
function is_identifier_start(code) {
return code == 36 || code == 95 || is_letter(code);
-};
+}
function is_identifier_char(ch) {
var code = ch.charCodeAt(0);
@@ -170,11 +182,11 @@ function is_identifier_char(ch) {
|| is_unicode_connector_punctuation(ch)
|| is_unicode_digit(code)
;
-};
+}
-function is_identifier_string(str){
+function is_identifier_string(str) {
return /^[a-z_$][a-z0-9_$]*$/i.test(str);
-};
+}
function parse_js_number(num) {
if (RE_HEX_NUMBER.test(num)) {
@@ -185,7 +197,7 @@ function parse_js_number(num) {
var val = parseFloat(num);
if (val == num) return val;
}
-};
+}
function JS_Parse_Error(message, filename, line, col, pos) {
this.message = message;
@@ -193,7 +205,7 @@ function JS_Parse_Error(message, filename, line, col, pos) {
this.line = line;
this.col = col;
this.pos = pos;
-};
+}
JS_Parse_Error.prototype = Object.create(Error.prototype);
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
JS_Parse_Error.prototype.name = "SyntaxError";
@@ -201,11 +213,11 @@ configure_error_stack(JS_Parse_Error);
function js_error(message, filename, line, col, pos) {
throw new JS_Parse_Error(message, filename, line, col, pos);
-};
+}
function is_token(token, type, val) {
return token.type == type && (val == null || token.value == val);
-};
+}
var EX_EOF = {};
@@ -227,13 +239,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
directive_stack : []
};
- function peek() { return S.text.charAt(S.pos); };
+ function peek() {
+ return S.text.charAt(S.pos);
+ }
function next(signal_eof, in_string) {
var ch = S.text.charAt(S.pos++);
if (signal_eof && !ch)
throw EX_EOF;
- if (NEWLINE_CHARS(ch)) {
+ if (NEWLINE_CHARS[ch]) {
S.newline_before = S.newline_before || !in_string;
++S.line;
S.col = 0;
@@ -246,43 +260,43 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
++S.col;
}
return ch;
- };
+ }
function forward(i) {
while (i-- > 0) next();
- };
+ }
function looking_at(str) {
return S.text.substr(S.pos, str.length) == str;
- };
+ }
function find_eol() {
var text = S.text;
for (var i = S.pos, n = S.text.length; i < n; ++i) {
var ch = text[i];
- if (NEWLINE_CHARS(ch))
+ if (NEWLINE_CHARS[ch])
return i;
}
return -1;
- };
+ }
function find(what, signal_eof) {
var pos = S.text.indexOf(what, S.pos);
if (signal_eof && pos == -1) throw EX_EOF;
return pos;
- };
+ }
function start_token() {
S.tokline = S.line;
S.tokcol = S.col;
S.tokpos = S.pos;
- };
+ }
var prev_was_dot = false;
function token(type, value, is_comment) {
- S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
- (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
- (type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
+ S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX[value]) ||
+ (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]) ||
+ (type == "punc" && PUNC_BEFORE_EXPRESSION[value]));
if (type == "punc" && value == ".") {
prev_was_dot = true;
} else if (!is_comment) {
@@ -305,35 +319,31 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
if (!is_comment) {
ret.comments_before = S.comments_before;
- S.comments_before = [];
- // make note of any newlines in the comments that came before
- for (var i = 0, len = ret.comments_before.length; i < len; i++) {
- ret.nlb = ret.nlb || ret.comments_before[i].nlb;
- }
+ ret.comments_after = S.comments_before = [];
}
S.newline_before = false;
return new AST_Token(ret);
- };
+ }
function skip_whitespace() {
- while (WHITESPACE_CHARS(peek()))
+ while (WHITESPACE_CHARS[peek()])
next();
- };
+ }
function read_while(pred) {
var ret = "", ch, i = 0;
while ((ch = peek()) && pred(ch, i++))
ret += next();
return ret;
- };
+ }
function parse_error(err) {
js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
- };
+ }
function read_num(prefix) {
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
- var num = read_while(function(ch, i){
+ var num = read_while(function(ch, i) {
var code = ch.charCodeAt(0);
switch (code) {
case 120: case 88: // xX
@@ -359,7 +369,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
} else {
parse_error("Invalid syntax: " + num);
}
- };
+ }
function read_escaped_char(in_string) {
var ch = next(true, in_string);
@@ -382,7 +392,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
if (ch >= "0" && ch <= "7")
return read_octal_escape_sequence(ch);
return ch;
- };
+ }
function read_octal_escape_sequence(ch) {
// Read
@@ -409,14 +419,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
num = (num << 4) | digit;
}
return num;
- };
+ }
- var read_string = with_eof_error("Unterminated string constant", function(quote_char){
+ var read_string = with_eof_error("Unterminated string constant", function(quote_char) {
var quote = next(), ret = "";
for (;;) {
var ch = next(true, true);
if (ch == "\\") ch = read_escaped_char(true);
- else if (NEWLINE_CHARS(ch)) parse_error("Unterminated string constant");
+ else if (NEWLINE_CHARS[ch]) parse_error("Unterminated string constant");
else if (ch == quote) break;
ret += ch;
}
@@ -439,9 +449,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
S.comments_before.push(token(type, ret, true));
S.regex_allowed = regex_allowed;
return next_token;
- };
+ }
- var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){
+ var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
var regex_allowed = S.regex_allowed;
var i = find("*/", true);
var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n');
@@ -468,16 +478,16 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
backslash = false;
}
}
- if (KEYWORDS(name) && escaped) {
+ if (KEYWORDS[name] && escaped) {
hex = name.charCodeAt(0).toString(16).toUpperCase();
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
}
return name;
- };
+ }
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)) {
+ while ((ch = next(true))) if (NEWLINE_CHARS[ch]) {
parse_error("Unexpected line terminator");
} else if (prev_backslash) {
source += "\\" + ch;
@@ -509,15 +519,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
function grow(op) {
if (!peek()) return op;
var bigger = op + peek();
- if (OPERATORS(bigger)) {
+ if (OPERATORS[bigger]) {
next();
return grow(bigger);
} else {
return op;
}
- };
+ }
return token("operator", grow(prefix || next()));
- };
+ }
function handle_slash() {
next();
@@ -530,23 +540,23 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
return skip_multiline_comment();
}
return S.regex_allowed ? read_regexp("") : read_operator("/");
- };
+ }
function handle_dot() {
next();
return is_digit(peek().charCodeAt(0))
? read_num(".")
: token("punc", ".");
- };
+ }
function read_word() {
var word = read_name();
if (prev_was_dot) return token("name", word);
- return KEYWORDS_ATOM(word) ? token("atom", word)
- : !KEYWORDS(word) ? token("name", word)
- : OPERATORS(word) ? token("operator", word)
+ return KEYWORDS_ATOM[word] ? token("atom", word)
+ : !KEYWORDS[word] ? token("name", word)
+ : OPERATORS[word] ? token("operator", word)
: token("keyword", word);
- };
+ }
function with_eof_error(eof_error, cont) {
return function(x) {
@@ -557,7 +567,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
else throw ex;
}
};
- };
+ }
function next_token(force_regexp) {
if (force_regexp != null)
@@ -595,13 +605,13 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
}
if (is_digit(code)) return read_num();
- if (PUNC_CHARS(ch)) return token("punc", next());
- if (OPERATOR_CHARS(ch)) return read_operator();
+ if (PUNC_CHARS[ch]) return token("punc", next());
+ if (OPERATOR_CHARS[ch]) return read_operator();
if (code == 92 || is_identifier_start(code)) return read_word();
break;
}
parse_error("Unexpected character '" + ch + "'");
- };
+ }
next_token.context = function(nc) {
if (nc) S = nc;
@@ -637,8 +647,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
return next_token;
-
-};
+}
/* -----[ Parser (constants) ]----- */
@@ -658,7 +667,7 @@ var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
-var PRECEDENCE = (function(a, ret){
+var PRECEDENCE = function(a, ret) {
for (var i = 0; i < a.length; ++i) {
var b = a[i];
for (var j = 0; j < b.length; ++j) {
@@ -666,28 +675,24 @@ var PRECEDENCE = (function(a, ret){
}
}
return ret;
-})(
- [
- ["||"],
- ["&&"],
- ["|"],
- ["^"],
- ["&"],
- ["==", "===", "!=", "!=="],
- ["<", ">", "<=", ">=", "in", "instanceof"],
- [">>", "<<", ">>>"],
- ["+", "-"],
- ["*", "/", "%"]
- ],
- {}
-);
+}([
+ ["||"],
+ ["&&"],
+ ["|"],
+ ["^"],
+ ["&"],
+ ["==", "===", "!=", "!=="],
+ ["<", ">", "<=", ">=", "in", "instanceof"],
+ [">>", "<<", ">>>"],
+ ["+", "-"],
+ ["*", "/", "%"]
+], {});
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
/* -----[ Parser ]----- */
function parse($TEXT, options) {
-
options = defaults(options, {
bare_returns : false,
expression : false,
@@ -716,9 +721,11 @@ function parse($TEXT, options) {
function is(type, value) {
return is_token(S.token, type, value);
- };
+ }
- function peek() { return S.peeked || (S.peeked = S.input()); };
+ function peek() {
+ return S.peeked || (S.peeked = S.input());
+ }
function next() {
S.prev = S.token;
@@ -732,11 +739,11 @@ function parse($TEXT, options) {
S.token.type == "string" || is("punc", ";")
);
return S.token;
- };
+ }
function prev() {
return S.prev;
- };
+ }
function croak(msg, line, col, pos) {
var ctx = S.input.context();
@@ -745,74 +752,81 @@ function parse($TEXT, options) {
line != null ? line : ctx.tokline,
col != null ? col : ctx.tokcol,
pos != null ? pos : ctx.tokpos);
- };
+ }
function token_error(token, msg) {
croak(msg, token.line, token.col);
- };
+ }
function unexpected(token) {
if (token == null)
token = S.token;
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
- };
+ }
function expect_token(type, val) {
if (is(type, val)) {
return next();
}
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
- };
+ }
+
+ function expect(punc) {
+ return expect_token("punc", punc);
+ }
- function expect(punc) { return expect_token("punc", punc); };
+ function has_newline_before(token) {
+ return token.nlb || !all(token.comments_before, function(comment) {
+ return !comment.nlb;
+ });
+ }
function can_insert_semicolon() {
- return !options.strict && (
- S.token.nlb || is("eof") || is("punc", "}")
- );
- };
+ return !options.strict
+ && (is("eof") || is("punc", "}") || has_newline_before(S.token));
+ }
function semicolon(optional) {
if (is("punc", ";")) next();
else if (!optional && !can_insert_semicolon()) unexpected();
- };
+ }
function parenthesised() {
expect("(");
var exp = expression(true);
expect(")");
return exp;
- };
+ }
function embed_tokens(parser) {
return function() {
var start = S.token;
- var expr = parser();
+ var expr = parser.apply(null, arguments);
var end = prev();
expr.start = start;
expr.end = end;
return expr;
};
- };
+ }
function handle_regexp() {
if (is("operator", "/") || is("operator", "/=")) {
S.peeked = null;
S.token = S.input(S.token.value.substr(1)); // force regexp
}
- };
+ }
- var statement = embed_tokens(function() {
+ var statement = embed_tokens(function(strict_defun) {
handle_regexp();
switch (S.token.type) {
case "string":
if (S.in_directives) {
var token = peek();
if (S.token.raw.indexOf("\\") == -1
- && (token.nlb
- || is_token(token, "eof")
- || is_token(token, "punc", ";")
- || is_token(token, "punc", "}"))) {
+ && (is_token(token, "punc", ";")
+ || is_token(token, "punc", "}")
+ || has_newline_before(token)
+ || is_token(token, "eof"))) {
S.input.add_directive(S.token.value);
} else {
S.in_directives = false;
@@ -888,6 +902,9 @@ function parse($TEXT, options) {
return for_();
case "function":
+ if (!strict_defun && S.input.has_directive("use strict")) {
+ croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
+ }
next();
return function_(AST_Defun);
@@ -919,7 +936,7 @@ function parse($TEXT, options) {
case "throw":
next();
- if (S.token.nlb)
+ if (has_newline_before(S.token))
croak("Illegal newline after 'throw'");
var value = expression(true);
semicolon();
@@ -953,7 +970,9 @@ function parse($TEXT, options) {
function labeled_statement() {
var label = as_symbol(AST_Label);
- if (find_if(function(l){ return l.name == label.name }, S.labels)) {
+ if (!all(S.labels, function(l) {
+ return l.name != label.name;
+ })) {
// ECMA-262, 12.12: An ECMAScript program is considered
// syntactically incorrect if it contains a
// LabelledStatement that is enclosed by a
@@ -968,7 +987,7 @@ function parse($TEXT, options) {
// check for `continue` that refers to this label.
// those should be reported as syntax errors.
// https://github.com/mishoo/UglifyJS2/issues/287
- label.references.forEach(function(ref){
+ label.references.forEach(function(ref) {
if (ref instanceof AST_Continue) {
ref = ref.label.start;
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
@@ -977,11 +996,11 @@ function parse($TEXT, options) {
});
}
return new AST_LabeledStatement({ body: stat, label: label });
- };
+ }
function simple_statement(tmp) {
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
- };
+ }
function break_cont(type) {
var label = null, ldef;
@@ -989,18 +1008,17 @@ function parse($TEXT, options) {
label = as_symbol(AST_LabelRef, true);
}
if (label != null) {
- ldef = find_if(function(l){ return l.name == label.name }, S.labels);
- if (!ldef)
- croak("Undefined label " + label.name);
+ ldef = find_if(function(l) {
+ return l.name == label.name;
+ }, S.labels);
+ if (!ldef) croak("Undefined label " + label.name);
label.thedef = ldef;
- }
- else if (S.in_loop == 0)
- croak(type.TYPE + " not inside a loop or switch");
+ } else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
semicolon();
var stat = new type({ label: label });
if (ldef) ldef.references.push(stat);
return stat;
- };
+ }
function for_() {
expect("(");
@@ -1021,7 +1039,7 @@ function parse($TEXT, options) {
}
}
return regular_for(init);
- };
+ }
function regular_for(init) {
expect(";");
@@ -1035,19 +1053,17 @@ function parse($TEXT, options) {
step : step,
body : in_loop(statement)
});
- };
+ }
function for_in(init) {
- var lhs = init instanceof AST_Var ? init.definitions[0].name : null;
var obj = expression(true);
expect(")");
return new AST_ForIn({
init : init,
- name : lhs,
object : obj,
body : in_loop(statement)
});
- };
+ }
var function_ = function(ctor) {
var in_statement = ctor === AST_Defun;
@@ -1070,7 +1086,7 @@ function parse($TEXT, options) {
S.input.push_directives_stack();
S.in_loop = 0;
S.labels = [];
- var body = block_();
+ var body = block_(true);
if (S.input.has_directive("use strict")) {
if (name) strict_verify_symbol(name);
argnames.forEach(strict_verify_symbol);
@@ -1097,18 +1113,18 @@ function parse($TEXT, options) {
body : body,
alternative : belse
});
- };
+ }
- function block_() {
+ function block_(strict_defun) {
expect("{");
var a = [];
while (!is("punc", "}")) {
if (is("eof")) unexpected();
- a.push(statement());
+ a.push(statement(strict_defun));
}
next();
return a;
- };
+ }
function switch_body_() {
expect("{");
@@ -1143,7 +1159,7 @@ function parse($TEXT, options) {
if (branch) branch.end = prev();
next();
return a;
- };
+ }
function try_() {
var body = block_(), bcatch = null, bfinally = null;
@@ -1176,7 +1192,7 @@ function parse($TEXT, options) {
bcatch : bcatch,
bfinally : bfinally
});
- };
+ }
function vardefs(no_in) {
var a = [];
@@ -1192,7 +1208,7 @@ function parse($TEXT, options) {
next();
}
return a;
- };
+ }
var var_ = function(no_in) {
return new AST_Var({
@@ -1212,12 +1228,14 @@ function parse($TEXT, options) {
} else {
args = [];
}
- return subscripts(new AST_New({
+ var call = new AST_New({
start : start,
expression : newexp,
args : args,
end : prev()
- }), allow_calls);
+ });
+ mark_pure(call);
+ return subscripts(call, allow_calls);
};
function as_atom_node() {
@@ -1256,7 +1274,7 @@ function parse($TEXT, options) {
}
next();
return ret;
- };
+ }
var expr_atom = function(allow_calls) {
if (is("operator", "new")) {
@@ -1268,9 +1286,26 @@ function parse($TEXT, options) {
case "(":
next();
var ex = expression(true);
+ var len = start.comments_before.length;
+ [].unshift.apply(ex.start.comments_before, start.comments_before);
+ start.comments_before = ex.start.comments_before;
+ start.comments_before_length = len;
+ if (len == 0 && start.comments_before.length > 0) {
+ var comment = start.comments_before[0];
+ if (!comment.nlb) {
+ comment.nlb = start.nlb;
+ start.nlb = false;
+ }
+ }
+ start.comments_after = ex.start.comments_after;
ex.start = start;
- ex.end = S.token;
expect(")");
+ var end = prev();
+ end.comments_before = ex.end.comments_before;
+ [].push.apply(ex.end.comments_after, end.comments_after);
+ end.comments_after = ex.end.comments_after;
+ ex.end = end;
+ if (ex instanceof AST_Call) mark_pure(ex);
return subscripts(ex, allow_calls);
case "[":
return subscripts(array_(), allow_calls);
@@ -1286,7 +1321,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();
@@ -1305,7 +1340,7 @@ function parse($TEXT, options) {
}
next();
return a;
- };
+ }
var array_ = embed_tokens(function() {
expect("[");
@@ -1332,7 +1367,7 @@ function parse($TEXT, options) {
if (type == "name" && !is("punc", ":")) {
var key = new AST_SymbolAccessor({
start: S.token,
- name: as_property_name(),
+ name: "" + as_property_name(),
end: prev()
});
if (name == "get") {
@@ -1358,7 +1393,7 @@ function parse($TEXT, options) {
a.push(new AST_ObjectKeyVal({
start : start,
quote : start.quote,
- key : name,
+ key : "" + name,
value : expression(false),
end : prev()
}));
@@ -1371,7 +1406,7 @@ function parse($TEXT, options) {
var tmp = S.token;
switch (tmp.type) {
case "operator":
- if (!KEYWORDS(tmp.value)) unexpected();
+ if (!KEYWORDS[tmp.value]) unexpected();
case "num":
case "string":
case "name":
@@ -1382,14 +1417,14 @@ function parse($TEXT, options) {
default:
unexpected();
}
- };
+ }
function as_name() {
var tmp = S.token;
if (tmp.type != "name") unexpected();
next();
return tmp.value;
- };
+ }
function _make_symbol(type) {
var name = S.token.value;
@@ -1398,7 +1433,7 @@ function parse($TEXT, options) {
start : S.token,
end : S.token
});
- };
+ }
function strict_verify_symbol(sym) {
if (sym.name == "arguments" || sym.name == "eval")
@@ -1416,7 +1451,20 @@ function parse($TEXT, options) {
}
next();
return sym;
- };
+ }
+
+ function mark_pure(call) {
+ var start = call.start;
+ var comments = start.comments_before;
+ var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
+ while (--i >= 0) {
+ var comment = comments[i];
+ if (/[@#]__PURE__/.test(comment.value)) {
+ call.pure = comment;
+ break;
+ }
+ }
+ }
var subscripts = function(expr, allow_calls) {
var start = expr.start;
@@ -1442,19 +1490,21 @@ function parse($TEXT, options) {
}
if (allow_calls && is("punc", "(")) {
next();
- return subscripts(new AST_Call({
+ var call = new AST_Call({
start : start,
expression : expr,
args : expr_list(")"),
end : prev()
- }), true);
+ });
+ mark_pure(call);
+ return subscripts(call, true);
}
return expr;
};
var maybe_unary = function(allow_calls) {
var start = S.token;
- if (is("operator") && UNARY_PREFIX(start.value)) {
+ if (is("operator") && UNARY_PREFIX[start.value]) {
next();
handle_regexp();
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
@@ -1463,7 +1513,7 @@ function parse($TEXT, options) {
return ex;
}
var val = expr_atom(allow_calls);
- while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
+ while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
val = make_unary(AST_UnaryPostfix, S.token, val);
val.start = start;
val.end = S.token;
@@ -1486,7 +1536,7 @@ function parse($TEXT, options) {
break;
}
return new ctor({ operator: op, expression: expr });
- };
+ }
var expr_op = function(left, min_prec, no_in) {
var op = is("operator") ? S.token.value : null;
@@ -1508,7 +1558,7 @@ function parse($TEXT, options) {
function expr_ops(no_in) {
return expr_op(maybe_unary(true), 0, no_in);
- };
+ }
var maybe_conditional = function(no_in) {
var start = S.token;
@@ -1530,12 +1580,12 @@ function parse($TEXT, options) {
function is_assignable(expr) {
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
- };
+ }
var maybe_assign = function(no_in) {
var start = S.token;
var left = maybe_conditional(no_in), val = S.token.value;
- if (is("operator") && ASSIGNMENT(val)) {
+ if (is("operator") && ASSIGNMENT[val]) {
if (is_assignable(left)) {
next();
return new AST_Assign({
@@ -1572,18 +1622,18 @@ function parse($TEXT, options) {
var ret = cont();
--S.in_loop;
return ret;
- };
+ }
if (options.expression) {
return expression(true);
}
- return (function(){
+ return function() {
var start = S.token;
var body = [];
S.input.push_directives_stack();
while (!is("eof"))
- body.push(statement());
+ body.push(statement(true));
S.input.pop_directives_stack();
var end = prev();
var toplevel = options.toplevel;
@@ -1594,6 +1644,5 @@ function parse($TEXT, options) {
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
}
return toplevel;
- })();
-
-};
+ }();
+}