Blame view

node_modules/eslint/lib/rules/prefer-reflect.js 3.75 KB
c39994410   Ryan Glover   wip converting to...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  /**
   * @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
      }
  ];