node/tools/eslint/lib/rules/no-extend-native.js
Roman Reiss d91e10b3bd tools: update eslint to 0.24.0
PR-URL: https://github.com/nodejs/io.js/pull/2072
Reviewed-By: Yosuke Furukawa <yosuke.furukawa@gmail.com>
Reviewed-by: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Alex Kocharin <alex@kocharin.ru>
2015-06-29 19:02:17 +02:00

103 lines
3.1 KiB
JavaScript

/**
* @fileoverview Rule to flag adding properties to native object's prototypes.
* @author David Nelson
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var BUILTINS = [
"Object", "Function", "Array", "String", "Boolean", "Number", "Date",
"RegExp", "Error", "EvalError", "RangeError", "ReferenceError",
"SyntaxError", "TypeError", "URIError"
];
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var config = context.options[0] || {};
var exceptions = config.exceptions || [];
var modifiedBuiltins = BUILTINS;
if (exceptions.length) {
modifiedBuiltins = BUILTINS.filter(function(builtIn) {
return exceptions.indexOf(builtIn) === -1;
});
}
return {
// handle the Array.prototype.extra style case
"AssignmentExpression": function(node) {
var lhs = node.left, affectsProto;
if (lhs.type !== "MemberExpression" || lhs.object.type !== "MemberExpression") {
return;
}
affectsProto = lhs.object.computed ?
lhs.object.property.type === "Literal" && lhs.object.property.value === "prototype" :
lhs.object.property.name === "prototype";
if (!affectsProto) {
return;
}
modifiedBuiltins.forEach(function(builtin) {
if (lhs.object.object.name === builtin) {
context.report(node, builtin + " prototype is read only, properties should not be added.");
}
});
},
// handle the Object.defineProperty(Array.prototype) case
"CallExpression": function(node) {
var callee = node.callee,
subject,
object;
// only worry about Object.defineProperty
if (callee.type === "MemberExpression" &&
callee.object.name === "Object" &&
callee.property.name === "defineProperty") {
// verify the object being added to is a native prototype
subject = node.arguments[0];
object = subject.object;
if (object &&
object.type === "Identifier" &&
(modifiedBuiltins.indexOf(object.name) > -1) &&
subject.property.name === "prototype") {
context.report(node, object.name + " prototype is read only, properties should not be added.");
}
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"exceptions": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
}
},
"additionalProperties": false
}
];