Files
2025-11-30 09:06:54 +08:00

264 lines
7.5 KiB
Markdown

# ast-grep Comprehensive Reference Guide
This guide provides comprehensive ast-grep knowledge for structural code search and transformation.
# Core ast-grep Concepts
## Pattern Syntax
- Use **actual code syntax** for the target language
- Use **metavariables** to capture patterns:
- `$VAR` - matches any single AST node (expression, identifier, etc.)
- `$$$ARGS` - matches multiple nodes (zero or more)
- `$$STMT` - matches multiple statements
## Basic Commands
```bash
# Search for pattern
ast-grep -p 'PATTERN'
# Specify language (always prefer explicit language)
ast-grep -l typescript -p 'PATTERN'
# Search and replace (preview)
ast-grep -p 'OLD_PATTERN' -r 'NEW_PATTERN'
# Apply changes (after verification)
ast-grep -p 'OLD_PATTERN' -r 'NEW_PATTERN' --update-all
# JSON output (for parsing)
ast-grep -p 'PATTERN' --json
```
**CRITICAL CONSTRAINT**: You cannot use interactive mode (`-i`) - you cannot respond to interactive prompts.
---
# Recommended Workflow
## 1. Search Phase (Discovery)
```bash
# First, find matches to understand scope
ast-grep -l LANG -p 'PATTERN' [file_or_dir]
# Count matches to verify expectations
ast-grep -p 'PATTERN' | wc -l
```
## 2. Verification Phase (Before Changes)
- **Always** run search first to see what will match
- Review matches to ensure pattern is correct
- Verify no false positives
## 3. Application Phase (Making Changes)
Two viable strategies:
**Strategy A: Direct Application** (for high confidence scenarios)
```bash
ast-grep -p 'OLD' -r 'NEW' # Preview first
ast-grep -p 'OLD' -r 'NEW' --update-all # Apply after thorough review
```
**Strategy B: Hybrid Approach** (RECOMMENDED for maximum control)
1. Use ast-grep to find matches: `ast-grep -l LANG -p 'PATTERN'`
2. Read the files to see actual context
3. Use Edit tool to apply changes with precise control
This combines ast-grep's structural search with Edit's precision.
## 4. Validation Phase
```bash
# After changes, verify the new pattern exists
ast-grep -p 'NEW_PATTERN' [file_or_dir]
```
---
# Common Use Cases with Examples
## 1. Function Call Refactoring
```bash
# Find all calls to a function
ast-grep -l typescript -p 'oldFunction($$$ARGS)'
# Replace with new function
ast-grep -l typescript -p 'oldFunction($$$ARGS)' -r 'newFunction($$$ARGS)'
```
## 2. Method Rename
```bash
# Find method calls on any object
ast-grep -l javascript -p '$OBJ.oldMethod($$$ARGS)' -r '$OBJ.newMethod($$$ARGS)'
```
## 3. Import Statement Changes
```bash
# TypeScript/JavaScript: change import source
ast-grep -l typescript -p 'import $WHAT from "old-package"' -r 'import $WHAT from "new-package"'
```
## 4. Adding Parameters to Function Calls
```bash
# Add a new parameter to all calls
ast-grep -l javascript -p 'doThing($ARG1, $ARG2)' -r 'doThing($ARG1, $ARG2, { new: true })'
```
## 5. Find Complex Patterns
```bash
# Find try-catch blocks with specific pattern
ast-grep -l javascript -p 'try { $$$BODY } catch ($ERR) { console.error($$$) }'
# Find async functions
ast-grep -l typescript -p 'async function $NAME($$$ARGS) { $$$BODY }'
```
## 6. Class Method Changes
```bash
# Find all methods in classes
ast-grep -l typescript -p 'class $CLASS { $$$A $METHOD($$$PARAMS) { $$$BODY } $$$B }'
```
---
# Language-Specific Tips
## JavaScript/TypeScript (`-l typescript` or `-l javascript`)
- Works for: .js, .jsx, .ts, .tsx
- Patterns use JS/TS syntax exactly as written
- Arrow functions: `($$$ARGS) => $BODY`
- Always use `-l typescript` for TypeScript files
## Python (`-l python`)
- Indentation in pattern matters less than structure
- Use Python syntax: `def $NAME($$$ARGS):`
## Go (`-l go`)
- Use Go syntax: `func $NAME($$$ARGS) $RET { $$$ }`
- Package/import matching: `import "$PKG"`
## Rust (`-l rust`)
- Use Rust syntax: `fn $NAME($$$ARGS) -> $RET { $$$ }`
- Match macros: `println!($$$ARGS)`
---
# Best Practices
## 1. Always Verify Before Applying
```bash
# NEVER apply changes without seeing matches first
# BAD: ast-grep -p 'pattern' -r 'replacement' --update-all
# GOOD:
ast-grep -p 'pattern' # Review matches
ast-grep -p 'pattern' -r 'replacement' # Preview changes
ast-grep -p 'pattern' -r 'replacement' --update-all # Apply only after review
```
## 2. Always Use Explicit Language Flag
```bash
# BAD: ast-grep -p 'pattern' # May auto-detect incorrectly
# GOOD: ast-grep -l typescript -p 'pattern' # Explicit and reliable
```
## 3. Start Specific, Broaden if Needed
- Begin with very specific patterns
- If no matches, gradually make pattern more general
- Use metavariables for parts that vary, keep fixed parts specific
## 4. Use Metavariables Appropriately
- `$VAR` - single expression (e.g., `$X + $Y`)
- `$$$ARGS` - multiple items in lists (e.g., function arguments)
- `$$STMT` - multiple statements (e.g., function body)
## 5. Combine with Other Tools
```bash
# Use ast-grep to find, pipe to other tools
ast-grep -p 'pattern' | rg -e 'additional-filter'
# Use ast-grep to find locations, then Edit to apply
ast-grep -l typescript -p 'pattern' # Find matches
# Then use Edit tool with precise context
```
---
# Common Pitfalls to Avoid
## 1. Overly Broad Patterns
`ast-grep -p '$X'` - matches everything
`ast-grep -l typescript -p 'specificFunction($X)'` - targeted
## 2. Forgetting Language Flag
`ast-grep -p 'pattern'` - may misdetect language
`ast-grep -l typescript -p 'pattern'` - explicit
## 3. Not Verifying Before --update-all
`ast-grep -p 'old' -r 'new' --update-all` - blind changes
✓ Preview first, verify matches, then apply
## 4. Expecting Exact Text Matching
ast-grep matches **structure**, not text:
- `foo( x )` and `foo(x)` are the same structurally
- Line breaks don't matter in most cases
- Comments are typically ignored
## 5. Using for Non-Code Files
ast-grep won't help with:
- Markdown content
- JSON/YAML values (not code structure)
- Plain text files
- Comments (usually)
---
# Error Handling
## If ast-grep fails or is unavailable:
1. Fall back to text-based tools immediately
2. Don't apologize excessively - just use the alternative approach
## If pattern doesn't match:
1. Verify language detection: ensure `-l LANG` is used
2. Simplify pattern - start with minimal matching case
3. Check syntax - ensure pattern is valid code for target language
4. Fall back to Grep for discovery, then use Edit
## If too many matches:
1. Make pattern more specific
2. Add context to pattern (surrounding code)
3. Use directory/file path to narrow scope
4. Consider using ast-grep for finding, Edit for selective changes
---
# Integration with Edit Tool
## Hybrid Strategy (Recommended for Precision)
When maximum control is needed:
1. **Use ast-grep to identify locations:**
```bash
ast-grep -l typescript -p 'pattern'
```
2. **Read the matched files** to see actual context
3. **Use Edit tool** with precise old_string/new_string based on actual file content
This combines ast-grep's structural search with Edit's precise control. This is often the best approach because:
- ast-grep finds the right locations structurally
- Edit gives precise control over the exact changes
- Each match can be handled differently if needed
- Lower risk of unintended changes
---
# Summary: Key Principles
1. **ast-grep solves the "not unique" problem** by matching code structure instead of text
2. **Always verify before applying** - search first, review matches, then apply
3. **Always use explicit language flag** (`-l typescript`, `-l python`, etc.)
4. **Use metavariables correctly** - `$VAR` for single nodes, `$$$ARGS` for multiple
5. **Consider hybrid approach** - ast-grep for finding, Edit for applying
6. **Fall back gracefully** - if ast-grep doesn't work, use text tools without hesitation