From: Mihai Bazon Date: Thu, 11 Oct 2012 08:07:42 +0000 (+0300) Subject: cleanup X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=172aa7a93ccd39feceefa058ad008e19eec0a073;p=UglifyJS.git cleanup - use prototype-less objects where feasible (minor speed improvement) - get rid of HOP --- diff --git a/lib/ast.js b/lib/ast.js index 529660fe..f90223ec 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -73,7 +73,7 @@ function DEFNODE(type, props, methods, base) { if (type) { ctor.prototype.TYPE = ctor.TYPE = type; } - if (methods) for (i in methods) if (HOP(methods, i)) { + if (methods) for (i in methods) if (methods.hasOwnProperty(i)) { if (/^\$/.test(i)) { ctor[i.substr(1)] = methods[i]; } else { diff --git a/lib/compress.js b/lib/compress.js index cace6f68..dadebe5e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1449,7 +1449,7 @@ merge(Compressor.prototype, { OPT(AST_SymbolRef, function(self, compressor){ if (self.undeclared()) { var defines = compressor.option("global_defs"); - if (defines && HOP(defines, self.name)) { + if (defines && defines.hasOwnProperty(self.name)) { return make_node_from_constant(compressor, defines[self.name], self); } switch (self.name) { diff --git a/lib/parse.js b/lib/parse.js index 2dfb76a6..65bde146 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -215,9 +215,9 @@ function is_unicode_connector_punctuation(ch) { function is_identifier(name) { return /^[a-z_$][a-z0-9_$]*$/i.test(name) && name != "this" - && !HOP(KEYWORDS_ATOM, name) - && !HOP(RESERVED_WORDS, name) - && !HOP(KEYWORDS, name); + && !KEYWORDS_ATOM[name] + && !RESERVED_WORDS[name] + && !KEYWORDS[name]; }; function is_identifier_start(ch) { @@ -317,9 +317,9 @@ function tokenizer($TEXT, filename) { }; function token(type, value, is_comment) { - S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) || - (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) || - (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value))); + S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX[value]) || + (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]) || + (type == "punc" && PUNC_BEFORE_EXPRESSION[value])); var ret = { type : type, value : value, @@ -343,7 +343,7 @@ function tokenizer($TEXT, filename) { }; function skip_whitespace() { - while (HOP(WHITESPACE_CHARS, peek())) + while (WHITESPACE_CHARS[peek()]) next(); }; @@ -493,7 +493,7 @@ function tokenizer($TEXT, filename) { backslash = false; } } - if (HOP(KEYWORDS, name) && escaped) { + if (KEYWORDS[name] && escaped) { hex = name.charCodeAt(0).toString(16).toUpperCase(); name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1); } @@ -528,7 +528,7 @@ function tokenizer($TEXT, filename) { function grow(op) { if (!peek()) return op; var bigger = op + peek(); - if (HOP(OPERATORS, bigger)) { + if (OPERATORS[bigger]) { next(); return grow(bigger); } else { @@ -563,11 +563,11 @@ function tokenizer($TEXT, filename) { function read_word() { var word = read_name(); - return HOP(KEYWORDS_ATOM, word) + return KEYWORDS_ATOM[word] ? token("atom", word) - : !HOP(KEYWORDS, word) + : !KEYWORDS[word] ? token("name", word) - : HOP(OPERATORS, word) + : OPERATORS[word] ? token("operator", word) : token("keyword", word); }; @@ -590,10 +590,10 @@ function tokenizer($TEXT, filename) { if (!ch) return token("eof"); if (is_digit(ch)) return read_num(); if (ch == '"' || ch == "'") return read_string(); - if (HOP(PUNC_CHARS, ch)) return token("punc", next()); + if (PUNC_CHARS[ch]) return token("punc", next()); if (ch == ".") return handle_dot(); if (ch == "/") return handle_slash(); - if (HOP(OPERATOR_CHARS, ch)) return read_operator(); + if (OPERATOR_CHARS[ch]) return read_operator(); if (ch == "\\" || is_identifier_start(ch)) return read_word(); parse_error("Unexpected character '" + ch + "'"); }; @@ -1200,7 +1200,7 @@ function parse($TEXT, options) { func.end = prev(); return subscripts(func, allow_calls); } - if (HOP(ATOMIC_START_TOKEN, S.token.type)) { + if (ATOMIC_START_TOKEN[S.token.type]) { return subscripts(as_atom_node(), allow_calls); } unexpected(); @@ -1348,7 +1348,7 @@ function parse($TEXT, options) { var maybe_unary = function(allow_calls) { var start = S.token; - if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) { + if (is("operator") && UNARY_PREFIX[S.token.value]) { var ex = make_unary(AST_UnaryPrefix, prog1(S.token.value, next), maybe_unary(allow_calls)); @@ -1357,7 +1357,7 @@ function parse($TEXT, options) { return ex; } var val = expr_atom(allow_calls); - while (is("operator") && HOP(UNARY_POSTFIX, S.token.value) && !S.token.nlb) { + while (is("operator") && UNARY_POSTFIX[S.token.value] && !S.token.nlb) { val = make_unary(AST_UnaryPostfix, S.token.value, val); val.start = start; val.end = S.token; @@ -1428,7 +1428,7 @@ function parse($TEXT, options) { var maybe_assign = function(no_in) { var start = S.token; var left = maybe_conditional(no_in), val = S.token.value; - if (is("operator") && HOP(ASSIGNMENT, val)) { + if (is("operator") && ASSIGNMENT[val]) { if (is_assignable(left)) { next(); return new AST_Assign({ diff --git a/lib/scope.js b/lib/scope.js index 40237b39..acc6fa25 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -75,7 +75,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){ // pass 1: setup scope chaining and handle definitions var self = this; var scope = self.parent_scope = null; - var labels = {}; + var labels = Object.create(null); var tw = new TreeWalker(function(node, descend){ if (node instanceof AST_Scope) { node.init_scope_vars(); @@ -157,7 +157,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){ // pass 2: find back references and eval var func = null; - var globals = self.globals = {}; + var globals = self.globals = Object.create(null); var tw = new TreeWalker(function(node, descend){ if (node instanceof AST_Lambda) { var prev_func = func; @@ -175,7 +175,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){ var sym = node.scope.find_variable(name); if (!sym) { var g; - if (HOP(globals, name)) { + if (globals[name]) { g = globals[name]; } else { g = new SymbolDef(self, node); @@ -202,8 +202,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){ AST_Scope.DEFMETHOD("init_scope_vars", function(){ this.directives = []; // contains the directives defined in this scope, i.e. "use strict" - this.variables = {}; // map name to AST_SymbolVar (variables defined in this scope; includes functions) - this.functions = {}; // map name to AST_SymbolDefun (functions defined in this scope) + this.variables = Object.create(null); // map name to AST_SymbolVar (variables defined in this scope; includes functions) + this.functions = Object.create(null); // map name to AST_SymbolDefun (functions defined in this scope) this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` this.parent_scope = null; // the parent scope @@ -245,9 +245,8 @@ AST_LabelRef.DEFMETHOD("reference", function(){ AST_Scope.DEFMETHOD("find_variable", function(name){ if (name instanceof AST_Symbol) name = name.name; - return HOP(this.variables, name) - ? this.variables[name] - : (this.parent_scope && this.parent_scope.find_variable(name)); + return this.variables[name] + || (this.parent_scope && this.parent_scope.find_variable(name)); }); AST_Scope.DEFMETHOD("has_directive", function(value){ @@ -261,7 +260,7 @@ AST_Scope.DEFMETHOD("def_function", function(symbol){ AST_Scope.DEFMETHOD("def_variable", function(symbol){ var def; - if (!HOP(this.variables, symbol.name)) { + if (!this.variables[symbol.name]) { def = new SymbolDef(this, symbol); this.variables[symbol.name] = def; def.global = !this.parent_scope; @@ -351,7 +350,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){ var p = tw.parent(); var is_setget = p instanceof AST_ObjectSetter || p instanceof AST_ObjectGetter; var a = node.variables; - for (var i in a) if (HOP(a, i)) { + for (var i in a) { var symbol = a[i]; if (!(is_setget && symbol instanceof AST_SymbolLambda)) { if (options.except.indexOf(symbol.name) < 0) { @@ -450,15 +449,14 @@ var base54 = (function() { var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; var chars, frequency; function reset() { - frequency = {}; + frequency = Object.create(null); chars = string.split(""); chars.map(function(ch){ frequency[ch] = 0 }); } base54.consider = function(str){ for (var i = str.length; --i >= 0;) { var ch = str.charAt(i); - if (string.indexOf(ch) >= 0) - ++frequency[ch]; + ++frequency[ch]; } }; base54.sort = function() { diff --git a/lib/utils.js b/lib/utils.js index 83e514a4..33dc8ff2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -57,7 +57,7 @@ function prog1(ret) { }; function array_to_hash(a) { - var ret = {}; + var ret = Object.create(null); for (var i = 0; i < a.length; ++i) ret[a[i]] = true; return ret; @@ -85,10 +85,6 @@ function find_if(func, array) { } }; -function HOP(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -}; - function repeat_string(str, i) { if (i <= 0) return ""; if (i == 1) return str; @@ -107,16 +103,16 @@ function defaults(args, defs, croak) { if (args === true) args = {}; var ret = args || {}; - if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) + if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i)) throw new DefaultsError("`" + i + "` is not a supported option", defs); - for (var i in defs) if (HOP(defs, i)) { - ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; + for (var i in defs) if (defs.hasOwnProperty(i)) { + ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i]; } return ret; }; function merge(obj, ext) { - for (var i in ext) if (HOP(ext, i)) { + for (var i in ext) if (ext.hasOwnProperty(i)) { obj[i] = ext[i]; } return obj; @@ -158,7 +154,7 @@ var MAP = (function(){ } } else { - for (i in a) if (HOP(a, i)) if (doit()) break; + for (i in a) if (a.hasOwnProperty(i)) if (doit()) break; } return top.concat(ret); };