warn about unreferenced symbols
authorMihai Bazon <mihai@bazon.net>
Tue, 21 Aug 2012 08:53:19 +0000 (11:53 +0300)
committerMihai Bazon <mihai@bazon.net>
Tue, 21 Aug 2012 09:07:34 +0000 (12:07 +0300)
lib/output.js
lib/scope.js

index e6b2dd1..0d6518d 100644 (file)
@@ -806,11 +806,8 @@ function OutputStream(options) {
         output.print_name(self.name);
     });
     DEFPRINT(AST_SymbolDeclaration, function(self, output){
-        if (self.uniq) {
-            self.uniq.print(output);
-        } else {
-            output.print_name(self.mangled_name || self.name);
-        }
+        var def = self.definition();
+        output.print_name(def.mangled_name || def.name);
     });
     DEFPRINT(AST_SymbolRef, function(self, output){
         var def = self.symbol;
index c6d655e..00bdcb0 100644 (file)
@@ -76,7 +76,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
 
 AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
     options = defaults(options, {
-        undeclared       : false,
+        undeclared       : false, // this makes a lot of noise
+        unreferenced     : true,
         assign_to_global : true,
         eval             : true
     });
@@ -114,6 +115,16 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
             && node.name == "eval") {
             AST_Node.warn("Eval is used [{line},{col}]", node.start);
         }
+        if (options.unreferenced
+            && node instanceof AST_SymbolDeclaration
+            && node.unreferenced()) {
+            AST_Node.warn("{type} {name} is declared but not referenced [{line},{col}]", {
+                type: node instanceof AST_Label ? "Label" : "Symbol",
+                name: node.name,
+                line: node.start.line,
+                col: node.start.col
+            });
+        }
     });
     this.walk(tw);
 });
@@ -207,6 +218,14 @@ AST_SymbolDeclaration.DEFMETHOD("mangle", function(){
     }
 });
 
+AST_SymbolDeclaration.DEFMETHOD("unreferenced", function(){
+    return this.definition().references.length == 0;
+});
+
+AST_SymbolDeclaration.DEFMETHOD("definition", function(){
+    return this.uniq || this;
+});
+
 AST_Toplevel.DEFMETHOD("mangle_names", function(){
     var tw = new TreeWalker(function(node){
         // We only need to mangle declarations.  Special logic wired