diff options
Diffstat (limited to 'lib/parse.js')
-rw-r--r-- | lib/parse.js | 209 |
1 files changed, 104 insertions, 105 deletions
diff --git a/lib/parse.js b/lib/parse.js index 21c89676..29df370c 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -130,7 +130,7 @@ 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") @@ -146,11 +146,11 @@ function is_surrogate_pair_tail(code) { 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)); @@ -158,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); -}; +} function is_identifier_start(code) { return code == 36 || code == 95 || is_letter(code); -}; +} function is_identifier_char(ch) { var code = ch.charCodeAt(0); @@ -182,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)) { @@ -197,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; @@ -205,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"; @@ -213,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 = {}; @@ -239,7 +239,9 @@ 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++); @@ -258,15 +260,15 @@ 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; @@ -276,19 +278,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { 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) { @@ -321,27 +323,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { } S.newline_before = false; return new AST_Token(ret); - }; + } function skip_whitespace() { 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 @@ -367,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); @@ -390,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 @@ -417,9 +419,9 @@ 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); @@ -447,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'); @@ -481,7 +483,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { 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; @@ -523,9 +525,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { } else { return op; } - }; + } return token("operator", grow(prefix || next())); - }; + } function handle_slash() { next(); @@ -538,14 +540,14 @@ 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(); @@ -554,7 +556,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { : !KEYWORDS[word] ? token("name", word) : OPERATORS[word] ? token("operator", word) : token("keyword", word); - }; + } function with_eof_error(eof_error, cont) { return function(x) { @@ -565,7 +567,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { else throw ex; } }; - }; + } function next_token(force_regexp) { if (force_regexp != null) @@ -609,7 +611,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { break; } parse_error("Unexpected character '" + ch + "'"); - }; + } next_token.context = function(nc) { if (nc) S = nc; @@ -645,8 +647,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { } return next_token; - -}; +} /* -----[ Parser (constants) ]----- */ @@ -666,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) { @@ -674,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, @@ -724,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; @@ -740,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(); @@ -753,26 +752,28 @@ 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) { @@ -783,19 +784,19 @@ function parse($TEXT, options) { function can_insert_semicolon() { 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() { @@ -806,14 +807,14 @@ function parse($TEXT, options) { 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(strict_defun) { handle_regexp(); @@ -986,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.", @@ -995,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; @@ -1007,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("("); @@ -1039,7 +1039,7 @@ function parse($TEXT, options) { } } return regular_for(init); - }; + } function regular_for(init) { expect(";"); @@ -1053,7 +1053,7 @@ function parse($TEXT, options) { step : step, body : in_loop(statement) }); - }; + } function for_in(init) { var obj = expression(true); @@ -1063,7 +1063,7 @@ function parse($TEXT, options) { object : obj, body : in_loop(statement) }); - }; + } var function_ = function(ctor) { var in_statement = ctor === AST_Defun; @@ -1113,7 +1113,7 @@ function parse($TEXT, options) { body : body, alternative : belse }); - }; + } function block_(strict_defun) { expect("{"); @@ -1124,7 +1124,7 @@ function parse($TEXT, options) { } next(); return a; - }; + } function switch_body_() { expect("{"); @@ -1159,7 +1159,7 @@ function parse($TEXT, options) { if (branch) branch.end = prev(); next(); return a; - }; + } function try_() { var body = block_(), bcatch = null, bfinally = null; @@ -1192,7 +1192,7 @@ function parse($TEXT, options) { bcatch : bcatch, bfinally : bfinally }); - }; + } function vardefs(no_in) { var a = []; @@ -1208,7 +1208,7 @@ function parse($TEXT, options) { next(); } return a; - }; + } var var_ = function(no_in) { return new AST_Var({ @@ -1274,7 +1274,7 @@ function parse($TEXT, options) { } next(); return ret; - }; + } var expr_atom = function(allow_calls) { if (is("operator", "new")) { @@ -1340,7 +1340,7 @@ function parse($TEXT, options) { } next(); return a; - }; + } var array_ = embed_tokens(function() { expect("["); @@ -1417,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; @@ -1433,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") @@ -1451,7 +1451,7 @@ function parse($TEXT, options) { } next(); return sym; - }; + } function mark_pure(call) { var start = call.start; @@ -1536,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; @@ -1558,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; @@ -1580,7 +1580,7 @@ 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; @@ -1622,13 +1622,13 @@ 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(); @@ -1644,6 +1644,5 @@ function parse($TEXT, options) { toplevel = new AST_Toplevel({ start: start, body: body, end: end }); } return toplevel; - })(); - -}; + }(); +} |