1 # We specify a custom path in XDG_CONFIG_HOME, which only works on some systems.
2 # UNSUPPORTED: system-windows
3 # UNSUPPORTED: system-darwin
6 # RUN: mkdir -p %t/clangd
7 # RUN: cp -r %S/Inputs/include-cleaner %t/include
8 # RUN: echo '-I%t/include' > %t/compile_flags.txt
9 # Create a config file enabling include-cleaner features.
10 # RUN: echo $'Diagnostics:\n UnusedIncludes: Strict\n MissingIncludes: Strict' >> %t/clangd/config.yaml
12 # RUN: env XDG_CONFIG_HOME=%t clangd -lit-test -enable-config --compile-commands-dir=%t < %s | FileCheck -strict-whitespace %s
13 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"workspace":{"workspaceEdit":{"documentChanges":true, "changeAnnotationSupport":{"groupsOnLabel":true}}}},"trace":"off"}}
17 "method": "textDocument/didOpen",
20 "uri": "test:///simple.cpp",
22 "text": "#include \"all1.h\"\n#include \"all2.h\"\n Foo* foo; Bar* bar;"
26 # First, the diagnostic from the config file.
27 # CHECK: "method": "textDocument/publishDiagnostics",
28 # CHECK-NEXT: "params": {
29 # CHECK-NEXT: "diagnostics": [],
31 # Then, diagnostic from the main cpp file.
32 # CHECK: "method": "textDocument/publishDiagnostics",
33 # CHECK-NEXT: "params": {
34 # CHECK-NEXT: "diagnostics": [
36 # CHECK-NEXT: "code": "missing-includes",
37 # CHECK-NEXT: "codeDescription": {
38 # CHECK-NEXT: "href": "{{.*}}"
40 # CHECK-NEXT: "message": "No header providing \"Foo\" is directly included (fixes available)",
41 # CHECK-NEXT: "range": {
42 # CHECK-NEXT: "end": {
43 # CHECK-NEXT: "character": 4,
44 # CHECK-NEXT: "line": 2
46 # CHECK-NEXT: "start": {
47 # CHECK-NEXT: "character": 1,
48 # CHECK-NEXT: "line": 2
51 # CHECK-NEXT: "severity": 3,
52 # CHECK-NEXT: "source": "clangd"
55 # CHECK-NEXT: "code": "missing-includes",
56 # CHECK-NEXT: "codeDescription": {
57 # CHECK-NEXT: "href": "{{.*}}"
59 # CHECK-NEXT: "message": "No header providing \"Bar\" is directly included (fixes available)",
60 # CHECK-NEXT: "range": {
61 # CHECK-NEXT: "end": {
62 # CHECK-NEXT: "character": 14,
63 # CHECK-NEXT: "line": 2
65 # CHECK-NEXT: "start": {
66 # CHECK-NEXT: "character": 11,
67 # CHECK-NEXT: "line": 2
70 # CHECK-NEXT: "severity": 3,
71 # CHECK-NEXT: "source": "clangd"
74 # CHECK-NEXT: "code": "unused-includes",
75 # CHECK-NEXT: "codeDescription": {
76 # CHECK-NEXT: "href": "{{.*}}"
78 # CHECK-NEXT: "message": "Included header all1.h is not used directly (fixes available)",
79 # CHECK-NEXT: "range": {
80 # CHECK-NEXT: "end": {
81 # CHECK-NEXT: "character": 17,
82 # CHECK-NEXT: "line": 0
84 # CHECK-NEXT: "start": {
85 # CHECK-NEXT: "character": 0,
86 # CHECK-NEXT: "line": 0
89 # CHECK-NEXT: "severity": 2,
90 # CHECK-NEXT: "source": "clangd",
91 # CHECK-NEXT: "tags": [
96 # CHECK-NEXT: "code": "unused-includes",
97 # CHECK-NEXT: "codeDescription": {
98 # CHECK-NEXT: "href": "{{.*}}"
100 # CHECK-NEXT: "message": "Included header all2.h is not used directly (fixes available)",
101 # CHECK-NEXT: "range": {
102 # CHECK-NEXT: "end": {
103 # CHECK-NEXT: "character": 17,
104 # CHECK-NEXT: "line": 1
106 # CHECK-NEXT: "start": {
107 # CHECK-NEXT: "character": 0,
108 # CHECK-NEXT: "line": 1
111 # CHECK-NEXT: "severity": 2,
112 # CHECK-NEXT: "source": "clangd",
113 # CHECK-NEXT: "tags": [
118 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
119 # CHECK-NEXT: "version": 0
122 {"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///simple.cpp"},"range":{"start":{"line":2,"character":1},"end":{"line":2,"character":4}},"context":{"diagnostics":[{"range":{"start": {"line": 2, "character": 1}, "end": {"line": 2, "character": 4}},"severity":3,"message":"No header providing \"Foo\" is directly included (fixes available)", "code": "missing-includes", "source": "clangd"}]}}}
124 # CHECK-NEXT: "jsonrpc": "2.0",
125 # CHECK-NEXT: "result": [
127 # CHECK-NEXT: "arguments": [
129 # CHECK-NEXT: "documentChanges": [
131 # CHECK-NEXT: "edits": [
133 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
134 # CHECK-NEXT: "range": {
135 # CHECK-NEXT: "end": {
136 # CHECK-NEXT: "character": 0,
137 # CHECK-NEXT: "line": 2
139 # CHECK-NEXT: "start": {
140 # CHECK-NEXT: "character": 0,
141 # CHECK-NEXT: "line": 2
146 # CHECK-NEXT: "textDocument": {
147 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
148 # CHECK-NEXT: "version": 0
154 # CHECK-NEXT: "command": "clangd.applyFix",
155 # CHECK-NEXT: "title": "Apply fix: #include {{.*}}foo.h{{.*}}"
158 # CHECK-NEXT: "arguments": [
160 # CHECK-NEXT: "documentChanges": [
162 # CHECK-NEXT: "edits": [
164 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
165 # CHECK-NEXT: "range": {
166 # CHECK-NEXT: "end": {
167 # CHECK-NEXT: "character": 0,
168 # CHECK-NEXT: "line": 2
170 # CHECK-NEXT: "start": {
171 # CHECK-NEXT: "character": 0,
172 # CHECK-NEXT: "line": 2
177 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
178 # CHECK-NEXT: "range": {
179 # CHECK-NEXT: "end": {
180 # CHECK-NEXT: "character": 0,
181 # CHECK-NEXT: "line": 2
183 # CHECK-NEXT: "start": {
184 # CHECK-NEXT: "character": 0,
185 # CHECK-NEXT: "line": 2
190 # CHECK-NEXT: "textDocument": {
191 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
192 # CHECK-NEXT: "version": 0
198 # CHECK-NEXT: "command": "clangd.applyFix",
199 # CHECK-NEXT: "title": "Apply fix: add all missing includes"
202 # CHECK-NEXT: "arguments": [
204 # CHECK-NEXT: "documentChanges": [
206 # CHECK-NEXT: "edits": [
208 # CHECK-NEXT: "newText": "",
209 # CHECK-NEXT: "range": {
210 # CHECK-NEXT: "end": {
211 # CHECK-NEXT: "character": 0,
212 # CHECK-NEXT: "line": 1
214 # CHECK-NEXT: "start": {
215 # CHECK-NEXT: "character": 0,
216 # CHECK-NEXT: "line": 0
221 # CHECK-NEXT: "newText": "",
222 # CHECK-NEXT: "range": {
223 # CHECK-NEXT: "end": {
224 # CHECK-NEXT: "character": 0,
225 # CHECK-NEXT: "line": 2
227 # CHECK-NEXT: "start": {
228 # CHECK-NEXT: "character": 0,
229 # CHECK-NEXT: "line": 1
234 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
235 # CHECK-NEXT: "range": {
236 # CHECK-NEXT: "end": {
237 # CHECK-NEXT: "character": 0,
238 # CHECK-NEXT: "line": 2
240 # CHECK-NEXT: "start": {
241 # CHECK-NEXT: "character": 0,
242 # CHECK-NEXT: "line": 2
247 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
248 # CHECK-NEXT: "range": {
249 # CHECK-NEXT: "end": {
250 # CHECK-NEXT: "character": 0,
251 # CHECK-NEXT: "line": 2
253 # CHECK-NEXT: "start": {
254 # CHECK-NEXT: "character": 0,
255 # CHECK-NEXT: "line": 2
260 # CHECK-NEXT: "textDocument": {
261 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
262 # CHECK-NEXT: "version": 0
268 # CHECK-NEXT: "command": "clangd.applyFix",
269 # CHECK-NEXT: "title": "Apply fix: fix all includes"
273 {"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///simple.cpp"},"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":17}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 0}, "end": {"line": 0, "character": 17}},"severity":2,"message":"Included header all1.h is not used directly (fixes available)", "code": "unused-includes", "source": "clangd"}]}}}
275 # CHECK-NEXT: "jsonrpc": "2.0",
276 # CHECK-NEXT: "result": [
278 # CHECK-NEXT: "arguments": [
280 # CHECK-NEXT: "documentChanges": [
282 # CHECK-NEXT: "edits": [
284 # CHECK-NEXT: "newText": "",
285 # CHECK-NEXT: "range": {
286 # CHECK-NEXT: "end": {
287 # CHECK-NEXT: "character": 0,
288 # CHECK-NEXT: "line": 1
290 # CHECK-NEXT: "start": {
291 # CHECK-NEXT: "character": 0,
292 # CHECK-NEXT: "line": 0
297 # CHECK-NEXT: "textDocument": {
298 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
299 # CHECK-NEXT: "version": 0
305 # CHECK-NEXT: "command": "clangd.applyFix",
306 # CHECK-NEXT: "title": "Apply fix: remove #include directive"
309 # CHECK-NEXT: "arguments": [
311 # CHECK-NEXT: "documentChanges": [
313 # CHECK-NEXT: "edits": [
315 # CHECK-NEXT: "newText": "",
316 # CHECK-NEXT: "range": {
317 # CHECK-NEXT: "end": {
318 # CHECK-NEXT: "character": 0,
319 # CHECK-NEXT: "line": 1
321 # CHECK-NEXT: "start": {
322 # CHECK-NEXT: "character": 0,
323 # CHECK-NEXT: "line": 0
328 # CHECK-NEXT: "newText": "",
329 # CHECK-NEXT: "range": {
330 # CHECK-NEXT: "end": {
331 # CHECK-NEXT: "character": 0,
332 # CHECK-NEXT: "line": 2
334 # CHECK-NEXT: "start": {
335 # CHECK-NEXT: "character": 0,
336 # CHECK-NEXT: "line": 1
341 # CHECK-NEXT: "textDocument": {
342 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
343 # CHECK-NEXT: "version": 0
349 # CHECK-NEXT: "command": "clangd.applyFix",
350 # CHECK-NEXT: "title": "Apply fix: remove all unused includes"
353 # CHECK-NEXT: "arguments": [
355 # CHECK-NEXT: "documentChanges": [
357 # CHECK-NEXT: "edits": [
359 # CHECK-NEXT: "newText": "",
360 # CHECK-NEXT: "range": {
361 # CHECK-NEXT: "end": {
362 # CHECK-NEXT: "character": 0,
363 # CHECK-NEXT: "line": 1
365 # CHECK-NEXT: "start": {
366 # CHECK-NEXT: "character": 0,
367 # CHECK-NEXT: "line": 0
372 # CHECK-NEXT: "newText": "",
373 # CHECK-NEXT: "range": {
374 # CHECK-NEXT: "end": {
375 # CHECK-NEXT: "character": 0,
376 # CHECK-NEXT: "line": 2
378 # CHECK-NEXT: "start": {
379 # CHECK-NEXT: "character": 0,
380 # CHECK-NEXT: "line": 1
385 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
386 # CHECK-NEXT: "range": {
387 # CHECK-NEXT: "end": {
388 # CHECK-NEXT: "character": 0,
389 # CHECK-NEXT: "line": 2
391 # CHECK-NEXT: "start": {
392 # CHECK-NEXT: "character": 0,
393 # CHECK-NEXT: "line": 2
398 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
399 # CHECK-NEXT: "range": {
400 # CHECK-NEXT: "end": {
401 # CHECK-NEXT: "character": 0,
402 # CHECK-NEXT: "line": 2
404 # CHECK-NEXT: "start": {
405 # CHECK-NEXT: "character": 0,
406 # CHECK-NEXT: "line": 2
411 # CHECK-NEXT: "textDocument": {
412 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
413 # CHECK-NEXT: "version": 0
419 # CHECK-NEXT: "command": "clangd.applyFix",
420 # CHECK-NEXT: "title": "Apply fix: fix all includes"
424 {"jsonrpc":"2.0","id":4,"method":"shutdown"}
426 {"jsonrpc":"2.0","method":"exit"}