2

我正在为自定义脚本语言实现 Visual Studio 语言服务。我设法实现了语法高亮、错误检查、代码完成和“转到定义”。我无法弄清楚如何连接到“查找所有参考”菜单选项(或者甚至在此时显示它)。

谁能指出我在 Visual Studio 中为自定义语言实现“查找所有引用”功能的有用资源? 我试过谷歌搜索有关它的任何信息,但我似乎找不到任何东西。

4

1 回答 1

5

首先,可以在多个位置调用 Find All References。主要的有:

  1. 通过右键单击类视图中的节点。
  2. 通过在文本编辑器中单击鼠标右键。

其他包括:

  1. 调用层次结构

入门

在理想的实现中,您将拥有一个IVsSimpleLibrary2将您的语言支持集成到类视图和对象浏览器窗口中的实现。Find All References 的实现IVsFindSymbol以 Visual Studio 提供的接口为中心。您的代码处理IVsSimpleLibrary2.GetList2.

支持类视图中节点的右键单击

  1. 确保您的库功能包括_LIB_FLAGS2.LF_SUPPORTSLISTREFERENCES.

  2. 在您的处理程序中IVsSimpleLibrary2.GetList2,您对以下所有情况都为真的情况感兴趣。

    1. pobSrch是一个长度为 1 的非空数组。我将假设第一个元素分配给criteria这些条件的其余部分的局部变量。
    2. criteria.eSrchType == VSOBSEARCHTYPE.SO_ENTIREWORD
    3. criteria.grfOptions有国旗_VSOBSEARCHOPTIONS.VSOBSO_LOOKINREFS
    4. criteria.grfOptions有国旗_VSOBSEARCHOPTIONS.VSOBSO_CASESENSITIVE
  3. 当满足上述条件时,返回一个IVsSimpleObjectList2实现,其子项是 Find All References 命令的延迟计算结果。

支持文本编辑器命令

  1. 在您的ViewFilter.QueryCommandStatus实现中,您何时guidCmdGroup == VSConstants.GUID_VSStandardCommandSet97需要nCmdId == VSStd97CmdID.FindReferences返回OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED.

    • 在 Visual Studio 2005 中,请注意,这将nCmdId与前面提到的相同。从 Visual Studio 2008 开始,此不匹配已得到纠正,此后不再使用该点。VSStd2KCmdID.FindReferencesguidCmdGroupVSStd2KCmdID.FindReferences
  2. 覆盖ViewFilter.HandlePreExec上面列出的命令 GUID 和 ID 的情况,并针对该情况执行以下代码:

    HandleFindReferences();
    return true;
    
  3. 添加以下扩展方法类:

    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));
        }
    }
    
  4. 将以下方法添加到您的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);
    }
    
  5. 更新您的IVsSimpleLibrary2.GetList2. 当搜索条件的dwCustom值设置为FindReferencesResults时,您无需在类视图或对象浏览器节点上计算 Find All References 命令的结果,您只需返回IVsSimpleObjectList2包装先前由您的HandleFindReferencesResponse方法计算的结果的 。

于 2014-02-25T01:51:37.890 回答