Skip to content
This repository was archived by the owner on Mar 25, 2021. It is now read-only.

Commit 20eec28

Browse files
saberduckJosh Goldberg
authored andcommitted
Add option to ignore accessors in adjacent-overload-signatures (#3718)
* add noAsyncWithoutAwait rule * fix lint * code review updates * Add option to ignore accessors in adjacent-overload-signatures * Fix options schema * allow return as well as await * remove unneeded lint ignore * improve rationale & fix performance issue * fixes according to review * finish fixing according to review * Initial feedback cleanups * Refactored to walk function * Reset tslint.json to master * Converted options to object form * Disabled no-object-literal-type-assertion complaint
1 parent 0807692 commit 20eec28

File tree

5 files changed

+75
-12
lines changed

5 files changed

+75
-12
lines changed

src/rules/adjacentOverloadSignaturesRule.ts

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,30 @@ import * as ts from "typescript";
2020

2121
import * as Lint from "../index";
2222

23+
const OPTION_IGNORE_ACCESSORS = "ignore-accessors";
24+
25+
interface Options {
26+
ignoreAccessors: boolean;
27+
}
28+
2329
export class Rule extends Lint.Rules.AbstractRule {
2430
/* tslint:disable:object-literal-sort-keys */
2531
public static metadata: Lint.IRuleMetadata = {
2632
ruleName: "adjacent-overload-signatures",
2733
description: "Enforces function overloads to be consecutive.",
28-
optionsDescription: "Not configurable.",
29-
options: null,
30-
optionExamples: [true],
34+
optionsDescription: Lint.Utils.dedent`
35+
If \`${OPTION_IGNORE_ACCESSORS}\` is specified, then getters and setters are not considered to be overloads
36+
of function with the same signature.`,
37+
options: {
38+
type: "object",
39+
properties: {
40+
[OPTION_IGNORE_ACCESSORS]: {
41+
type: "boolean",
42+
},
43+
},
44+
additionalProperties: false,
45+
},
46+
optionExamples: [true, [true, { OPTION_IGNORE_ACCESSORS: true }]],
3147
rationale:
3248
"Improves readability and organization by grouping naturally related items together.",
3349
type: "typescript",
@@ -40,11 +56,15 @@ export class Rule extends Lint.Rules.AbstractRule {
4056
}
4157

4258
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
43-
return this.applyWithFunction(sourceFile, walk);
59+
// tslint:disable-next-line: no-object-literal-type-assertion
60+
const rawOptions = { ...this.ruleArguments[0] } as { [OPTION_IGNORE_ACCESSORS]?: boolean };
61+
return this.applyWithFunction(sourceFile, walk, {
62+
ignoreAccessors: !!rawOptions[OPTION_IGNORE_ACCESSORS],
63+
});
4464
}
4565
}
4666

47-
function walk(ctx: Lint.WalkContext): void {
67+
function walk(ctx: Lint.WalkContext<Options>): void {
4868
const { sourceFile } = ctx;
4969
visitStatements(sourceFile.statements);
5070
return ts.forEachChild(sourceFile, function cb(node: ts.Node): void {
@@ -61,8 +81,13 @@ function walk(ctx: Lint.WalkContext): void {
6181
| ts.ClassDeclaration
6282
| ts.TypeLiteralNode;
6383
addFailures(
64-
getMisplacedOverloads<ts.TypeElement | ts.ClassElement>(members, member =>
65-
utils.isSignatureDeclaration(member) ? getOverloadKey(member) : undefined,
84+
getMisplacedOverloads<ts.TypeElement | ts.ClassElement>(
85+
members,
86+
member =>
87+
utils.isSignatureDeclaration(member)
88+
? getOverloadKey(member)
89+
: undefined,
90+
ctx.options.ignoreAccessors,
6691
),
6792
);
6893
}
@@ -73,10 +98,13 @@ function walk(ctx: Lint.WalkContext): void {
7398

7499
function visitStatements(statements: ReadonlyArray<ts.Statement>): void {
75100
addFailures(
76-
getMisplacedOverloads(statements, statement =>
77-
utils.isFunctionDeclaration(statement) && statement.name !== undefined
78-
? statement.name.text
79-
: undefined,
101+
getMisplacedOverloads(
102+
statements,
103+
statement =>
104+
utils.isFunctionDeclaration(statement) && statement.name !== undefined
105+
? statement.name.text
106+
: undefined,
107+
ctx.options.ignoreAccessors,
80108
),
81109
);
82110
}
@@ -92,12 +120,16 @@ function walk(ctx: Lint.WalkContext): void {
92120
function getMisplacedOverloads<T extends ts.Node>(
93121
overloads: ReadonlyArray<T>,
94122
getKey: (node: T) => string | undefined,
123+
ignoreAccessors: boolean,
95124
): ts.SignatureDeclaration[] {
96125
const result: ts.SignatureDeclaration[] = [];
97126
let lastKey: string | undefined;
98127
const seen = new Set<string>();
99128
for (const node of overloads) {
100-
if (node.kind === ts.SyntaxKind.SemicolonClassElement) {
129+
if (
130+
node.kind === ts.SyntaxKind.SemicolonClassElement ||
131+
(ignoreAccessors && isAccessor(node))
132+
) {
101133
continue;
102134
}
103135

@@ -115,6 +147,10 @@ function getMisplacedOverloads<T extends ts.Node>(
115147
return result;
116148
}
117149

150+
function isAccessor(member: ts.Node): boolean {
151+
return member.kind === ts.SyntaxKind.GetAccessor || member.kind === ts.SyntaxKind.SetAccessor;
152+
}
153+
118154
function printOverload(node: ts.SignatureDeclaration): string {
119155
const info = getOverloadInfo(node);
120156
return typeof info === "string" ? info : info === undefined ? "<unknown>" : info.name;

test/rules/adjacent-overload-signatures/test.ts.lint renamed to test/rules/adjacent-overload-signatures/default/test.ts.lint

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,14 @@ interface I {
153153
[Symbol.iterator](): void;
154154
~~~~~~~~~~~~~~~~~~~~~~~~~~ [All 'Symbol.iterator' signatures should be adjacent]
155155
}
156+
157+
class Accessors {
158+
private x: number;
159+
private y: number;
160+
get x() {return this.x;}
161+
get y() {return this.y;}
162+
set x(newX: number) {this.x = newX;}
163+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [All 'x' signatures should be adjacent]
164+
set y(newY: number) {this.y = newY;}
165+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [All 'y' signatures should be adjacent]
166+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// good
2+
3+
class Accessors {
4+
private x: number;
5+
private y: number;
6+
get x() {return this.x;}
7+
get y() {return this.y;}
8+
// setter is not considered as an overload of getter
9+
set x(newX: number) {this.x = newX;}
10+
set y(newY: number) {this.y = newY;}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rules": {
3+
"adjacent-overload-signatures": [true, { "ignore-accessors": true }]
4+
}
5+
}

0 commit comments

Comments
 (0)