Saya menulis add-in COM yang memperluas IDE yang sangat membutuhkannya. Ada banyak fitur yang terlibat, tetapi mari kita persempit menjadi 2 untuk kepentingan posting ini:
- Ada jendela alat Code Explorer yang menampilkan tampilan pohon yang memungkinkan pengguna menavigasi modul dan anggota mereka.
- Ada alat bantu inspeksi kode yang menampilkan tampilan datagridview yang memungkinkan pengguna menavigasi masalah kode dan secara otomatis memperbaikinya.
Kedua alat memiliki tombol "Refresh" yang memulai tugas asinkron yang mem-parsing semua kode di semua proyek yang dibuka; yang Kode Explorer menggunakan hasil parse untuk membangun treeview , dan Kode Inspeksi menggunakan hasil parse untuk menemukan masalah kode dan menampilkan hasilnya di dalam datagridview .
Yang saya coba lakukan di sini, adalah untuk berbagi hasil parse antara fitur, sehingga ketika Kode Explorer refresh, maka Kode Inspeksi tahu tentang hal itu dan bisa menyegarkan sendiri tanpa harus mengulang pekerjaan parsing bahwa Kode Explorer hanya melakukan .
Jadi apa yang saya lakukan, saya menjadikan kelas parser saya sebagai penyedia acara yang fitur-fiturnya dapat didaftarkan ke:
private void _parser_ParseCompleted(object sender, ParseCompletedEventArgs e)
{
Control.Invoke((MethodInvoker) delegate
{
Control.SolutionTree.Nodes.Clear();
foreach (var result in e.ParseResults)
{
var node = new TreeNode(result.Project.Name);
node.ImageKey = "Hourglass";
node.SelectedImageKey = node.ImageKey;
AddProjectNodes(result, node);
Control.SolutionTree.Nodes.Add(node);
}
Control.EnableRefresh();
});
}
private void _parser_ParseStarted(object sender, ParseStartedEventArgs e)
{
Control.Invoke((MethodInvoker) delegate
{
Control.EnableRefresh(false);
Control.SolutionTree.Nodes.Clear();
foreach (var name in e.ProjectNames)
{
var node = new TreeNode(name + " (parsing...)");
node.ImageKey = "Hourglass";
node.SelectedImageKey = node.ImageKey;
Control.SolutionTree.Nodes.Add(node);
}
});
}
Dan itu berhasil. Masalah yang saya alami adalah apakah ... itu berfungsi - maksud saya, ketika inspeksi kode disegarkan, parser memberi tahu penjelajah kode (dan semua orang) "Bung, penguraian seseorang, apa yang ingin Anda lakukan? " - dan ketika parsing selesai, parser memberi tahu pendengarnya "kawan, saya punya hasil parsing baru untuk Anda, apa yang ingin Anda lakukan?".
Biarkan saya membimbing Anda melalui contoh untuk menggambarkan masalah yang diciptakan ini:
- Pengguna menampilkan Kode Explorer, yang memberi tahu pengguna "tunggu, saya bekerja di sini"; pengguna terus bekerja di IDE, Code Explorer menggambar ulang sendiri, hidup itu indah.
- Pengguna kemudian memunculkan Inspeksi Kode, yang memberi tahu pengguna "tunggu, saya sedang bekerja di sini"; parser memberi tahu Code Explorer "dude, parsing seseorang, apa yang ingin Anda lakukan?" - Code Explorer memberi tahu pengguna "tunggu, saya sedang bekerja di sini"; pengguna masih dapat bekerja di IDE, tetapi tidak dapat menavigasi Code Explorer karena ini menyegarkan. Dan dia juga menunggu inspeksi kode selesai.
- Pengguna melihat masalah kode dalam hasil inspeksi yang ingin mereka atasi; mereka mengklik dua kali untuk menavigasi ke sana, mengkonfirmasi ada masalah dengan kode, dan klik tombol "Perbaiki". Modul telah dimodifikasi dan perlu diurai kembali, sehingga inspeksi kode dilanjutkan dengannya; Penjelajah Kode memberi tahu pengguna "tunggu, saya sedang bekerja di sini", ...
Lihat kemana ini? Saya tidak suka, dan saya yakin pengguna juga tidak akan menyukainya. Apa yang saya lewatkan? Bagaimana cara saya membagi hasil parse di antara fitur, tetapi tetap membiarkan pengguna mengontrol kapan fitur harus melakukan fungsinya ?
Alasan saya bertanya, adalah karena saya pikir jika saya menunda pekerjaan yang sebenarnya sampai pengguna secara aktif memutuskan untuk menyegarkan, dan "cache" hasil parse ketika mereka masuk ... baik maka saya akan menyegarkan treeview dan menemukan masalah kode pada hasil parse yang mungkin basi ... yang benar-benar membawa saya kembali ke titik awal, di mana setiap fitur bekerja dengan hasil parse sendiri: apakah ada cara saya dapat membagikan hasil parsing antara fitur dan memiliki UX yang indah?
Kode ini adalah c # , tetapi saya tidak mencari kode, saya mencari konsep .
VBAParser
dihasilkan oleh ANTLR dan memberi saya pohon parse, tetapi fitur tidak mengonsumsinya. The RubberduckParser
take the parse tree, berjalan, dan mengeluarkan a VBProjectParseResult
yang berisi Declaration
objek yang memiliki semua References
penyelesaiannya - itulah yang dilakukan fitur untuk input .. jadi ya, ini cukup banyak situasi semua atau tidak sama sekali. The RubberduckParser
cukup pintar untuk tidak kembali parse modul yang belum dimodifikasi sekalipun. Tetapi jika ada hambatan bukan dengan parsing, itu dengan inspeksi kode.