mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.8 KiB
101 lines
3.8 KiB
9 years ago
|
/**
|
||
|
* @fileoverview Rule to suggest using "Reflect" api over Function/Object methods
|
||
|
* @author Keith Cirkel <http://keithcirkel.co.uk>
|
||
|
* @copyright 2015 Keith Cirkel. All rights reserved.
|
||
|
*/
|
||
|
"use strict";
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Rule Definition
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
module.exports = function(context) {
|
||
|
var existingNames = {
|
||
|
"apply": "Function.prototype.apply",
|
||
|
"call": "Function.prototype.call",
|
||
|
"defineProperty": "Object.defineProperty",
|
||
|
"getOwnPropertyDescriptor": "Object.getOwnPropertyDescriptor",
|
||
|
"getPrototypeOf": "Object.getPrototypeOf",
|
||
|
"setPrototypeOf": "Object.setPrototypeOf",
|
||
|
"isExtensible": "Object.isExtensible",
|
||
|
"getOwnPropertyNames": "Object.getOwnPropertyNames",
|
||
|
"preventExtensions": "Object.preventExtensions"
|
||
|
};
|
||
|
|
||
|
var reflectSubsitutes = {
|
||
|
"apply": "Reflect.apply",
|
||
|
"call": "Reflect.apply",
|
||
|
"defineProperty": "Reflect.defineProperty",
|
||
|
"getOwnPropertyDescriptor": "Reflect.getOwnPropertyDescriptor",
|
||
|
"getPrototypeOf": "Reflect.getPrototypeOf",
|
||
|
"setPrototypeOf": "Reflect.setPrototypeOf",
|
||
|
"isExtensible": "Reflect.isExtensible",
|
||
|
"getOwnPropertyNames": "Reflect.getOwnPropertyNames",
|
||
|
"preventExtensions": "Reflect.preventExtensions"
|
||
|
};
|
||
|
|
||
|
var exceptions = (context.options[0] || {}).exceptions || [];
|
||
|
|
||
|
/**
|
||
|
* Reports the Reflect violation based on the `existing` and `substitute`
|
||
|
* @param {Object} node The node that violates the rule.
|
||
|
* @param {string} existing The existing method name that has been used.
|
||
|
* @param {string} substitute The Reflect substitute that should be used.
|
||
|
* @returns {void}
|
||
|
*/
|
||
|
function report(node, existing, substitute) {
|
||
|
context.report(node, "Avoid using {{existing}}, instead use {{substitute}}", {
|
||
|
existing: existing,
|
||
|
substitute: substitute
|
||
|
});
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
"CallExpression": function(node) {
|
||
|
var methodName = (node.callee.property || {}).name;
|
||
|
var isReflectCall = (node.callee.object || {}).name === "Reflect";
|
||
|
var hasReflectSubsitute = reflectSubsitutes.hasOwnProperty(methodName);
|
||
|
var userConfiguredException = exceptions.indexOf(methodName) !== -1;
|
||
|
if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) {
|
||
|
report(node, existingNames[methodName], reflectSubsitutes[methodName]);
|
||
|
}
|
||
|
},
|
||
|
"UnaryExpression": function(node) {
|
||
|
var isDeleteOperator = node.operator === "delete";
|
||
|
var targetsIdentifier = node.argument.type === "Identifier";
|
||
|
var userConfiguredException = exceptions.indexOf("delete") !== -1;
|
||
|
if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) {
|
||
|
report(node, "the delete keyword", "Reflect.deleteProperty");
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
};
|
||
|
|
||
|
module.exports.schema = [
|
||
|
{
|
||
|
"type": "object",
|
||
|
"properties": {
|
||
|
"exceptions": {
|
||
|
"type": "array",
|
||
|
"items": {
|
||
|
"enum": [
|
||
|
"apply",
|
||
|
"call",
|
||
|
"delete",
|
||
|
"defineProperty",
|
||
|
"getOwnPropertyDescriptor",
|
||
|
"getPrototypeOf",
|
||
|
"setPrototypeOf",
|
||
|
"isExtensible",
|
||
|
"getOwnPropertyNames",
|
||
|
"preventExtensions"
|
||
|
]
|
||
|
},
|
||
|
"uniqueItems": true
|
||
|
}
|
||
|
},
|
||
|
"additionalProperties": false
|
||
|
}
|
||
|
];
|