Skip to content

Commit c07ca39

Browse files
committed
Breaking: merges keyword spacing rules (fixes #3869)
Also refs #1338, fixes #3878, fixes #4006, fixes #4585. This commit creates a new rule: `keyword-spacing` (merged from `space-after-keywords`, `space-before-keywords`, and `space-return-throw-case`). - `keyword-spacing` rule ignores usage of spacing at some places to not conflict other spacing rules. - `keyword-spacing` rule has `"overrides"` option to configure more preference.
1 parent 009a949 commit c07ca39

File tree

11 files changed

+3577
-5
lines changed

11 files changed

+3577
-5
lines changed

conf/eslint.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
"init-declarations": 0,
154154
"jsx-quotes": [0, "prefer-double"],
155155
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],
156+
"keyword-spacing": 0,
156157
"lines-around-comment": 0,
157158
"max-depth": [0, 4],
158159
"max-len": [0, 80, 4],

conf/replacements.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
"no-space-before-semi": ["semi-spacing"],
1111
"no-wrap-func": ["no-extra-parens"],
1212
"space-after-function-name": ["space-before-function-paren"],
13+
"space-after-keywords": ["keyword-spacing"],
1314
"space-before-function-parentheses": ["space-before-function-paren"],
15+
"space-before-keywords": ["keyword-spacing"],
1416
"space-in-brackets": ["object-curly-spacing", "array-bracket-spacing", "computed-property-spacing"],
17+
"space-return-throw-case": ["keyword-spacing"],
1518
"space-unary-word-ops": ["space-unary-ops"],
1619
"spaced-line-comment": ["spaced-comment"]
1720
}

docs/rules/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ These rules are purely matters of style and are quite subjective.
160160
* [indent](indent.md) - specify tab or space width for your code (fixable)
161161
* [jsx-quotes](jsx-quotes.md) - specify whether double or single quotes should be used in JSX attributes
162162
* [key-spacing](key-spacing.md) - enforce spacing between keys and values in object literal properties
163+
* [keyword-spacing](keyword-spacing.md) - enforce spacing before and after keywords (fixable)
163164
* [linebreak-style](linebreak-style.md) - disallow mixed 'LF' and 'CRLF' as linebreaks
164165
* [lines-around-comment](lines-around-comment.md) - enforce empty lines around comments
165166
* [max-depth](max-depth.md) - specify the maximum depth that blocks can be nested
@@ -199,13 +200,10 @@ These rules are purely matters of style and are quite subjective.
199200
* [semi-spacing](semi-spacing.md) - enforce spacing before and after semicolons (fixable)
200201
* [semi](semi.md) - require or disallow use of semicolons instead of ASI (fixable)
201202
* [sort-vars](sort-vars.md) - sort variables within the same declaration block
202-
* [space-after-keywords](space-after-keywords.md) - require a space after certain keywords (fixable)
203203
* [space-before-blocks](space-before-blocks.md) - require or disallow a space before blocks (fixable)
204204
* [space-before-function-paren](space-before-function-paren.md) - require or disallow a space before function opening parenthesis (fixable)
205-
* [space-before-keywords](space-before-keywords.md) - require a space before certain keywords (fixable)
206205
* [space-in-parens](space-in-parens.md) - require or disallow spaces inside parentheses
207206
* [space-infix-ops](space-infix-ops.md) - require spaces around operators (fixable)
208-
* [space-return-throw-case](space-return-throw-case.md) - require a space after `return`, `throw`, and `case` (fixable)
209207
* [space-unary-ops](space-unary-ops.md) - require or disallow spaces before/after unary operators (fixable)
210208
* [spaced-comment](spaced-comment.md) - require or disallow a space immediately following the `//` or `/*` in a comment
211209
* [wrap-regex](wrap-regex.md) - require regex literals to be wrapped in parentheses
@@ -251,7 +249,10 @@ These rules existed in a previous version of ESLint but have since been replaced
251249
* [no-space-before-semi](no-space-before-semi.md) - disallow space before semicolon (replaced by [semi-spacing](semi-spacing.md))
252250
* [no-wrap-func](no-wrap-func.md) - disallow wrapping of non-IIFE statements in parens (replaced by [no-extra-parens](no-extra-parens.md))
253251
* [space-after-function-name](space-after-function-name.md) - require a space after function names (replaced by [space-before-function-paren](space-before-function-paren.md))
252+
* [space-after-keywords](space-after-keywords.md) - require a space after certain keywords (fixable) (replaced by [keyword-spacing](keyword-spacing.md))
254253
* [space-before-function-parentheses](space-before-function-parentheses.md) - require or disallow space before function parentheses (replaced by [space-before-function-paren](space-before-function-paren.md))
254+
* [space-before-keywords](space-before-keywords.md) - require a space before certain keywords (fixable) (replaced by [keyword-spacing](keyword-spacing.md))
255255
* [space-in-brackets](space-in-brackets.md) - require or disallow spaces inside brackets (replaced by [object-curly-spacing](object-curly-spacing.md) and [array-bracket-spacing](array-bracket-spacing.md))
256+
* [space-return-throw-case](space-return-throw-case.md) - require a space after `return`, `throw`, and `case` (fixable) (replaced by [keyword-spacing](keyword-spacing.md))
256257
* [space-unary-word-ops](space-unary-word-ops.md) - require or disallow spaces before/after unary operators (replaced by [space-unary-ops](space-unary-ops.md))
257258
* [spaced-line-comment](spaced-line-comment.md) - require or disallow a space immediately following the `//` in a line comment (replaced by [spaced-comment](spaced-comment.md))

