UNPKG

5.11 kBJavaScriptView Raw
1/**
2 * require all DI parameters to be located in their own line
3 *
4 * Injected dependencies should be written one per line.
5 *
6 * @version 0.14.0
7 * @category conventions
8 * @sinceAngularVersion 1.x
9 */
10'use strict';
11
12var utils = require('./utils/utils');
13
14module.exports = {
15 meta: {
16 schema: []
17 },
18 create: function(context) {
19 var angularObjectList = ['animation', 'config', 'constant', 'controller', 'directive', 'factory', 'filter', 'provider', 'service', 'value', 'decorator'];
20
21 function checkArgumentPositionInFunction(node) {
22 if (!node.params || node.params.length < 2) {
23 return;
24 }
25
26 var linesFound = [];
27 node.params.forEach(reportMultipleItemsInOneLine.bind(null, node, linesFound));
28 }
29
30 function reportMultipleItemsInOneLine(node, linesFound, item) {
31 var currentLine = item.loc.start.line;
32 if (linesFound.indexOf(currentLine) !== -1) {
33 context.report({
34 node: node,
35 message: 'Do not use multiple dependencies in one line',
36 loc: item.loc.start
37 });
38 }
39 linesFound.push(currentLine);
40 }
41
42 function checkArgumentPositionArrayExpression(angularComponentNode, arrayNode) {
43 var linesFound = [];
44
45 arrayNode.elements.forEach(function(element) {
46 if (element.type === 'Literal') {
47 reportMultipleItemsInOneLine(arrayNode, linesFound, element);
48 }
49 if (element.type === 'FunctionExpression') {
50 checkArgumentPositionInFunction(element);
51 }
52 if (element.type === 'Identifier') {
53 var fn = getFunctionDeclaration(angularComponentNode, element.name);
54 checkArgumentPositionInFunction(fn);
55 }
56 });
57 }
58
59 function findFunctionDeclarationByDeclaration(body, fName) {
60 return body.find(function(item) {
61 return item.type === 'FunctionDeclaration' && item.id.name === fName;
62 });
63 }
64
65 function findFunctionDeclarationByVariableDeclaration(body, fName) {
66 var fn;
67 body.forEach(function(item) {
68 if (fn) {
69 return;
70 }
71 if (item.type === 'VariableDeclaration') {
72 item.declarations.forEach(function(declaration) {
73 if (declaration.type === 'VariableDeclarator' &&
74 declaration.id &&
75 declaration.id.name === fName &&
76 declaration.init &&
77 declaration.init.type === 'FunctionExpression'
78 ) {
79 fn = declaration.init;
80 }
81 });
82 }
83 });
84 return fn;
85 }
86
87 function getFunctionDeclaration(node, fName) {
88 if (node.type === 'BlockStatement' || node.type === 'Program') {
89 if (node.body) {
90 var fn = findFunctionDeclarationByDeclaration(node.body, fName);
91 if (fn) {
92 return fn;
93 }
94 fn = findFunctionDeclarationByVariableDeclaration(node.body, fName);
95 if (fn) {
96 return fn;
97 }
98 }
99 }
100 if (node.parent) {
101 return getFunctionDeclaration(node.parent, fName);
102 }
103 }
104
105 return {
106
107 CallExpression: function(node) {
108 var fn;
109 if (utils.isAngularComponent(node) &&
110 node.callee.type === 'MemberExpression' &&
111 node.arguments[1].type === 'FunctionExpression' &&
112 angularObjectList.indexOf(node.callee.property.name) >= 0) {
113 fn = node.arguments[1];
114 return checkArgumentPositionInFunction(fn);
115 }
116 if (utils.isAngularComponent(node) &&
117 node.callee.type === 'MemberExpression' &&
118 node.arguments[1].type === 'Identifier' &&
119 angularObjectList.indexOf(node.callee.property.name) >= 0) {
120 var fName = node.arguments[1].name;
121 fn = getFunctionDeclaration(node, fName);
122 if (fn) {
123 return checkArgumentPositionInFunction(fn);
124 }
125 }
126 if (utils.isAngularComponent(node) &&
127 node.callee.type === 'MemberExpression' &&
128 node.arguments[1].type === 'ArrayExpression' &&
129 angularObjectList.indexOf(node.callee.property.name) >= 0) {
130 return checkArgumentPositionArrayExpression(node, node.arguments[1]);
131 }
132 }
133 };
134 }
135};