Skip to content

Commit defbe48

Browse files
committed
Merge 0.0.9
2 parents 24951ed + 4148cf5 commit defbe48

24 files changed

+213
-83
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ We provide also three samples :
7070
| 'ng_no_services': [2, ['$http', '$resource', 'Restangular']] | Some services should be used only in a specific AngularJS service (Ajax-based service for example), in order to follow the separation of concerns paradigm. The second parameter specifies the services. The third parameter can be a list of angular objects (controller, factory, etc.). Or second parameter can be an object, where keys are angular object names and value is a list of services (like {controller: ['$http'], factory: ['$q']}) |
7171
| 'ng_no_service_method': 2 | You should prefer the factory() method instead of service() [Y181](https://github.com/johnpapa/angular-styleguide#style-y181)|
7272
| 'ng_on_watch': 2 | Watch and On methods on the scope object should be assigned to a variable, in order to be deleted in a $destroy event handler [Y035](https://github.com/johnpapa/angular-styleguide#style-y035) |
73-
| 'ng_on_watch': 2 | All your services should have a name starting with the parameter you can define in your config object. The second parameter can be a Regexp wrapped in quotes. You can not prefix your services by "$" (reserved keyword for AngularJS services) ("ng_service_name": [2, "ng"]) [Y125](https://github.com/johnpapa/angular-styleguide#style-y125) |
73+
| 'ng_service_name': 2 | All your services should have a name starting with the parameter you can define in your config object. The second parameter can be a Regexp wrapped in quotes. You can not prefix your services by "$" (reserved keyword for AngularJS services) ("ng_service_name": [2, "ng"]) [Y125](https://github.com/johnpapa/angular-styleguide#style-y125) |
7474
| 'ng_timeout_service': 2 | Instead of the default setTimeout function, you should use the AngularJS wrapper service $timeout [Y181](https://github.com/johnpapa/angular-styleguide#style-y181) |
7575
| 'ng_typecheck_array': 2 | You should use the angular.isArray method instead of the default JavaScript implementation (typeof [] === "[object Array]"). |
7676
| 'ng_typecheck_boolean': 2 | You should use the angular.isBoolean method instead of the default JavaScript implementation (typeof true === "[object Boolean]"). |
@@ -81,6 +81,10 @@ We provide also three samples :
8181
| 'ng_typecheck_regexp': 2 | You should use the angular.isRegexp method instead of the default JavaScript implementation (toString.call(/^A/) === "[object RegExp]"). |
8282
| 'ng_typecheck_string': 2 | You should use the angular.isString method instead of the default JavaScript implementation (typeof "" === "[object String]"). |
8383
| 'ng_window_service': 2 | Instead of the default window object, you should prefer the AngularJS wrapper service $window. [Y180](https://github.com/johnpapa/angular-styleguide#style-y180) |
84+
<<<<<<< HEAD
85+
=======
86+
87+
>>>>>>> 0.0.9
8488

8589
# Need your help
8690
It is an opensource project. Any help will be very useful. You can :

rules/ng_module_getter.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ module.exports = function(context) {
88

99
'ExpressionStatement': function(node) {
1010

11-
var calleeObject;
11+
if ((utils.isAngularControllerDeclaration(node.expression) ||
12+
utils.isAngularFilterDeclaration(node.expression) ||
13+
utils.isAngularServiceDeclaration(node.expression) ||
14+
utils.isAngularDirectiveDeclaration(node.expression) ||
15+
utils.isAngularRunSection(node.expression) ||
16+
utils.isAngularConfigSection(node.expression))
1217

13-
if (utils.isAngularComponent(node.expression) || utils.isAngularRunSection(node.expression) || utils.isAngularConfigSection(node.expression)) {
18+
&& !utils.isAngularModuleDeclaration(node.expression)) {
1419

15-
calleeObject = node.expression.callee.object;
16-
if (!(calleeObject.type === 'CallExpression' && utils.isAngularModuleGetter(calleeObject))) {
20+
var calleeObject = node.expression.callee.object;
21+
while(calleeObject !== undefined && calleeObject.type === 'CallExpression' && !utils.isAngularModuleGetter(calleeObject)){
22+
calleeObject = calleeObject.callee.object;
23+
}
24+
25+
if (!(calleeObject !== undefined && calleeObject.type === 'CallExpression' && utils.isAngularModuleGetter(calleeObject))) {
1726
context.report(node, 'Avoid using a variable and instead use chaining with the getter syntax.');
1827
}
1928
}

rules/ng_no_services.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,21 @@ module.exports = function(context) {
5050

5151
'CallExpression': function(node) {
5252

53-
var callee = node.callee,
54-
angularObjectName = callee.property.name;
53+
var callee = node.callee;
5554

56-
if (utils.isAngularComponent(node) && callee.type === 'MemberExpression' && angularObjectList.indexOf(angularObjectName) >= 0) {
55+
if (utils.isAngularComponent(node) && callee.type === 'MemberExpression' && angularObjectList.indexOf(callee.property.name) >= 0) {
5756
if(utils.isFunctionType(node.arguments[1])){
5857
node.arguments[1].params.forEach(function(service){
59-
if(service.type === 'Identifier' && isSetBedService(service.name, angularObjectName)){
60-
context.report(node, message + ' (' + service.name + ' in ' + angularObjectName + ')', {});
58+
if(service.type === 'Identifier' && isSetBedService(service.name, callee.property.name)){
59+
context.report(node, message + ' (' + service.name + ' in ' + callee.property.name + ')', {});
6160
}
6261
});
6362
}
6463

6564
if(utils.isArrayType(node.arguments[1])){
6665
node.arguments[1].elements.forEach(function(service){
67-
if(service.type === 'Literal' && isSetBedService(service.value, angularObjectName)){
68-
context.report(node, message + ' (' + service.value + ' in ' + angularObjectName + ')', {});
66+
if(service.type === 'Literal' && isSetBedService(service.value, callee.property.name)){
67+
context.report(node, message + ' (' + service.value + ' in ' + callee.property.name + ')', {});
6968
}
7069
});
7170
}

rules/ng_on_watch.js

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,70 @@ module.exports = function(context) {
99
});
1010
}
1111

12-
return {
12+
/**
13+
* Return true if the given node is a call expression calling a function
14+
* named '$on' or '$watch' on an object named '$scope', '$rootScope' or
15+
* 'scope'.
16+
*/
17+
function isScopeOnOrWatch(node) {
18+
if (node.type !== 'CallExpression') {
19+
return false;
20+
}
1321

14-
'CallExpression': function(node) {
15-
if(node.callee.type === 'MemberExpression' &&
16-
(node.callee.object.name === '$scope' || node.callee.object.name === '$rootScope' || node.callee.object.name === 'scope')){
22+
var calledFunction = node.callee;
23+
if(calledFunction.type !== 'MemberExpression') {
24+
return false;
25+
}
26+
27+
// can only easily tell what name was used if a simple
28+
// identifiers were used to access it.
29+
var parentObject = calledFunction.object;
30+
var accessedFunction = calledFunction.property;
1731

18-
if(node.callee.property.name === '$on' || node.callee.property.name === '$watch'){
32+
// cannot check name of the parent object if it is returned from a
33+
// complex expression.
34+
if (parentObject.type !== 'Identifier' ||
35+
accessedFunction.type !== 'Identifier') {
36+
return false;
37+
}
38+
39+
var objectName = parentObject.name;
40+
var functionName = accessedFunction.name;
1941

20-
if(node.parent.type !== 'VariableDeclarator' && node.parent.type !== 'AssignmentExpression'){
21-
report(node, node.callee.property.name);
22-
}
42+
return (objectName === '$rootScope' ||
43+
objectName === '$scope' ||
44+
objectName === 'scope') && (functionName === '$on' ||
45+
functionName === '$watch');
46+
}
47+
48+
/**
49+
* Return true if the given node is a call expression that has a first
50+
* argument of the string '$destroy'.
51+
*/
52+
function isFirstArgDestroy(node) {
53+
if (node.type !== 'CallExpression') {
54+
return false;
55+
}
56+
57+
var args = node.arguments;
58+
59+
return (args.length >= 1 &&
60+
args[0].type === 'Literal' &&
61+
args[0].value === '$destroy');
62+
}
63+
64+
return {
65+
66+
'CallExpression': function(node) {
67+
if (isScopeOnOrWatch(node) && !isFirstArgDestroy(node)) {
68+
if (node.parent.type !== 'VariableDeclarator' &&
69+
node.parent.type !== 'AssignmentExpression' &&
70+
!(isScopeOnOrWatch(node.parent) &&
71+
isFirstArgDestroy(node.parent))) {
72+
report(node, node.callee.property.name);
2373
}
24-
}
74+
75+
}
2576
}
2677
};
27-
2878
};

rules/ng_typecheck_array.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ module.exports = function(context) {
1919
'BinaryExpression': function(node) {
2020

2121
if(node.operator === '===' || node.operator === '!=='){
22-
if(utils.isTypeOfStatement(node.left)){
22+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
2323
recordError(node.right, node);
2424
}
25-
else if(utils.isTypeOfStatement(node.right)){
25+
else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2626
recordError(node.left, node);
2727
}
2828
}

rules/ng_typecheck_boolean.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ module.exports = function(context) {
1515
'BinaryExpression': function(node) {
1616

1717
if(node.operator === '===' || node.operator === '!=='){
18-
if(utils.isTypeOfStatement(node.left)){
18+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
1919
recordError(node.right, node);
2020
}
21-
else if(utils.isTypeOfStatement(node.right)){
21+
else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2222
recordError(node.left, node);
2323
}
2424
}

rules/ng_typecheck_date.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ module.exports = function(context) {
1515
'BinaryExpression': function(node) {
1616

1717
if(node.operator === '===' || node.operator === '!=='){
18-
if(utils.isTypeOfStatement(node.left)){
18+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
1919
recordError(node.right, node);
2020
}
21-
else if(utils.isTypeOfStatement(node.right)){
21+
else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2222
recordError(node.left, node);
2323
}
2424
}

rules/ng_typecheck_function.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = function(context) {
55
var utils = require('./utils/utils');
66

77
function recordError(node, origin){
8-
if(node.type === 'Literal' && node.value === 'function') {
8+
if(node.type === 'Literal' && (node.value === 'function' || node.value === '[object Function]')) {
99
context.report(origin, 'You should use the angular.isFunction method', {});
1010
}
1111
}
@@ -15,10 +15,10 @@ module.exports = function(context) {
1515
'BinaryExpression': function(node) {
1616

1717
if(node.operator === '===' || node.operator === '!=='){
18-
if(utils.isTypeOfStatement(node.left)){
18+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
1919
recordError(node.right, node);
2020
}
21-
else if(utils.isTypeOfStatement(node.right)){
21+
else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2222
recordError(node.left, node);
2323
}
2424
}

rules/ng_typecheck_number.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ module.exports = function(context) {
1515
'BinaryExpression': function(node) {
1616

1717
if(node.operator === '===' || node.operator === '!=='){
18-
if(utils.isTypeOfStatement(node.left)){
18+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
1919
recordError(node.right, node);
2020
}
21-
else if(utils.isTypeOfStatement(node.right)){
21+
else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2222
recordError(node.left, node);
2323
}
2424
}

rules/ng_typecheck_object.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = function(context) {
55
var utils = require('./utils/utils');
66

77
function recordError(node, origin){
8-
if(node.type === 'Literal' && node.value === 'object') {
8+
if(node.type === 'Literal' && (node.value === 'object' || node.value === '[object Object]')) {
99
context.report(origin, 'You should use the angular.isObject method', {});
1010
}
1111
}
@@ -14,9 +14,9 @@ module.exports = function(context) {
1414
'BinaryExpression': function(node) {
1515

1616
if(node.operator === '===' || node.operator === '!=='){
17-
if(utils.isTypeOfStatement(node.left)){
17+
if(utils.isTypeOfStatement(node.left) || utils.isToStringStatement(node.left)){
1818
recordError(node.right, node);
19-
} else if(utils.isTypeOfStatement(node.right)){
19+
} else if(utils.isTypeOfStatement(node.right) || utils.isToStringStatement(node.right)){
2020
recordError(node.left, node);
2121
}
2222
}

0 commit comments

Comments
 (0)