docs/rules/keyword-spacing.md

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
# Enforce spacing before and after keywords (keyword-spacing)
2+
3+
Keywords are syntax elements of JavaScript, such as `function` and `if`.
4+
These identifiers have special meaning to the language and so often appear in a different color in code editors.
5+
As an important part of the language, style guides often refer to the spacing that should be used around keywords.
6+
For example, you might have a style guide that says keywords should be always surrounded by spaces, which would mean `if-else` statements must look like this:
7+
8+
```js
9+
if (foo) {
10+
// ...
11+
} else {
12+
// ...
13+
}
14+
```
15+
16+
Of course, you could also have a style guide that disallows spaces around keywords.
17+
18+
**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.
19+
20+
## Rule Details
21+
22+
This rule will enforce consistency of spacing around keywords and keyword-like tokens: `as` (in module declarations), `break`, `case`, `catch`, `class`, `const`, `continue`, `debugger`, `default`, `delete`, `do`, `else`, `export`, `extends`, `finally`, `for`, `from` (in module declarations), `function`, `get` (of getters), `if`, `import`, `in`, `instanceof`, `let`, `new`, `of` (in for-of statements), `return`, `set` (of setters), `static`, `super`, `switch`, `this`, `throw`, `try`, `typeof`, `var`, `void`, `while`, `with`, and `yield`.
23+
24+
The following patterns are considered problems:
25+
26+
```js
27+
/*eslint keyword-spacing: 2*/
28+
/*eslint-env es6*/
29+
30+
if(foo){ /*error Expected space(s) after "if".*/
31+
//...
32+
}else if (bar) { /*error Expected space(s) before "else".*/
33+
//...
34+
} else{ /*error Expected space(s) after "else".*/
35+
//...
36+
}
37+
38+
try{ /*error Expected space(s) after "try".*/
39+
//...
40+
}catch(e) { /*error Expected space(s) before "catch".*/
41+
/*error Expected space(s) after "catch".*/
42+
//...
43+
}
44+
45+
switch (a) {
46+
case+1: /*error Expected space(s) after "case".*/
47+
break;
48+
}
49+
50+
function foo() {
51+
return[0, 1, 2]; /*error Expected space(s) after "return".*/
52+
}
53+
54+
for (let[a, b]of[foo, bar, baz]) { /*error Expected space(s) after "let".*/
55+
/*error Expected space(s) before "of".*/
56+
/*error Expected space(s) after "of".*/
57+
//...
58+
}
59+
60+
let obj = {
61+
get[FOO]() { /*error Expected space(s) after "get".*/
62+
//...
63+
},
64+
set[FOO](value) { /*error Expected space(s) after "set".*/
65+
//...
66+
}
67+
};
68+
69+
import{foo}from"foo"; /*error Expected space(s) after "import".*/
70+
/*error Expected space(s) before "from".*/
71+
/*error Expected space(s) after "from".*/
72+
import*as bar from "foo"; /*error Expected space(s) after "import".*/
73+
/*error Expected space(s) before "as".*/
74+
```
75+
76+
The following patterns are considered not problems:
77+
78+
```js
79+
/*eslint keyword-spacing: 2*/
80+
/*eslint-env es6*/
81+
82+
if (foo) {
83+
//...
84+
} else if (bar) {
85+
//...
86+
} else {
87+
//...
88+
}
89+
90+
try {
91+
//...
92+
} catch (e) {
93+
//...
94+
}
95+
96+
switch (a) {
97+
case +1:
98+
break;
99+
}
100+
101+
function foo() {
102+
return [0, 1, 2];
103+
}
104+
105+
for (let [a, b] of [foo, bar, baz]) {
106+
//...
107+
}
108+
109+
let obj = {
110+
get [FOO]() {
111+
//...
112+
},
113+
set [FOO](value) {
114+
//...
115+
}
116+
};
117+
118+
import {foo} from "foo";
119+
import * as bar from "foo";
120+
```
121+
122+
This rule is designed carefully to not conflict with other spacing rules.
123+
Basically this rule ignores usage of spacing at places that other rules are catching.
124+
So the following patterns are considered not problems.
125+
126+
```js
127+
/*eslint keyword-spacing: 2*/
128+
/*eslint-env es6*/
129+
130+
// not conflict with `array-bracket-spacing`
131+
let a = [this];
132+
let b = [function() {}];
133+
134+
// not conflict with `arrow-spacing`
135+
let a = () =>this.foo;
136+
137+
// not conflict with `block-spacing`
138+
{function foo() {}}
139+
140+
// not conflict with `comma-spacing`
141+
let a = [100,this.foo, this.bar];
142+
143+
// not conflict with `computed-property-spacing`
144+
obj[this.foo] = 0;
145+
146+
// not conflict with `generator-star-spacing`
147+
function* foo() {}
148+
149+
// not conflict with `key-spacing`
150+
let obj = {
151+
foo:function() {}
152+
};
153+
154+
// not conflict with `no-spaced-func`
155+
class A {
156+
constructor() {
157+
super();
158+
}
159+
}
160+
161+
// not conflict with `object-curly-spacing`
162+
let obj = {foo: this};
163+
164+
// not conflict with `semi-spacing`
165+
let a = this;function foo() {}
166+
167+
// not conflict with `space-before-function-paren`
168+
// not conflict with `space-in-parens`
169+
(function() {})();
170+
171+
// not conflict with `space-infix-ops`
172+
if ("foo"in{foo: 0}) {}
173+
if (10+this.foo <=this.bar) {}
174+
175+
// not conflict with `space-unary-ops`
176+
function* foo(a) {
177+
return yield+a;
178+
}
179+
180+
// not conflict with `yield-star-spacing`
181+
function* foo(a) {
182+
return yield* a;
183+
}
184+
185+
// not conflict with `jsx-curly-spacing`
186+
let a = <A foo={this.foo} bar={function(){}} />
187+
```
188+
189+
190+
### Options
191+
192+
This rule has 3 options.
193+
194+
```json
195+
{
196+
"keyword-spacing": [2, {"before": true, "after": true, "overrides": null}]
197+
}
198+
```
199+
200+
- `"before"` (`boolean`, default is `true`) -
201+
This option specifies usage of spacing before the keywords.
202+
If `true` then the keywords must be preceded by at least one space.
203+
Otherwise, no spaces will be allowed before the keywords (if possible).
204+
- `"after"` (`boolean`, default is `true`) -
205+
This option specifies usage of spacing after the keywords.
206+
If `true` then the keywords must be followed by at least one space.
207+
Otherwise, no spaces will be allowed after the keywords (if possible).
208+
- `"overrides"` (`object`, default is `null`) -
209+
This option specifies overwriting usage of spacing for each keyword.
210+
For Example:
211+
212+
```json
213+
{
214+
"keyword-spacing": [2, {"overrides": {
215+
"if": {"after": false},
216+
"for": {"after": false},
217+
"while": {"after": false}
218+
}}]
219+
}
220+
```
221+
222+
In this case, no spaces will be allowed only after `if`, `for`, and `while`.
223+
224+
The following patterns are considered problems when configured `{"before": false, "after": false}`:
225+
226+
```js
227+
/*eslint keyword-spacing: [2, {before: false, after: false}]*/
228+
/*eslint-env es6*/
229+
230+
if (foo){ /*error Unexpected space(s) after "if".*/
231+
//...
232+
} else if(bar) { /*error Unexpected space(s) before "else".*/
233+
//...
234+
}else { /*error Unexpected space(s) after "else".*/
235+
//...
236+
}
237+
238+
try { /*error Unexpected space(s) after "try".*/
239+
//...
240+
} catch (e) { /*error Unexpected space(s) before "catch".*/
241+
/*error Unexpected space(s) after "catch".*/
242+
//...
243+
}
244+
245+
switch(a) {
246+
case +1: /*error Unexpected space(s) after "case".*/
247+
break;
248+
}
249+
250+
function foo() {
251+
return [0, 1, 2]; /*error Unexpected space(s) after "return".*/
252+
}
253+
254+
for (let [a, b] of [foo, bar, baz]) { /*error Unexpected space(s) after "let".*/
255+
/*error Unexpected space(s) before "of".*/
256+
/*error Unexpected space(s) after "of".*/
257+
//...
258+
}
259+
260+
let obj = {
261+
get [FOO]() { /*error Unexpected space(s) after "get".*/
262+
//...
263+
},
264+
set [FOO](value) { /*error Unexpected space(s) after "set".*/
265+
//...
266+
}
267+
};
268+
269+
import {foo} from "foo"; /*error Unexpected space(s) after "import".*/
270+
/*error Unexpected space(s) before "from".*/
271+
/*error Unexpected space(s) after "from".*/
272+
import * as bar from"foo"; /*error Unexpected space(s) after "import".*/
273+
/*error Unexpected space(s) before "as".*/
274+
```
275+
276+
The following patterns are considered not problems when configured `{"before": false, "after": false}`:
277+
278+
```js
279+
/*eslint keyword-spacing: [2, {before: false, after: false}]*/
280+
/*eslint-env es6*/
281+
282+
if(foo) {
283+
//...
284+
}else if(bar) {
285+
//...
286+
}else{
287+
//...
288+
}
289+
290+
try{
291+
//...
292+
}catch(e) {
293+
//...
294+
}
295+
296+
switch(a) {
297+
case+1:
298+
break;
299+
}
300+
301+
function foo() {
302+
return[0, 1, 2];
303+
}
304+
305+
for(let[a, b]of[foo, bar, baz]) {
306+
//...
307+
}
308+
309+
let obj = {
310+
get[FOO]() {
311+
//...
312+
},
313+
set[FOO](value) {
314+
//...
315+
}
316+
};
317+
```
318+
319+
## When Not To Use It
320+
321+
If you don't want to enforce consistency on keyword spacing, then it's safe to disable this rule.

