164 lines
5.6 KiB
JavaScript
164 lines
5.6 KiB
JavaScript
|
|
/**
|
||
|
|
* require a consistent DI syntax
|
||
|
|
*
|
||
|
|
* All your DI should use the same syntax : the Array, function, or $inject syntaxes ("di": [2, "array, function, or $inject"])
|
||
|
|
*
|
||
|
|
* @version 0.1.0
|
||
|
|
* @category conventions
|
||
|
|
* @sinceAngularVersion 1.x
|
||
|
|
*/
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
var utils = require('./utils/utils');
|
||
|
|
|
||
|
|
var angularRule = require('./utils/angular-rule');
|
||
|
|
|
||
|
|
|
||
|
|
module.exports = {
|
||
|
|
meta: {
|
||
|
|
docs: {
|
||
|
|
url: 'https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/di.md'
|
||
|
|
},
|
||
|
|
schema: [{
|
||
|
|
enum: [
|
||
|
|
'function',
|
||
|
|
'array',
|
||
|
|
'$inject'
|
||
|
|
]
|
||
|
|
}, {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
matchNames: {
|
||
|
|
type: 'boolean'
|
||
|
|
},
|
||
|
|
stripUnderscores: {
|
||
|
|
type: 'boolean'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}]
|
||
|
|
},
|
||
|
|
create: angularRule(function(context) {
|
||
|
|
var syntax = context.options[0] || 'function';
|
||
|
|
|
||
|
|
var extra = context.options[1] || {};
|
||
|
|
var matchNames = extra.matchNames !== false;
|
||
|
|
var stripUnderscores = extra.stripUnderscores === true;
|
||
|
|
|
||
|
|
function report(node) {
|
||
|
|
context.report(node, 'You should use the {{syntax}} syntax for DI', {
|
||
|
|
syntax: syntax
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
var $injectProperties = {};
|
||
|
|
|
||
|
|
function maybeNoteInjection(node) {
|
||
|
|
if (syntax === '$inject' && node.left && node.left.property &&
|
||
|
|
((utils.isLiteralType(node.left.property) && node.left.property.value === '$inject') ||
|
||
|
|
(utils.isIdentifierType(node.left.property) && node.left.property.name === '$inject'))) {
|
||
|
|
$injectProperties[node.left.object.name] = node.right;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function normalizeParameter(param) {
|
||
|
|
return param.replace(/^_(.+)_$/, function(match, p1) {
|
||
|
|
return p1;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function checkDi(callee, fn) {
|
||
|
|
if (!fn || !fn.params) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (syntax === 'array') {
|
||
|
|
if (utils.isArrayType(fn.parent)) {
|
||
|
|
if (fn.parent.elements.length - 1 !== fn.params.length) {
|
||
|
|
context.report(fn, 'The signature of the method is incorrect', {});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (matchNames) {
|
||
|
|
var invalidArray = fn.params.filter(function(e, i) {
|
||
|
|
var name = e.name;
|
||
|
|
|
||
|
|
if (stripUnderscores) {
|
||
|
|
name = normalizeParameter(name);
|
||
|
|
}
|
||
|
|
|
||
|
|
return name !== fn.parent.elements[i].value;
|
||
|
|
});
|
||
|
|
if (invalidArray.length > 0) {
|
||
|
|
context.report(fn, 'You have an error in your DI configuration. Each items of the array should match exactly one function parameter', {});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (fn.params.length === 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
report(fn);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (syntax === 'function') {
|
||
|
|
if (utils.isArrayType(fn.parent)) {
|
||
|
|
report(fn);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (syntax === '$inject') {
|
||
|
|
if (fn && fn.id && utils.isIdentifierType(fn.id)) {
|
||
|
|
var $injectArray = $injectProperties[fn.id.name];
|
||
|
|
|
||
|
|
if ($injectArray && utils.isArrayType($injectArray)) {
|
||
|
|
if ($injectArray.elements.length !== fn.params.length) {
|
||
|
|
context.report(fn, 'The signature of the method is incorrect', {});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (matchNames) {
|
||
|
|
var invalidInjectArray = fn.params.filter(function(e, i) {
|
||
|
|
var name = e.name;
|
||
|
|
|
||
|
|
if (stripUnderscores) {
|
||
|
|
name = normalizeParameter(name);
|
||
|
|
}
|
||
|
|
|
||
|
|
return name !== $injectArray.elements[i].value;
|
||
|
|
});
|
||
|
|
if (invalidInjectArray.length > 0) {
|
||
|
|
context.report(fn, 'You have an error in your DI configuration. Each items of the array should match exactly one function parameter', {});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else if (fn.params.length > 0) {
|
||
|
|
report(fn);
|
||
|
|
}
|
||
|
|
} else if (fn.params && fn.params.length !== 0) {
|
||
|
|
report(fn);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
'angular?animation': checkDi,
|
||
|
|
'angular?config': checkDi,
|
||
|
|
'angular?controller': checkDi,
|
||
|
|
'angular?directive': checkDi,
|
||
|
|
'angular?factory': checkDi,
|
||
|
|
'angular?filter': checkDi,
|
||
|
|
'angular?inject': checkDi,
|
||
|
|
'angular?run': checkDi,
|
||
|
|
'angular?service': checkDi,
|
||
|
|
'angular?provider': function(callee, providerFn, $get) {
|
||
|
|
checkDi(null, providerFn);
|
||
|
|
checkDi(null, $get);
|
||
|
|
},
|
||
|
|
AssignmentExpression: function(node) {
|
||
|
|
maybeNoteInjection(node);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
})
|
||
|
|
};
|