block-spacing.js
3.93 KB
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"]}
];