1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var BUILTINS = [
|
11 | "Object", "Function", "Array", "String", "Boolean", "Number", "Date",
|
12 | "RegExp", "Error", "EvalError", "RangeError", "ReferenceError",
|
13 | "SyntaxError", "TypeError", "URIError"
|
14 | ];
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | module.exports = function(context) {
|
21 |
|
22 | "use strict";
|
23 |
|
24 | return {
|
25 |
|
26 |
|
27 | "AssignmentExpression": function(node) {
|
28 | var lhs = node.left, affectsProto;
|
29 |
|
30 | if (lhs.type !== "MemberExpression" || lhs.object.type !== "MemberExpression") { return; }
|
31 |
|
32 | affectsProto = lhs.object.computed ?
|
33 | lhs.object.property.type === "Literal" && lhs.object.property.value === "prototype" :
|
34 | lhs.object.property.name === "prototype";
|
35 |
|
36 | if (!affectsProto) { return; }
|
37 |
|
38 | BUILTINS.forEach(function(builtin) {
|
39 | if (lhs.object.object.name === builtin) {
|
40 | context.report(node, builtin + " prototype is read only, properties should not be added.");
|
41 | }
|
42 | });
|
43 | },
|
44 |
|
45 |
|
46 | "CallExpression": function(node) {
|
47 |
|
48 | var callee = node.callee,
|
49 | subject,
|
50 | object;
|
51 |
|
52 |
|
53 | if (callee.type === "MemberExpression" &&
|
54 | callee.object.name === "Object" &&
|
55 | callee.property.name === "defineProperty") {
|
56 |
|
57 |
|
58 | subject = node.arguments[0];
|
59 | object = subject.object;
|
60 |
|
61 | if (object &&
|
62 | object.type === "Identifier" &&
|
63 | (BUILTINS.indexOf(object.name) > -1) &&
|
64 | subject.property.name === "prototype") {
|
65 |
|
66 | context.report(node, object.name + " prototype is read only, properties should not be added.");
|
67 | }
|
68 | }
|
69 |
|
70 | }
|
71 | };
|
72 |
|
73 | };
|