ng-annotate
Version:
add, remove and rebuild angularjs dependency injection annotations
1,019 lines (923 loc) • 27 kB
JavaScript
// long form
angular.module("MyMod").controller("MyCtrl", function($scope, $timeout) {
});
// w/ dependencies
angular.module("MyMod", ["OtherMod"]).controller("MyCtrl", function($scope, $timeout) {
});
// simple
myMod.controller("foo", function($scope, $timeout) {
});
myMod.service("foo", function($scope, $timeout) {
});
myMod.factory("foo", function($scope, $timeout) {
});
myMod.directive("foo", function($scope, $timeout) {
});
myMod.filter("foo", function($scope, $timeout) {
});
myMod.animation("foo", function($scope, $timeout) {
});
myMod.invoke("foo", function($scope, $timeout) {
});
myMod.store("foo", function($scope, $timeout) {
});
myMod.decorator("foo", function($scope, $timeout) {
});
myMod.component("foo", {controller: function($scope, $timeout) {}});
// implicit config function
angular.module("MyMod", function($interpolateProvider) {});
angular.module("MyMod", ["OtherMod"], function($interpolateProvider) {});
angular.module("MyMod", ["OtherMod"], function($interpolateProvider) {}).controller("foo", function($scope) {});
// object property
var myObj = {};
myObj.myMod = angular.module("MyMod");
myObj.myMod.controller("foo", function($scope, $timeout) { a });
// no dependencies => no need to wrap the function in an array
myMod.controller("foo", function() {
});
myMod.service("foo", function() {
});
myMod.factory("foo", function() {
});
myMod.directive("foo", function() {
});
myMod.filter("foo", function() {
});
myMod.animation("foo", function() {
});
myMod.invoke("foo", function() {
});
myMod.store("foo", function() {
});
myMod.decorator("foo", function() {
});
myMod.component("foo", {controller: function() {}});
// run, config don't take names
myMod.run(function($scope, $timeout) {
});
angular.module("MyMod").run(function($scope) {
});
myMod.config(function($scope, $timeout) {
});
angular.module("MyMod").config(function() {
});
// directive return object
myMod.directive("foo", function($scope) {
return {
controller: function($scope, $timeout) {
bar;
}
}
});
myMod.directive("foo", function($scope) {
return {
controller: function() {
bar;
}
}
});
// provider, provider $get
myMod.provider("foo", function($scope) {
this.$get = function($scope, $timeout) {
bar;
};
self.$get = function($scope) {};
that.$get = function($scope) {};
ignore.$get = function($scope) {};
});
myMod.provider("foo", function() {
this.$get = function() {
bar;
};
});
myMod.provider("foo", function() {
return {
$get: function($scope, $timeout) {
bar;
}};
});
myMod.provider("foo", function() {
return {
$get: function() {
bar;
}};
});
myMod.provider("foo", {
$get: function($scope, $timeout) {
bar;
}
});
myMod.provider("foo", {
$get: function() {
bar;
}
});
myMod.provider("foo", {
"$get": function($scope, $timeout) {
bar;
}
});
myMod.provider("foo", {
'$get': function($scope, $timeout) {
bar;
}
});
myMod.provider("foo", function(x) {
this.$get = function(a,b) {};
});
myMod.provider("foo", extprov);
function extprov(x) {
this.$get = function(a,b) {};
this.$get = fooget;
this.$get = inner;
function inner(c, d) {
}
}
function fooget(b) {
this.$get = fooget2;
}
function fooget2(c) {
}
// chaining
myMod.directive("foo", function($a, $b) {
a;
}).factory("foo", function() {
b;
}).config(function($c) {
c;
}).filter("foo", function($d, $e) {
d;
}).animation("foo", function($f, $g) {
e;
}).component("foo", {controller: function($scope, $timeout) {
i;
}}).invoke("foo", function($f, $g) {
f;
}).decorator("foo", function($f, $g) {
g;
}).store("foo", function($f, $g) {
h;
});
angular.module("MyMod").directive("foo", function($a, $b) {
a;
}).provider("foo", function() {
return {
$get: function($scope, $timeout) {
bar;
}};
}).value("foo", "bar")
.constant("foo", "bar")
.bootstrap(element, [], {})
.factory("foo", function() {
b;
}).config(function($c) {
c;
}).filter("foo", function($d, $e) {
d;
}).animation("foo", function($f, $g) {
e;
}).component("foo", {controller: function($scope, $timeout) {
i;
}}).invoke("foo", function($h, $i) {
f;
}).decorator("foo", function($h, $i) {
g;
}).store("foo", function($f, $g) {
h;
});
// $provide
angular.module("myMod").controller("foo", function() {
$provide.decorator("foo", function($scope) {});
$provide.service("foo", function($scope) {});
$provide.factory("foo", function($scope) {});
//$provide.provider
$provide.provider("foo", function($scope) {
this.$get = function($scope) {};
return { $get: function($scope, $timeout) {}};
});
$provide.provider("foo", {
$get: function($scope, $timeout) {}
});
});
// negative $provide
function notInContext() {
$provide.decorator("foo", function($scope) {});
$provide.service("foo", function($scope) {});
$provide.factory("foo", function($scope) {});
$provide.provider("foo", function($scope) {
this.$get = function($scope) {};
return { $get: function($scope, $timeout) {}};
});
$provide.provider("foo", {
$get: function($scope, $timeout) {}
});
}
// $controllerProvider
angular.module("myMod").controller("foo", function() {
$controllerProvider.register("foo", function($scope) {});
});
function notInContext() {
$controllerProvider.register("foo", function($scope) {});
}
// special handling for TypeScript __extends
function outer1() {
a;
__extends();
b;
function foo($a) {
"ngInject";
}
}
function outer2() {
a;
__not_extends();
b;
function foo($a) {
"ngInject";
}
}
// all the patterns below matches only when we're inside a detected angular module
angular.module("MyMod").directive("pleasematchthis", function() {
// $injector.invoke
$injector.invoke(function($compile) {
$compile(myElement)(scope);
});
// $httpProvider
$httpProvider.interceptors.push(function($scope) { a });
$httpProvider.responseInterceptors.push(function($scope) { a }, function(a, b) { b }, function() { c });
// $routeProvider
$routeProvider.when("path", {
controller: function($scope) { a }
}).when("path2", {
controller: function($scope) { b },
resolve: {
zero: function() { a },
more: function($scope, $timeout) { b },
something: "else",
},
dontAlterMe: function(arg) {},
});
// ui-router
$stateProvider.state("myState", {
resolve: {
simpleObj: function() { a },
promiseObj: function($scope, $timeout) { b },
translations: "translations",
},
params: {
simple: function($scope) {},
inValue: { value: function($scope) {}, notThis: function($scope) {} },
},
views: {
viewa: {
controller: function($scope, myParam) {},
controllerProvider: function($stateParams) {},
templateProvider: function($scope) {},
dontAlterMe: function(arg) {},
resolve: {
myParam: function($stateParams) {
return $stateParams.paramFromDI;
}
},
},
viewb: {
dontAlterMe: function(arg) {},
templateProvider: function($scope) {},
controller: function($scope) {},
},
dontAlterMe: null,
},
controller: function($scope, simpleObj, promiseObj, translations) { c },
controllerProvider: function($scope) { g },
templateProvider: function($scope) { h },
onEnter: function($scope) { d },
onExit: function($scope) { e },
dontAlterMe: function(arg) { f },
}).state("myState2", {
controller: function($scope) {},
}).state({
name: "myState3",
controller: function($scope, simpleObj, promiseObj, translations) { c },
});
$urlRouterProvider.when("/", function($match) { a; });
$urlRouterProvider.otherwise("", function(a) { a; });
$urlRouterProvider.rule(function(a) { a; }).anything().when("/", function($location) { a; });
stateHelperProvider.setNestedState({
controller: function($scope, simpleObj, promiseObj, translations) { c },
children: [
{
name: "a",
controller: function(a) {},
resolve: {
f: function($a) {},
},
children: [
{
name: "ab",
controller: function(ab) {},
resolve: {
f: function($ab) {},
},
children: [
{
name: "abc",
controller: function(abc) {},
resolve: {
f: function($abc) {},
},
},
],
},
],
},
{
name: "b",
controller: function(b) {},
views: {
viewa: {
controller: function($scope, myParam) {},
controllerProvider: function($stateParams) {},
templateProvider: function($scope) {},
dontAlterMe: function(arg) {},
resolve: {
myParam: function($stateParams) {
return $stateParams.paramFromDI;
}
},
},
viewb: {
dontAlterMe: function(arg) {},
templateProvider: function($scope) {},
controller: function($scope) {},
},
dontAlterMe: null,
},
},
],
});
stateHelperProvider.setNestedState({
controller: function($scope, simpleObj, promiseObj, translations) { c },
}, true);
// angular ui / ui-bootstrap $modal
$modal.open({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$uibModal.open({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
// angular material design $mdBottomSheet, $mdDialog, $mdToast
$mdDialog.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$mdBottomSheet.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$mdToast.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
});
// none of the patterns below matches because they are not in an angular module context
// this should be a straight copy of the code above, with identical copies in
// with_annotations.js
foobar.irrespective("dontmatchthis", function() {
// $injector.invoke
$injector.invoke(function($compile) {
$compile(myElement)(scope);
});
// $httpProvider
$httpProvider.interceptors.push(function($scope) { a });
$httpProvider.responseInterceptors.push(function($scope) { a }, function(a, b) { b }, function() { c });
// $routeProvider
$routeProvider.when("path", {
controller: function($scope) { a }
}).when("path2", {
controller: function($scope) { b },
resolve: {
zero: function() { a },
more: function($scope, $timeout) { b },
something: "else",
},
dontAlterMe: function(arg) {},
});
// ui-router
$stateProvider.state("myState", {
resolve: {
simpleObj: function() { a },
promiseObj: function($scope, $timeout) { b },
translations: "translations",
},
views: {
viewa: {
controller: function($scope, myParam) {},
controllerProvider: function($stateParams) {},
templateProvider: function($scope) {},
dontAlterMe: function(arg) {},
resolve: {
myParam: function($stateParams) {
return $stateParams.paramFromDI;
}
},
},
viewb: {
dontAlterMe: function(arg) {},
templateProvider: function($scope) {},
controller: function($scope) {},
},
dontAlterMe: null,
},
controller: function($scope, simpleObj, promiseObj, translations) { c },
controllerProvider: function($scope) { g },
templateProvider: function($scope) { h },
onEnter: function($scope) { d },
onExit: function($scope) { e },
dontAlterMe: function(arg) { f },
}).state("myState2", {
controller: function($scope) {},
}).state({
name: "myState3",
controller: function($scope, simpleObj, promiseObj, translations) { c },
});
$urlRouterProvider.when("/", function($match) { a; });
$urlRouterProvider.otherwise("", function(a) { a; });
$urlRouterProvider.rule(function(a) { a; }).anything().when("/", function($location) { a; });
stateHelperProvider.setNestedState({
controller: function($scope, simpleObj, promiseObj, translations) { c },
children: [
{
name: "a",
controller: function(a) {},
resolve: {
f: function($a) {},
},
children: [
{
name: "ab",
controller: function(ab) {},
resolve: {
f: function($ab) {},
},
children: [
{
name: "abc",
controller: function(abc) {},
resolve: {
f: function($abc) {},
},
},
],
},
],
},
{
name: "b",
controller: function(b) {},
views: {
viewa: {
controller: function($scope, myParam) {},
controllerProvider: function($stateParams) {},
templateProvider: function($scope) {},
dontAlterMe: function(arg) {},
resolve: {
myParam: function($stateParams) {
return $stateParams.paramFromDI;
}
},
},
viewb: {
dontAlterMe: function(arg) {},
templateProvider: function($scope) {},
controller: function($scope) {},
},
dontAlterMe: null,
},
},
],
});
stateHelperProvider.setNestedState({
controller: function($scope, simpleObj, promiseObj, translations) { c },
}, true);
// angular ui / ui-bootstrap $modal
$modal.open({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$uibModal.open({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
// angular material design $mdBottomSheet, $mdDialog, $mdToast
$mdDialog.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$mdBottomSheet.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
$mdToast.show({
templateUrl: "str",
controller: function($scope) {},
resolve: {
items: function(MyService) {},
data: function(a, b) {},
its: 42,
},
donttouch: function(me) {},
});
});
// explicit annotations
var x = /* @ngInject */ function($scope) {
};
var obj = {};
obj.bar = /*@ngInject*/ function($scope) {};
obj = {
controller: /*@ngInject*/ function($scope) {},
};
obj = /*@ngInject*/ {
foo: function(a) {},
bar: function(b, c) {},
val: 42,
inner: {
circle: function(d) {},
alalalala: "long",
},
nest: { many: {levels: function(x) {}}},
but: { onlythrough: ["object literals", {donttouch: function(me) {}}]},
};
obj = {
/*@ngInject*/
foo: function(a) {},
bar: function(b, c) {},
};
/*@ngInject*/
obj = {
foo: function(a) {},
bar: function(b, c) {},
val: 42,
inner: {
circle: function(d) {},
alalalala: "long",
},
nest: { many: {levels: function(x) {}}},
but: { onlythrough: ["object literals", {donttouch: function(me) {}}]},
};
/*@ngInject*/
var obj = {
foo: function(a) {},
bar: function(b, c) {},
val: 42,
inner: {
circle: function(d) {},
alalalala: "long",
},
nest: { many: {levels: function(x) {}}},
but: { onlythrough: ["object literals", {donttouch: function(me) {}}]},
};
// @ngInject
function foo($scope) {
}
// @ngInject
// otherstuff
function Foo($scope) {
}
// @ngInject
// has trailing semicolon
var foo1 = function($scope) {
};
// @ngInject
// lacks trailing semicolon
var foo2 = function($scope) {
}
// @ngInject
// has trailing semicolon
bar.foo1 = function($scope) {
};
// @ngInject
// lacks trailing semicolon
bar.foo2 = function($scope) {
}
// let's zip-zag indentation to make sure that the $inject array lines up properly
// @ngInject
function foo3($scope) {}
// @ngInject
function foo4($scope) {
}
/* @ngInject */ function foo5($scope) {}
/* @ngInject */ function foo6($scope) {
}
// @ngInject
var foo7 = function($scope) {
};
// @ngInject
var foo8 = function($scope) {};
// @ngInject
var foo9 = function($scope) {
}
// @ngInject
var foo10 = function($scope) {}
/* @ngInject */ var foo11 = function($scope) {
};
/* @ngInject */var foo12 = function($scope) {};
/* @ngInject */var foo13 = function($scope) {
}
/* @ngInject */var foo14 = function($scope) {}
// adding an explicit annotation where it isn't needed should work fine
myMod.controller("foo", /*@ngInject*/ function($scope, $timeout) {
});
// troublesome return forces different placement of $inject array
function outer() {
foo;
return {
controller: MyCtrl,
};
// @ngInject
function MyCtrl(a) {
}
}
// explicit annotations using ngInject() instead of /*@ngInject*/
var x = ngInject(function($scope) {});
obj = ngInject({
foo: function(a) {},
bar: function(b, c) {},
val: 42,
inner: {
circle: function(d) {},
alalalala: "long",
},
nest: { many: {levels: function(x) {}}},
but: { onlythrough: ["object literals", {donttouch: function(me) {}}]},
});
// explicit annotations using "ngInject" Directive Prologue
function Foo2($scope) {
"ngInject";
}
var foos3 = function($scope) {
// comments are ok before the Directive Prologues
// and there may be multiple Prologues
"use strict"; "ngInject";
};
var dual1 = function(a) { "ngInject" }, dual2 = function(b) { "ngInject" };
g(function(c) {
"ngInject"
});
// Traceur class output example
// class C {
// constructor($scope) {
// "ngInject"
// }
// }
$traceurRuntime.ModuleStore.getAnonymousModule(function() {
"use strict";
var C = function C($scope) {
"ngInject";
};
($traceurRuntime.createClass)(C, {}, {});
return {};
});
// suppress false positives with /*@ngNoInject*/, ngNoInject() and "ngNoInject"
myMod.controller("suppressed", /*@ngNoInject*/function($scope) {
});
myMod.controller("suppressed", ngNoInject(function($scope) {
}));
myMod.controller("suppressed", function($scope) {
"ngNoInject";
});
// works the same as ngInject i.e. reference-following, IIFE-jumping and so on
/*@ngNoInject*/
myMod.controller("suppressed", SupFoo1);
myMod.controller("suppressed", SupFoo2);
myMod.controller("suppressed", SupFoo3);
function SupFoo1($scope) {
"ngNoInject";
}
/*@ngNoInject*/
function SupFoo2($scope) {
}
var SupFoo3 = ngNoInject(function($scope) {
"ngNoInject";
});
// regression-test for https://github.com/olov/ng-annotate/issues/221
var FooBar = (function (_super) {
__extends(FooBar, _super);
/*@ngInject*/
function FooBar($a, $b) {
_super.call(this);
}
/*@ngInject*/
FooBar.onEnter = function (callback) {
x;
};
return FooBar;
})(Bar);
var FooBar2 = (function (_super) {
__extends(FooBar, _super);
function FooBar($a, $b) {
"ngInject";
_super.call(this);
}
FooBar.onEnter = function (callback) {
"ngInject";
x;
};
return FooBar;
})(Bar);
// snippets that shouldn't fool ng-annotate into generating false positives,
// whether we're inside an angular module or not
myMod.controller("donttouchme", function() {
// lo-dash regression that happened in the brief time frame when
// notes (instad of "notes") would match. see issue #22
var notesForCurrentPage = _.filter(notes, function (note) {
return note.page.uid === page.uid;
});
});
// not a module declaration short-form, see https://github.com/olov/ng-annotate/issues/82
$stateProvider.decorator('parent', function (state, parentFn) {
doStuff();
});
// $get is only valid inside provider
myMod.service("donttouch", function() {
this.$get = function(me) {
};
});
myMod.service("donttouch", mefn);
function mefn() {
this.$get = function(me) {
};
}
// directive return object is only valid inside directive
myMod.service("donttouch", function() {
return {
controller: function($scope, $timeout) {
bar;
}
}
});
myMod.directive("donttouch", function() {
foo.decorator("me", function($scope) {
});
});
// IIFE-jumping (primarily for compile-to-JS langs)
angular.module("MyMod").directive("foo", function($a, $b) {
$uibModal.open({
resolve: {
collection: (function(_this) {
return function($c) {
};
})(this),
},
});
});
var x = /*@ngInject*/ (function() {
return function($a) {
};
})();
// IIFE-jumping with reference support
var myCtrl = (function () {
return function($scope) {
};
})();
angular.module("MyMod").controller("MyCtrl", myCtrl);
// advanced IIFE-jumping (with reference support)
var myCtrl10 = (function() {
"use strict";
// the return statement can appear anywhere on the functions topmost level,
// including before the myCtrl function definition
return myCtrl;
function myCtrl($scope) {
foo;
}
post;
})();
angular.module("MyMod").controller("MyCtrl", myCtrl10);
var myCtrl11 = (function() {
pre;
var myCtrl = function($scope) {
foo;
};
mid;
// the return statement can appear anywhere on the functions topmost level,
// including before the myCtrl function definition
return myCtrl;
post;
})();
angular.module("MyMod").controller("MyCtrl", myCtrl11);
// reference support
function MyCtrl1(a, b) {
}
if (true) {
// proper scope analysis including shadowing
let MyCtrl1 = function(c) {
};
angular.module("MyMod").directive("foo", MyCtrl1);
}
angular.module("MyMod").controller("bar", MyCtrl1);
function MyCtrl2(z) {
}
funcall(/*@ngInject*/ MyCtrl2); // explicit annotation on reference flows back to definition
angular.module("MyMod").directive("foo", MyDirective);
function MyDirective($stateProvider) {
$stateProvider.state('astate', {
resolve: {
yoyo: function(ma) {
},
}
});
}
/* @ngInject */
function MyDirective2($stateProvider) {
$stateProvider.state('astate', {
resolve: {
yoyo: function(ma) {
},
}
});
}
// issue 84
(function() {
var MyCtrl = function($someDependency) {};
angular.module('myApp').controller("MyCtrl", MyCtrl);
MyCtrl.prototype.someFunction = function() {};
})();
// empty var declarator
var MyCtrl12;
angular.module("MyMod").controller('MyCtrl', MyCtrl12);
// issue 115
module.exports = function() {
"use strict";
return {
restrict: 'E',
replace: true,
scope: { },
controller: /*@ngInject*/function($scope, myService) {
},
templateUrl: "mytemplate"
};
};
// issue #135
var MyCtrl = (function() {
/*@ngInject*/
function MyCtrl(a) {
}
return MyCtrl;
})();
myMod.service("a", MyCtrl);
;