docs/rules/space-after-keywords.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Require or disallow spaces following keywords (space-after-keywords)
22

3+
**Replacement notice**: This rule was removed in ESLint v2.0 and replaced by [keyword-spacing](keyword-spacing.md) rule.
4+
35
Some style guides will require or disallow spaces following the certain keywords.
46

57
```js

docs/rules/space-before-keywords.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Require or disallow spaces before keywords (space-before-keywords)
22

3+
**Replacement notice**: This rule was removed in ESLint v2.0 and replaced by [keyword-spacing](keyword-spacing.md) rule.
4+
35
Keywords are syntax elements of JavaScript, such as `function` and `if`. These identifiers have special meaning to the language and so often appear in a different color in code editors. As an important part of the language, style guides often refer to the spacing that should be used around keywords. For example, you might have a style guide that says keywords should be always be preceded by spaces, which would mean `if-else` statements must look like this:
46

57
```js

docs/rules/space-return-throw-case.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Require spaces following `return`, `throw`, and `case` (space-return-throw-case)
22

3+
**Replacement notice**: This rule was removed in ESLint v2.0 and replaced by [keyword-spacing](keyword-spacing.md) rule.
4+
35
Require spaces following `return`, `throw`, and `case`.
46

57
**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line.

0 commit comments

Comments
 (0)