Skip to content

Commit

Permalink
Add support for class get/set accessors (resolves #297)
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Oct 17, 2023
1 parent 3e29758 commit d027e97
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
21 changes: 20 additions & 1 deletion fixtures/members/members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,29 @@ export class MyClass {
};

dUnusedMember() {}
dUsedExternal() {}
dUsedExternal() {
const value = this.usedGetter;
this.usedSetter = value;
}

static eUnusedStatic = 1;
static eUsedExternal = 1;

public get usedGetter(): string {
return 'usedGetter';
}

public set usedSetter(value: string) {
console.log(value);
}

public get unusedGetter(): string {
return 'unusedGetter';
}

public set unusedSetter(value: string) {
console.log(value);
}
}

MyClass.displayName = 'My Class';
8 changes: 7 additions & 1 deletion src/typescript/ast-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ export function isValidImportTypeNode(node: ts.Node): node is ValidImportTypeNod
return ts.isImportTypeNode(node);
}

export function isPrivateMember(node: ts.MethodDeclaration | ts.PropertyDeclaration): boolean {
export function isGetOrSetAccessorDeclaration(node: ts.Node): node is ts.AccessorDeclaration {
return node.kind === ts.SyntaxKind.SetAccessor || node.kind === ts.SyntaxKind.GetAccessor;
}

export function isPrivateMember(
node: ts.MethodDeclaration | ts.PropertyDeclaration | ts.SetAccessorDeclaration | ts.GetAccessorDeclaration
): boolean {
return node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.PrivateKeyword) ?? false;
}

Expand Down
7 changes: 5 additions & 2 deletions src/typescript/visitors/exports/exportKeyword.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ts from 'typescript';
import { SymbolType } from '../../../types/issues.js';
import { compact } from '../../../util/array.js';
import { isPrivateMember, stripQuotes } from '../../ast-helpers.js';
import { isGetOrSetAccessorDeclaration, isPrivateMember, stripQuotes } from '../../ast-helpers.js';
import { exportVisitor as visit } from '../index.js';

export default visit(
Expand Down Expand Up @@ -62,7 +62,10 @@ export default visit(
const members = node.members
.filter(
(member): member is ts.MethodDeclaration | ts.PropertyDeclaration =>
(ts.isPropertyDeclaration(member) || ts.isMethodDeclaration(member)) && !isPrivateMember(member)
(ts.isPropertyDeclaration(member) ||
ts.isMethodDeclaration(member) ||
isGetOrSetAccessorDeclaration(member)) &&
!isPrivateMember(member)
)
.map(member => ({
node: member,
Expand Down
6 changes: 4 additions & 2 deletions test/members.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,18 @@ test('Find unused enum and class members', async () => {
assert(issues.enumMembers['members.ts']['B_Unused']);
assert(issues.enumMembers['members.ts']['D_Key']);

assert.equal(Object.keys(issues.classMembers['members.ts']).length, 4);
assert.equal(Object.keys(issues.classMembers['members.ts']).length, 6);
assert(issues.classMembers['members.ts']['bUnusedPublic']);
assert(issues.classMembers['members.ts']['cUnusedProp']);
assert(issues.classMembers['members.ts']['dUnusedMember']);
assert(issues.classMembers['members.ts']['eUnusedStatic']);
assert(issues.classMembers['members.ts']['unusedGetter']);
assert(issues.classMembers['members.ts']['unusedSetter']);

assert.deepEqual(counters, {
...baseCounters,
enumMembers: 2,
classMembers: 4,
classMembers: 6,
processed: 2,
total: 2,
});
Expand Down

0 comments on commit d027e97

Please sign in to comment.