mirror of
https://github.com/bluetech/ng-annotate-patched.git
synced 2026-07-02 00:17:42 +08:00
committed by
Ran Benita
parent
4ecfe6b43a
commit
c8544a2b77
+64
-19
@@ -63,13 +63,32 @@ function matchMaterialShowModalOpen(node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getObjectExpressionReturnProperties(node) {
|
||||
// matches object return via `return`:
|
||||
// 1. function() { return {} }
|
||||
// 2. () => { return {} }
|
||||
if (node.type === "ReturnStatement" &&
|
||||
node.argument && node.argument.type === "ObjectExpression") {
|
||||
return node.argument.properties;
|
||||
}
|
||||
|
||||
// matches object return via arrow function shortcut:
|
||||
// 1. () => ({})
|
||||
if (node.type === "ArrowFunctionExpression" && node.expression === true &&
|
||||
node.body.type === "ObjectExpression") {
|
||||
return node.body.properties;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function matchDirectiveReturnObject(node) {
|
||||
// only matches inside directives
|
||||
// return { .. controller: function($scope, $timeout), ...}
|
||||
// { .. controller: function($scope, $timeout), ...}
|
||||
const properties = getObjectExpressionReturnProperties(node);
|
||||
|
||||
return limit("directive", node.type === "ReturnStatement" &&
|
||||
node.argument && node.argument.type === "ObjectExpression" &&
|
||||
matchProp("controller", node.argument.properties));
|
||||
return limit("directive", properties &&
|
||||
matchProp("controller", properties));
|
||||
}
|
||||
|
||||
function limit(name, node) {
|
||||
@@ -606,7 +625,7 @@ function judgeSuspects(ctx) {
|
||||
replaceArray(ctx, target, fragments, quot);
|
||||
} else if (mode === "remove" && isAnnotatedArray(target)) {
|
||||
removeArray(target, fragments);
|
||||
} else if (["add", "rebuild"].includes(mode) && isFunctionExpressionWithArgs(target)) {
|
||||
} else if (["add", "rebuild"].includes(mode) && isFunctionOrArrowFunctionExpressionWithArgs(target)) {
|
||||
insertArray(ctx, target, target, fragments, quot);
|
||||
} else if (["add", "rebuild"].includes(mode) && isClassExpression(target) && (constructor = findClassConstructorWithArgs(target))) {
|
||||
insertArray(ctx, constructor.value, target, fragments, quot);
|
||||
@@ -710,7 +729,7 @@ function followReference(node) {
|
||||
// {type: "VariableDeclarator", id: {type: "Identifier", name: "foo"}, init: ..}
|
||||
return parent;
|
||||
} else if (kind === "fun") {
|
||||
assert(ptype === "FunctionDeclaration" || ptype === "FunctionExpression")
|
||||
assert(ptype === "FunctionDeclaration" || isFunctionOrArrowFunctionExpression(ptype))
|
||||
// FunctionDeclaration is the common case, i.e.
|
||||
// function foo(a, b) {}
|
||||
|
||||
@@ -843,7 +862,11 @@ function judgeInjectArraySuspect(node, ctx) {
|
||||
},
|
||||
className);
|
||||
|
||||
} else if (ctx.isFunctionExpressionWithArgs(node)) {
|
||||
} else if (node.type === "ArrowFunctionExpression" && onode.type === "ExportDefaultDeclaration") {
|
||||
// not implemented
|
||||
// this is a default exported arrow function like:
|
||||
// - export default (a, b) => {}
|
||||
} else if (ctx.isFunctionOrArrowFunctionExpressionWithArgs(node)) {
|
||||
// var x = 1, y = function(a,b) {}, z;
|
||||
|
||||
assert(declaratorName);
|
||||
@@ -864,7 +887,7 @@ function judgeInjectArraySuspect(node, ctx) {
|
||||
node.id.name);
|
||||
|
||||
} else if (node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" &&
|
||||
ctx.isFunctionExpressionWithArgs(node.expression.right)) {
|
||||
ctx.isFunctionOrArrowFunctionExpressionWithArgs(node.expression.right)) {
|
||||
// /*@ngInject*/ foo.bar[0] = function($scope) {}
|
||||
|
||||
const name = ctx.srcForRange(node.expression.left.range);
|
||||
@@ -1004,16 +1027,35 @@ function judgeInjectArraySuspect(node, ctx) {
|
||||
}
|
||||
|
||||
function jumpOverIife(node) {
|
||||
let outerfn;
|
||||
if (!(node.type === "CallExpression" && (outerfn = node.callee).type === "FunctionExpression")) {
|
||||
if (node.type !== "CallExpression") {
|
||||
return node;
|
||||
}
|
||||
|
||||
const outerbody = outerfn.body.body;
|
||||
for (let i = 0; i < outerbody.length; i++) {
|
||||
const statement = outerbody[i];
|
||||
if (statement.type === "ReturnStatement") {
|
||||
return statement.argument;
|
||||
const outerfn = node.callee;
|
||||
|
||||
/**
|
||||
* IIFE as in:
|
||||
* - (() => 'value')()
|
||||
*/
|
||||
if (outerfn.type === "ArrowFunctionExpression" && outerfn.expression) {
|
||||
return outerfn.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* IIFE as in:
|
||||
* - (() => { return 'value' })()
|
||||
* - (function { return 'value' })()
|
||||
*
|
||||
* needs to loop over children, as the return could be anywhere inside the body, as in:
|
||||
* - (function { console.log('something before'); return 'value'; console.log('something behind, but valid javascript'); }()
|
||||
*/
|
||||
if (isFunctionOrArrowFunctionExpression(outerfn.type)) {
|
||||
const outerbody = outerfn.body.body;
|
||||
for (let i = 0; i < outerbody.length; i++) {
|
||||
const statement = outerbody[i];
|
||||
if (statement.type === "ReturnStatement") {
|
||||
return statement.argument;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1036,7 +1078,7 @@ function isAnnotatedArray(node) {
|
||||
const elements = node.elements;
|
||||
|
||||
// last should be a function expression
|
||||
if (elements.length === 0 || last(elements).type !== "FunctionExpression") {
|
||||
if (elements.length === 0 || !isFunctionOrArrowFunctionExpression(last(elements).type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1060,8 +1102,11 @@ function isClassExpression(node) {
|
||||
function isClassDeclaration(node) {
|
||||
return node.type === "ClassDeclaration";
|
||||
}
|
||||
function isFunctionExpressionWithArgs(node) {
|
||||
return node.type === "FunctionExpression" && node.params.length >= 1;
|
||||
function isFunctionOrArrowFunctionExpression(type) {
|
||||
return type === "FunctionExpression" || type === "ArrowFunctionExpression";
|
||||
}
|
||||
function isFunctionOrArrowFunctionExpressionWithArgs(node) {
|
||||
return isFunctionOrArrowFunctionExpression(node.type) && node.params.length >= 1;
|
||||
}
|
||||
function isFunctionDeclarationWithArgs(node) {
|
||||
// For `export default function() {...}`, `id` is null, which means
|
||||
@@ -1222,7 +1267,7 @@ module.exports = function ngAnnotate(src, options) {
|
||||
lut: lut,
|
||||
isClassExpression: isClassExpression,
|
||||
isClassDeclaration: isClassDeclaration,
|
||||
isFunctionExpressionWithArgs: isFunctionExpressionWithArgs,
|
||||
isFunctionOrArrowFunctionExpressionWithArgs: isFunctionOrArrowFunctionExpressionWithArgs,
|
||||
isFunctionDeclarationWithArgs: isFunctionDeclarationWithArgs,
|
||||
isAnnotatedArray: isAnnotatedArray,
|
||||
findClassConstructorWithArgs: findClassConstructorWithArgs,
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ function inspectNode(node, ctx) {
|
||||
inspectCallExpression(node, ctx);
|
||||
} else if (node.$parent && node.$parent.type === "MethodDefinition") {
|
||||
// Ignore method function, constructor is processed below
|
||||
} else if (node.type === "FunctionExpression" || node.type === "FunctionDeclaration") {
|
||||
} else if (node.type === "FunctionExpression" || (node.type === "ArrowFunctionExpression" && !node.expression) || node.type === "FunctionDeclaration") {
|
||||
inspectFunction(node, ctx);
|
||||
} else if (node.type === "MethodDefinition" && node.kind === 'constructor') {
|
||||
inspectConstructor(node, ctx);
|
||||
@@ -208,7 +208,7 @@ function nestedObjectValues(node, res) {
|
||||
|
||||
node.properties.forEach(function(prop) {
|
||||
const v = prop.value;
|
||||
if (["FunctionExpression", "ArrayExpression"].includes(v.type)) {
|
||||
if (["FunctionExpression", "ArrowFunctionExpression", "ArrayExpression"].includes(v.type)) {
|
||||
res.push(v);
|
||||
} else if (v.type === "ObjectExpression") {
|
||||
nestedObjectValues(v, res);
|
||||
|
||||
+2
-2
@@ -171,7 +171,7 @@ function isConstLet(kind) {
|
||||
}
|
||||
|
||||
function isNonFunctionBlock(node, parent) {
|
||||
return node.type === "BlockStatement" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression";
|
||||
return node.type === "BlockStatement" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression" && parent.type !== "ArrowFunctionExpression";
|
||||
}
|
||||
|
||||
function isForWithConstLet(node) {
|
||||
@@ -187,7 +187,7 @@ function isForInOf(node) {
|
||||
}
|
||||
|
||||
function isFunction(node) {
|
||||
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
||||
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
||||
}
|
||||
|
||||
function isReference(node) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,961 @@
|
||||
"use strict";
|
||||
|
||||
// long form
|
||||
angular.module("MyMod").controller("MyCtrl", ($scope, $timeout) => {
|
||||
});
|
||||
|
||||
// w/ dependencies
|
||||
angular.module("MyMod", ["OtherMod"]).controller("MyCtrl", ($scope, $timeout) => {
|
||||
});
|
||||
|
||||
// simple
|
||||
myMod.controller("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.service("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.factory("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.directive("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.filter("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.animation("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.invoke("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.store("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.decorator("foo", ($scope, $timeout) => {
|
||||
});
|
||||
myMod.component("foo", {controller: ($scope, $timeout) => {}});
|
||||
|
||||
// implicit config function
|
||||
angular.module("MyMod", $interpolateProvider => {});
|
||||
angular.module("MyMod", ["OtherMod"], $interpolateProvider => {});
|
||||
angular.module("MyMod", ["OtherMod"], $interpolateProvider => {}).controller("foo", $scope => {});
|
||||
|
||||
// object property
|
||||
var myObj = {};
|
||||
myObj.myMod = angular.module("MyMod");
|
||||
myObj.myMod.controller("foo", ($scope, $timeout) => { a });
|
||||
|
||||
// no dependencies => no need to wrap the function in an array
|
||||
myMod.controller("foo", () => {
|
||||
});
|
||||
myMod.service("foo", () => {
|
||||
});
|
||||
myMod.factory("foo", () => {
|
||||
});
|
||||
myMod.directive("foo", () => {
|
||||
});
|
||||
myMod.filter("foo", () => {
|
||||
});
|
||||
myMod.animation("foo", () => {
|
||||
});
|
||||
myMod.invoke("foo", () => {
|
||||
});
|
||||
myMod.store("foo", () => {
|
||||
});
|
||||
myMod.decorator("foo", () => {
|
||||
});
|
||||
myMod.component("foo", {controller: () => {}});
|
||||
|
||||
// run, config don't take names
|
||||
myMod.run(($scope, $timeout) => {
|
||||
});
|
||||
angular.module("MyMod").run($scope => {
|
||||
});
|
||||
myMod.config(($scope, $timeout) => {
|
||||
});
|
||||
angular.module("MyMod").config(() => {
|
||||
});
|
||||
|
||||
// directive return object
|
||||
myMod.directive("foo", $scope => ({
|
||||
controller: ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
}));
|
||||
myMod.directive("foo", $scope => ({
|
||||
controller: () => {
|
||||
bar;
|
||||
}
|
||||
}));
|
||||
|
||||
// provider, provider $get
|
||||
myMod.provider("foo", function($scope) {
|
||||
this.$get = ($scope, $timeout) => {
|
||||
bar;
|
||||
};
|
||||
self.$get = $scope => {};
|
||||
that.$get = $scope => {};
|
||||
ignore.$get = $scope => {};
|
||||
});
|
||||
myMod.provider("foo", function() {
|
||||
this.$get = () => {
|
||||
bar;
|
||||
};
|
||||
});
|
||||
myMod.provider("foo", () => ({
|
||||
$get: ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
}));
|
||||
myMod.provider("foo", () => ({
|
||||
$get: () => {
|
||||
bar;
|
||||
}
|
||||
}));
|
||||
myMod.provider("foo", {
|
||||
$get: ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
});
|
||||
myMod.provider("foo", {
|
||||
$get: () => {
|
||||
bar;
|
||||
}
|
||||
});
|
||||
myMod.provider("foo", {
|
||||
"$get": ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
});
|
||||
myMod.provider("foo", {
|
||||
'$get': ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
});
|
||||
|
||||
myMod.provider("foo", function(x) {
|
||||
this.$get = (a, b) => {};
|
||||
});
|
||||
|
||||
myMod.provider("foo", extprov);
|
||||
function extprov(x) {
|
||||
this.$get = (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", ($a, $b) => {
|
||||
a;
|
||||
}).factory("foo", () => {
|
||||
b;
|
||||
}).config($c => {
|
||||
c;
|
||||
}).filter("foo", ($d, $e) => {
|
||||
d;
|
||||
}).animation("foo", ($f, $g) => {
|
||||
e;
|
||||
}).component("foo", {controller: ($scope, $timeout) => {
|
||||
i;
|
||||
}
|
||||
}).invoke("foo", ($f, $g) => {
|
||||
f;
|
||||
}).decorator("foo", ($f, $g) => {
|
||||
g;
|
||||
}).store("foo", ($f, $g) => {
|
||||
h;
|
||||
});
|
||||
|
||||
angular.module("MyMod").directive("foo", ($a, $b) => {
|
||||
a;
|
||||
}).provider("foo", () => ({
|
||||
$get: ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
})).value("foo", "bar")
|
||||
.constant("foo", "bar")
|
||||
.bootstrap(element, [], {})
|
||||
.factory("foo", () => {
|
||||
b;
|
||||
}).config($c => {
|
||||
c;
|
||||
}).filter("foo", ($d, $e) => {
|
||||
d;
|
||||
}).animation("foo", ($f, $g) => {
|
||||
e;
|
||||
}).component("foo", {controller: ($scope, $timeout) => {
|
||||
i;
|
||||
}
|
||||
}).invoke("foo", ($h, $i) => {
|
||||
f;
|
||||
}).decorator("foo", ($h, $i) => {
|
||||
g;
|
||||
}).store("foo", ($f, $g) => {
|
||||
h;
|
||||
});
|
||||
|
||||
// $provide
|
||||
angular.module("myMod").controller("foo", () => {
|
||||
$provide.decorator("foo", $scope => {});
|
||||
$provide.service("foo", $scope => {});
|
||||
$provide.factory("foo", $scope => {});
|
||||
//$provide.provider
|
||||
$provide.provider("foo", function($scope) {
|
||||
this.$get = $scope => {};
|
||||
return { $get: ($scope, $timeout) => {}};
|
||||
});
|
||||
$provide.provider("foo", {
|
||||
$get: ($scope, $timeout) => {}
|
||||
});
|
||||
});
|
||||
// negative $provide
|
||||
function notInContext() {
|
||||
$provide.decorator("foo", $scope => {});
|
||||
$provide.service("foo", $scope => {});
|
||||
$provide.factory("foo", $scope => {});
|
||||
$provide.provider("foo", function($scope) {
|
||||
this.$get = $scope => {};
|
||||
return { $get: ($scope, $timeout) => {}};
|
||||
});
|
||||
$provide.provider("foo", {
|
||||
$get: ($scope, $timeout) => {}
|
||||
});
|
||||
}
|
||||
|
||||
// $controllerProvider
|
||||
angular.module("myMod").controller("foo", () => {
|
||||
$controllerProvider.register("foo", $scope => {});
|
||||
});
|
||||
function notInContext() {
|
||||
$controllerProvider.register("foo", $scope => {});
|
||||
}
|
||||
|
||||
// all the patterns below matches only when we're inside a detected angular module
|
||||
angular.module("MyMod").directive("pleasematchthis", () => {
|
||||
|
||||
// $injector.invoke
|
||||
$injector.invoke($compile => {
|
||||
$compile(myElement)(scope);
|
||||
});
|
||||
|
||||
// $httpProvider
|
||||
$httpProvider.interceptors.push($scope => { a });
|
||||
$httpProvider.responseInterceptors.push($scope => { a }, (a, b) => { b }, () => { c });
|
||||
|
||||
// $routeProvider
|
||||
$routeProvider.when("path", {
|
||||
controller: $scope => { a }
|
||||
}).when("path2", {
|
||||
controller: $scope => { b },
|
||||
resolve: {
|
||||
zero: () => { a },
|
||||
more: ($scope, $timeout) => { b },
|
||||
something: "else",
|
||||
},
|
||||
dontAlterMe: arg => {},
|
||||
});
|
||||
|
||||
// ui-router
|
||||
$stateProvider.state("myState", {
|
||||
resolve: {
|
||||
simpleObj: () => { a },
|
||||
promiseObj: ($scope, $timeout) => { b },
|
||||
translations: "translations",
|
||||
},
|
||||
params: {
|
||||
simple: $scope => {},
|
||||
inValue: { value: $scope => {}, notThis: $scope => {}},
|
||||
},
|
||||
views: {
|
||||
viewa: {
|
||||
controller: ($scope, myParam) => {},
|
||||
controllerProvider: $stateParams => {},
|
||||
templateProvider: $scope => {},
|
||||
dontAlterMe: arg => {},
|
||||
resolve: {
|
||||
myParam: $stateParams => $stateParams.paramFromDI
|
||||
},
|
||||
},
|
||||
viewb: {
|
||||
dontAlterMe: arg => {},
|
||||
templateProvider: $scope => {},
|
||||
controller: $scope => {},
|
||||
},
|
||||
dontAlterMe: null,
|
||||
},
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
controllerProvider: $scope => { g },
|
||||
templateProvider: $scope => { h },
|
||||
onEnter: $scope => { d },
|
||||
onExit: $scope => { e },
|
||||
dontAlterMe: arg => { f },
|
||||
}).state("myState2", {
|
||||
controller: $scope => {},
|
||||
}).state({
|
||||
name: "myState3",
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
});
|
||||
$urlRouterProvider.when("/", $match => { a; });
|
||||
$urlRouterProvider.otherwise("", a => { a; });
|
||||
$urlRouterProvider.rule(a => { a; }).anything().when("/", $location => { a; });
|
||||
|
||||
stateHelperProvider.setNestedState({
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
|
||||
children: [
|
||||
{
|
||||
name: "a",
|
||||
controller: a => {},
|
||||
resolve: {
|
||||
f: $a => {},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: "ab",
|
||||
controller: ab => {},
|
||||
resolve: {
|
||||
f: $ab => {},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: "abc",
|
||||
controller: abc => {},
|
||||
resolve: {
|
||||
f: $abc => {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
controller: b => {},
|
||||
views: {
|
||||
viewa: {
|
||||
controller: ($scope, myParam) => {},
|
||||
controllerProvider: $stateParams => {},
|
||||
templateProvider: $scope => {},
|
||||
dontAlterMe: arg => {},
|
||||
resolve: {
|
||||
myParam: $stateParams => $stateParams.paramFromDI
|
||||
},
|
||||
},
|
||||
viewb: {
|
||||
dontAlterMe: arg => {},
|
||||
templateProvider: $scope => {},
|
||||
controller: $scope => {},
|
||||
},
|
||||
dontAlterMe: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
stateHelperProvider.setNestedState({
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
}, true);
|
||||
|
||||
// angular ui / ui-bootstrap $modal
|
||||
$modal.open({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$uibModal.open({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
|
||||
// angular material design $mdBottomSheet, $mdDialog, $mdToast
|
||||
$mdDialog.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$mdBottomSheet.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$mdToast.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: 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", () => {
|
||||
|
||||
// $injector.invoke
|
||||
$injector.invoke($compile => {
|
||||
$compile(myElement)(scope);
|
||||
});
|
||||
|
||||
// $httpProvider
|
||||
$httpProvider.interceptors.push($scope => { a });
|
||||
$httpProvider.responseInterceptors.push($scope => { a }, (a, b) => { b }, () => { c });
|
||||
|
||||
// $routeProvider
|
||||
$routeProvider.when("path", {
|
||||
controller: $scope => { a }
|
||||
}).when("path2", {
|
||||
controller: $scope => { b },
|
||||
resolve: {
|
||||
zero: () => { a },
|
||||
more: ($scope, $timeout) => { b },
|
||||
something: "else",
|
||||
},
|
||||
dontAlterMe: arg => {},
|
||||
});
|
||||
|
||||
// ui-router
|
||||
$stateProvider.state("myState", {
|
||||
resolve: {
|
||||
simpleObj: () => { a },
|
||||
promiseObj: ($scope, $timeout) => { b },
|
||||
translations: "translations",
|
||||
},
|
||||
views: {
|
||||
viewa: {
|
||||
controller: ($scope, myParam) => {},
|
||||
controllerProvider: $stateParams => {},
|
||||
templateProvider: $scope => {},
|
||||
dontAlterMe: arg => {},
|
||||
resolve: {
|
||||
myParam: $stateParams => $stateParams.paramFromDI
|
||||
},
|
||||
},
|
||||
viewb: {
|
||||
dontAlterMe: arg => {},
|
||||
templateProvider: $scope => {},
|
||||
controller: $scope => {},
|
||||
},
|
||||
dontAlterMe: null,
|
||||
},
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
controllerProvider: $scope => { g },
|
||||
templateProvider: $scope => { h },
|
||||
onEnter: $scope => { d },
|
||||
onExit: $scope => { e },
|
||||
dontAlterMe: arg => { f },
|
||||
}).state("myState2", {
|
||||
controller: $scope => {},
|
||||
}).state({
|
||||
name: "myState3",
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
});
|
||||
$urlRouterProvider.when("/", $match => { a; });
|
||||
$urlRouterProvider.otherwise("", a => { a; });
|
||||
$urlRouterProvider.rule(a => { a; }).anything().when("/", $location => { a; });
|
||||
|
||||
stateHelperProvider.setNestedState({
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
|
||||
children: [
|
||||
{
|
||||
name: "a",
|
||||
controller: a => {},
|
||||
resolve: {
|
||||
f: $a => {},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: "ab",
|
||||
controller: ab => {},
|
||||
resolve: {
|
||||
f: $ab => {},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: "abc",
|
||||
controller: abc => {},
|
||||
resolve: {
|
||||
f: $abc => {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "b",
|
||||
controller: b => {},
|
||||
views: {
|
||||
viewa: {
|
||||
controller: ($scope, myParam) => {},
|
||||
controllerProvider: $stateParams => {},
|
||||
templateProvider: $scope => {},
|
||||
dontAlterMe: arg => {},
|
||||
resolve: {
|
||||
myParam: $stateParams => $stateParams.paramFromDI
|
||||
},
|
||||
},
|
||||
viewb: {
|
||||
dontAlterMe: arg => {},
|
||||
templateProvider: $scope => {},
|
||||
controller: $scope => {},
|
||||
},
|
||||
dontAlterMe: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
stateHelperProvider.setNestedState({
|
||||
controller: ($scope, simpleObj, promiseObj, translations) => { c },
|
||||
}, true);
|
||||
|
||||
// angular ui / ui-bootstrap $modal
|
||||
$modal.open({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$uibModal.open({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
|
||||
// angular material design $mdBottomSheet, $mdDialog, $mdToast
|
||||
$mdDialog.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$mdBottomSheet.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
$mdToast.show({
|
||||
templateUrl: "str",
|
||||
controller: $scope => {},
|
||||
resolve: {
|
||||
items: MyService => {},
|
||||
data: (a, b) => {},
|
||||
its: 42,
|
||||
},
|
||||
donttouch: me => {},
|
||||
});
|
||||
});
|
||||
|
||||
// explicit annotations
|
||||
var x = /* @ngInject */ $scope => {
|
||||
};
|
||||
|
||||
var obj = {};
|
||||
obj.bar = /*@ngInject*/ $scope => {};
|
||||
|
||||
obj = {
|
||||
controller: /*@ngInject*/ $scope => {},
|
||||
};
|
||||
|
||||
obj = /*@ngInject*/ {
|
||||
foo: a => {},
|
||||
bar: (b, c) => {},
|
||||
val: 42,
|
||||
inner: {
|
||||
circle: d => {},
|
||||
alalalala: "long",
|
||||
},
|
||||
nest: { many: {levels: x => {}}},
|
||||
but: { onlythrough: ["object literals", {donttouch: me => {}}]},
|
||||
};
|
||||
|
||||
obj = {
|
||||
/*@ngInject*/
|
||||
foo: a => {},
|
||||
bar: (b, c) => {},
|
||||
};
|
||||
|
||||
/*@ngInject*/
|
||||
obj = {
|
||||
foo: a => {},
|
||||
bar: (b, c) => {},
|
||||
val: 42,
|
||||
inner: {
|
||||
circle: d => {},
|
||||
alalalala: "long",
|
||||
},
|
||||
nest: { many: {levels: x => {}}},
|
||||
but: { onlythrough: ["object literals", {donttouch: me => {}}]},
|
||||
};
|
||||
|
||||
/*@ngInject*/
|
||||
var obj = {
|
||||
foo: a => {},
|
||||
bar: (b, c) => {},
|
||||
val: 42,
|
||||
inner: {
|
||||
circle: d => {},
|
||||
alalalala: "long",
|
||||
},
|
||||
nest: { many: {levels: x => {}}},
|
||||
but: { onlythrough: ["object literals", {donttouch: me => {}}]},
|
||||
};
|
||||
|
||||
// @ngInject
|
||||
function foo($scope) {
|
||||
}
|
||||
|
||||
// @ngInject
|
||||
// otherstuff
|
||||
function Foo($scope) {
|
||||
}
|
||||
|
||||
// @ngInject
|
||||
// has trailing semicolon
|
||||
var foo1 = $scope => {
|
||||
};
|
||||
|
||||
// @ngInject
|
||||
// lacks trailing semicolon
|
||||
var foo2 = $scope => {
|
||||
}
|
||||
|
||||
// @ngInject
|
||||
// has trailing semicolon
|
||||
bar.foo1 = $scope => {
|
||||
};
|
||||
|
||||
// @ngInject
|
||||
// lacks trailing semicolon
|
||||
bar.foo2 = $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 = $scope => {
|
||||
};
|
||||
// @ngInject
|
||||
var foo8 = $scope => {};
|
||||
// @ngInject
|
||||
var foo9 = $scope => {
|
||||
}
|
||||
// @ngInject
|
||||
var foo10 = $scope => {}
|
||||
|
||||
/* @ngInject */ var foo11 = $scope => {
|
||||
};
|
||||
/* @ngInject */var foo12 = $scope => {};
|
||||
/* @ngInject */var foo13 = $scope => {
|
||||
}
|
||||
/* @ngInject */var foo14 = $scope => {}
|
||||
|
||||
// adding an explicit annotation where it isn't needed should work fine
|
||||
myMod.controller("foo", /*@ngInject*/ ($scope, $timeout) => {
|
||||
});
|
||||
|
||||
|
||||
// explicit annotations using ngInject() instead of /*@ngInject*/
|
||||
var x = ngInject($scope => {});
|
||||
|
||||
obj = ngInject({
|
||||
foo: a => {},
|
||||
bar: (b, c) => {},
|
||||
val: 42,
|
||||
inner: {
|
||||
circle: d => {},
|
||||
alalalala: "long",
|
||||
},
|
||||
nest: { many: {levels: x => {}}},
|
||||
but: { onlythrough: ["object literals", {donttouch: me => {}}]},
|
||||
});
|
||||
|
||||
|
||||
// explicit annotations using "ngInject" Directive Prologue
|
||||
function Foo2($scope) {
|
||||
"ngInject";
|
||||
}
|
||||
|
||||
var foos3 = $scope => {
|
||||
// comments are ok before the Directive Prologues
|
||||
// and there may be multiple Prologues
|
||||
"use strict"; "ngInject";
|
||||
};
|
||||
|
||||
var dual1 = a => { "ngInject" }, dual2 = b => { "ngInject" };
|
||||
|
||||
g(c => {
|
||||
"ngInject"
|
||||
});
|
||||
|
||||
// Traceur class output example
|
||||
// class C {
|
||||
// constructor($scope) {
|
||||
// "ngInject"
|
||||
// }
|
||||
// }
|
||||
$traceurRuntime.ModuleStore.getAnonymousModule(() => {
|
||||
"use strict";
|
||||
var C = $scope => {
|
||||
"ngInject";
|
||||
};
|
||||
($traceurRuntime.createClass)(C, {}, {});
|
||||
return {};
|
||||
});
|
||||
|
||||
|
||||
// suppress false positives with /*@ngNoInject*/, ngNoInject() and "ngNoInject"
|
||||
myMod.controller("suppressed", /*@ngNoInject*/$scope => {
|
||||
});
|
||||
myMod.controller("suppressed", ngNoInject($scope => {
|
||||
}));
|
||||
myMod.controller("suppressed", $scope => {
|
||||
"ngNoInject";
|
||||
});
|
||||
|
||||
// works the same as ngInject i.e. reference-following, IIFE-jumping and so on
|
||||
/*@ngNoInject*/
|
||||
myMod.controller("suppressed", SupFoo3);
|
||||
var SupFoo3 = ngNoInject($scope => {
|
||||
"ngNoInject";
|
||||
});
|
||||
|
||||
|
||||
// regression-test for https://github.com/olov/ng-annotate/issues/221
|
||||
var FooBar = (_super => {
|
||||
__extends(FooBar, _super);
|
||||
/*@ngInject*/
|
||||
function FooBar($a, $b) {
|
||||
_super.call(this);
|
||||
}
|
||||
/*@ngInject*/
|
||||
FooBar.onEnter = callback => {
|
||||
x;
|
||||
};
|
||||
return FooBar;
|
||||
})(Bar);
|
||||
var FooBar2 = (_super => {
|
||||
__extends(FooBar, _super);
|
||||
function FooBar($a, $b) {
|
||||
"ngInject";
|
||||
_super.call(this);
|
||||
}
|
||||
FooBar.onEnter = 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", () => {
|
||||
// lo-dash regression that happened in the brief time frame when
|
||||
// notes (instad of "notes") would match. see issue #22
|
||||
var notesForCurrentPage = _.filter(notes, note => note.page.uid === page.uid);
|
||||
});
|
||||
|
||||
// not a module declaration short-form, see https://github.com/olov/ng-annotate/issues/82
|
||||
$stateProvider.decorator('parent', (state, parentFn) => {
|
||||
doStuff();
|
||||
});
|
||||
|
||||
// $get is only valid inside provider
|
||||
myMod.service("donttouch", function() {
|
||||
this.$get = me => {
|
||||
};
|
||||
});
|
||||
myMod.service("donttouch", mefn);
|
||||
function mefn() {
|
||||
this.$get = me => {
|
||||
};
|
||||
}
|
||||
|
||||
// directive return object is only valid inside directive
|
||||
myMod.service("donttouch", () => ({
|
||||
controller: ($scope, $timeout) => {
|
||||
bar;
|
||||
}
|
||||
}));
|
||||
|
||||
myMod.directive("donttouch", () => {
|
||||
foo.decorator("me", $scope => {
|
||||
});
|
||||
});
|
||||
|
||||
// IIFE-jumping (primarily for compile-to-JS langs)
|
||||
angular.module("MyMod").directive("foo", function($a, $b) {
|
||||
$uibModal.open({
|
||||
resolve: {
|
||||
collection: (_this => $c => {
|
||||
})(this),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var x = /*@ngInject*/ (() => $a => {
|
||||
})();
|
||||
|
||||
// IIFE-jumping with reference support
|
||||
var myCtrl = (() => $scope => {
|
||||
})();
|
||||
angular.module("MyMod").controller("MyCtrl", myCtrl);
|
||||
|
||||
|
||||
// advanced IIFE-jumping (with reference support)
|
||||
var myCtrl10 = (() => {
|
||||
"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 = (() => {
|
||||
pre;
|
||||
var myCtrl = $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 = 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: ma => {
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* @ngInject */
|
||||
function MyDirective2($stateProvider) {
|
||||
$stateProvider.state('astate', {
|
||||
resolve: {
|
||||
yoyo: ma => {
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// issue 84
|
||||
(() => {
|
||||
var MyCtrl = $someDependency => {};
|
||||
angular.module('myApp').controller("MyCtrl", MyCtrl);
|
||||
MyCtrl.prototype.someFunction = () => {};
|
||||
})();
|
||||
|
||||
// empty var declarator
|
||||
var MyCtrl12;
|
||||
angular.module("MyMod").controller('MyCtrl', MyCtrl12);
|
||||
|
||||
// issue 115
|
||||
module.exports = () => {
|
||||
"use strict";
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope: { },
|
||||
controller: /*@ngInject*/($scope, myService) => {
|
||||
},
|
||||
templateUrl: "mytemplate"
|
||||
};
|
||||
};
|
||||
|
||||
// issue #135
|
||||
var MyCtrl = (() => {
|
||||
/*@ngInject*/
|
||||
function MyCtrl(a) {
|
||||
}
|
||||
|
||||
return MyCtrl;
|
||||
})();
|
||||
|
||||
myMod.service("a", MyCtrl);
|
||||
|
||||
import "foo";
|
||||
export const bar = "";
|
||||
|
||||
// NOT IMPLEMENTED FOR ARROW FUNCTIONS:
|
||||
/* @ngInject */
|
||||
export default $scope => {}
|
||||
@@ -123,6 +123,11 @@ function run(ngAnnotate) {
|
||||
const annotated = ngAnnotate(original, {add: true}).src;
|
||||
test(slurp("tests/with_annotations.js"), annotated, "with_annotations.js");
|
||||
|
||||
console.log("testing adding annotations with arrow functions");
|
||||
const arrowFunctions = slurp("tests/arrow-functions.js");
|
||||
const arrowFunctionsAnnotated = ngAnnotate(arrowFunctions, {add: true}).src;
|
||||
test(slurp("tests/arrow-functions.annotated.js"), arrowFunctionsAnnotated, "arrow-functions.annotated.js");
|
||||
|
||||
console.log("testing adding annotations with dynamicImport enabled");
|
||||
const annotatedWithDynamicImportEnabled = ngAnnotate(original, {add: true, dynamicImport: true}).src;
|
||||
test(slurp("tests/with_annotations.js"), annotatedWithDynamicImportEnabled, "with_annotations.js");
|
||||
|
||||
Reference in New Issue
Block a user