Refaktor kode secara struktural
Panduan ini menunjukkan cara meminta agen melakukan perubahan mekanis yang luas — codemod, migrasi API massal, pola yang ingin Anda hilangkan — memakai pencarian dan penulisan ulang struktural, dengan perubahannya di-staging untuk ditinjau sebelum apa pun ditulis.
ast_grep mencocokkan kode berdasarkan bentuk. ast_edit menulis ulangnya. resolve melakukan commit atau membuangnya.
Sebelum memulai
Bagian berjudul “Sebelum memulai”Alat struktural mencakup bahasa yang diuraikan graf kode: Dart, JavaScript, TypeScript, TSX, PHP, Python, Rust, Zig, C, C++, Go, Java, Ruby, C#, Swift, Kotlin, R, Assembly, MATLAB, dan Ada. Alat-alat ini memerlukan grammar tree-sitter yang sudah disiapkan, dan itu selalu tersedia pada build yang dikirim — grammar yang hilang menghentikan server alih-alih menurunkan kualitas pencarian.
Temukan bentuknya lebih dulu
Bagian berjudul “Temukan bentuknya lebih dulu”Jangan pernah menulis ulang sesuatu yang belum Anda lihat. Minta agen mencari:
Temukan setiap tempat kita memanggil
dispose()pada nilai nullable yang baru saja kita periksa null-nya.
ast_grep(pattern: "if ($X != null) $X.dispose()", language: "dart")Outputnya adalah file:line beserta kode sumber yang cocok untuk setiap situs.
Apa yang Anda dapatkan dari sintaks pola
Bagian berjudul “Apa yang Anda dapatkan dari sintaks pola”| Token | Kecocokan |
|---|---|
$NAME |
Satu node mana pun, ditangkap |
$$$NAME |
Rangkaian saudara mana pun — argumen, pernyataan |
$_ |
Apa pun, ditangkap tanpa nama |
Yang paling penting: $NAME yang diulang harus menangkap teks yang sama.
if ($X != null) $X.dispose()menemukan penjaga yang membuang apa yang diujinya. Pola ini tidak menemukan if (a != null) b.dispose() — yang biasanya justru bug yang Anda cari. Tidak ada pencarian tekstual yang dapat mengungkapkan hal itu.
Saat pola tidak menemukan apa pun
Bagian berjudul “Saat pola tidak menemukan apa pun”Dua hal yang bisa dicoba, secara berurutan:
- Kecilkan polanya. Coba
foo($X)sebelumif (a) { foo($X); }. Pola yang tidak valid sebagai kode mandiri sering kali bukan konstruk yang Anda maksud. - Sebutkan bahasanya.
language:hanya disimpulkan saatpathmenunjuk satu file.
Pola yang tidak diterima konteks penguraian mana pun dilaporkan sebagai tidak dapat diuraikan — alat menyatakannya, alih-alih melaporkan “tidak ada kecocokan” untuk sesuatu yang memang tidak pernah dibaca sesuai penampilannya.
Tulis ulang, dan periksa sebelum diterapkan
Bagian berjudul “Tulis ulang, dan periksa sebelum diterapkan”ast_edit( pattern: "if ($X != null) $X.dispose()", rewrite: "$X?.dispose()", language: "dart",)Hasilnya adalah proposal:
(proposed) ast_edit: if ($X != null) $X.dispose() → $X?.dispose()12 replacements in 4 files: lib/features/a/x.dart (3) lib/features/b/y.dart (5) …Nothing has been written. Call resolve with edit_id "edit_1" and action"accept" to apply it, or "discard" to drop it.Belum ada apa pun yang tertulis di disk. Baca daftarnya, periksa beberapa situs yang dilaporkan pencarian, lalu:
resolve(edit_id: "edit_1", action: "accept")atau
resolve(edit_id: "edit_1", action: "discard")Periksa hasil kerja Anda dengan compiler
Bagian berjudul “Periksa hasil kerja Anda dengan compiler”Inti melakukannya secara struktural adalah jangkauannya yang luas. Perubahan luas justru tempat penulisan ulang yang tampak masuk akal merusak sebuah tipe. Minta diagnostik setelah Anda menjalankan resolve:
lsp(action: "diagnostics", file: "*")file: "*" menjalankan pemeriksa milik proyek (dart analyze, tsc --noEmit, cargo check, go build), bukan kueri per file — bentuk pertanyaan yang tepat setelah perubahan yang menyentuh empat puluh file.
Contoh penerapan: memigrasikan pemanggilan
Bagian berjudul “Contoh penerapan: memigrasikan pemanggilan”Misalnya log(msg, level) akan diubah menjadi log(level: level, message: msg).
ast_grep(pattern: "log($MSG, $LEVEL)", language: "dart")Perhatikan hasil yang cocok. Jika sebagian di antaranya adalah log dua argumen yang berbeda, persempit pola dengan membatasi path ke direktori pemilik log yang Anda maksud, alih-alih mencoba mengungkapkan perbedaannya di dalam pola.
ast_edit( pattern: "log($MSG, $LEVEL)", rewrite: "log(level: $LEVEL, message: $MSG)", path: "lib/features/telemetry", language: "dart",)Lalu resolve, lalu lsp(action: "diagnostics", file: "*").
Kapan menggunakan alat lain
Bagian berjudul “Kapan menggunakan alat lain”| Situasi | Alat yang lebih baik |
|---|---|
| Mengganti nama simbol | lsp_rename — alat ini mengikuti referensi, bukan bentuk |
| Menemukan string, komentar, atau nama file | search (konten) / search_files (nama) |
| “Apa yang rusak jika saya mengubah ini?” | Graf kode |
| Bahasa yang tidak dicakup grammar | search ditambah edit |
Terkait
Bagian berjudul “Terkait”- Kecerdasan kode — mengapa pencocokan struktural bukan regex dengan langkah tambahan
- Alat agen bawaan — daftar argumen lengkap
- Cari kode dengan graf kode — sisi simbol dan dampaknya