Реализация поиска ссылок в языковой службе Visual Studio 2010
Я реализую языковой сервис Visual Studio для пользовательского языка сценариев. Мне удалось реализовать подсветку синтаксиса, проверку ошибок, завершение кода и "Перейти к определению". У меня возникают проблемы с выяснением того, как подключиться к пункту меню "Найти все ссылки" (или даже заставить его отображаться в данный момент).
Может кто-нибудь указать мне полезный ресурс для реализации функциональности "Найти все ссылки" в Visual Studio для пользовательского языка? Я пробовал поискать в Google любую информацию, но не могу ничего найти.
1 ответ
Прежде всего, есть несколько мест, где можно найти все ссылки. Основные из них:
- Правым щелчком мыши по узлу в представлении классов.
- Щелкнув правой кнопкой мыши в текстовом редакторе.
Другие включают в себя:
- Иерархия вызовов
Начиная
В идеальной реализации у вас будет реализация IVsSimpleLibrary2
который интегрирует поддержку вашего языка в окнах просмотра классов и объектов. Реализация Find All References сосредоточена вокруг IVsFindSymbol
интерфейс, который предоставляется Visual Studio. Ваш код обрабатывает соответствующие поиски в реализации IVsSimpleLibrary2.GetList2
,
Поддержка правой кнопки мыши на узле в представлении классов
Убедитесь, что ваши библиотечные возможности включают
_LIB_FLAGS2.LF_SUPPORTSLISTREFERENCES
,В вашем обработчике для
IVsSimpleLibrary2.GetList2
Вы заинтересованы в случае, когда все следующее верно.pobSrch
ненулевой массив длины 1. Я предполагаю, что первый элемент назначен локальной переменнойcriteria
для остальной части этих условий.criteria.eSrchType == VSOBSEARCHTYPE.SO_ENTIREWORD
criteria.grfOptions
имеет флаг_VSOBSEARCHOPTIONS.VSOBSO_LOOKINREFS
criteria.grfOptions
имеет флаг_VSOBSEARCHOPTIONS.VSOBSO_CASESENSITIVE
Если вышеуказанные условия выполнены, вернуть
IVsSimpleObjectList2
реализации, чьи потомки являются лениво вычисленными результатами команды Find All References.
Поддержка команды текстового редактора
В вашем
ViewFilter.QueryCommandStatus
реализация, когдаguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97
а такжеnCmdId == VSStd97CmdID.FindReferences
вам нужно вернутьсяOLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED
,- В Visual Studio 2005 обратите внимание, что
nCmdId
будетVSStd2KCmdID.FindReferences
ноguidCmdGroup
будет таким же, как упоминалось ранее. Это несоответствие было исправлено начиная с Visual Studio 2008, после чегоVSStd2KCmdID.FindReferences
больше не использовался.
- В Visual Studio 2005 обратите внимание, что
Override
ViewFilter.HandlePreExec
для случая команды GUID и ID, перечисленных выше, и выполните следующий код для этого случая:HandleFindReferences(); return true;
Добавьте следующий класс метода расширения:
public static class IVsFindSymbolExtensions { public static void DoSearch(this IVsFindSymbol findSymbol, Guid symbolScope, VSOBSEARCHCRITERIA2 criteria) { if (findSymbol == null) throw new ArgumentNullException("findSymbol"); VSOBSEARCHCRITERIA2[] criteriaArray = { criteria }; ErrorHandler.ThrowOnFailure(findSymbol.DoSearch(ref symbolScope, criteriaArray)); } }
Добавьте следующий метод к вашему
ViewFilter
учебный класс:public virtual void HandleFindReferences() { int line; int col; // Get the caret position ErrorHandler.ThrowOnFailure( TextView.GetCaretPos( out line, out col ) ); // Get the tip text at that location. Source.BeginParse(line, col, new TokenInfo(), ParseReason.Autos, TextView, HandleFindReferencesResponse); } // this can be any constant value, it's just used in the next step. public const int FindReferencesResults = 100; void HandleFindReferencesResponse( ParseRequest req ) { if ( req == null ) return; // make sure the caret hasn't moved int line; int col; ErrorHandler.ThrowOnFailure( TextView.GetCaretPos( out line, out col ) ); if ( req.Line != line || req.Col != col ) return; IVsFindSymbol findSymbol = CodeWindowManager.LanguageService.GetService(typeof(SVsObjectSearch)) as IVsFindSymbol; if ( findSymbol == null ) return; // TODO: calculate references as an IEnumerable<IVsSimpleObjectList2> // TODO: set the results on the IVsSimpleLibrary2 (used as described below) VSOBSEARCHCRITERIA2 criteria = new VSOBSEARCHCRITERIA2() { dwCustom = FindReferencesResults, eSrchType = VSOBSEARCHTYPE.SO_ENTIREWORD, grfOptions = (uint)_VSOBSEARCHOPTIONS2.VSOBSO_LISTREFERENCES, pIVsNavInfo = null, szName = "Find All References" }; findSymbol.DoSearch(new Guid(SymbolScopeGuids80.All), criteria); }
Обновите вашу реализацию
IVsSimpleLibrary2.GetList2
, Когда критерии поискаdwCustom
значение установлено вFindReferencesResults
вместо того, чтобы вычислять результаты команды Find All References на узле Class View или Object Browser, вам нужно только вернутьIVsSimpleObjectList2
который оборачивает результаты, предварительно рассчитанные вашимHandleFindReferencesResponse
метод.