Skip to content

Commit 64c0607

Browse files
authored
feat(space-before-function-paren)!: handle catch clause with param (#821)
* perf: skip ignored cases early * feat(space-before-function-paren): handle catch clause with param * docs: update * fix(keyword-spacing)!: do not handle catch clause with param * docs: update
1 parent 7c6d6ef commit 64c0607

7 files changed

Lines changed: 214 additions & 34 deletions

File tree

packages/eslint-plugin/rules/keyword-spacing/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
---
22
title: keyword-spacing
33
rule_type: layout
4+
related_rules:
5+
- space-before-function-paren
46
---
57

68
# keyword-spacing
@@ -20,7 +22,10 @@ if (foo) {
2022

2123
Of course, you could also have a style guide that disallows spaces around keywords.
2224

23-
However, if you want to enforce the style of spacing between the `function` keyword and the following opening parenthesis, please refer to [space-before-function-paren](space-before-function-paren).
25+
However, if you want to enforce the style of following spacing cases, please refer to [space-before-function-paren](space-before-function-paren).
26+
27+
- Between the `function` keyword and the following opening parenthesis
28+
- After the `catch` keyword and the following opening parenthesis (only when parameters are present)
2429

2530
## Rule Details
2631

packages/eslint-plugin/rules/keyword-spacing/keyword-spacing._js_.test.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ run<RuleOptions, MessageIds>({
353353
// catch
354354
// ----------------------------------------------------------------------
355355

356+
'try {} catch {}',
357+
{ code: 'try{}catch{}', options: [NEITHER] },
358+
{ code: 'try{} catch {}', options: [override('catch', BOTH)] },
359+
{ code: 'try {}catch{}', options: [override('catch', NEITHER)] },
360+
'try {}\ncatch {}',
361+
{ code: 'try{}\ncatch{}', options: [NEITHER] },
356362
'try {} catch (e) {}',
357363
{ code: 'try{}catch(e) {}', options: [NEITHER] },
358364
{ code: 'try{} catch (e) {}', options: [override('catch', BOTH)] },
@@ -1979,28 +1985,51 @@ run<RuleOptions, MessageIds>({
19791985
// ----------------------------------------------------------------------
19801986

19811987
{
1982-
code: 'try {}catch(e) {}',
1983-
output: 'try {} catch (e) {}',
1988+
code: 'try {}catch{}',
1989+
output: 'try {} catch {}',
19841990
errors: expectedBeforeAndAfter('catch'),
19851991
},
19861992
{
1987-
code: 'try{} catch (e) {}',
1988-
output: 'try{}catch(e) {}',
1993+
code: 'try{} catch {}',
1994+
output: 'try{}catch{}',
19891995
options: [NEITHER],
19901996
errors: unexpectedBeforeAndAfter('catch'),
19911997
},
19921998
{
1993-
code: 'try{}catch(e) {}',
1994-
output: 'try{} catch (e) {}',
1999+
code: 'try{}catch{}',
2000+
output: 'try{} catch {}',
19952001
options: [override('catch', BOTH)],
19962002
errors: expectedBeforeAndAfter('catch'),
19972003
},
19982004
{
1999-
code: 'try {} catch (e) {}',
2000-
output: 'try {}catch(e) {}',
2005+
code: 'try {} catch {}',
2006+
output: 'try {}catch{}',
20012007
options: [override('catch', NEITHER)],
20022008
errors: unexpectedBeforeAndAfter('catch'),
20032009
},
2010+
{
2011+
code: 'try {}catch(e) {}',
2012+
output: 'try {} catch(e) {}',
2013+
errors: expectedBefore('catch'),
2014+
},
2015+
{
2016+
code: 'try{} catch (e) {}',
2017+
output: 'try{}catch (e) {}',
2018+
options: [NEITHER],
2019+
errors: unexpectedBefore('catch'),
2020+
},
2021+
{
2022+
code: 'try{}catch(e) {}',
2023+
output: 'try{} catch(e) {}',
2024+
options: [override('catch', BOTH)],
2025+
errors: expectedBefore('catch'),
2026+
},
2027+
{
2028+
code: 'try {} catch (e) {}',
2029+
output: 'try {}catch (e) {}',
2030+
options: [override('catch', NEITHER)],
2031+
errors: unexpectedBefore('catch'),
2032+
},
20042033

20052034
// ----------------------------------------------------------------------
20062035
// class

packages/eslint-plugin/rules/keyword-spacing/keyword-spacing.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,19 @@ export default createRule<RuleOptions, MessageIds>({
467467
ReturnStatement: checkSpacingAroundFirstToken,
468468
ThrowStatement: checkSpacingAroundFirstToken,
469469
TryStatement(node) {
470+
// try
470471
checkSpacingAroundFirstToken(node)
471-
checkSpacingAroundFirstToken(node.handler)
472+
// catch
473+
if (node.handler) {
474+
// The space after `catch` handled by the `space-before-function-paren`
475+
if (node.handler.param) {
476+
checkSpacingBeforeFirstToken(node.handler)
477+
}
478+
else {
479+
checkSpacingAroundFirstToken(node.handler)
480+
}
481+
}
482+
// finally
472483
checkSpacingAroundTokenBefore(node.finalizer)
473484
},
474485

packages/eslint-plugin/rules/space-before-function-paren/README.md

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ This rule has a string option or an object option:
4040
"space-before-function-paren": ["error", {
4141
"anonymous": "always",
4242
"named": "always",
43-
"asyncArrow": "always"
43+
"asyncArrow": "always",
44+
"catch": "always"
4445
}],
4546
}
4647
```
@@ -56,6 +57,7 @@ Each of the following options can be set to `"always"`, `"never"`, or `"ignore"`
5657
- `anonymous` is for anonymous function expressions (e.g. `function () {}`).
5758
- `named` is for named function expressions (e.g. `function foo () {}`).
5859
- `asyncArrow` is for async arrow function expressions (e.g. `async () => {}`).
60+
- `catch` is for catch clause with params (e.g. `catch (e) {}`).
5961

6062
### "always"
6163

@@ -92,6 +94,12 @@ var baz = {
9294
};
9395

9496
var baz = async() => 1
97+
98+
try {
99+
// ...
100+
} catch(e) {
101+
// ...
102+
}
95103
```
96104

97105
:::
@@ -129,6 +137,12 @@ var baz = {
129137
};
130138

131139
var baz = async () => 1
140+
141+
try {
142+
// ...
143+
} catch (e) {
144+
// ...
145+
}
132146
```
133147

134148
:::
@@ -168,6 +182,12 @@ var baz = {
168182
};
169183

170184
var baz = async () => 1
185+
186+
try {
187+
// ...
188+
} catch (e) {
189+
// ...
190+
}
171191
```
172192

173193
:::
@@ -205,18 +225,24 @@ var baz = {
205225
};
206226

207227
var baz = async() => 1
228+
229+
try {
230+
// ...
231+
} catch(e) {
232+
// ...
233+
}
208234
```
209235

210236
:::
211237

212-
### `{"anonymous": "always", "named": "never", "asyncArrow": "always"}`
238+
### `{"anonymous": "always", "named": "never", "asyncArrow": "always", "catch": "always"}`
213239

214-
Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option:
240+
Examples of **incorrect** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always", "catch": "always"}` option:
215241

216242
::: incorrect
217243

218244
```js
219-
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/
245+
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always", "catch": "always"}]*/
220246
/*eslint-env es6*/
221247

222248
function foo () {
@@ -240,16 +266,22 @@ var baz = {
240266
};
241267

242268
var baz = async(a) => await a
269+
270+
try {
271+
// ...
272+
} catch(e) {
273+
// ...
274+
}
243275
```
244276

245277
:::
246278

247-
Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always"}` option:
279+
Examples of **correct** code for this rule with the `{"anonymous": "always", "named": "never", "asyncArrow": "always", "catch": "always"}` option:
248280

249281
::: correct
250282

251283
```js
252-
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}]*/
284+
/*eslint space-before-function-paren: ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always", "catch": "always"}]*/
253285
/*eslint-env es6*/
254286

255287
function foo() {
@@ -273,18 +305,24 @@ var baz = {
273305
};
274306

275307
var baz = async (a) => await a
308+
309+
try {
310+
// ...
311+
} catch (e) {
312+
// ...
313+
}
276314
```
277315

278316
:::
279317

280-
### `{"anonymous": "never", "named": "always"}`
318+
### `{"anonymous": "never", "named": "always", "catch": "never"}`
281319

282-
Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
320+
Examples of **incorrect** code for this rule with the `{"anonymous": "never", "named": "always", "catch": "never"}` option:
283321

284322
::: incorrect
285323

286324
```js
287-
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/
325+
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always", "catch": "never" }]*/
288326
/*eslint-env es6*/
289327

290328
function foo() {
@@ -306,16 +344,22 @@ var baz = {
306344
// ...
307345
}
308346
};
347+
348+
try {
349+
// ...
350+
} catch (e) {
351+
// ...
352+
}
309353
```
310354

311355
:::
312356

313-
Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always"}` option:
357+
Examples of **correct** code for this rule with the `{"anonymous": "never", "named": "always", "catch": "never"}` option:
314358

315359
::: correct
316360

317361
```js
318-
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always" }]*/
362+
/*eslint space-before-function-paren: ["error", { "anonymous": "never", "named": "always", "catch": "never" }]*/
319363
/*eslint-env es6*/
320364

321365
function foo () {
@@ -337,18 +381,24 @@ var baz = {
337381
// ...
338382
}
339383
};
384+
385+
try {
386+
// ...
387+
} catch(e) {
388+
// ...
389+
}
340390
```
341391

342392
:::
343393

344-
### `{"anonymous": "ignore", "named": "always"}`
394+
### `{"anonymous": "ignore", "named": "always", "catch": "never"}`
345395

346-
Examples of **incorrect** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option:
396+
Examples of **incorrect** code for this rule with the `{"anonymous": "ignore", "named": "always", "catch": "never"}` option:
347397

348398
::: incorrect
349399

350400
```js
351-
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/
401+
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always", "catch": "never" }]*/
352402
/*eslint-env es6*/
353403

354404
function foo() {
@@ -366,16 +416,22 @@ var baz = {
366416
// ...
367417
}
368418
};
419+
420+
try {
421+
// ...
422+
} catch (e) {
423+
// ...
424+
}
369425
```
370426

371427
:::
372428

373-
Examples of **correct** code for this rule with the `{"anonymous": "ignore", "named": "always"}` option:
429+
Examples of **correct** code for this rule with the `{"anonymous": "ignore", "named": "always", "catch": "never"}` option:
374430

375431
::: correct
376432

377433
```js
378-
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always" }]*/
434+
/*eslint space-before-function-paren: ["error", { "anonymous": "ignore", "named": "always", "catch": "never" }]*/
379435
/*eslint-env es6*/
380436

381437
var bar = function() {
@@ -401,6 +457,12 @@ var baz = {
401457
// ...
402458
}
403459
};
460+
461+
try {
462+
// ...
463+
} catch(e) {
464+
// ...
465+
}
404466
```
405467

406468
:::

packages/eslint-plugin/rules/space-before-function-paren/space-before-function-paren._js_.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ run<RuleOptions, MessageIds>({
117117
{ code: 'async () => 1', parserOptions: { ecmaVersion: 8 } },
118118
{ code: 'async () => 1', options: ['always'], parserOptions: { ecmaVersion: 8 } },
119119
{ code: 'async() => 1', options: ['never'], parserOptions: { ecmaVersion: 8 } },
120+
121+
// Catch clause
122+
{ code: 'try {} catch (e) {}' },
123+
{ code: 'try {} catch (e) {}', options: ['always'] },
124+
{ code: 'try {} catch(e) {}', options: ['never'] },
125+
{ code: 'try {} catch (e) {}', options: [{ catch: 'always' }] },
126+
{ code: 'try {} catch(e) {}', options: [{ catch: 'never' }] },
127+
{ code: 'try {} catch (e) {}', options: [{ catch: 'ignore' }] },
128+
{ code: 'try {} catch(e) {}', options: [{ catch: 'ignore' }] },
120129
],
121130

122131
invalid: [
@@ -612,5 +621,36 @@ run<RuleOptions, MessageIds>({
612621
parserOptions: { ecmaVersion: 8 },
613622
errors: [{ messageId: 'unexpectedSpace', type: 'ArrowFunctionExpression' }],
614623
},
624+
625+
// Catch clause
626+
{
627+
code: 'try {} catch(e) {}',
628+
output: 'try {} catch (e) {}',
629+
errors: [{ messageId: 'missingSpace', type: 'CatchClause' }],
630+
},
631+
{
632+
code: 'try {} catch(e) {}',
633+
output: 'try {} catch (e) {}',
634+
options: ['always'],
635+
errors: [{ messageId: 'missingSpace', type: 'CatchClause' }],
636+
},
637+
{
638+
code: 'try {} catch (e) {}',
639+
output: 'try {} catch(e) {}',
640+
options: ['never'],
641+
errors: [{ messageId: 'unexpectedSpace', type: 'CatchClause' }],
642+
},
643+
{
644+
code: 'try {} catch(e) {}',
645+
output: 'try {} catch (e) {}',
646+
options: [{ catch: 'always' }],
647+
errors: [{ messageId: 'missingSpace', type: 'CatchClause' }],
648+
},
649+
{
650+
code: 'try {} catch (e) {}',
651+
output: 'try {} catch(e) {}',
652+
options: [{ catch: 'never' }],
653+
errors: [{ messageId: 'unexpectedSpace', type: 'CatchClause' }],
654+
},
615655
],
616656
})

0 commit comments

Comments
 (0)