访问 VS 语言服务中的其他文件(Visual Studio 可扩展性)

Access other files in VS Language Service (Visual Studio Extensibility)

我正在按照中所述编写自定义语言服务 https://msdn.microsoft.com/en-us/library/bb166533.aspx

现在我正在为 AuthoringScope (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.package.authoringscope.aspx) 编写代码,我的问题出在 GetDeclarations 方法中。

我可以通过 ParseRequest.Text 属性 访问当前文件的文本。 它允许我列出文件中的所有方法和变量,但我如何访问其他文件内容?我需要访问其他文件内容以构建此文件的 AST 树,但我不知道该怎么做。

我个人认为 MPF "helper" 类(如 AuthoringScope)有点限制,并且手动执行所有操作(我承认,这确实需要更多时间,但是最终要灵活得多)。

无论如何,听起来您的语言(和大多数语言一样!)在语义解析级别的文件之间具有依赖性。这意味着您要么必须:

a) 一直重新解析大量文本,这在大型项目中可能太慢了
或 b) 维护项目文件的全局聚合解析,并在文件(或项目的属性)更改时动态更新它

b) 显然要难得多,但几乎可以肯定是最好的方法。一个大纲是在通过 EnvDTE 打开解决方案后发现所有项目,解析它们(再次通过 EnvDTE 发现每个项目中的所有文件),并将所有内容存储在某种可索引的数据结构中,以便您可以进行快速查询反对它(用于语义语法突出显示,转到定义等)。然后你需要监听所有地方的变化并适当地重新解析——你需要检查解决方案 open/close (IVsSolutionEvents),项目是 added/removed/renamed/unloaded/loaded (IVsSolutionEvents/IVsSolutionEvents4),文件正在 added/removed/renamed (IVsHierarchyEvents),文件正在编辑 (IVsTextViewCreationListener + ITextBuffer.Changed),项目配置正在更改 (IVsUpdateSolutionEventsIVsHierarchyEvents).

无论您选择 a) 还是 b),您仍然需要能够检查文件是否在编辑器中打开(可能有未保存的更改)。您可以通过 IVsRunningDocumentTable 服务检查文件是否已在 运行 文档 Table 中打开(但不要忘记首先使用 Path.GetFullPath() 规范化路径),该服务将 return 一个 IntPtr 到文档数据,可以诱导它为文件生成一个 ITextBuffer,其中包含文件的文本(和整个缓冲区历史记录!)。当然,如果它没有打开,你将不得不从磁盘读取它。