Clangd代码检查器


文档摘要

Clangd利用LLVM模块架构的优势,与其他Clang工具有着非常紧密的集成。特别是,Clangd使用Clang-Format库来提供格式化功能,并使用Clang-Tidy库(如带有clang-tidy检查的库)来在IDE中支持代码检查器。 这种集成在下面的图中示意性地展示了出来: 格式化配置来自.clang-format(参见第7.4.1节,Clang-Format配置和使用示例),而代码检查器的配置来自.clang-tidy(参见图5.12,Clang-Tidy配置)。来看看Clangd中格式化是如何工作的。 Clangd为代码格式化提供了强大的支持。这个特性对于开发者在他们的C和C++项目中保持一致的代码风格和可读性至关重要。

Clangd利用LLVM模块架构的优势,与其他Clang工具有着非常紧密的集成。特别是,Clangd使用Clang-Format库来提供格式化功能,并使用Clang-Tidy库(如带有clang-tidy检查的库)来在IDE中支持代码检查器。

这种集成在下面的图中示意性地展示了出来:

格式化配置来自.clang-format(参见第7.4.1节,Clang-Format配置和使用示例),而代码检查器的配置来自.clang-tidy(参见图5.12,Clang-Tidy配置)。来看看Clangd中格式化是如何工作的。

Clangd为代码格式化提供了强大的支持。这个特性对于开发者在他们的C和C++项目中保持一致的代码风格和可读性至关重要。Clangd通过LSP消息实现此功能,主要是使用"textDocument/formatting"和"textDocument/rangeFormatting"请求。

当开发者想要格式化文档的全部内容时,会使用"textDocument/formatting"请求。在VS
Code中,这个请求通常是通过用户按下Ctrl + Shift + I(或者在macOS上是
image + Shift +
I)来发起的;IDE会向Clangd发送一个针对整个文档的"textDocument/formatting"请求:

"id": 9, "jsonrpc": "2.0", "method": "textDocument/formatting",
"params": "options": "insertSpaces": true, "tabSize": 4 ,
"textDocument": "uri": "file:///home/ivanmurashko/clangbook/helper.hpp"

图8.28:VS Code向Clangd发送(textDocument/formatting请求)

Clangd通过使用项目中.clang-format文件指定的代码风格配置来处理这个请求。.clang-format文件包含了格式化规则和偏好设置,允许开发者定义期望的代码风格;详见第7.4.1节,Clang-Format配置和使用示例。

响应包含了要应用于打开文档的修改列表:

"id": 9, "jsonrpc": "2.0", "result": [ "newText": "", "range": "end":
"character": 0, "line": 5 , "start": "character": 7, "line": 4 ]

图8.29:Clangd向VS Code返回(textDocument/formatting响应)

示例中,应该在图8.29中的第7-16行指定的范围内,用第6行指定的新文本替换文本。

除了格式化整个文档外,Clangd还支持在文档内格式化特定的代码范围。这是通过使用"textDocument/rangeFormatting"请求实现的。开发者可以在代码中选择一个范围,比如一个函数、一个代码块,甚至只是几行,然后请求对该特定范围的格式化,如下面的屏幕截图所示:

当选择菜单项或按下Ctrl + K然后Ctrl + F(或者在macOS上是
image + K然后
image + F),VS
Code会向Clangd发送以下请求:

"id": 89, "jsonrpc": "2.0", "method": "textDocument/rangeFormatting",
"params": "options": "insertSpaces": true, "tabSize": 4 , "range":
"end": "character": 2, "line": 10 , "start": "character": 0, "line": 3 ,
"textDocument": "uri": "file:///home/ivanmurashko/clangbook/helper.hpp"

图8.31:VS Code向Clangd发送(textDocument/rangeFormatting请求)

"textDocument/rangeFormatting"请求指定了要在文档中格式化的范围,Clangd将相同的格式化规则应用于这个特定的代码段,这些规则来自.clang-format文件。响应将与用于格式化请求的响应类似,并将包含应应用于原始文本的修改,如图8.29所示。唯一的区别将是方法名称,在这种情况下应该是"textDocument/rangeFormatting"。

通过Clangd集成的另一个工具是Clang-Tidy,与刚刚描述的格式化功能相比,以不同的方式使用LSP协议。

Clangd使用特定的LSP方法来实现与Clang-Format的集成:

  • "textDocument/formatting"

  • "textDocument/rangeFormatting"

另一方面,与Clang-Tidy的集成实现方式不同,重用"publishDiagnostics"通知来报告代码检查器的警告和错误。

探究一下它是如何工作的,并首先创建一个自定义的Clang-Tidy配置。

运行最近为测试方法重命名而创建的misc-methodrename检查,参见第7.3节,Clang-Tidy作为代码修改工具。Clang-Tidy配置将如下所示:

Checks: ’-*,misc-methodrename’

图8.32:用于IDE集成的.clang-tidy配置

带有配置的.clang-tidy文件应放置在测试项目文件夹中。

如果把helper类重命名为TestHelper,将能够观察到在第7.3节,Clang-Tidy作为代码修改工具中创建的lint检查,开始报告关于测试类使用的不正确方法名的诊断信息。相应的诊断信息显示,在下拉窗格和PROBLEMS标签页中,如下面的屏幕截图所示:

消息作为诊断信息的一部分显示。具体来说,以下通知是从Clang发送到VS
Code的:

图8.34:Clangd向VS Code发送(publishDiagnostics通知)

如图所示(第11行),问题的修复也是可用的。在IDE中应用Clang-Tidy修复是一个惊人的机会。让我们探索一下这个功能是如何通过LSP实现的。

修复可以在IDE中应用,该功能是通过"textDocument/codeAction"方法提供的。VS
Code使用这个方法来提示Clangd计算特定文档和范围的命令。命令的最重要部分在以下示例中提供:

图8.35:VS Code向Clangd发送(textDocument/codeAction请求)

请求的最重要部分在第7-11行,可以看到原始诊断通知的副本。这些信息将用来检索由激活检查中的clang::FixItHint提供的必要的文档修改。因此,Clangd可以响应描述所需修改的动作:

图8.36:Clangd向VS Code返回(codeAction响应)

图8.36中的"edit"字段是响应的最重要部分,因为它描述了要应用于原始文本的更改。

与Clang-Tidy的集成可以在不进行额外计算的情况下实现,因为Clangd核心为了导航和诊断目的构建了AST(抽象语法树)。AST可以作为Clang-Tidy检查的种子,从而消除了运行单独的Clang-Tidy可执行文件以从代码检查器检索消息的需要。这并不是Clangd进行的唯一优化;现在来看另一个Clangd性能优化的例子。


发布者: 作者: 转发
评论区 (0)
U