Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(eslint-plugin): [adjacent-overload-signatures] fix false positive on call signatures and a method named call #2313

Merged
merged 1 commit into from Jul 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
68 changes: 47 additions & 21 deletions packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts
Expand Up @@ -30,16 +30,24 @@ export default util.createRule({
create(context) {
const sourceCode = context.getSourceCode();

interface Method {
name: string;
static: boolean;
callSignature: boolean;
}

/**
* Gets the name of the member being processed.
* Gets the name and attribute of the member being processed.
* @param member the member being processed.
* @returns the name of the member or null if it's a member not relevant to the rule.
* @returns the name and attribute of the member or null if it's a member not relevant to the rule.
*/
function getMemberName(member: TSESTree.Node): string | null {
function getMemberMethod(member: TSESTree.Node): Method | null {
if (!member) {
return null;
}

const isStatic = 'static' in member && !!member.static;

switch (member.type) {
case AST_NODE_TYPES.ExportDefaultDeclaration:
case AST_NODE_TYPES.ExportNamedDeclaration: {
Expand All @@ -49,33 +57,55 @@ export default util.createRule({
return null;
}

return getMemberName(member.declaration);
return getMemberMethod(member.declaration);
}
case AST_NODE_TYPES.TSDeclareFunction:
case AST_NODE_TYPES.FunctionDeclaration:
return member.id?.name ?? null;
case AST_NODE_TYPES.FunctionDeclaration: {
const name = member.id?.name ?? null;
if (name === null) {
return null;
}
return {
name,
static: isStatic,
callSignature: false,
};
}
case AST_NODE_TYPES.TSMethodSignature:
return util.getNameFromMember(member, sourceCode);
return {
name: util.getNameFromMember(member, sourceCode),
static: isStatic,
callSignature: false,
};
case AST_NODE_TYPES.TSCallSignatureDeclaration:
return 'call';
return {
name: 'call',
static: isStatic,
callSignature: true,
};
case AST_NODE_TYPES.TSConstructSignatureDeclaration:
return 'new';
return {
name: 'new',
static: isStatic,
callSignature: false,
};
case AST_NODE_TYPES.MethodDefinition:
return util.getNameFromMember(member, sourceCode);
return {
name: util.getNameFromMember(member, sourceCode),
static: isStatic,
callSignature: false,
};
}

return null;
}

interface Method {
name: string;
static: boolean;
}
function isSameMethod(method1: Method, method2: Method | null): boolean {
return (
!!method2 &&
method1.name === method2.name &&
method1.static === method2.static
method1.static === method2.static &&
method1.callSignature === method2.callSignature
);
}

Expand Down Expand Up @@ -104,15 +134,11 @@ export default util.createRule({
const seenMethods: Method[] = [];

members.forEach(member => {
const name = getMemberName(member);
if (name === null) {
const method = getMemberMethod(member);
if (method === null) {
lastMethod = null;
return;
}
const method = {
name,
static: 'static' in member && !!member.static,
};

const index = seenMethods.findIndex(seenMethod =>
isSameMethod(method, seenMethod),
Expand Down
Expand Up @@ -131,6 +131,17 @@ interface Foo {
}
`,
`
interface Foo {
(s: string): void;
(n: number): void;
(sn: string | number): void;
foo(n: number): void;
bar(): void;
baz(): void;
call(): void;
}
`,
`
interface Foo {
foo(s: string): void;
foo(n: number): void;
Expand Down Expand Up @@ -534,6 +545,7 @@ interface Foo {
(sn: string | number): void;
bar(): void;
baz(): void;
call(): void;
}
`,
errors: [
Expand Down