cleanup
authorMihai Bazon <mihai@bazon.net>
Thu, 11 Oct 2012 08:07:42 +0000 (11:07 +0300)
committerMihai Bazon <mihai@bazon.net>
Thu, 11 Oct 2012 08:07:42 +0000 (11:07 +0300)
- use prototype-less objects where feasible (minor speed improvement)
- get rid of HOP

lib/ast.js
lib/compress.js
lib/parse.js
lib/scope.js
lib/utils.js

index 529660f..f90223e 100644 (file)
@@ -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 {
index cace6f6..dadebe5 100644 (file)
@@ -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) {
index 2dfb76a..65bde14 100644 (file)
@@ -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({
index 40237b3..acc6fa2 100644 (file)
@@ -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() {
index 83e514a..33dc8ff 100644 (file)
@@ -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);
     };