Created
April 13, 2025 02:42
-
-
Save HerringtonDarkholme/42e4ada80f59274f91bf54b362c9df41 to your computer and use it in GitHub Desktop.
use async/await instead of enter/leave
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// a generic node for example | |
interface GNode { text: string; kind: string; next(): GNode | null; children(): GNode[]; } | |
// Process one node during traversal | |
type Process<T> = (n: GNode, t: Traversal) => Promise<T> | T | |
// continue the traversal to process children/siblings | |
interface Next { <T>(f: Process<T>): Promise<T> | T } | |
// traversal context | |
interface Traversal { | |
// past nodes will be ready in Array | |
ancestors: GNode[]; prevSiblings: GNode[] | |
// future nodes access needs function | |
descendants: Next | |
nextAll: Next // all next siblings | |
dfs: Next // all nodes in dfs order | |
} | |
// example usage | |
async function collectImportUsage(node: GNode, { dfs, descendants }: Traversal) { | |
if (node.kind !== 'import') { return } // not import statement, skip | |
// find the imported identifier name | |
const importee = await descendants(n => n.kind === 'identifier' && n.text) | |
let count = 0 // local variable to count the importee usage | |
// collect info using closure, no extra book-keeping | |
await dfs(n => { count += n.kind === 'identifier' && n.text === importee ? 1 : 0 }) | |
return count | |
} | |
declare function traverse<T>(node: GNode, f: Process<T>, init: T): Promise<T> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment