aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMihai Bazon <mihai@bazon.net>2012-09-19 12:27:38 +0300
committerMihai Bazon <mihai@bazon.net>2012-09-19 12:27:38 +0300
commite8da72d304778cdaf4570f24838effee73f6b993 (patch)
tree7213ba7a34f620e7e3572149d3476ecab4da2b1b /lib
parentd53e1a9931d29c875d2bb23e50a2d2f535b01890 (diff)
downloadtracifyjs-e8da72d304778cdaf4570f24838effee73f6b993.tar.gz
tracifyjs-e8da72d304778cdaf4570f24838effee73f6b993.zip
drop unused variables
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js55
-rw-r--r--lib/scope.js3
2 files changed, 56 insertions, 2 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 9d5dac17..834cc388 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -65,6 +65,7 @@ function Compressor(options, false_by_default) {
booleans : !false_by_default,
loops : !false_by_default,
unused_func : !false_by_default,
+ unused_vars : !false_by_default,
hoist_funs : !false_by_default,
hoist_vars : !false_by_default,
if_return : !false_by_default,
@@ -222,6 +223,9 @@ function Compressor(options, false_by_default) {
// step. nevertheless, it's good to check.
continue loop;
case stat instanceof AST_If:
+ // compressor.warn("Current if: {code}", {
+ // code: stat.condition.print_to_string()
+ // });
if (stat.body instanceof AST_Return) {
//---
// pretty silly case, but:
@@ -692,7 +696,7 @@ function Compressor(options, false_by_default) {
});
def(AST_Binary, function(){
return this.left.has_side_effects()
- || this.right.has_side_effects ();
+ || this.right.has_side_effects();
});
def(AST_Assign, function(){ return true });
def(AST_Conditional, function(){
@@ -721,6 +725,13 @@ function Compressor(options, false_by_default) {
return true;
return false;
});
+ def(AST_Dot, function(){
+ return this.expression.has_side_effects();
+ });
+ def(AST_Sub, function(){
+ return this.expression.has_side_effects()
+ || this.property.has_side_effects();
+ });
})(function(node, func){
node.DEFMETHOD("has_side_effects", func);
});
@@ -793,9 +804,49 @@ function Compressor(options, false_by_default) {
return self;
});
+ AST_Scope.DEFMETHOD("drop_unused_vars", function(compressor){
+ if (compressor.option("unused_vars")) {
+ var self = this;
+ var tw = new TreeWalker(function(node){
+ if (node !== self) {
+ if (node instanceof AST_Scope)
+ return true; // don't go in nested scopes
+ if (node instanceof AST_Definitions) {
+ if (!(tw.parent() instanceof AST_ForIn)) {
+ var a = node.definitions;
+ for (var i = a.length; --i >= 0;) {
+ var def = a[i];
+ var sym = def.name;
+ if (sym.unreferenced()) {
+ var warn = {
+ name: sym.name,
+ line: sym.start.line,
+ col: sym.start.col
+ };
+ if (def.value && def.value.has_side_effects()) {
+ compressor.warn("Side effects in initialization of unreferenced variable {name} [{line},{col}]", warn);
+ } else {
+ compressor.warn("Dropping unreferenced variable {name} [{line},{col}]", warn);
+ a.splice(i, 1);
+ }
+ }
+ }
+ }
+ return true;
+ }
+ if (!(node instanceof AST_Statement)) {
+ return true; // pointless to visit expressions
+ }
+ }
+ });
+ this.walk(tw);
+ }
+ });
+
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
var hoist_funs = compressor.option("hoist_funs");
var hoist_vars = compressor.option("hoist_vars");
+ this.drop_unused_vars(compressor);
if (hoist_funs || hoist_vars) {
var self = this;
var hoisted = [];
@@ -1161,6 +1212,8 @@ function Compressor(options, false_by_default) {
});
SQUEEZE(AST_Definitions, function(self, compressor){
+ if (self.definitions.length == 0)
+ return make_node(AST_EmptyStatement, self);
if (self.hoisted) {
var seq = self.to_assignments();
var p = compressor.parent();
diff --git a/lib/scope.js b/lib/scope.js
index 0e615eb8..196af91c 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -296,7 +296,8 @@ AST_Label.DEFMETHOD("unmangleable", function(){
});
AST_Symbol.DEFMETHOD("unreferenced", function(){
- return this.definition().references.length == 0;
+ return this.definition().references.length == 0
+ && !(this.scope.uses_eval || this.scope.uses_with);
});
AST_Symbol.DEFMETHOD("undeclared", function(){