---
id: wiki-2026-0508-abstract-syntax-tree-transformat
title: Abstract Syntax Tree Transformation
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [AST Transform, AST Rewrite, Code Transformation]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
verification_status: applied
tags: [compiler, ast, codemod, transformation, static-analysis]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: TypeScript/Python
  framework: Babel/ts-morph/LibCST
---

# Abstract Syntax Tree Transformation

## 매 한 줄
> **"매 source-as-data — 매 string 의 X, 매 tree 의 mutation."**. AST transformation 의 source code 의 parse tree 의 structured manipulation — 매 1970s compiler theory 의 root, 매 2026 의 codemod / linter / formatter / LLM-assisted refactor backbone (Babel, ts-morph, LibCST, tree-sitter).

## 매 핵심

### 매 Pipeline
- **Parse**: source string → token stream → AST (lexer + parser).
- **Visit/Traverse**: 매 node 의 type-based dispatch (visitor pattern).
- **Transform**: node insert / replace / remove / wrap.
- **Print**: AST → source string (preserving comments / formatting via concrete syntax tree or sourcemap).

### 매 Tools (2026)
- **Babel** (JS/TS): `@babel/parser` + `@babel/traverse` + `@babel/generator`. 매 ecosystem standard.
- **ts-morph** (TS): high-level wrapper over TypeScript compiler API. 매 type-aware transform.
- **LibCST** (Python): concrete syntax tree, formatting-preserving. Instagram-grade codemod.
- **tree-sitter**: incremental parser, multi-language. 매 editor / LSP foundation.
- **jscodeshift**: Facebook codemod runner over Babel.
- **swc / oxc**: Rust-based, 10-50x faster than Babel.

### 매 응용
1. **Codemod**: API migration (e.g., React class → hooks).
2. **Linter / formatter**: ESLint, Prettier, Ruff.
3. **LLM context compression**: AST-based code summarization.
4. **Security scanner**: Semgrep AST pattern matching.

## 💻 패턴

### Pattern 1 — Babel: Replace function call name

```typescript
import * as parser from "@babel/parser";
import traverse from "@babel/traverse";
import generate from "@babel/generator";
import * as t from "@babel/types";

const code = `console.log("hi"); console.error("err");`;
const ast = parser.parse(code, { sourceType: "module" });

traverse(ast, {
  CallExpression(path) {
    const callee = path.node.callee;
    if (t.isMemberExpression(callee) && t.isIdentifier(callee.object, { name: "console" })) {
      callee.object = t.identifier("logger");
    }
  },
});

console.log(generate(ast).code);
// → logger.log("hi"); logger.error("err");
```

### Pattern 2 — ts-morph: Add type annotation

```typescript
import { Project } from "ts-morph";

const project = new Project();
const sf = project.addSourceFileAtPath("src/foo.ts");

sf.getFunctions().forEach((fn) => {
  fn.getParameters().forEach((p) => {
    if (!p.getTypeNode()) p.setType("unknown");
  });
});

await sf.save();
```

### Pattern 3 — LibCST: Python codemod (preserves formatting)

```python
import libcst as cst

class RenameImport(cst.CSTTransformer):
    def leave_ImportFrom(self, orig, updated):
        if updated.module and updated.module.value == "old_pkg":
            return updated.with_changes(module=cst.Attribute(
                value=cst.Name("new_pkg"), attr=cst.Name("submod")
            ))
        return updated

tree = cst.parse_module(open("foo.py").read())
new_tree = tree.visit(RenameImport())
open("foo.py", "w").write(new_tree.code)
```

### Pattern 4 — tree-sitter query (Semgrep-like)

```scheme
; Find all `console.log(...)` calls
(call_expression
  function: (member_expression
    object: (identifier) @obj
    property: (property_identifier) @prop)
  (#eq? @obj "console")
  (#eq? @prop "log")) @match
```

### Pattern 5 — jscodeshift script

```javascript
module.exports = function (file, api) {
  const j = api.jscodeshift;
  return j(file.source)
    .find(j.VariableDeclaration, { kind: "var" })
    .forEach((p) => { p.value.kind = "const"; })
    .toSource();
};
```

### Pattern 6 — Type-aware refactor with TS compiler API

```typescript
import ts from "typescript";

function transformer<T extends ts.Node>(ctx: ts.TransformationContext) {
  return (root: T) => {
    function visit(node: ts.Node): ts.Node {
      if (ts.isCallExpression(node) && node.expression.getText() === "deprecated") {
        return ts.factory.createCallExpression(
          ts.factory.createIdentifier("modern"),
          undefined, node.arguments
        );
      }
      return ts.visitEachChild(node, visit, ctx);
    }
    return ts.visitNode(root, visit) as T;
  };
}
```

## 매 결정 기준

| 상황 | Approach |
|---|---|
| JS/TS quick codemod | jscodeshift + Babel |
| Type-aware TS refactor | ts-morph |
| Python large-scale | LibCST |
| Multi-language editor / search | tree-sitter |
| Performance-critical CI | swc / oxc |
| Security pattern detection | Semgrep |
| LLM-driven refactor | tree-sitter + LLM tool-use |

**기본값**: Babel for JS/TS, LibCST for Python, tree-sitter for cross-language.

## 🔗 Graph
- 부모: [[Static-Analysis]]
- 변형: [[Concrete-Syntax-Tree]]
- 응용: [[Linter]]

## 🤖 LLM 활용
**언제**: large-scale code migration, repo-wide rename, API deprecation cleanup, structured code understanding for LLM context.
**언제 X**: one-off edits (use sed/IDE), formatting-only changes (use Prettier/Ruff direct), single-file simple regex.

## ❌ 안티패턴
- **Regex-as-AST**: complex code transform 의 regex 의 fragile — comment / string literal 의 false match.
- **Format loss**: 매 round-trip 의 comment / whitespace 의 drop — concrete syntax tree (LibCST) 또는 sourcemap 사용.
- **Type-blind refactor**: TS 의 type info 의 ignore — runtime error.
- **No idempotency**: codemod 의 re-run 의 duplicate transform — guard idempotent.

## 🧪 검증 / 중복
- Verified (Babel docs, ts-morph docs, LibCST Instagram engineering blog).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — FULL content (Babel/ts-morph/LibCST/tree-sitter, 6 patterns, decision table) |
