Blame view

node_modules/eslint/lib/rules/block-spacing.js 3.93 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
115
116
117
118
119
  /**
   * @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
   * @author Toru Nagashima
   * @copyright 2015 Toru Nagashima. All rights reserved.
   */
  
  "use strict";
  
  var util = require("../ast-utils");
  
  //------------------------------------------------------------------------------
  // Rule Definition
  //------------------------------------------------------------------------------
  
  module.exports = function(context) {
      var always = (context.options[0] !== "never"),
          message = always ? "Requires a space" : "Unexpected space(s)",
          sourceCode = context.getSourceCode();
  
      /**
       * Gets the open brace token from a given node.
       * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get.
       * @returns {Token} The token of the open brace.
       */
      function getOpenBrace(node) {
          if (node.type === "SwitchStatement") {
              if (node.cases.length > 0) {
                  return context.getTokenBefore(node.cases[0]);
              }
              return context.getLastToken(node, 1);
          }
          return context.getFirstToken(node);
      }
  
      /**
       * Checks whether or not:
       *   - given tokens are on same line.
       *   - there is/isn't a space between given tokens.
       * @param {Token} left - A token to check.
       * @param {Token} right - The token which is next to `left`.
       * @returns {boolean}
       *    When the option is `"always"`, `true` if there are one or more spaces between given tokens.
       *    When the option is `"never"`, `true` if there are not any spaces between given tokens.
       *    If given tokens are not on same line, it's always `true`.
       */
      function isValid(left, right) {
          return (
              !util.isTokenOnSameLine(left, right) ||
              sourceCode.isSpaceBetweenTokens(left, right) === always
          );
      }
  
      /**
       * Reports invalid spacing style inside braces.
       * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get.
       * @returns {void}
       */
      function checkSpacingInsideBraces(node) {
          // Gets braces and the first/last token of content.
          var openBrace = getOpenBrace(node);
          var closeBrace = context.getLastToken(node);
          var firstToken = sourceCode.getTokenOrCommentAfter(openBrace);
          var lastToken = sourceCode.getTokenOrCommentBefore(closeBrace);
  
          // Skip if the node is invalid or empty.
          if (openBrace.type !== "Punctuator" ||
              openBrace.value !== "{" ||
              closeBrace.type !== "Punctuator" ||
              closeBrace.value !== "}" ||
              firstToken === closeBrace
          ) {
              return;
          }
  
          // Skip line comments for option never
          if (!always && firstToken.type === "Line") {
              return;
          }
  
          // Check.
          if (!isValid(openBrace, firstToken)) {
              context.report({
                  node: node,
                  loc: openBrace.loc.start,
                  message: message + " after \"{\".",
                  fix: function(fixer) {
                      if (always) {
                          return fixer.insertTextBefore(firstToken, " ");
                      }
  
                      return fixer.removeRange([openBrace.range[1], firstToken.range[0]]);
                  }
              });
          }
          if (!isValid(lastToken, closeBrace)) {
              context.report({
                  node: node,
                  loc: closeBrace.loc.start,
                  message: message + " before \"}\".",
                  fix: function(fixer) {
                      if (always) {
                          return fixer.insertTextAfter(lastToken, " ");
                      }
  
                      return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]);
                  }
              });
          }
      }
  
      return {
          BlockStatement: checkSpacingInsideBraces,
          SwitchStatement: checkSpacingInsideBraces
      };
  };
  
  module.exports.schema = [
      {enum: ["always", "never"]}
  ];