In a very simple C++ program I try to sue clang-tidy
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
char *pC = 0;
return 0;
}
Unfortunately some tooltip contain the same text several times, e.g.:

Other tooltip windows show text only once or maybe twice.
In https://github.com/Shadouw/HelloGitPod use the "Open in Gitpod" button to checkout and build the program. It automatically creates compile_comands.json using cmake
The reason that there are multiple clang-tidy fix-me available for the same line is due to there being an overlap in clang-tidy regarding multiple different checks each providing the same fix. There is however a bug, since looking at the problems-widget only max 2 of the fix-me should actually be available not 4.
If my settings.json I had the following, "cpp.clangTidyChecks": "hicpp-*" I only get one fix-me, and if I had "cpp.clangTidyChecks": "modernize-*" I also get one. If I combine the two and use "cpp.clangTidyChecks": "hicpp-*, modernize-*" I get 4 which seems bogus to me.
@lmcbout perhaps you can take a look?
I 'll have a look
I agree, that "cpp.clangTidyChecks": "*" includes way too much tests, but nevertheless the linter should list hints only once.
I agree, that
"cpp.clangTidyChecks": "*"includes way too much tests, but nevertheless the linter should list hints only once.
I believe they are in fact different fix-me because they come from different sources (just the same fix), but you are right that they are being duplicated, in this case there should be 2.
After adding some traces, I found what Theia is receiving from clangd:
clangd return duplication of the diagnostics for each code type
In the example below, clang-tidy returns 2 quick fixes for "hicpp-uppercase-literal-suffix" and two quick fixes for "readability-uppercase-literal-suffix". When opening the "Fixed it" context menu, I have 4 suggestions, i.e. 2 for each variable.
I should expect only one diagnostic for each variable.
[Trace - 08:55:48] Sending request 'textDocument/hover - (63)'.
Params: {
"textDocument": {
"uri": "file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp"
},
"position": {
"line": 11,
"character": 6
}
}
[Trace - 08:55:48] Received response 'textDocument/hover - (63)' in 11ms.
No result returned.
[Trace - 08:55:48] Sending request 'textDocument/codeAction - (64)'.
Params: {
"textDocument": {
"uri": "file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp"
},
"range": {
"start": {
"line": 11,
"character": 7
},
"end": {
"line": 11,
"character": 7
}
},
"context": {
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 6
},
"end": {
"line": 11,
"character": 10
}
},
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"severity": 1,
"code": "hicpp-uppercase-literal-suffix",
"source": "clang-tidy"
},
{
"range": {
"start": {
"line": 11,
"character": 6
},
"end": {
"line": 11,
"character": 10
}
},
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"severity": 2,
"code": "readability-uppercase-literal-suffix",
"source": "clang-tidy"
}
]
}
}
[Trace - 08:55:48] Received response 'textDocument/codeAction - (64)' in 23ms.
Result: [
{
"diagnostics": [
{
"code": "hicpp-uppercase-literal-suffix",
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 6,
"line": 11
}
},
"severity": 1,
"source": "clang-tidy"
}
],
"edit": {
"changes": {
"file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp": [
{
"newText": "F",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 9,
"line": 11
}
}
}
]
}
},
"kind": "quickfix",
"title": "change 'f' to 'F'"
},
{
"diagnostics": [
{
"code": "hicpp-uppercase-literal-suffix",
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 6,
"line": 11
}
},
"severity": 1,
"source": "clang-tidy"
}
],
"edit": {
"changes": {
"file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp": [
{
"newText": "F",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 9,
"line": 11
}
}
}
]
}
},
"kind": "quickfix",
"title": "change 'f' to 'F'"
},
{
"diagnostics": [
{
"code": "readability-uppercase-literal-suffix",
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 6,
"line": 11
}
},
"severity": 2,
"source": "clang-tidy"
}
],
"edit": {
"changes": {
"file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp": [
{
"newText": "F",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 9,
"line": 11
}
}
}
]
}
},
"kind": "quickfix",
"title": "change 'f' to 'F'"
},
{
"diagnostics": [
{
"code": "readability-uppercase-literal-suffix",
"message": "Floating point literal has suffix 'f', which is not uppercase (fix available)",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 6,
"line": 11
}
},
"severity": 2,
"source": "clang-tidy"
}
],
"edit": {
"changes": {
"file:///home/lmcbout/theia/workspace-cpp/bird-flocking-sim-tbb/Vector.cpp": [
{
"newText": "F",
"range": {
"end": {
"character": 10,
"line": 11
},
"start": {
"character": 9,
"line": 11
}
}
}
]
}
},
"kind": "quickfix",
"title": "change 'f' to 'F'"
}
]
Based on a brief investigation, I believe the problem is that clangd internally uses just the (message, range) pair of a diagnostic as a "key" for tracking diagnostics.
If you have two checkers which produce diagnostics with the same "key" and fixits for them, then clangd will associate both fixits with the same "key".
When clangd then receives a code action request containing two diagnostic with that key, it will return the two fixits for each of them, for a total of four.
Filed a clangd issue for this.
This issue has been resolved with clangd r365204
See issue https://github.com/clangd/clangd/issues/75
Available with different release starting with Xenial (16.04) and newer versions
Most helpful comment
Filed a clangd issue for this.