diff --git a/README.md b/README.md index 00de7ad..3111c05 100644 --- a/README.md +++ b/README.md @@ -22,26 +22,26 @@ pnpm install oxc-walker ### Walk a parsed AST ```ts -import { parseSync } from 'oxc-parser' -import { walk } from 'oxc-walker' +import { parseSync } from "oxc-parser"; +import { walk } from "oxc-walker"; -const ast = parseSync('example.js', 'const x = 1') +const ast = parseSync("example.js", "const x = 1"); walk(ast.program, { enter(node, parent, ctx) { // ... }, -}) +}); ``` ### Parse and walk directly ```js -import { parseAndWalk } from 'oxc-walker' +import { parseAndWalk } from "oxc-walker"; -parseAndWalk('const x = 1', 'example.js', (node, parent, ctx) => { +parseAndWalk("const x = 1", "example.js", (node, parent, ctx) => { // ... -}) +}); ``` ## ⚙️ API @@ -56,30 +56,30 @@ interface WalkOptions { /** * The function to be called when entering a node. */ - enter?: (node: Node, parent: Node | null, ctx: CallbackContext) => void + enter?: (node: Node, parent: Node | null, ctx: CallbackContext) => void; /** * The function to be called when leaving a node. */ - leave?: (node: Node, parent: Node | null, ctx: CallbackContext) => void + leave?: (node: Node, parent: Node | null, ctx: CallbackContext) => void; /** * The instance of `ScopeTracker` to use for tracking declarations and references. */ - scopeTracker?: ScopeTracker + scopeTracker?: ScopeTracker; } interface CallbackContext { /** * The key of the current node within its parent node object, if applicable. */ - key: string | number | symbol | null | undefined + key: string | number | symbol | null | undefined; /** * The zero-based index of the current node within its parent's children array, if applicable. */ - index: number | null + index: number | null; /** * The full Abstract Syntax Tree (AST) that is being walked, starting from the root node. */ - ast: Program | Node + ast: Program | Node; } ``` @@ -118,19 +118,19 @@ interface ParseAndWalkOptions { /** * The function to be called when entering a node. */ - enter?: (node: Node, parent: Node | null, ctx: CallbackContext) => void + enter?: (node: Node, parent: Node | null, ctx: CallbackContext) => void; /** * The function to be called when leaving a node. */ - leave?: (node: Node, parent: Node | null, ctx: CallbackContext) => void + leave?: (node: Node, parent: Node | null, ctx: CallbackContext) => void; /** * The instance of `ScopeTracker` to use for tracking declarations and references. */ - scopeTracker?: ScopeTracker + scopeTracker?: ScopeTracker; /** * The options for `oxc-parser` to use when parsing the code. */ - parseOptions?: ParserOptions + parseOptions?: ParserOptions; } ``` @@ -145,30 +145,30 @@ interface ScopeTrackerOptions { * If true, the scope tracker will preserve exited scopes in memory. * @default false */ - preserveExitedScopes?: boolean + preserveExitedScopes?: boolean; } ``` #### Example usage: ```ts -import { parseAndWalk, ScopeTracker } from 'oxc-walker' +import { parseAndWalk, ScopeTracker } from "oxc-walker"; -const scopeTracker = new ScopeTracker() +const scopeTracker = new ScopeTracker(); -parseAndWalk('const x = 1; function foo() { console.log(x) }', 'example.js', { +parseAndWalk("const x = 1; function foo() { console.log(x) }", "example.js", { scopeTracker, enter(node, parent) { - if (node.type === 'Identifier' && node.name === 'x' && parent?.type === 'CallExpression') { - const declaration = scopeTracker.getDeclaration(node.name) - console.log(declaration) // ScopeTrackerVariable + if (node.type === "Identifier" && node.name === "x" && parent?.type === "CallExpression") { + const declaration = scopeTracker.getDeclaration(node.name); + console.log(declaration); // ScopeTrackerVariable } }, -}) +}); ``` ```ts -import { parseAndWalk, ScopeTracker, walk } from 'oxc-walker' +import { parseAndWalk, ScopeTracker, walk } from "oxc-walker"; const code = ` function foo() { @@ -176,31 +176,31 @@ function foo() { } const a = 1 -` +`; const scopeTracker = new ScopeTracker({ preserveExitedScopes: true, -}) +}); // pre-pass to collect hoisted declarations -const { program } = parseAndWalk(code, 'example.js', { +const { program } = parseAndWalk(code, "example.js", { scopeTracker, -}) +}); // freeze the scope tracker to prevent further modifications // and prepare it for second pass -scopeTracker.freeze() +scopeTracker.freeze(); // main pass to analyze references walk(program, { scopeTracker, enter(node) { - if (node.type === 'CallExpression' && node.callee.type === 'MemberExpression' /* ... */) { - const declaration = scopeTracker.getDeclaration('a') - console.log(declaration) // ScopeTrackerVariable; would be `null` without the pre-pass + if (node.type === "CallExpression" && node.callee.type === "MemberExpression" /* ... */) { + const declaration = scopeTracker.getDeclaration("a"); + console.log(declaration); // ScopeTrackerVariable; would be `null` without the pre-pass } - } -}) + }, +}); ``` #### Helpers: diff --git a/package.json b/package.json index 5630f13..6d7f3c4 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "knip": "^5.69.1", "lint-staged": "16.2.7", "oxc-parser": "0.107.0", - "oxfmt": "^0.21.0", + "oxfmt": "^0.23.0", "oxlint": "^1.29.0", "simple-git-hooks": "2.13.1", "typescript": "5.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 20d141a..37ceee0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,11 +31,11 @@ importers: specifier: 0.107.0 version: 0.107.0 oxfmt: - specifier: ^0.21.0 - version: 0.21.0 + specifier: ^0.23.0 + version: 0.23.0 oxlint: specifier: ^1.29.0 - version: 1.36.0 + version: 1.38.0 simple-git-hooks: specifier: 2.13.1 version: 2.13.1 @@ -516,91 +516,91 @@ packages: cpu: [x64] os: [win32] - '@oxfmt/darwin-arm64@0.21.0': - resolution: {integrity: sha512-defgGcchFCq2F7f5Nr3E4VXYW1sUhBGmIejgcPZ1gSsc8FAeT+vP5cSeGnDv+kcX+OKFDt89C67c31qZ6yZBsQ==} + '@oxfmt/darwin-arm64@0.23.0': + resolution: {integrity: sha512-shGng2EjBspvuqtFtcjcKf0WoZ9QCdL8iLYgdOoKSiSQ9pPyLJ4jQf62yhm4b2PpZNVcV/20gV6d8SyKzg6SZQ==} cpu: [arm64] os: [darwin] - '@oxfmt/darwin-x64@0.21.0': - resolution: {integrity: sha512-rYJinOZRabPF2V3kn0TWX4vcYHV2F+DkGewNP8HZ/OXQ3CEJKP+E7KCnEz/x614g3/S5J7cahr9l5Mr3AEZigA==} + '@oxfmt/darwin-x64@0.23.0': + resolution: {integrity: sha512-DxQ7Hm7B+6JiIkiRU3CSJmM15nTJDDezyaAv+x9NN8BfU0C49O8JuZIFu1Lr9AKEPV+ECIYM2X4HU0xm6IdiMQ==} cpu: [x64] os: [darwin] - '@oxfmt/linux-arm64-gnu@0.21.0': - resolution: {integrity: sha512-ILTv8stX3r2gK+pgSc2alJrbpI4i8zlLXzuuhUsjeEN/Ti//Z38MDi6kTov3pzcaBEnQ/xEMgQyczokp7jpyyQ==} + '@oxfmt/linux-arm64-gnu@0.23.0': + resolution: {integrity: sha512-7qTXPpENi45sEKsaYFit4VRywPVkX+ZJc5JVA17KW1coJ/SLUuRAdLjRipU+QTZsr1TF93HCmGFSlUjB7lmEVQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@oxfmt/linux-arm64-musl@0.21.0': - resolution: {integrity: sha512-kFZ0vPJzsGjkrwq2MPEpp8TjV7/Znv9kCEwLF+HcFwvfcSt75dWloGmTRRrViH0ACaCM7YBSDUOV8E4nyLvxPA==} + '@oxfmt/linux-arm64-musl@0.23.0': + resolution: {integrity: sha512-qkFXbf+K01B++j69o9mLvvyfhmmL4+qX7hGPA2PRDkE5xxuUTWdqboQQc1FgGI0teUlIYYyxjamq9UztL2A7NA==} cpu: [arm64] os: [linux] libc: [musl] - '@oxfmt/linux-x64-gnu@0.21.0': - resolution: {integrity: sha512-VH8ZcS2TkTBE0v9cLxjNGX++vB9Xvx/7VTFrbwHYzY/fYypYTwQ+n1KplUQoU+LrMC0nKqwPWYzvA5/cAfo5zg==} + '@oxfmt/linux-x64-gnu@0.23.0': + resolution: {integrity: sha512-J7Q13Ujyn8IgjHD96urA377GOy8HerxC13OrEyYaM8iwH3gc/EoboK9AKu0bxp9qai4btPFDhnkRnpCwJE9pAw==} cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/linux-x64-musl@0.21.0': - resolution: {integrity: sha512-qleaVEFHw/kmbvNj3hjobX1kwbP2/d7SVJzQjyEFULou1v3EZj7jWbblIu7GmDCSspdiEk1j/pZDYH801Dn8QA==} + '@oxfmt/linux-x64-musl@0.23.0': + resolution: {integrity: sha512-3gb25Zk2/y4An8fi399KdpLkDYFTJEB5Nq/sSHmeXG0pZlR/jnKoXEFHsjU+9nqF2wsuZ+tmkoi/swcaGG8+Qg==} cpu: [x64] os: [linux] libc: [musl] - '@oxfmt/win32-arm64@0.21.0': - resolution: {integrity: sha512-JLZUo5qEyJfxhoj6KEU/CqI8FQlzIP8rBq7qGTq0kCJ2yZJC9tysBqJYZXvX88ShiNe89/T/H3khodaKGBBNgg==} + '@oxfmt/win32-arm64@0.23.0': + resolution: {integrity: sha512-JKfRP2ENWwRZ73rMZFyChvRi/+oDEW+3obp1XIwecot8gvDHgGZ4nX3hTp4VPiBFL89JORMpWSKzJvjRDucJIw==} cpu: [arm64] os: [win32] - '@oxfmt/win32-x64@0.21.0': - resolution: {integrity: sha512-DYNpbuPzUhTuWUIqDhwSaV1mK+VcknD4ANaEON+/ygaNGriSZ4pRUt1BTRcXfcOF9GZ4BO9udjv31S0bAEsFeQ==} + '@oxfmt/win32-x64@0.23.0': + resolution: {integrity: sha512-vgqtYK1X1n/KexCNQKWXao3hyOnmWuCzk2sQyCSpkLhjSNIDPm7dmnEkvOXhf1t0O5RjCwHpk2VB6Fuaq3GULg==} cpu: [x64] os: [win32] - '@oxlint/darwin-arm64@1.36.0': - resolution: {integrity: sha512-MJkj82GH+nhvWKJhSIM6KlZ8tyGKdogSQXtNdpIyP02r/tTayFJQaAEWayG2Jhsn93kske+nimg5MYFhwO/rlg==} + '@oxlint/darwin-arm64@1.38.0': + resolution: {integrity: sha512-9rN3047QTyA4i73FKikDUBdczRcLtOsIwZ5TsEx5Q7jr5nBjolhYQOFQf9QdhBLdInxw1iX4+lgdMCf1g74zjg==} cpu: [arm64] os: [darwin] - '@oxlint/darwin-x64@1.36.0': - resolution: {integrity: sha512-VvEhfkqj/99dCTqOcfkyFXOSbx4lIy5u2m2GHbK4WCMDySokOcMTNRHGw8fH/WgQ5cDrDMSTYIGQTmnBGi9tiQ==} + '@oxlint/darwin-x64@1.38.0': + resolution: {integrity: sha512-Y1UHW4KOlg5NvyrSn/bVBQP8/LRuid7Pnu+BWGbAVVsFcK0b565YgMSO3Eu9nU3w8ke91dr7NFpUmS+bVkdkbw==} cpu: [x64] os: [darwin] - '@oxlint/linux-arm64-gnu@1.36.0': - resolution: {integrity: sha512-EMx92X5q+hHc3olTuj/kgkx9+yP0p/AVs4yvHbUfzZhBekXNpUWxWvg4hIKmQWn+Ee2j4o80/0ACGO0hDYJ9mg==} + '@oxlint/linux-arm64-gnu@1.38.0': + resolution: {integrity: sha512-ZiVxPZizlXSnAMdkEFWX/mAj7U3bNiku8p6I9UgLrXzgGSSAhFobx8CaFGwVoKyWOd+gQgZ/ogCrunvx2k0CFg==} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/linux-arm64-musl@1.36.0': - resolution: {integrity: sha512-7YCxtrPIctVYLqWrWkk8pahdCxch6PtsaucfMLC7TOlDt4nODhnQd4yzEscKqJ8Gjrw1bF4g+Ngob1gB+Qr9Fw==} + '@oxlint/linux-arm64-musl@1.38.0': + resolution: {integrity: sha512-ELtlCIGZ72A65ATZZHFxHMFrkRtY+DYDCKiNKg6v7u5PdeOFey+OlqRXgXtXlxWjCL+g7nivwI2FPVsWqf05Qw==} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/linux-x64-gnu@1.36.0': - resolution: {integrity: sha512-lnaJVlx5r3NWmoOMesfQXJSf78jHTn8Z+sdAf795Kgteo72+qGC1Uax2SToCJVN2J8PNG3oRV5bLriiCNR2i6Q==} + '@oxlint/linux-x64-gnu@1.38.0': + resolution: {integrity: sha512-E1OcDh30qyng1m0EIlsOuapYkqk5QB6o6IMBjvDKqIoo6IrjlVAasoJfS/CmSH998gXRL3BcAJa6Qg9IxPFZnQ==} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/linux-x64-musl@1.36.0': - resolution: {integrity: sha512-AhuEU2Qdl66lSfTGu/Htirq8r/8q2YnZoG3yEXLMQWnPMn7efy8spD/N1NA7kH0Hll+cdfwgQkQqC2G4MS2lPQ==} + '@oxlint/linux-x64-musl@1.38.0': + resolution: {integrity: sha512-4AfpbM/4sQnr6S1dMijEPfsq4stQbN5vJ2jsahSy/QTcvIVbFkgY+RIhrA5UWlC6eb0rD5CdaPQoKGMJGeXpYw==} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/win32-arm64@1.36.0': - resolution: {integrity: sha512-GlWCBjUJY2QgvBFuNRkiRJu7K/djLmM0UQKfZV8IN+UXbP/JbjZHWKRdd4LXlQmzoz7M5Hd6p+ElCej8/90FCg==} + '@oxlint/win32-arm64@1.38.0': + resolution: {integrity: sha512-OvUVYdI68OwXh3d1RjH9N/okCxb6PrOGtEtzXyqGA7Gk+IxyZcX0/QCTBwV8FNbSSzDePSSEHOKpoIB+VXdtvg==} cpu: [arm64] os: [win32] - '@oxlint/win32-x64@1.36.0': - resolution: {integrity: sha512-J+Vc00Utcf8p77lZPruQgb0QnQXuKnFogN88kCnOqs2a83I+vTBB8ILr0+L9sTwVRvIDMSC0pLdeQH4svWGFZg==} + '@oxlint/win32-x64@1.38.0': + resolution: {integrity: sha512-7IuZMYiZiOcgg5zHvpJY6jRlEwh8EB/uq7GsoQJO9hANq96TIjyntGByhIjFSsL4asyZmhTEki+MO/u5Fb/WQA==} cpu: [x64] os: [win32] @@ -1307,13 +1307,13 @@ packages: oxc-resolver@11.16.2: resolution: {integrity: sha512-Uy76u47vwhhF7VAmVY61Srn+ouiOobf45MU9vGct9GD2ARy6hKoqEElyHDB0L+4JOM6VLuZ431KiLwyjI/A21g==} - oxfmt@0.21.0: - resolution: {integrity: sha512-EXK5pd1kGbI8hp9Ld69oy/ObAoe+gfH3dYHBviKqwSAHNkAHiqxWF1hnrWj5oun1GnQ8bVpqBMMVXJESMx6/+g==} + oxfmt@0.23.0: + resolution: {integrity: sha512-dh4rlNBua93aVf2ZaDecbQxVLMnUUTvDi1K1fdvBdontQeEf6K22Z1KQg5QKl2D9aNFeFph+wOVwcjjYUIO6Mw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - oxlint@1.36.0: - resolution: {integrity: sha512-IicUdXfXgI8OKrDPnoSjvBfeEF8PkKtm+CoLlg4LYe4ypc8U+T4r7730XYshdBGZdelg+JRw8GtCb2w/KaaZvw==} + oxlint@1.38.0: + resolution: {integrity: sha512-XT7tBinQS+hVLxtfJOnokJ9qVBiQvZqng40tDgR6qEJMRMnpVq/JwYfbYyGntSq8MO+Y+N9M1NG4bAMFUtCJiw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2096,52 +2096,52 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@11.16.2': optional: true - '@oxfmt/darwin-arm64@0.21.0': + '@oxfmt/darwin-arm64@0.23.0': optional: true - '@oxfmt/darwin-x64@0.21.0': + '@oxfmt/darwin-x64@0.23.0': optional: true - '@oxfmt/linux-arm64-gnu@0.21.0': + '@oxfmt/linux-arm64-gnu@0.23.0': optional: true - '@oxfmt/linux-arm64-musl@0.21.0': + '@oxfmt/linux-arm64-musl@0.23.0': optional: true - '@oxfmt/linux-x64-gnu@0.21.0': + '@oxfmt/linux-x64-gnu@0.23.0': optional: true - '@oxfmt/linux-x64-musl@0.21.0': + '@oxfmt/linux-x64-musl@0.23.0': optional: true - '@oxfmt/win32-arm64@0.21.0': + '@oxfmt/win32-arm64@0.23.0': optional: true - '@oxfmt/win32-x64@0.21.0': + '@oxfmt/win32-x64@0.23.0': optional: true - '@oxlint/darwin-arm64@1.36.0': + '@oxlint/darwin-arm64@1.38.0': optional: true - '@oxlint/darwin-x64@1.36.0': + '@oxlint/darwin-x64@1.38.0': optional: true - '@oxlint/linux-arm64-gnu@1.36.0': + '@oxlint/linux-arm64-gnu@1.38.0': optional: true - '@oxlint/linux-arm64-musl@1.36.0': + '@oxlint/linux-arm64-musl@1.38.0': optional: true - '@oxlint/linux-x64-gnu@1.36.0': + '@oxlint/linux-x64-gnu@1.38.0': optional: true - '@oxlint/linux-x64-musl@1.36.0': + '@oxlint/linux-x64-musl@1.38.0': optional: true - '@oxlint/win32-arm64@1.36.0': + '@oxlint/win32-arm64@1.38.0': optional: true - '@oxlint/win32-x64@1.36.0': + '@oxlint/win32-x64@1.38.0': optional: true '@rollup/plugin-alias@5.1.1(rollup@4.53.2)': @@ -2871,29 +2871,29 @@ snapshots: '@oxc-resolver/binding-win32-ia32-msvc': 11.16.2 '@oxc-resolver/binding-win32-x64-msvc': 11.16.2 - oxfmt@0.21.0: + oxfmt@0.23.0: dependencies: tinypool: 2.0.0 optionalDependencies: - '@oxfmt/darwin-arm64': 0.21.0 - '@oxfmt/darwin-x64': 0.21.0 - '@oxfmt/linux-arm64-gnu': 0.21.0 - '@oxfmt/linux-arm64-musl': 0.21.0 - '@oxfmt/linux-x64-gnu': 0.21.0 - '@oxfmt/linux-x64-musl': 0.21.0 - '@oxfmt/win32-arm64': 0.21.0 - '@oxfmt/win32-x64': 0.21.0 - - oxlint@1.36.0: + '@oxfmt/darwin-arm64': 0.23.0 + '@oxfmt/darwin-x64': 0.23.0 + '@oxfmt/linux-arm64-gnu': 0.23.0 + '@oxfmt/linux-arm64-musl': 0.23.0 + '@oxfmt/linux-x64-gnu': 0.23.0 + '@oxfmt/linux-x64-musl': 0.23.0 + '@oxfmt/win32-arm64': 0.23.0 + '@oxfmt/win32-x64': 0.23.0 + + oxlint@1.38.0: optionalDependencies: - '@oxlint/darwin-arm64': 1.36.0 - '@oxlint/darwin-x64': 1.36.0 - '@oxlint/linux-arm64-gnu': 1.36.0 - '@oxlint/linux-arm64-musl': 1.36.0 - '@oxlint/linux-x64-gnu': 1.36.0 - '@oxlint/linux-x64-musl': 1.36.0 - '@oxlint/win32-arm64': 1.36.0 - '@oxlint/win32-x64': 1.36.0 + '@oxlint/darwin-arm64': 1.38.0 + '@oxlint/darwin-x64': 1.38.0 + '@oxlint/linux-arm64-gnu': 1.38.0 + '@oxlint/linux-arm64-musl': 1.38.0 + '@oxlint/linux-x64-gnu': 1.38.0 + '@oxlint/linux-x64-musl': 1.38.0 + '@oxlint/win32-arm64': 1.38.0 + '@oxlint/win32-x64': 1.38.0 path-parse@1.0.7: {}