Support @ngInject with `angular` compressor option. Close #395.
authorMihai Bazon <mihai@bazon.net>
Wed, 8 Jan 2014 09:28:32 +0000 (11:28 +0200)
committerMihai Bazon <mihai@bazon.net>
Wed, 8 Jan 2014 09:28:32 +0000 (11:28 +0200)
lib/compress.js

index 7fdc8f2..488818c 100644 (file)
@@ -71,6 +71,7 @@ function Compressor(options, false_by_default) {
         negate_iife   : !false_by_default,
         screw_ie8     : false,
         drop_console  : false,
+        angular       : false,
 
         warnings      : true,
         global_defs   : {}
@@ -211,6 +212,9 @@ merge(Compressor.prototype, {
             if (compressor.option("join_vars")) {
                 statements = join_consecutive_vars(statements, compressor);
             }
+            if (compressor.option("angular")) {
+                statements = process_for_angular(statements);
+            }
         } while (CHANGED);
 
         if (compressor.option("negate_iife")) {
@@ -219,6 +223,50 @@ merge(Compressor.prototype, {
 
         return statements;
 
+        function process_for_angular(statements) {
+            function make_injector(func, name) {
+                return make_node(AST_SimpleStatement, func, {
+                    body: make_node(AST_Assign, func, {
+                        operator: "=",
+                        left: make_node(AST_Dot, name, {
+                            expression: make_node(AST_SymbolRef, name, name),
+                            property: "$inject"
+                        }),
+                        right: make_node(AST_Array, func, {
+                            elements: func.argnames.map(function(sym){
+                                return make_node(AST_String, sym, { value: sym.name });
+                            })
+                        })
+                    })
+                });
+            }
+            return statements.reduce(function(a, stat){
+                a.push(stat);
+                var token = stat.start;
+                var comments = token.comments_before;
+                if (comments && comments.length > 0) {
+                    var last = comments.pop();
+                    if (/@ngInject/.test(last.value)) {
+                        // case 1: defun
+                        if (stat instanceof AST_Defun) {
+                            a.push(make_injector(stat, stat.name));
+                        }
+                        else if (stat instanceof AST_Definitions) {
+                            stat.definitions.forEach(function(def){
+                                if (def.value && def.value instanceof AST_Lambda) {
+                                    a.push(make_injector(def.value, def.name));
+                                }
+                            });
+                        }
+                        else {
+                            compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]", token);
+                        }
+                    }
+                }
+                return a;
+            }, []);
+        }
+
         function eliminate_spurious_blocks(statements) {
             var seen_dirs = [];
             return statements.reduce(function(a, stat){