From c2b4af3fa8f9648f6f1b2ed9a3f164000ffcf9ea Mon Sep 17 00:00:00 2001 From: seiya <20365512+seiyab@users.noreply.github.com> Date: Sun, 3 Dec 2023 18:33:16 +0900 Subject: [PATCH 1/5] utilize @babel/types to support babel-ts in following commits --- build.ts | 1 + bun.lockb | Bin 51164 -> 52732 bytes lib/ast/index.ts | 63 +------------ lib/ast/member-like.ts | 48 ++++++++++ lib/ast/member-like.typeckeck.ts | 19 ++++ lib/comparator/abstracted.ts | 12 +-- lib/comparator/accessibility.ts | 12 +-- lib/comparator/index.ts | 84 ++++++++++-------- lib/comparator/key-identifier-name.ts | 8 +- lib/comparator/method-kind.ts | 15 ++-- lib/comparator/select.ts | 19 ---- lib/preprocess.ts | 51 ++++++----- lib/visit.ts | 19 ++-- package.json | 1 + tests/format/__snapshots__/index.test.ts.snap | 4 +- 15 files changed, 189 insertions(+), 167 deletions(-) create mode 100644 lib/ast/member-like.ts create mode 100644 lib/ast/member-like.typeckeck.ts diff --git a/build.ts b/build.ts index 0e9af9c..bd9c481 100644 --- a/build.ts +++ b/build.ts @@ -3,6 +3,7 @@ await Bun.build({ outdir: "./dist", external: [ "prettier", + "@babel/types", "@typescript-eslint/visitor-keys", "@typescript-eslint/types", ], diff --git a/bun.lockb b/bun.lockb index 110d80a4f2838788da9636fb066112975375d153..4282cc2dbf8ad6422af895205c60ac08c04760c4 100755 GIT binary patch delta 9607 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 + +export const functionExpressions: NodeTypes[] = [ AST_NODE_TYPES.FunctionExpression, AST_NODE_TYPES.ArrowFunctionExpression, ]; @@ -12,61 +15,3 @@ export type Node = ( ) & { type: T; }; - -// --- babel specific nodes -export enum BabelNodeTypes { - ClassProperty = "ClassProperty", - ClassPrivateProperty = "ClassPrivateProperty", - ClassMethod = "ClassMethod", - ClassPrivateMethod = "ClassPrivateMethod", - TSDeclareMethod = "TSDeclareMethod", - PrivateName = "PrivateName", - File = "File", -} -// type BabelNodeTypes = (typeof BabelNodeTypes)[keyof typeof BabelNodeTypes]; - -type BabelNode = - | ClassProperty - | ClassPrivateProperty - | ClassMethod - | ClassPrivateMethod - | TSDeclareMethod - | PrivateName - | File; - -type ClassProperty = Override< - TSESTree.PropertyDefinition, - { type: BabelNodeTypes.ClassProperty; abstract: boolean; key: Node } ->; - -type ClassPrivateProperty = Override< - ClassProperty, - { type: BabelNodeTypes.ClassPrivateProperty } ->; - -type ClassMethod = Override< - TSESTree.MethodDefinition, - { type: BabelNodeTypes.ClassMethod; key: Node } ->; - -type ClassPrivateMethod = Override< - ClassMethod, - { type: BabelNodeTypes.ClassPrivateMethod } ->; - -type TSDeclareMethod = Override< - TSESTree.TSAbstractMethodDefinition, - { type: BabelNodeTypes.TSDeclareMethod; abstract: boolean; key: Node } ->; - -type PrivateName = { - type: BabelNodeTypes.PrivateName; - id: Node; -}; - -type File = { - type: BabelNodeTypes.File; - program: Node; -}; - -type Override = Omit & U; diff --git a/lib/ast/member-like.ts b/lib/ast/member-like.ts new file mode 100644 index 0000000..4891462 --- /dev/null +++ b/lib/ast/member-like.ts @@ -0,0 +1,48 @@ +import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types"; +import * as BabelTypes from "@babel/types"; + +export const MemberLikeNodeTypesArray = [ + // ts-es-tree + AST_NODE_TYPES.PropertyDefinition, + AST_NODE_TYPES.MethodDefinition, + AST_NODE_TYPES.TSAbstractMethodDefinition, + AST_NODE_TYPES.TSAbstractPropertyDefinition, + AST_NODE_TYPES.TSConstructSignatureDeclaration, + AST_NODE_TYPES.TSIndexSignature, + AST_NODE_TYPES.TSMethodSignature, + AST_NODE_TYPES.TSPropertySignature, + + // babel-ast + "ClassMethod", + "ClassPrivateMethod", + "ClassPrivateProperty", + "ClassProperty", + "TSDeclareMethod", +] as const; + +export const MemberTypes = Object.fromEntries( + MemberLikeNodeTypesArray.map((type) => [type, type]), +) as { [K in MemberType]: K }; + +export type MemberType = (typeof MemberLikeNodeTypesArray)[number]; + +export type MemberNode = ( + | never // avoid prettier bug + + // babel-ast + | TSESTree.PropertyDefinition + | TSESTree.MethodDefinition + | TSESTree.TSAbstractMethodDefinition + | TSESTree.TSAbstractPropertyDefinition + | TSESTree.TSConstructSignatureDeclaration + | TSESTree.TSIndexSignature + | TSESTree.TSMethodSignature + | TSESTree.TSPropertySignature + + // ts-es-tree + | BabelTypes.ClassMethod + | BabelTypes.ClassPrivateMethod + | BabelTypes.ClassPrivateProperty + | BabelTypes.ClassProperty + | BabelTypes.TSDeclareMethod +) & { type: K }; diff --git a/lib/ast/member-like.typeckeck.ts b/lib/ast/member-like.typeckeck.ts new file mode 100644 index 0000000..6ce4648 --- /dev/null +++ b/lib/ast/member-like.typeckeck.ts @@ -0,0 +1,19 @@ +import { NodeTypes } from "."; +import { + MemberNode, + MemberType, + MemberLikeNodeTypesArray, +} from "./member-like"; + +(function _() { + check; + check; + check; + check; + check; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function check(_a: T, _b: S): never { + throw new Error("Just for type check"); + } +})(); diff --git a/lib/comparator/abstracted.ts b/lib/comparator/abstracted.ts index 5850c3a..1438809 100644 --- a/lib/comparator/abstracted.ts +++ b/lib/comparator/abstracted.ts @@ -1,13 +1,13 @@ -import { AST_NODE_TYPES } from "@typescript-eslint/types"; -import { BabelNodeTypes, Node } from "../ast"; +import { Node } from "../ast"; +import { MemberTypes } from "../ast/member-like"; export function abstracted(node: Node): boolean { switch (node.type) { - case AST_NODE_TYPES.TSAbstractPropertyDefinition: - case AST_NODE_TYPES.TSAbstractMethodDefinition: + case MemberTypes.TSAbstractPropertyDefinition: + case MemberTypes.TSAbstractMethodDefinition: return true; - case BabelNodeTypes.ClassProperty: - case BabelNodeTypes.TSDeclareMethod: + case MemberTypes.ClassProperty: + case MemberTypes.TSDeclareMethod: return node.abstract === true; } return false; diff --git a/lib/comparator/accessibility.ts b/lib/comparator/accessibility.ts index 7b118aa..7ea487f 100644 --- a/lib/comparator/accessibility.ts +++ b/lib/comparator/accessibility.ts @@ -1,8 +1,8 @@ import { AST_NODE_TYPES } from "@typescript-eslint/types"; import { C, Comparator } from "./comparator"; -import { BabelNodeTypes, Node } from "../ast"; +import { MemberNode, MemberTypes } from "../ast/member-like"; -export function accessibility(): Comparator { +export function accessibility(): Comparator { return C.by(($) => { if ("accessibility" in $) { switch ($.accessibility) { @@ -15,12 +15,12 @@ export function accessibility(): Comparator { } } switch ($.type) { - case AST_NODE_TYPES.PropertyDefinition: - case AST_NODE_TYPES.MethodDefinition: + case MemberTypes.PropertyDefinition: + case MemberTypes.MethodDefinition: if ($.key.type === AST_NODE_TYPES.PrivateIdentifier) return 3; break; - case BabelNodeTypes.ClassPrivateMethod: - case BabelNodeTypes.ClassPrivateProperty: + case MemberTypes.ClassPrivateMethod: + case MemberTypes.ClassPrivateProperty: return 3; } return 0; diff --git a/lib/comparator/index.ts b/lib/comparator/index.ts index 966529c..994ee44 100644 --- a/lib/comparator/index.ts +++ b/lib/comparator/index.ts @@ -1,23 +1,25 @@ -import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types"; -import { C } from "./comparator"; +import { AST_NODE_TYPES } from "@typescript-eslint/types"; +import bt from "@babel/types"; +import { C, Comparator } from "./comparator"; import { select } from "./select"; import { keyIdentifierName } from "./key-identifier-name"; -import { BabelNodeTypes, Node, functionExpressions } from "../ast"; +import { functionExpressions } from "../ast"; import { accessibility } from "./accessibility"; import { decorated } from "./decorated"; import { abstracted } from "./abstracted"; import { methodKind } from "./method-kind"; +import { MemberNode, MemberType, MemberTypes } from "../ast/member-like"; export type Options = { sortMembersAlphabetically?: boolean; }; -export function comparator(options: Partial) { +export function comparator(options: Partial): Comparator { const alpha = options.sortMembersAlphabetically === true; - return C.chain( - // Signature + return C.chain( + // signature C.capture( - select.node(AST_NODE_TYPES.TSIndexSignature), + node(MemberTypes.TSIndexSignature), C.by(functionSignature, C.defer), ), @@ -26,17 +28,21 @@ export function comparator(options: Partial) { select .or( select.and( - select.node(AST_NODE_TYPES.TSPropertySignature), + node(MemberTypes.TSPropertySignature), select.not(functionSignature), ), ) .or( select.and( select - .or(select.node(AST_NODE_TYPES.PropertyDefinition)) - .or(select.node(AST_NODE_TYPES.TSAbstractPropertyDefinition)) - .or(select.node(BabelNodeTypes.ClassProperty)) - .or(select.node(BabelNodeTypes.ClassPrivateProperty)), + .or(node(MemberTypes.PropertyDefinition)) + .or(node(MemberTypes.TSAbstractPropertyDefinition)) + .or( + select.and( + bt.isNode, + select.or(bt.isClassProperty).or(bt.isClassPrivateProperty), + ), + ), ($) => !($.value && functionExpressions.includes($.value.type)), ), ), @@ -45,7 +51,6 @@ export function comparator(options: Partial) { C.by(decorated, C.prefer), C.by(abstracted, C.defer), accessibility(), - C.property("computed", C.defer), alpha ? keyIdentifierName() : C.nop, ), ), @@ -54,17 +59,15 @@ export function comparator(options: Partial) { // constructor in class is handled as method C.capture( select - .or(select.node(AST_NODE_TYPES.TSConstructSignatureDeclaration)) + .or(node(MemberTypes.TSConstructSignatureDeclaration)) .or( select.and( - select.node(AST_NODE_TYPES.MethodDefinition), - ($) => - $.key.type === AST_NODE_TYPES.Identifier && - $.key.name === "constructor", + node(MemberTypes.MethodDefinition), + ($) => $.key.type === "Identifier" && $.key.name === "constructor", ), ), C.by(($) => { - if ($.type !== AST_NODE_TYPES.TSConstructSignatureDeclaration) return 0; + if ($.type !== MemberTypes.TSConstructSignatureDeclaration) return 0; return $.params.length; }, C.number), ), @@ -72,27 +75,31 @@ export function comparator(options: Partial) { // method C.capture( select - .or(select.node(AST_NODE_TYPES.TSMethodSignature)) - .or(select.node(AST_NODE_TYPES.MethodDefinition)) - .or(select.node(AST_NODE_TYPES.TSAbstractMethodDefinition)) - .or(select.node(BabelNodeTypes.ClassMethod)) - .or(select.node(BabelNodeTypes.ClassPrivateMethod)) + .or(node(MemberTypes.TSMethodSignature)) + .or(node(MemberTypes.MethodDefinition)) + .or(node(MemberTypes.TSAbstractMethodDefinition)) .or( select.and( - select.node( - AST_NODE_TYPES.PropertyDefinition, - BabelNodeTypes.ClassProperty, - BabelNodeTypes.ClassPrivateProperty, - ), - ($) => - $.value != null && functionExpressions.includes($.value.type), + bt.isNode, + select.or(bt.isClassMethod).or(bt.isClassPrivateMethod), ), ) .or( select.and( - select.node(AST_NODE_TYPES.TSPropertySignature), - functionSignature, + select + .or(node(MemberTypes.PropertyDefinition)) + .or( + select.and( + bt.isNode, + select.or(bt.isClassProperty).or(bt.isClassPrivateProperty), + ), + ), + ($) => + $.value != null && functionExpressions.includes($.value.type), ), + ) + .or( + select.and(node(MemberTypes.TSPropertySignature), functionSignature), ), C.chain( C.property("static", C.prefer), @@ -100,7 +107,6 @@ export function comparator(options: Partial) { methodKind(), C.by(abstracted, C.defer), accessibility(), - C.property("computed", C.defer), alpha ? keyIdentifierName() : C.nop, ), ), @@ -108,9 +114,17 @@ export function comparator(options: Partial) { } function functionSignature( - node: TSESTree.TSPropertySignature | TSESTree.TSIndexSignature, + node: MemberNode< + AST_NODE_TYPES.TSPropertySignature | AST_NODE_TYPES.TSIndexSignature + >, ): boolean { return ( node.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSFunctionType ); } + +function node(key: K) { + return function (node: MemberNode): node is MemberNode { + return node.type === key; + }; +} diff --git a/lib/comparator/key-identifier-name.ts b/lib/comparator/key-identifier-name.ts index 2c72d4d..2ceee99 100644 --- a/lib/comparator/key-identifier-name.ts +++ b/lib/comparator/key-identifier-name.ts @@ -1,6 +1,7 @@ import { AST_NODE_TYPES } from "@typescript-eslint/types"; import { C, Comparator } from "./comparator"; -import { BabelNodeTypes, Node } from "../ast"; +import { Node } from "../ast"; +import { isNode, isPrivateName } from "@babel/types"; export const keyIdentifierName = < T extends { @@ -12,8 +13,9 @@ export const keyIdentifierName = < case AST_NODE_TYPES.Identifier: case AST_NODE_TYPES.PrivateIdentifier: return $.key.name; - case BabelNodeTypes.PrivateName: - if ($.key.id.type === AST_NODE_TYPES.Identifier) return $.key.id.name; + } + if (isNode($.key) && isPrivateName($.key)) { + if ($.key.id.type === AST_NODE_TYPES.Identifier) return $.key.id.name; } return null; }, C.maybe(C.string)); diff --git a/lib/comparator/method-kind.ts b/lib/comparator/method-kind.ts index 43fd98f..80fa06b 100644 --- a/lib/comparator/method-kind.ts +++ b/lib/comparator/method-kind.ts @@ -1,15 +1,14 @@ -import { AST_NODE_TYPES } from "@typescript-eslint/types"; import { C, Comparator } from "./comparator"; -import { BabelNodeTypes, Node } from "../ast"; +import { MemberNode, MemberTypes } from "../ast/member-like"; -export function methodKind(): Comparator { +export function methodKind(): Comparator { return C.by(($) => { switch ($.type) { - case AST_NODE_TYPES.TSMethodSignature: - case AST_NODE_TYPES.MethodDefinition: - case AST_NODE_TYPES.TSAbstractMethodDefinition: - case BabelNodeTypes.ClassMethod: - case BabelNodeTypes.TSDeclareMethod: + case MemberTypes.TSMethodSignature: + case MemberTypes.MethodDefinition: + case MemberTypes.TSAbstractMethodDefinition: + case MemberTypes.ClassMethod: + case MemberTypes.TSDeclareMethod: switch ($.kind) { case "constructor": return 0; diff --git a/lib/comparator/select.ts b/lib/comparator/select.ts index 9b3368b..4cc563f 100644 --- a/lib/comparator/select.ts +++ b/lib/comparator/select.ts @@ -1,7 +1,4 @@ -import { Node, NodeTypes } from "../ast"; - export const select = { - node, and, or, not(predicate: (a: T) => boolean): (a: T) => boolean { @@ -9,22 +6,6 @@ export const select = { }, }; -function node(key: K): (node: Node) => node is Node; -function node( - key1: K1, - key2: K2, -): (node: Node) => node is Node; -function node( - key1: K1, - key2: K2, - key3: K3, -): (node: Node) => node is Node; -function node(...keys: K[]) { - return function (node: Node): node is Node { - return keys.some((key) => node.type === key); - }; -} - function and( p1: (a: T) => a is U, p2: (a: U) => a is V, diff --git a/lib/preprocess.ts b/lib/preprocess.ts index 448a891..44c5fbc 100644 --- a/lib/preprocess.ts +++ b/lib/preprocess.ts @@ -1,27 +1,38 @@ import { type AST } from "prettier"; import { visit } from "./visit"; import { Options, comparator } from "./comparator"; +import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types"; +import { C } from "./comparator/comparator"; +import { MemberLikeNodeTypesArray, MemberNode } from "./ast/member-like"; +import { Node } from "./ast"; export function preprocess(ast: AST, options: unknown): AST { - const comp = comparator(options as Options); - return visit(ast, { - TSInterfaceBody(node) { - return { - ...node, - body: node.body.slice().sort(comp), - }; - }, - ClassBody(node) { - return { - ...node, - body: node.body.slice().sort(comp), - }; - }, - TSTypeLiteral(node) { - return { - ...node, - members: node.members.slice().sort(comp), - }; - }, + const memcomp = comparator(options as Options); + const comp = C.capture(memberNodes, memcomp); + return visit(ast, (node: T): T => { + switch (node.type) { + case AST_NODE_TYPES.TSInterfaceBody: + return { + ...node, + body: node.body.slice().sort(comp), + } as TSESTree.TSInterfaceBody as T; + case AST_NODE_TYPES.ClassBody: + return { + ...node, + body: node.body.slice().sort(comp), + } as TSESTree.ClassBody as T; + case AST_NODE_TYPES.TSTypeLiteral: + return { + ...node, + members: node.members.slice().sort(comp), + } as TSESTree.TSTypeLiteral as T; + } + return node; }); } + +function memberNodes(node: Node): node is MemberNode { + return membersSet.has(node.type); +} + +const membersSet = new Set(MemberLikeNodeTypesArray); diff --git a/lib/visit.ts b/lib/visit.ts index 7ff5d94..4b1698d 100644 --- a/lib/visit.ts +++ b/lib/visit.ts @@ -1,16 +1,17 @@ import { visitorKeys } from "@typescript-eslint/visitor-keys"; -import { Node, NodeTypes } from "./ast"; +import { Node } from "./ast"; -type Modifier = Partial<{ - [K in NodeTypes]?: >(node: T) => T; -}>; - -export function visit(node: T, modifier: Modifier): T { +export function visit( + node: T, + modifier: (node: S) => S, +): T { if (node?.type == null) return node; if (node.type === "File") - return { ...cloneNode(node), program: visit(node.program, modifier) }; // babel - const modr = modifier[node.type] as ((n: T) => T) | undefined; - const modified = cloneNode(modr?.(node) ?? node); + return { + ...cloneNode(node), + program: visit(node.program, modifier), + }; // babel + const modified = cloneNode(modifier(node)); for (const key of visitorKeys[node.type] ?? []) { const k = key as keyof T; const child = modified[k]; diff --git a/package.json b/package.json index b8446f4..8d4a90f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "prettier": "^3.0.0" }, "dependencies": { + "@babel/types": "^7.23.5", "@typescript-eslint/types": "^6.11.0", "@typescript-eslint/visitor-keys": "^6.11.0" }, diff --git a/tests/format/__snapshots__/index.test.ts.snap b/tests/format/__snapshots__/index.test.ts.snap index 71f01cb..a05bfbe 100644 --- a/tests/format/__snapshots__/index.test.ts.snap +++ b/tests/format/__snapshots__/index.test.ts.snap @@ -152,8 +152,8 @@ exports[`format {} type-alias.ts 1`] = ` [t: string]: unknown; [u: number]: () => number; y: number; - r?: number; [\`s\`]: number; + r?: number; new (a: 0, b: 1): A; get w(): number; z(): number; @@ -528,8 +528,8 @@ exports[`format {"sortMembersAlphabetically":false} type-alias.ts 1`] = ` [t: string]: unknown; [u: number]: () => number; y: number; - r?: number; [\`s\`]: number; + r?: number; new (a: 0, b: 1): A; get w(): number; z(): number; From d2ac74fdc03210797ffb0ce520e0abc095ac07c8 Mon Sep 17 00:00:00 2001 From: seiya <20365512+seiyab@users.noreply.github.com> Date: Sun, 3 Dec 2023 22:10:49 +0900 Subject: [PATCH 2/5] add failing test --- tests/format/index.test.ts | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/format/index.test.ts b/tests/format/index.test.ts index ea45796..0053f8c 100644 --- a/tests/format/index.test.ts +++ b/tests/format/index.test.ts @@ -5,14 +5,15 @@ import { format } from "prettier"; const plugins = ["./index.ts"]; -describe("format", async () => { +const dir = join(import.meta.dir, "testdata"); +const filenames = await readdir(dir); + +describe("format", () => { const options = [ {}, { sortMembersAlphabetically: true }, { sortMembersAlphabetically: false }, ]; - const dir = join(import.meta.dir, "testdata"); - const filenames = await readdir(dir); describe.each(options)("%j", (opts) => { test.each(filenames)("%s", async (name) => { @@ -43,5 +44,29 @@ describe("format", async () => { expect(result2).toEqual(result1); }); }); + + describe("parser agnostic", () => { + describe("TypeScript", () => { + const parsers = ["typescript", "babel-ts"]; + describe.each(parsers)("%s", async (parser) => { + test.each(filenames)("%s", async (name) => { + const path = join(dir, name); + const code = await readFile(path, "utf-8"); + const expected = await format(code, { + ...opts, + filepath: path, + plugins, + }); + const actual = await format(code, { + ...opts, + filepath: path, + plugins, + parser, + }); + expect(actual).toBe(expected); + }); + }); + }); + }); }); }); From b55e097b08649b010b4e8775dab907e07c4cfee8 Mon Sep 17 00:00:00 2001 From: seiya <20365512+seiyab@users.noreply.github.com> Date: Sun, 3 Dec 2023 22:55:27 +0900 Subject: [PATCH 3/5] WIP --- lib/comparator/decorated.ts | 12 ++++-- lib/comparator/index.ts | 7 +++- lib/comparator/method-kind.ts | 1 + lib/visit.ts | 10 ++++- tests/format/__snapshots__/index.test.ts.snap | 42 +++++++++---------- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/lib/comparator/decorated.ts b/lib/comparator/decorated.ts index a0b3096..df5fc91 100644 --- a/lib/comparator/decorated.ts +++ b/lib/comparator/decorated.ts @@ -1,11 +1,15 @@ -import { AST_NODE_TYPES } from "@typescript-eslint/types"; import { Node } from "../ast"; +import { MemberTypes } from "../ast/member-like"; export function decorated(node: Node): boolean { switch (node.type) { - case AST_NODE_TYPES.PropertyDefinition: - case AST_NODE_TYPES.MethodDefinition: - return node.decorators.length > 0; + case MemberTypes.PropertyDefinition: + case MemberTypes.MethodDefinition: + case MemberTypes.ClassProperty: + case MemberTypes.ClassPrivateProperty: + case MemberTypes.ClassMethod: + case MemberTypes.ClassPrivateMethod: + return (node.decorators?.length ?? 0) > 0; } return false; } diff --git a/lib/comparator/index.ts b/lib/comparator/index.ts index 994ee44..7a3ae27 100644 --- a/lib/comparator/index.ts +++ b/lib/comparator/index.ts @@ -68,7 +68,10 @@ export function comparator(options: Partial): Comparator { ), C.by(($) => { if ($.type !== MemberTypes.TSConstructSignatureDeclaration) return 0; - return $.params.length; + return ( + $.params?.length ?? + ($ as unknown as bt.TSConstructSignatureDeclaration).parameters.length + ); }, C.number), ), @@ -102,9 +105,9 @@ export function comparator(options: Partial): Comparator { select.and(node(MemberTypes.TSPropertySignature), functionSignature), ), C.chain( + methodKind(), C.property("static", C.prefer), C.by(decorated, C.prefer), - methodKind(), C.by(abstracted, C.defer), accessibility(), alpha ? keyIdentifierName() : C.nop, diff --git a/lib/comparator/method-kind.ts b/lib/comparator/method-kind.ts index 80fa06b..e68f7de 100644 --- a/lib/comparator/method-kind.ts +++ b/lib/comparator/method-kind.ts @@ -8,6 +8,7 @@ export function methodKind(): Comparator { case MemberTypes.MethodDefinition: case MemberTypes.TSAbstractMethodDefinition: case MemberTypes.ClassMethod: + case MemberTypes.ClassPrivateMethod: case MemberTypes.TSDeclareMethod: switch ($.kind) { case "constructor": diff --git a/lib/visit.ts b/lib/visit.ts index 4b1698d..56ebe98 100644 --- a/lib/visit.ts +++ b/lib/visit.ts @@ -1,4 +1,5 @@ -import { visitorKeys } from "@typescript-eslint/visitor-keys"; +import { visitorKeys as esVisitorKeys } from "@typescript-eslint/visitor-keys"; +import { VISITOR_KEYS as babelVisitorKeys } from "@babel/types"; import { Node } from "./ast"; export function visit( @@ -12,7 +13,12 @@ export function visit( program: visit(node.program, modifier), }; // babel const modified = cloneNode(modifier(node)); - for (const key of visitorKeys[node.type] ?? []) { + const keys = new Set( + (esVisitorKeys[modified.type] ?? []).concat( + babelVisitorKeys[modified.type] ?? [], + ), + ) as Set; + for (const key of keys) { const k = key as keyof T; const child = modified[k]; if (Array.isArray(child)) { diff --git a/tests/format/__snapshots__/index.test.ts.snap b/tests/format/__snapshots__/index.test.ts.snap index a05bfbe..caa0294 100644 --- a/tests/format/__snapshots__/index.test.ts.snap +++ b/tests/format/__snapshots__/index.test.ts.snap @@ -18,17 +18,17 @@ exports[`format {} class.ts 1`] = ` private a: unknown; abstract t: unknown; constructor() {} - static f(): void {} - @deco - o(): void {} - @deco - protected r(): void {} get z(): 0 { return 0; } protected set x(_: unknown) {} private set w(_: unknown) {} abstract set y(_: unknown); + static f(): void {} + @deco + o(): void {} + @deco + protected r(): void {} c(): void {} public i(): void {} n(): void {} @@ -175,10 +175,10 @@ exports[`format {} class.js 1`] = ` } class MyClass2 { - b; - c; @deco g; + b; + c; #f; constructor() {} a() {} @@ -206,17 +206,17 @@ exports[`format {"sortMembersAlphabetically":true} class.ts 1`] = ` private a: unknown; abstract t: unknown; constructor() {} - static f(): void {} - @deco - o(): void {} - @deco - protected r(): void {} get z(): 0 { return 0; } protected set x(_: unknown) {} private set w(_: unknown) {} abstract set y(_: unknown); + static f(): void {} + @deco + o(): void {} + @deco + protected r(): void {} c(): void {} public i(): void {} n(): void {} @@ -363,10 +363,10 @@ exports[`format {"sortMembersAlphabetically":true} class.js 1`] = ` } class MyClass2 { - b; - c; @deco g; + b; + c; #f; constructor() {} a() {} @@ -394,17 +394,17 @@ exports[`format {"sortMembersAlphabetically":false} class.ts 1`] = ` private a: unknown; abstract t: unknown; constructor() {} - static f(): void {} - @deco - o(): void {} - @deco - protected r(): void {} get z(): 0 { return 0; } protected set x(_: unknown) {} private set w(_: unknown) {} abstract set y(_: unknown); + static f(): void {} + @deco + o(): void {} + @deco + protected r(): void {} c(): void {} public i(): void {} n(): void {} @@ -551,10 +551,10 @@ exports[`format {"sortMembersAlphabetically":false} class.js 1`] = ` } class MyClass2 { - b; - c; @deco g; + b; + c; #f; constructor() {} a() {} From 477d12c5d1f22d9fba111c49c4ea022096886d78 Mon Sep 17 00:00:00 2001 From: seiya <20365512+seiyab@users.noreply.github.com> Date: Mon, 4 Dec 2023 12:47:27 +0900 Subject: [PATCH 4/5] fix a bug --- lib/comparator/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/comparator/index.ts b/lib/comparator/index.ts index 7a3ae27..e92c284 100644 --- a/lib/comparator/index.ts +++ b/lib/comparator/index.ts @@ -81,6 +81,7 @@ export function comparator(options: Partial): Comparator { .or(node(MemberTypes.TSMethodSignature)) .or(node(MemberTypes.MethodDefinition)) .or(node(MemberTypes.TSAbstractMethodDefinition)) + .or(node(MemberTypes.TSDeclareMethod)) .or( select.and( bt.isNode, From e52fe065ae4f57313e19b13e5d2c29673342c1fd Mon Sep 17 00:00:00 2001 From: seiya <20365512+seiyab@users.noreply.github.com> Date: Mon, 4 Dec 2023 13:00:33 +0900 Subject: [PATCH 5/5] reafator and refine type --- lib/comparator/class-member.ts | 9 +++++++++ lib/comparator/index.ts | 5 +++-- lib/comparator/key-identifier-name.ts | 22 ++++++++++------------ 3 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 lib/comparator/class-member.ts diff --git a/lib/comparator/class-member.ts b/lib/comparator/class-member.ts new file mode 100644 index 0000000..d368b80 --- /dev/null +++ b/lib/comparator/class-member.ts @@ -0,0 +1,9 @@ +import { Node } from "../ast"; +import { C, Comparator } from "./comparator"; + +export function classMember(): Comparator { + return C.by(($) => { + if ("static" in $) return $.static === true; + return false; + }, C.prefer); +} diff --git a/lib/comparator/index.ts b/lib/comparator/index.ts index e92c284..0453b6d 100644 --- a/lib/comparator/index.ts +++ b/lib/comparator/index.ts @@ -9,6 +9,7 @@ import { decorated } from "./decorated"; import { abstracted } from "./abstracted"; import { methodKind } from "./method-kind"; import { MemberNode, MemberType, MemberTypes } from "../ast/member-like"; +import { classMember } from "./class-member"; export type Options = { sortMembersAlphabetically?: boolean; @@ -47,7 +48,7 @@ export function comparator(options: Partial): Comparator { ), ), C.chain( - C.property("static", C.prefer), + classMember(), C.by(decorated, C.prefer), C.by(abstracted, C.defer), accessibility(), @@ -107,7 +108,7 @@ export function comparator(options: Partial): Comparator { ), C.chain( methodKind(), - C.property("static", C.prefer), + classMember(), C.by(decorated, C.prefer), C.by(abstracted, C.defer), accessibility(), diff --git a/lib/comparator/key-identifier-name.ts b/lib/comparator/key-identifier-name.ts index 2ceee99..b66adfa 100644 --- a/lib/comparator/key-identifier-name.ts +++ b/lib/comparator/key-identifier-name.ts @@ -3,19 +3,17 @@ import { C, Comparator } from "./comparator"; import { Node } from "../ast"; import { isNode, isPrivateName } from "@babel/types"; -export const keyIdentifierName = < - T extends { - key: Node; - }, ->(): Comparator => +export const keyIdentifierName = (): Comparator => C.by(($) => { - switch ($.key.type) { - case AST_NODE_TYPES.Identifier: - case AST_NODE_TYPES.PrivateIdentifier: - return $.key.name; - } - if (isNode($.key) && isPrivateName($.key)) { - if ($.key.id.type === AST_NODE_TYPES.Identifier) return $.key.id.name; + if ("key" in $) { + switch ($.key.type) { + case AST_NODE_TYPES.Identifier: + case AST_NODE_TYPES.PrivateIdentifier: + return $.key.name; + } + if (isNode($.key) && isPrivateName($.key)) { + if ($.key.id.type === AST_NODE_TYPES.Identifier) return $.key.id.name; + } } return null; }, C.maybe(C.string));