Проблемы, предлагающие языковой сервис

Я нашел два способа предложить языковой сервис в интернете.

Первый способ предполагает использование IOleComponentManager и регистрация таймера для вызова моей службы во время простоя.

Второй способ заключается в том, чтобы оформить мой сервис как IServiceContainer и добавив ServiceCreatorCallback "предложить услугу по требованию".

Предположительно, второй способ теперь является "предпочтительным" способом ведения дел. К сожалению, когда я использую этот метод, OnSynchronizeDropdowns никогда не вызывается на мой TypeAndMembersDropdownBars реализация.

Кроме того, когда мой LanguageService находит ошибки в файле, он использует ParseRequest.Sink.AddError() добавить ошибки в список ошибок. При предложении "По требованию" эти ошибки не отображаются в графическом интерфейсе, хотя я вижу, что они добавляются при отладке кода.

Я знаю, что моя языковая служба регистрируется, поскольку подсветка синтаксиса, "Перейти к определению" и "Найти все ссылки" по-прежнему работают.

Вот код, который я использую, чтобы "предложить свой сервис по требованию":

IServiceContainer serviceContainer = this as IServiceContainer;
ServiceCreatorCallback callback = new ServiceCreatorCallback(CreateLanguageService);
serviceContainer.AddService(typeof(MyLanguageService), callback, true);

Может кто-нибудь сказать мне, почему некоторые функции моего LanguageService не работает, предлагая его по требованию? Я что-то упустил или просто не предназначен для полнофункциональной языковой службы?

1 ответ

Решение

Похоже, что по крайней мере отсутствующая функциональность требует использования IOleComponentManager метод, который регистрирует таймер для вызова языковой службы в периоды простоя.

Используя dotPeek, я обнаружил, что OnSynchronizeDropdowns() вызывается из OnCaretMoved() для синхронизации выбранного элемента при нажатии в редакторе. OnCaretMoved() само по себе, кажется, вызывается только из LanguageService.OnIdle() метод, который я считаю, требует использования таймера простоя.

Еще покопавшись, я также обнаружил, что список ошибок требует, чтобы ParseRequest.Reason быть установленным ParseReason.Checkв противном случае он игнорирует вызов. Копая код еще немного, единственное место, где я обнаружил, что причина разбора была в Source.OnIdle(),

Обновление: я полагаю, что я подтвердил, что регистрация таймера простоя необходима для этих двух функций. Из MSDN на LanguageService.OnIdle:

Примечание. Этот метод не вызывается, пока вы не настроите свой собственный таймер и не вызовете этот метод из обработчика таймера.

Базовый метод вызывает OnCaretMoved, если каретка перемещена с момента последнего вызова OnIdle. Затем базовый метод вызывает метод OnIdle объекта Source для текущего представления. Если текущий объект Source не может быть получен, базовый метод вообще ничего не делает, в том числе не вызывает OnCaretMoved.

Другие вопросы по тегам