Я пишу COM-надбудову, яка розширює IDE, яка відчайдушно потребує цього. Є багато функцій, але давайте звузимо їх до 2 заради цієї публікації:
- Існує вікно інструментів Code Explorer, яке відображає вигляд дерева, що дозволяє користувачеві переміщатися по модулях та їх членам.
- Там в Інспектування коду ToolWindow , який відображає DataGridView , який дозволяє проблеми користувачеві переміщатися код і автоматично виправити їх.
В обох інструментах є кнопка «Оновити», яка запускає асинхронну задачу, яка аналізує весь код у всіх відкритих проектах; Code Explorer використовує результати синтаксичного аналізу для побудови TreeView , а код Огляди використовує синтаксичнийаналіз результати пошуку проблем коди і відображення результатів у своїй DataGridView .
Що я намагаюся зробити тут, це поділити результати аналізу між функціями, так що коли Code Explorer оновлюється, то Кодекс перевірки знає про це і може оновитись без необхідності повторювати роботу розбору, яку щойно робив Провідник коду .
Отже, що я зробив, я зробив свій аналізатор класу провайдером подій, до яких функції можуть зареєструватися:
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);
}
});
}
І це працює. Проблема, яка у мене виникає, полягає в тому, що ... це працює - я маю на увазі, коли перевірки коду будуть оновлені, аналізатор повідомляє провідникові коду (і всім іншим) "чувак, чийсь синтаксичний розбір, все, що ти хочеш з цим робити?" " - і коли синтаксичний розбір завершується, аналізатор повідомляє своїм слухачам "хлопці, у мене є для вас свіжі результати розбору, все, що ви хочете з цим зробити?".
Дозвольте ознайомити вас із прикладом, щоб проілюструвати проблему, яку це створює:
- Користувач виводить Провідник коду, який говорить користувачеві "тримайтесь, я працюю тут"; Користувач продовжує працювати в IDE, Code Explorer переробляє себе, життя прекрасне.
- Потім користувач відкриває інспекції коду, які повідомляють користувачеві "затримайтеся, я працюю тут"; аналізатор каже Провідник коду: "чувак, чийсь розбір, все, що ти хочеш з цим зробити?" - Провідник коду повідомляє користувачеві "тримайтесь, я працюю тут"; Користувач все ще може працювати в IDE, але не може переміщатися в Провіднику кодів, оскільки він оновлює. І він також чекає завершення перевірок коду.
- Користувач бачить проблему з кодом у результатах перевірки, до яких хоче звернутися; вони двічі клацнуть, щоб перейти до нього, підтвердити наявність проблеми з кодом та натиснути кнопку "Виправити". Модуль був модифікований і його потрібно переаналізувати, тому перевірки коду тривають з ним; Провідник коду каже користувачеві "тримайтесь, я працюю тут", ...
Бачите, куди це йде? Мені це не подобається, і сподіваюся, що і користувачам це не сподобається. Що я пропускаю? Як мені слід ділитися результатами розбору між функціями, але все ж залишати користувачеві контроль, коли функція повинна виконувати свою роботу ?
Причина, про яку я питаю, полягає в тому, що я зрозумів, що якщо я відкладу фактичну роботу, поки користувач активно не вирішить оновити, і "кешував" результати аналізу, коли вони надходять ... ну тоді я б освіжив вигляд дерева і пошук проблем з кодом у можливо несвіжий результат розбору ... що буквально повертає мене до прямого, де кожна функція працює з власними результатами розбору: чи можна я поділитись результатами розбору між функціями та мати чудовий UX?
Код є c # , але я не шукаю коду, я шукаю поняття .
VBAParser
генерується ANTLR і дає мені розбір дерева, але функції цього не використовують. RubberduckParser
Приймає дерево розбору, прогулянки, і видає , VBProjectParseResult
що містить Declaration
об'єкти , які мають всі їх References
вирішити - що - х , які функції приймають на вхід .. так що так, це в значній мірі все-або-нічого ситуація. Це RubberduckParser
досить розумно, щоб не переаналізувати модулі, які не були змінені. Але якщо є вузьке вузьке місце, це не те, що він розбирає, це перевірка коду.