Kecerdasan kode
Control Center memberi agen empat cara untuk memahami kode di luar sekadar membacanya. Keempatnya menjawab pertanyaan yang benar-benar berbeda, dan alasan ada empat alih-alih satu adalah karena tidak ada satu mekanisme pun yang dapat menjawab semuanya.
| Mekanisme | Menjawab | Biaya |
|---|---|---|
| Graf kode | Apa yang ada di sini, dan apa yang bergantung padanya | Satu proses indeks; murah untuk dikueri |
| Server bahasa | Apakah ini benar-benar terkompilasi, dan apa tipe ini | Satu proses server per proyek |
| Pencarian struktural | Di mana BENTUK ini muncul | Satu penguraian per file |
| Debugger | Apa yang benar pada momen ini, di frame ini | Satu proses yang berhenti |
Celah yang ditutup server bahasa
Bagian berjudul “Celah yang ditutup server bahasa”Graf kode dibangun dari tree-sitter: simbol, tepi pemanggilan, radius dampak. Graf ini cepat, murah, dan tidak tahu apa pun tentang tipe. Graf ini tidak dapat memberi tahu Anda apakah pemanggilan yang baru Anda tulis dapat dikompilasi, apakah field itu ada pada objek, atau apakah penggantian nama Anda melewatkan sebuah re-ekspor.
Tanpa server bahasa, agen baru mengetahuinya saat pengujian — atau tidak pernah sama sekali. Agen menulis sesuatu yang tampak masuk akal, melanjutkan pekerjaan, dan kegagalannya muncul tiga giliran kemudian, menempel pada perubahan yang berbeda.
Jadi manfaat utamanya sebenarnya bukan alat lsp. Manfaatnya adalah write, edit, dan apply_patch dibungkus: setelah setiap penulisan, file melewati server bahasa dan diagnostik yang baru muncul dilipat ke dalam hasil alat. Agen langsung tahu bahwa ia merusak build pada saat ia merusaknya, terlepas dari apakah ia sempat terpikir untuk bertanya.
Hanya diagnostik baru
Bagian berjudul “Hanya diagnostik baru”Mengulangi apa yang sudah diberitahukan kepada agen lebih buruk daripada tidak mengatakan apa pun: hal itu mengisi hasil dengan kebisingan yang membuat agen terbiasa melewatinya begitu saja, dan satu error baru ikut terlewat bersamanya. Sebuah catatan per eksekusi melacak apa yang sudah dilaporkan, dengan kunci berupa tingkat keparahan, kode, dan pesan — bukan posisi, sehingga diagnostik yang hanya bergeser empat baris ke bawah tidak dilaporkan ulang sebagai baru.
Bersifat malas, dan jujur tentang ketidakhadirannya
Bagian berjudul “Bersifat malas, dan jujur tentang ketidakhadirannya”Tidak ada server yang dimulai saat boot. Sebuah server dimulai pada permintaan pertama yang membutuhkannya, yang hampir selalu merupakan edit pertama pada file yang diklaimnya, dan server yang menganggur akan dibersihkan. Host yang tidak pernah menyentuh Dart tidak akan pernah memulai analyzer.
Deteksi adalah sebuah irisan: penanda root harus ada di checkout dan biner-nya harus dapat di-resolve. Penanda saja hanya mengatakan “proyek ini adalah Python” dan tidak mengatakan apa pun tentang apakah server-nya terpasang; biner yang dapat di-resolve saja hanya mengatakan bahwa host memiliki toolchain dan tidak mengatakan apa pun tentang checkout ini. Hanya keduanya bersama-sama yang berarti sebuah kueri dapat berhasil, dan alat yang ditawarkan tetapi selalu gagal lebih buruk daripada alat yang tidak ada.
Mengapa pencarian struktural, padahal grep sudah ada
Bagian berjudul “Mengapa pencarian struktural, padahal grep sudah ada”grep mencocokkan karakter. Alat itu tepat untuk sebuah nama dan salah untuk sebuah bentuk.
Pola struktural diuraikan oleh grammar yang sama dengan file, sehingga dispose($X) menemukan pemanggilan tersebut bagaimanapun spasi, pembungkusan, atau pemenggalan barisnya, dan tidak akan pernah mencocokkan karakter yang sama di dalam literal string atau komentar.
Sifat yang membuatnya lebih dari sekadar regex dengan langkah tambahan adalah bahwa metavariabel yang diulang dalam satu pola harus menangkap teks yang sama:
if ($X != null) $X.dispose()Pola ini cocok dengan penjaga yang membuang apa yang diujinya, dan tidak cocok dengan penjaga yang membuang hal lain. Itu adalah kelas bug yang sama sekali tidak dapat Anda ekspresikan secara tekstual.
Alat ini berjalan di atas tree-sitter yang sudah tertaut
Bagian berjudul “Alat ini berjalan di atas tree-sitter yang sudah tertaut”Tidak ada mesin kedua. cc_natives sudah memuat tree-sitter dan grammar-nya untuk graf kode, lengkap dengan cache kueri terkompilasi dan tabel bahasa. Pencocoknya murni Dart di atas pohon yang memang sedang diuraikan. Mesin struktural kedua akan berarti parser kedua, rangkaian grammar kedua yang harus dibangun dan disiapkan untuk setiap platform, serta dua jawaban untuk “apa itu ekspresi pemanggilan”.
Sebuah fragmen perlu tempat untuk hidup
Bagian berjudul “Sebuah fragmen perlu tempat untuk hidup”Sebuah grammar hanya mendefinisikan apa itu sebuah file secara utuh. Jika diuraikan mentah-mentah pada tingkat atas Dart, dispose(x) adalah signature fungsi yang sepenuhnya valid — deklarasi bernama dispose yang menerima parameter x — tanpa ada error di mana pun yang membocorkannya. Pencocok yang dibangun di atas penguraian itu akan mencari deklarasi, tidak menemukan pemanggilan apa pun, dan melaporkan “tidak ada kecocokan” untuk pola yang sebenarnya tidak pernah dibaca sesuai penampilannya.
Jadi sebuah pola dicoba dalam tangga kerangka — pernyataan, ekspresi, anggota kelas, tingkat atas — dan kerangka pertama yang menerimanya yang menang. Fragmen yang tidak diterima oleh konteks mana pun dilaporkan sebagai tidak dapat diuraikan, alih-alih dicari lalu diam-diam tidak ditemukan.
Mengapa penulisan ulang memakai staging alih-alih langsung menulis
Bagian berjudul “Mengapa penulisan ulang memakai staging alih-alih langsung menulis”Penulisan ulang struktural adalah edit terluas yang dapat dilakukan agen: satu pola, empat puluh file, dan tidak ada yang membaca hasilnya baris demi baris — bukan modelnya, dan bukan orang yang memintanya. Menuliskannya lalu melaporkan “selesai” berarti tatapan jujur pertama terhadap perubahan itu adalah git diff setelahnya.
Jadi ast_edit melaporkan apa yang akan dilakukannya — jumlahnya, file-nya, situs yang cocok — dan perubahan itu baru diterapkan ketika resolve melakukan commit. Itulah juga yang memungkinkan sebuah diff serta Terima/Buang berada di hadapan manusia sebelum apa pun menyentuh disk.
Commit bersifat semua-atau-tidak sama sekali, dan setiap file diperiksa terhadap konten yang ditangkap pada saat staging. Antara staging dan commit, agen mungkin telah mengedit salah satu file itu secara manual, proses diagnostik mungkin telah menulis ulang file itu, atau formatter mungkin telah menyentuhnya — tetap melakukan commit akan membuang pekerjaan itu dan diff-nya akan tampak disengaja. Ketidakcocokan apa pun akan menolak seluruh perubahan, karena penulisan ulang struktural yang baru diterapkan sebagian meninggalkan pohon yang tidak dapat dikompilasi dalam kedua bentuk tersebut.
Apa yang dijawab debugger yang tidak dapat dijawab pernyataan print
Bagian berjudul “Apa yang dijawab debugger yang tidak dapat dijawab pernyataan print”Siklus pernyataan print adalah: tambahkan print, jalankan seluruhnya lagi, baca output-nya, hapus print tersebut. Siklus ini memakan satu kali pengujian penuh untuk setiap pertanyaan, dan hanya menjawab pertanyaan yang sempat Anda pikirkan sebelum menjalankannya.
Frame yang berhenti menjawab semua pertanyaan tentang momen itu sekaligus — setiap variabel lokal, setiap pemanggil, dan ekspresi yang dievaluasi dalam scope milik frame itu sendiri. Untuk proses yang macet atau kegagalan yang hanya terulang sekali dalam sepuluh kali eksekusi, itulah perbedaan antara seharian dan satu menit.
Dibatasi seperti kurungan, dan karena alasan yang sama
Bagian berjudul “Dibatasi seperti kurungan, dan karena alasan yang sama”Adapter debug memiliki sebuah proses yang berhenti yang memegang apa pun yang dipegang proses itu — port, lock, koneksi basis data. Sesi yang tidak dijalankan siapa pun adalah kebocoran yang hidup lebih lama daripada giliran yang memulainya. Karena itu ada TTL yang tegas, tepat satu sesi per percakapan, dan launch kedua ditolak alih-alih diam-diam menggantikan yang pertama: agen yang memulai sesi kedua tanpa mengakhiri yang pertama hampir pasti telah kehilangan jejak sesi pertama.
Satu transport, dua protokol
Bagian berjudul “Satu transport, dua protokol”Debug Adapter Protocol berbagi framing Content-Length milik Language Server Protocol dan tidak berbagi apa pun di atasnya — kunci korelasi yang berbeda, bentuk kegagalan yang berbeda, dan jenis pesan ketiga (peristiwa) yang tidak memiliki padanan di LSP. Framing-nya berada di satu tempat; protokol-protokolnya duduk di atasnya secara terpisah.
Menulis framing dua kali akan berarti dua jawaban untuk “sebuah pesan membentang dua chunk”, “sebuah chunk memuat tiga pesan”, dan “server menulis banner ke stdout sebelum frame pertamanya”, dan hanya salah satunya yang akan mendapatkan perbaikan.
Terkait
Bagian berjudul “Terkait”- Cari kode dengan graf kode — sisi simbol dan dampaknya
- Debug pengujian yang gagal — debugger, dari awal sampai akhir
- Refaktor kode secara struktural —
ast_grepdanast_edit - Alat agen bawaan — setiap operasi dan argumen