Skip to content

Commit

Permalink
Put getter and setter together automatically (#54)
Browse files Browse the repository at this point in the history
Issue: #49
  • Loading branch information
seiyab authored Sep 18, 2024
1 parent 41df453 commit a270488
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 70 deletions.
30 changes: 30 additions & 0 deletions lib/ast/name-of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { AST_NODE_TYPES } from "@typescript-eslint/types";
import { isNode, isPrivateName, isStringLiteral } from "@babel/types";
import type { Node } from ".";

export function nameOf(n: Node): string | null {
if ("key" in n) {
switch (n.key.type) {
case AST_NODE_TYPES.Identifier:
case AST_NODE_TYPES.PrivateIdentifier:
if ("computed" in n && n.computed === true) return null;
return n.key.name;
case AST_NODE_TYPES.Literal: {
const value = n.key.value;
if (typeof value !== "string") return null;
return value;
}
}
if (isNode(n.key)) {
// babel nodes
switch (true) {
case isPrivateName(n.key):
if (n.key.id.type !== AST_NODE_TYPES.Identifier) return null;
return n.key.id.name;
case isStringLiteral(n.key):
return n.key.value;
}
}
}
return null;
}
30 changes: 2 additions & 28 deletions lib/comparator/key-identifier-name.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
import { AST_NODE_TYPES } from "@typescript-eslint/types";
import { C, Comparator } from "./comparator";
import { Node } from "../ast";
import { isNode, isPrivateName, isStringLiteral } from "@babel/types";
import { nameOf } from "../ast/name-of";

export const keyIdentifierName = (): Comparator<Node> =>
C.by(($) => {
if ("key" in $) {
switch ($.key.type) {
case AST_NODE_TYPES.Identifier:
case AST_NODE_TYPES.PrivateIdentifier:
if ("computed" in $ && $.computed === true) return null;
return $.key.name;
case AST_NODE_TYPES.Literal: {
const value = $.key.value;
if (typeof value !== "string") return null;
return value;
}
}
if (isNode($.key)) {
// babel nodes
switch (true) {
case isPrivateName($.key):
if ($.key.id.type !== AST_NODE_TYPES.Identifier) return null;
return $.key.id.name;
case isStringLiteral($.key):
return $.key.value;
}
}
}
return null;
}, C.maybe(C.string));
C.by(nameOf, C.maybe(C.string));
11 changes: 8 additions & 3 deletions lib/preprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { C } from "./comparator/comparator";
import { MemberLikeNodeTypesArray, MemberNode } from "./ast/member-like";
import { Node } from "./ast";
import { isExcludedSubclass } from "./subclass";
import { putGettersAndSettersTogether } from "./put-getters-and-setters-together";

export function preprocess(ast: AST, options: unknown): AST {
const memcomp = comparator(options as Options);
const opt = options as Options;
const memcomp = comparator(opt);
const comp = C.capture(memberNodes, memcomp);
return visit(ast, <T extends Node>(node: T): T | typeof stopModifying => {
switch (node.type) {
Expand All @@ -17,11 +19,14 @@ export function preprocess(ast: AST, options: unknown): AST {
...node,
body: node.body.slice().sort(comp),
} as TSESTree.TSInterfaceBody as T;
case AST_NODE_TYPES.ClassBody:
case AST_NODE_TYPES.ClassBody: {
const sorted = node.body.slice().sort(comp)
const body = opt.keepGettersAndSettersTogether ? putGettersAndSettersTogether(sorted) : sorted;
return {
...node,
body: node.body.slice().sort(comp),
body,
} as TSESTree.ClassBody as T;
}
case AST_NODE_TYPES.TSTypeLiteral:
return {
...node,
Expand Down
37 changes: 37 additions & 0 deletions lib/put-getters-and-setters-together.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Node } from "./ast";
import { nameOf } from "./ast/name-of";

export function putGettersAndSettersTogether(members: Node[]): Node[] {
const getterNames = new Set<string>(
members.flatMap((m) => {
const name = nameOf(m);
if (!("kind" in m) || m.kind !== "get" || name === null) return [];
return [name];
}),
);
const setters = new Map<string, Node>(
members.flatMap((m) => {
const name = nameOf(m);
if (!("kind" in m) || m.kind !== "set" || name === null) return [];
return [[name, m]];
}),
);

return members.flatMap((m) => {
const name = nameOf(m);
if (!("kind" in m) || name === null) return [m];

switch (m.kind) {
case "get": {
const danglingSetter = setters.get(name);
if (danglingSetter !== undefined) return [m, danglingSetter];
return [m];
}
case "set": {
if (getterNames.has(name)) return [];
return [m];
}
}
return [m];
});
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`@typescript-eslint/keep-getters-and-setters-together true getter-setter.ts 1`] = `
exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: true sortMembersAlphabetically: true getter-setter.ts 1`] = `
"export class TestClass {
get theme(): string {
return "light";
Expand Down Expand Up @@ -29,7 +29,7 @@ class A {
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together true getter-setter.js 1`] = `
exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: true sortMembersAlphabetically: true getter-setter.js 1`] = `
"export class TestClass {
get theme() {}
get visible() {}
Expand All @@ -43,10 +43,76 @@ class A {
set b(value) {}
set c(value) {}
}
class B {
get c() {}
set c(value) {}
get d() {}
set d(value) {}
get e() {}
set e(value) {}
set f(value) {}
}
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: true sortMembersAlphabetically: false getter-setter.ts 1`] = `
"export class TestClass {
get visible(): boolean {
return true;
}
set visible(_val: boolean) {}
get theme(): string {
return "light";
}
}
class A {
a: number;
b: string;
get c(): boolean {
return true;
}
set c(_val: boolean) {}
get d(): string {
return "d";
}
set d(_val: string) {}
get e(): boolean {
return false;
}
}
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: true sortMembersAlphabetically: false getter-setter.js 1`] = `
"export class TestClass {
get visible() {}
set visible(value) {}
get theme() {}
}
class A {
a = 1;
d = 2;
get b() {}
set b(value) {}
set c(value) {}
}
class B {
get d() {}
set d(value) {}
get c() {}
set c(value) {}
set f(value) {}
get e() {}
set e(value) {}
}
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together false getter-setter.ts 1`] = `
exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: false sortMembersAlphabetically: true getter-setter.ts 1`] = `
"export class TestClass {
get theme(): string {
return "light";
Expand Down Expand Up @@ -75,7 +141,7 @@ class A {
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together false getter-setter.js 1`] = `
exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: false sortMembersAlphabetically: true getter-setter.js 1`] = `
"export class TestClass {
get theme() {}
get visible() {}
Expand All @@ -89,5 +155,71 @@ class A {
set b(value) {}
set c(value) {}
}
class B {
get c() {}
get d() {}
get e() {}
set c(value) {}
set d(value) {}
set e(value) {}
set f(value) {}
}
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: false sortMembersAlphabetically: false getter-setter.ts 1`] = `
"export class TestClass {
get visible(): boolean {
return true;
}
get theme(): string {
return "light";
}
set visible(_val: boolean) {}
}
class A {
a: number;
b: string;
get c(): boolean {
return true;
}
get d(): string {
return "d";
}
get e(): boolean {
return false;
}
set c(_val: boolean) {}
set d(_val: string) {}
}
"
`;

exports[`@typescript-eslint/keep-getters-and-setters-together keepGettersAndSettersTogether: false sortMembersAlphabetically: false getter-setter.js 1`] = `
"export class TestClass {
get visible() {}
get theme() {}
set visible(value) {}
}
class A {
a = 1;
d = 2;
get b() {}
set c(value) {}
set b(value) {}
}
class B {
get d() {}
get c() {}
get e() {}
set e(value) {}
set f(value) {}
set c(value) {}
set d(value) {}
}
"
`;
Loading

0 comments on commit a270488

Please sign in to comment.