10000 Fix: arrow-parens no reporting for comments inside (fixes #12995) (#1… · eslint/eslint@cc01451 · GitHub
[go: up one dir, main page]

Skip to content

Commit cc01451

Browse files
authored
Fix: arrow-parens no reporting for comments inside (fixes #12995) (#13312)
* Fix: no reportin for comments inside (fixes #12995) * Update: handled some cases for comments in parens * Chore: added some more tests * Chore: removed unnecessary blanklines * Update: added docs example and function refactor * Update: changed hasComment checks * Update: refactore and docs update * Docs: added docs example
1 parent a195141 commit cc01451

File tree

3 files changed

+165
-4
lines changed

3 files changed

+165
-4
lines changed

docs/rules/arrow-parens.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ Examples of **incorrect** code for this rule with the `"as-needed"` option:
159159
a.then((foo) => {});
160160
a.then((foo) => a);
161161
a((foo) => { if (true) {} });
162+
const f = /** @type {number} */(a) => a + a;
163+
const g = /* comment */ (a) => a + a;
164+
const h = (a) /* comment */ => a + a;
162165
```
163166

164167
Examples of **correct** code for this rule with the `"as-needed"` option:
@@ -177,6 +180,9 @@ a.then(foo => { if (true) {} });
177180
(a = 10) => a;
178181
([a, b]) => a;
179182
({a, b}) => a;
183+
const f = (/** @type {number} */a) => a + a;
184+
const g = (/* comment */ a) => a + a;
185+
const h = (a /* comment */) => a + a;
180186
```
181187

182188
### requireForBlockBody

lib/rules/arrow-parens.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,27 @@ module.exports = {
105105
], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
106106
}
107107

108+
/**
109+
* Checks whether there are comments inside the params or not.
110+
* @returns {boolean} `true` if there are comments inside of parens, else `false`
111+
*/
112+
function hasCommentsInParens() {
113+
if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
114+
const closingParenToken = sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
115+
116+
return closingParenToken && sourceCode.commentsExistBetween(firstTokenOfParam, closingParenToken);
117+
}
118+
return false;
119+
120+
}
121+
122+
if (hasCommentsInParens()) {
123+
return;
124+
}
125+
108126
// "as-needed", { "requireForBlockBody": true }: x => x
109127
if (
110128
requireForBlockBody &&
111-
node.params.length === 1 &&
112129
node.params[0].type === "Identifier" &&
113130
!node.params[0].typeAnnotation &&
114131
node.body.type !== "BlockStatement" &&
@@ -144,7 +161,6 @@ module.exports = {
144161

145162
// "as-needed": x => x
146163
if (asNeeded &&
147-
node.params.length === 1 &&
148164
node.params[0].type === "Identifier" &&
149165
!node.params[0].typeAnnotation &&
150166
!node.returnType
@@ -178,7 +194,7 @@ module.exports = {
178194
}
179195

180196
return {
181-
ArrowFunctionExpression: parens
197+
"ArrowFunctionExpression[params.length=1]": parens
182198
};
183199
}
184200
};

tests/lib/rules/arrow-parens.js

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ const valid = [
2929
"(a) => {\n}",
3030
"a.then((foo) => {});",
3131
"a.then((foo) => { if (true) {}; });",
32+
"const f = (/* */a) => a + a;",
33+
"const f = (a/** */) => a + a;",
34+
"const f = (a//\n) => a + a;",
35+
"const f = (//\na) => a + a;",
36+
"const f = (/*\n */a//\n) => a + a;",
37+
"const f = (/** @type {number} */a/**hello*/) => a + a;",
3238
{ code: "a.then(async (foo) => { if (true) {}; });", parserOptions: { ecmaVersion: 8 } },
3339

3440
// "always" (explicit)
@@ -68,7 +74,69 @@ const valid = [
6874
{ code: "async a => ({})", options: ["as-needed", { requireForBlockBody: true }], parserOptions: { ecmaVersion: 8 } },
6975
{ code: "async a => a", options: ["as-needed", { requireForBlockBody: true }], parserOptions: { ecmaVersion: 8 } },
7076
{ code: "(a: T) => a", options: ["as-needed", { requireForBlockBody: true }], parser: parser("identifer-type") },
71-
{ code: "(a): T => a", options: ["as-needed", { requireForBlockBody: true }], parser: parser("return-type") }
77+
{ code: "(a): T => a", options: ["as-needed", { requireForBlockBody: true }], parser: parser("return-type") },
78+
{
79+
code: "const f = (/** @type {number} */a/**hello*/) => a + a;",
80+
options: ["as-needed"]
81+
},
82+
{
83+
code: "const f = (/* */a) => a + a;",
84+
options: ["as-needed"]
85+
},
86+
{
87+
code: "const f = (a/** */) => a + a;",
88+
options: ["as-needed"]
89+
},
90+
{
91+
code: "const f = (a//\n) => a + a;",
92+
options: ["as-needed"]
93+
},
94+
{
95+
code: "const f = (//\na) => a + a;",
96+
options: ["as-needed"]
97+
},
98+
{
99+
code: "const f = (/*\n */a//\n) => a + a;",
100+
options: ["as-needed"]
101+
},
102+
{
103+
code: "var foo = (a,/**/) => b;",
104+
parserOptions: { ecmaVersion: 2017 },
105+
options: ["as-needed"]
106+
},
107+
{
108+
code: "var foo = (a , /**/) => b;",
109+
parserOptions: { ecmaVersion: 2017 },
110+
options: ["as-needed"]
111+
},
112+
{
113+
code: "var foo = (a\n,\n/**/) => b;",
114+
parserOptions: { ecmaVersion: 2017 },
115+
options: [< 10000 /span>"as-needed"]
116+
},
117+
{
118+
code: "var foo = (a,//\n) => b;",
119+
parserOptions: { ecmaVersion: 2017 },
120+
options: ["as-needed"]
121+
},
122+
{
123+
code: "const i = (a/**/,) => a + a;",
124+
parserOptions: { ecmaVersion: 2017 },
125+
options: ["as-needed"]
126+
},
127+
{
128+
code: "const i = (a \n /**/,) => a + a;",
129+
parserOptions: { ecmaVersion: 2017 },
130+
options: ["as-needed"]
131+
},
132+
{
133+
code: "var bar = ({/*comment here*/a}) => a",
134+
options: ["as-needed"]
135+
},
136+
{
137+
code: "var bar = (/*comment here*/{a}) => a",
138+
options: ["as-needed"]
139+
}
72140
];
73141

74142
const type = "ArrowFunctionExpression";
@@ -271,7 +339,78 @@ const invalid = [
271339
messageId: "unexpectedParensInline",
272340
type
273341
}]
342+
},
343+
{
344+
code: "const f = /** @type {number} */(a)/**hello*/ => a + a;",
345+
options: ["as-needed"],
346+
output: "const f = /** @type {number} */a/**hello*/ => a + a;",
347+
errors: [{
348+
line: 1,
349+
column: 33,
350+
type,
351+
messageId: "unexpectedParens",
352+
endLine: 1,
353+
endColumn: 34
354+
}]
355+
},
356+
{
357+
code: "const f = //\n(a) => a + a;",
358+
output: "const f = //\na => a + a;",
359+
options: ["as-needed"],
360+
errors: [{
361+
line: 2,
362+
column: 2,
363+
type,
364+
messageId: "unexpectedParens",
365+
endLine: 2,
366+
endColumn: 3
367+
}]
368+
},
369+
{
370+
code: "var foo = /**/ a => b;",
371+
output: "var foo = /**/ (a) => b;",
372+
errors: [{
373+
line: 1,
374+
column: 16,
375+
type: "ArrowFunctionExpression",
376+
messageId: "expectedParens",
377+
endLine: 1,
378+
endColumn: 17
379+
}]
380+
},
381+
{
382+
code: "var bar = a /**/ => b;",
383+
output: "var bar = (a) /**/ => b;",
384+
errors: [{
385+
line: 1,
386+
column: 11,
387+
type: "ArrowFunctionExpression",
388+
messageId: "expectedParens",
389+
endLine: 1,
390+
endColumn: 12
391+
}]
392+
},
393+
{
394+
code: `const foo = a => {};
395+
396+
// comment between 'a' and an unrelated closing paren
397+
398+
bar();`,
399+
output: `const foo = (a) => {};
400+
401+
// comment between 'a' and an unrelated closing paren
402+
403+
bar();`,
404+
errors: [{
405+
line: 1,
406+
column: 13,
407+
type: "ArrowFunctionExpression",
408+
messageId: "expectedParens",
409+
endLine: 1,
410+
endColumn: 14
411+
}]
274412
}
413+
275414
];
276415

277416
ruleTester.run("arrow-parens", rule, {

0 commit comments

Comments
 (0)
0