Blame view

node_modules/eslint/lib/rules/generator-star-spacing.js 3.73 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  /**
   * @fileoverview Rule to check the spacing around the * in generator functions.
   * @author Jamund Ferguson
   * @copyright 2015 Brandon Mills. All rights reserved.
   * @copyright 2014 Jamund Ferguson. All rights reserved.
   */
  
  "use strict";
  
  //------------------------------------------------------------------------------
  // Rule Definition
  //------------------------------------------------------------------------------
  
  module.exports = function(context) {
  
      var mode = (function(option) {
          if (!option || typeof option === "string") {
              return {
                  before: { before: true, after: false },
                  after: { before: false, after: true },
                  both: { before: true, after: true },
                  neither: { before: false, after: false }
              }[option || "before"];
          }
          return option;
      }(context.options[0]));
  
      /**
       * Checks the spacing between two tokens before or after the star token.
       * @param {string} side Either "before" or "after".
       * @param {Token} leftToken `function` keyword token if side is "before", or
       *     star token if side is "after".
       * @param {Token} rightToken Star token if side is "before", or identifier
       *     token if side is "after".
       * @returns {void}
       */
      function checkSpacing(side, leftToken, rightToken) {
          if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) {
              var after = leftToken.value === "*";
              var spaceRequired = mode[side];
              var node = after ? leftToken : rightToken;
              var type = spaceRequired ? "Missing" : "Unexpected";
              var message = type + " space " + side + " *.";
              context.report({
                  node: node,
                  message: message,
                  fix: function(fixer) {
                      if (spaceRequired) {
                          if (after) {
                              return fixer.insertTextAfter(node, " ");
                          }
                          return fixer.insertTextBefore(node, " ");
                      }
                      return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
                  }
              });
          }
      }
  
      /**
       * Enforces the spacing around the star if node is a generator function.
       * @param {ASTNode} node A function expression or declaration node.
       * @returns {void}
       */
      function checkFunction(node) {
          var prevToken, starToken, nextToken;
  
          if (!node.generator) {
              return;
          }
  
          if (node.parent.method || node.parent.type === "MethodDefinition") {
              starToken = context.getTokenBefore(node, 1);
          } else {
              starToken = context.getFirstToken(node, 1);
          }
  
          // Only check before when preceded by `function` keyword
          prevToken = context.getTokenBefore(starToken);
          if (prevToken.value === "function" || prevToken.value === "static") {
              checkSpacing("before", prevToken, starToken);
          }
  
          // Only check after when followed by an identifier
          nextToken = context.getTokenAfter(starToken);
          if (nextToken.type === "Identifier") {
              checkSpacing("after", starToken, nextToken);
          }
      }
  
      return {
          "FunctionDeclaration": checkFunction,
          "FunctionExpression": checkFunction
      };
  
  };
  
  module.exports.schema = [
      {
          "oneOf": [
              {
                  "enum": ["before", "after", "both", "neither"]
              },
              {
                  "type": "object",
                  "properties": {
                      "before": {"type": "boolean"},
                      "after": {"type": "boolean"}
                  },
                  "additionalProperties": false
              }
          ]
      }
  ];