Files
2nd/10_Wiki/Topics/Architecture/AST_Traversal.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

6.4 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-ast-traversal AST Traversal 10_Wiki/Topics verified self
ast-walk
syntax-tree-traversal
visitor-pattern
none A 0.9 applied
ast
compilers
codemod
static-analysis
2026-05-10 pending
language framework
typescript ts-morph

AST Traversal

매 한 줄

"매 code 의 tree 의 walk 한다". 매 AST (Abstract Syntax Tree) traversal 의 compiler/linter/codemod/IDE 의 foundation. 매 2026 의 tree-sitter (Atom, 2018; 매 GitHub 의 sole semantic search engine) + ts-morph + Babel + RustPython AST 의 dominant tooling.

매 핵심

매 traversal strategies

  • Pre-order DFS: 매 visit parent → children. 매 default (most visitors).
  • Post-order DFS: 매 visit children → parent. 매 type inference, dead-code elim.
  • BFS: 매 level-by-level. 매 rare — scope analysis.
  • Visitor pattern: 매 node-type-keyed callbacks. 매 ESLint, Babel, ts-morph standard.

매 mutating vs read-only

  • Read-only: linter, complexity metrics, security scanner.
  • Mutating: codemod, formatter, transpiler. 매 immutability + new tree 의 produce 의 best-practice (Babel: path.replaceWith).

매 응용

  1. ESLint rule — 매 pattern detection.
  2. Codemod — jscodeshift, ts-morph, ast-grep.
  3. Tree-sitter query — 매 IDE syntax highlight, code nav.
  4. AST-based diffing — 매 difftastic, semantic diff.

💻 패턴

Babel visitor (JavaScript)

import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import generate from '@babel/generator';
import * as t from '@babel/types';

const code = `console.log("hello"); foo("world");`;
const ast = parse(code);

traverse(ast, {
  CallExpression(path) {
    const callee = path.node.callee;
    if (t.isMemberExpression(callee) &&
        t.isIdentifier(callee.object, { name: 'console' })) {
      // strip console.* calls
      path.remove();
    }
  }
});

console.log(generate(ast).code); // foo("world");

ts-morph (TypeScript refactor)

import { Project, SyntaxKind } from 'ts-morph';

const project = new Project({ tsConfigFilePath: 'tsconfig.json' });
for (const sf of project.getSourceFiles()) {
  sf.forEachDescendant(node => {
    if (node.getKind() === SyntaxKind.CallExpression) {
      const ce = node.asKindOrThrow(SyntaxKind.CallExpression);
      if (ce.getExpression().getText() === 'fetch') {
        ce.replaceWithText(`httpClient.${ce.getText().replace('fetch', '')}`);
      }
    }
  });
}
await project.save();

Python — ast + NodeTransformer

import ast

class StripPrint(ast.NodeTransformer):
    def visit_Expr(self, node):
        if (isinstance(node.value, ast.Call)
            and isinstance(node.value.func, ast.Name)
            and node.value.func.id == "print"):
            return None  # remove
        return node

src = "print('hi')\nx = 1"
tree = ast.parse(src)
StripPrint().visit(tree)
ast.fix_missing_locations(tree)
print(ast.unparse(tree))  # x = 1

tree-sitter query (multi-language)

; queries/python/calls.scm — find all decorated functions
(decorated_definition
  (decorator (call function: (identifier) @decorator-name))
  definition: (function_definition name: (identifier) @func-name))
import tree_sitter_python as tspython
from tree_sitter import Language, Parser, Query

PY = Language(tspython.language())
parser = Parser(PY)
tree = parser.parse(b"@app.route('/')\ndef home(): pass")
q = Query(PY, open("queries/python/calls.scm").read())
for node, name in q.captures(tree.root_node):
    print(name, node.text)

ast-grep (rule-based, polyglot)

# rule.yml
id: no-console-log
language: js
rule:
  pattern: console.log($$$)
fix: ''
ast-grep scan -r rule.yml --update

Rust — syn (proc-macro / codegen)

use syn::{visit::Visit, ItemFn, File};

struct FnCounter(usize);
impl<'ast> Visit<'ast> for FnCounter {
    fn visit_item_fn(&mut self, i: &'ast ItemFn) {
        self.0 += 1;
        syn::visit::visit_item_fn(self, i);
    }
}

let src = std::fs::read_to_string("src/lib.rs").unwrap();
let file: File = syn::parse_file(&src).unwrap();
let mut c = FnCounter(0);
c.visit_file(&file);
println!("functions: {}", c.0);

ESLint custom rule

module.exports = {
  meta: { type: 'problem', schema: [] },
  create(ctx) {
    return {
      'CallExpression[callee.name="eval"]'(node) {
        ctx.report({ node, message: 'eval is forbidden' });
      }
    };
  }
};

Pre-order vs post-order (manual walk)

function walkPre(node: Node, fn: (n: Node) => void) {
  fn(node);
  for (const c of node.children) walkPre(c, fn);
}
function walkPost(node: Node, fn: (n: Node) => void) {
  for (const c of node.children) walkPost(c, fn);
  fn(node);
}

매 결정 기준

Goal Tool
JS/TS lint rule ESLint visitor
TS large refactor ts-morph
Python codemod LibCST (preserves whitespace) > ast
Polyglot pattern search ast-grep, Semgrep
IDE / syntax highlight tree-sitter
Rust macro syn / quote
Babel plugin @babel/traverse

기본값: 매 ts-morph (TS refactor) · ast-grep (polyglot scan) · LibCST (Python codemod).

🔗 Graph

🤖 LLM 활용

언제: 매 codebase 의 LLM-driven structural query — 매 ast-grep + Claude 의 hybrid (LLM 의 generate pattern, ast 의 execute). 언제 X: 매 LLM 의 raw text find/replace — 매 AST-aware tool 의 사용.

안티패턴

  • Regex on code: 매 multiline construct 의 break — 매 AST 의 사용.
  • Mutating during traversal: 매 visitor 의 reentrancy bug — 매 collect-then-apply.
  • Ignore comments/whitespace: 매 codemod 의 lose comments — 매 LibCST/Recast 의 사용.
  • Single-pass dependence: 매 transformation order 의 fragile — 매 idempotent 의 design.

🧪 검증 / 중복

  • Verified (Babel docs; ts-morph guide; tree-sitter playground; Crafting Interpreters — Nystrom).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — Babel/ts-morph/tree-sitter/ast-grep patterns