Skip to content

Commit 69aac01

Browse files
authored
fix: support TSFunctionType in getFunctionHeadLoc (#21335)
fix: correct `max-params` report location for TS function types
1 parent 686630e commit 69aac01

3 files changed

Lines changed: 160 additions & 2 deletions

File tree

lib/rules/utils/ast-utils.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,8 @@ module.exports = {
23942394
* ^^^^^^^^^^^^^^^^^^^^^
23952395
* - `class A { foo = (a, b) => {} }`
23962396
* ^^^^^^
2397+
* - `type F = (a, b) => void`
2398+
* ^^
23972399
* @param {ASTNode} node The function node to get.
23982400
* @param {SourceCode} sourceCode The source code object to get tokens.
23992401
* @returns {string} The location of the function node for reporting.
@@ -2418,6 +2420,14 @@ module.exports = {
24182420
isArrowToken,
24192421
);
24202422

2423+
start = arrowToken.loc.start;
2424+
end = arrowToken.loc.end;
2425+
} else if (node.type === "TSFunctionType") {
2426+
const arrowToken = sourceCode.getTokenBefore(
2427+
node.returnType.typeAnnotation,
2428+
isArrowToken,
2429+
);
2430+
24212431
start = arrowToken.loc.start;
24222432
end = arrowToken.loc.end;
24232433
} else {

tests/lib/rules/max-params.js

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,124 @@ ruleTesterTypeScript.run("max-params", rule, {
328328
declare function makeDate(m: number, d: number, y: number): Date;
329329
`,
330330
options: [{ max: 1 }],
331-
errors: [{ messageId: "exceed" }],
331+
errors: [
332+
{
333+
messageId: "exceed",
334+
data: { name: "Function 'makeDate'", count: 3, max: 1 },
335+
line: 2,
336+
column: 3,
337+
endLine: 2,
338+
endColumn: 28,
339+
},
340+
],
332341
},
333342
{
334343
code: `
335344
type sum = (a: number, b: number) => number;
336345
`,
337346
options: [{ max: 1 }],
338-
errors: [{ messageId: "exceed" }],
347+
errors: [
348+
{
349+
messageId: "exceed",
350+
data: { name: "Function", count: 2, max: 1 },
351+
line: 2,
352+
column: 37,
353+
endLine: 2,
354+
endColumn: 39,
355+
},
356+
],
357+
},
358+
{
359+
code: "let f: (a: number, b: number) => number;",
360+
options: [{ max: 1 }],
361+
errors: [
362+
{
363+
messageId: "exceed",
364+
data: { name: "Function", count: 2, max: 1 },
365+
line: 1,
366+
column: 31,
367+
endLine: 1,
368+
endColumn: 33,
369+
},
370+
],
371+
},
372+
{
373+
code: "interface I { m: (a: number, b: number) => number; }",
374+
options: [{ max: 1 }],
375+
errors: [
376+
{
377+
messageId: "exceed",
378+
data: { name: "Function", count: 2, max: 1 },
379+
line: 1,
380+
column: 41,
381+
endLine: 1,
382+
endColumn: 43,
383+
},
384+
],
385+
},
386+
{
387+
code: "function g(cb: (a: number, b: number) => number) {}",
388+
options: [{ max: 1 }],
389+
errors: [
390+
{
391+
messageId: "exceed",
392+
data: { name: "Function", count: 2, max: 1 },
393+
line: 1,
394+
column: 39,
395+
endLine: 1,
396+
endColumn: 41,
397+
},
398+
],
399+
},
400+
{
401+
code: "declare function g(): (a: number, b: number) => number;",
402+
options: [{ max: 1 }],
403+
errors: [
404+
{
405+
messageId: "exceed",
406+
data: { name: "Function", count: 2, max: 1 },
407+
line: 1,
408+
column: 46,
409+
endLine: 1,
410+
endColumn: 48,
411+
},
412+
],
413+
},
414+
{
415+
code: "type F = <T>(a: T, b: T) => T;",
416+
options: [{ max: 1 }],
417+
errors: [
418+
{
419+
messageId: "exceed",
420+
data: { name: "Function", count: 2, max: 1 },
421+
line: 1,
422+
column: 26,
423+
endLine: 1,
424+
endColumn: 28,
425+
},
426+
],
427+
},
428+
{
429+
code: "type F = (a: number, b: number) => (c: number, d: number) => number;",
430+
options: [{ max: 1 }],
431+
errors: [
432+
{
433+
messageId: "exceed",
434+
data: { name: "Function", count: 2, max: 1 },
435+
line: 1,
436+
column: 33,
437+
endLine: 1,
438+
endColumn: 35,
439+
},
440+
{
441+
messageId: "exceed",
442+
data: { name: "Function", count: 2, max: 1 },
443+
line: 1,
444+
column: 59,
445+
endLine: 1,
446+
endColumn: 61,
447+
},
448+
],
339449
},
340450
{
341451
code: `function foo(this: unknown[], a, b, c) {}`,

tests/lib/rules/utils/ast-utils.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,44 @@ describe("ast-utils", () => {
12571257
);
12581258
});
12591259
});
1260+
1261+
it('should return the location of the `=>` token for "type F = (a, b) => void".', () => {
1262+
const expectedLoc = {
1263+
start: { line: 1, column: 16 },
1264+
end: { line: 1, column: 18 },
1265+
};
1266+
1267+
linter.verify(
1268+
"type F = (a, b) => void",
1269+
{
1270+
files: ["**/*.ts"],
1271+
languageOptions: {
1272+
parser: require("@typescript-eslint/parser"),
1273+
},
1274+
plugins: {
1275+
test: {
1276+
rules: {
1277+
checker: {
1278+
create: mustCall(() => ({
1279+
TSFunctionType: mustCall(node => {
1280+
assert.deepStrictEqual(
1281+
astUtils.getFunctionHeadLoc(
1282+
node,
1283+
linter.getSourceCode(),
1284+
),
1285+
expectedLoc,
1286+
);
1287+
}),
1288+
})),
1289+
},
1290+
},
1291+
},
1292+
},
1293+
rules: { "test/checker": "error" },
1294+
},
1295+
"test.ts",
1296+
);
1297+
});
12601298
});
12611299

12621300
describe("isEmptyBlock", () => {

0 commit comments

Comments
 (0)