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: "changeAnnotations": {
161 # CHECK-NEXT: "AddAllMissingIncludes0": {
162 # CHECK-NEXT: "label": "",
163 # CHECK-NEXT: "needsConfirmation": true
165 # CHECK-NEXT: "AddAllMissingIncludes1": {
166 # CHECK-NEXT: "label": "",
167 # CHECK-NEXT: "needsConfirmation": true
170 # CHECK-NEXT: "documentChanges": [
172 # CHECK-NEXT: "edits": [
174 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes0",
175 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
176 # CHECK-NEXT: "range": {
177 # CHECK-NEXT: "end": {
178 # CHECK-NEXT: "character": 0,
179 # CHECK-NEXT: "line": 2
181 # CHECK-NEXT: "start": {
182 # CHECK-NEXT: "character": 0,
183 # CHECK-NEXT: "line": 2
188 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes1",
189 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
190 # CHECK-NEXT: "range": {
191 # CHECK-NEXT: "end": {
192 # CHECK-NEXT: "character": 0,
193 # CHECK-NEXT: "line": 2
195 # CHECK-NEXT: "start": {
196 # CHECK-NEXT: "character": 0,
197 # CHECK-NEXT: "line": 2
202 # CHECK-NEXT: "textDocument": {
203 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
204 # CHECK-NEXT: "version": 0
210 # CHECK-NEXT: "command": "clangd.applyFix",
211 # CHECK-NEXT: "title": "Apply fix: add all missing includes"
214 # CHECK-NEXT: "arguments": [
216 # CHECK-NEXT: "changeAnnotations": {
217 # CHECK-NEXT: "AddAllMissingIncludes0": {
218 # CHECK-NEXT: "label": "",
219 # CHECK-NEXT: "needsConfirmation": true
221 # CHECK-NEXT: "AddAllMissingIncludes1": {
222 # CHECK-NEXT: "label": "",
223 # CHECK-NEXT: "needsConfirmation": true
225 # CHECK-NEXT: "RemoveAllUnusedIncludes0": {
226 # CHECK-NEXT: "label": "",
227 # CHECK-NEXT: "needsConfirmation": true
229 # CHECK-NEXT: "RemoveAllUnusedIncludes1": {
230 # CHECK-NEXT: "label": "",
231 # CHECK-NEXT: "needsConfirmation": true
234 # CHECK-NEXT: "documentChanges": [
236 # CHECK-NEXT: "edits": [
238 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes0",
239 # CHECK-NEXT: "newText": "",
240 # CHECK-NEXT: "range": {
241 # CHECK-NEXT: "end": {
242 # CHECK-NEXT: "character": 0,
243 # CHECK-NEXT: "line": 1
245 # CHECK-NEXT: "start": {
246 # CHECK-NEXT: "character": 0,
247 # CHECK-NEXT: "line": 0
252 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes1",
253 # CHECK-NEXT: "newText": "",
254 # CHECK-NEXT: "range": {
255 # CHECK-NEXT: "end": {
256 # CHECK-NEXT: "character": 0,
257 # CHECK-NEXT: "line": 2
259 # CHECK-NEXT: "start": {
260 # CHECK-NEXT: "character": 0,
261 # CHECK-NEXT: "line": 1
266 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes0",
267 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
268 # CHECK-NEXT: "range": {
269 # CHECK-NEXT: "end": {
270 # CHECK-NEXT: "character": 0,
271 # CHECK-NEXT: "line": 2
273 # CHECK-NEXT: "start": {
274 # CHECK-NEXT: "character": 0,
275 # CHECK-NEXT: "line": 2
280 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes1",
281 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
282 # CHECK-NEXT: "range": {
283 # CHECK-NEXT: "end": {
284 # CHECK-NEXT: "character": 0,
285 # CHECK-NEXT: "line": 2
287 # CHECK-NEXT: "start": {
288 # CHECK-NEXT: "character": 0,
289 # CHECK-NEXT: "line": 2
294 # CHECK-NEXT: "textDocument": {
295 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
296 # CHECK-NEXT: "version": 0
302 # CHECK-NEXT: "command": "clangd.applyFix",
303 # CHECK-NEXT: "title": "Apply fix: fix all includes"
307 {"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"}]}}}
309 # CHECK-NEXT: "jsonrpc": "2.0",
310 # CHECK-NEXT: "result": [
312 # CHECK-NEXT: "arguments": [
314 # CHECK-NEXT: "documentChanges": [
316 # CHECK-NEXT: "edits": [
318 # CHECK-NEXT: "newText": "",
319 # CHECK-NEXT: "range": {
320 # CHECK-NEXT: "end": {
321 # CHECK-NEXT: "character": 0,
322 # CHECK-NEXT: "line": 1
324 # CHECK-NEXT: "start": {
325 # CHECK-NEXT: "character": 0,
326 # CHECK-NEXT: "line": 0
331 # CHECK-NEXT: "textDocument": {
332 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
333 # CHECK-NEXT: "version": 0
339 # CHECK-NEXT: "command": "clangd.applyFix",
340 # CHECK-NEXT: "title": "Apply fix: remove #include directive"
343 # CHECK-NEXT: "arguments": [
345 # CHECK-NEXT: "changeAnnotations": {
346 # CHECK-NEXT: "RemoveAllUnusedIncludes0": {
347 # CHECK-NEXT: "label": "",
348 # CHECK-NEXT: "needsConfirmation": true
350 # CHECK-NEXT: "RemoveAllUnusedIncludes1": {
351 # CHECK-NEXT: "label": "",
352 # CHECK-NEXT: "needsConfirmation": true
355 # CHECK-NEXT: "documentChanges": [
357 # CHECK-NEXT: "edits": [
359 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes0",
360 # CHECK-NEXT: "newText": "",
361 # CHECK-NEXT: "range": {
362 # CHECK-NEXT: "end": {
363 # CHECK-NEXT: "character": 0,
364 # CHECK-NEXT: "line": 1
366 # CHECK-NEXT: "start": {
367 # CHECK-NEXT: "character": 0,
368 # CHECK-NEXT: "line": 0
373 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes1",
374 # CHECK-NEXT: "newText": "",
375 # CHECK-NEXT: "range": {
376 # CHECK-NEXT: "end": {
377 # CHECK-NEXT: "character": 0,
378 # CHECK-NEXT: "line": 2
380 # CHECK-NEXT: "start": {
381 # CHECK-NEXT: "character": 0,
382 # CHECK-NEXT: "line": 1
387 # CHECK-NEXT: "textDocument": {
388 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
389 # CHECK-NEXT: "version": 0
395 # CHECK-NEXT: "command": "clangd.applyFix",
396 # CHECK-NEXT: "title": "Apply fix: remove all unused includes"
399 # CHECK-NEXT: "arguments": [
401 # CHECK-NEXT: "changeAnnotations": {
402 # CHECK-NEXT: "AddAllMissingIncludes0": {
403 # CHECK-NEXT: "label": "",
404 # CHECK-NEXT: "needsConfirmation": true
406 # CHECK-NEXT: "AddAllMissingIncludes1": {
407 # CHECK-NEXT: "label": "",
408 # CHECK-NEXT: "needsConfirmation": true
410 # CHECK-NEXT: "RemoveAllUnusedIncludes0": {
411 # CHECK-NEXT: "label": "",
412 # CHECK-NEXT: "needsConfirmation": true
414 # CHECK-NEXT: "RemoveAllUnusedIncludes1": {
415 # CHECK-NEXT: "label": "",
416 # CHECK-NEXT: "needsConfirmation": true
419 # CHECK-NEXT: "documentChanges": [
421 # CHECK-NEXT: "edits": [
423 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes0",
424 # CHECK-NEXT: "newText": "",
425 # CHECK-NEXT: "range": {
426 # CHECK-NEXT: "end": {
427 # CHECK-NEXT: "character": 0,
428 # CHECK-NEXT: "line": 1
430 # CHECK-NEXT: "start": {
431 # CHECK-NEXT: "character": 0,
432 # CHECK-NEXT: "line": 0
437 # CHECK-NEXT: "annotationId": "RemoveAllUnusedIncludes1",
438 # CHECK-NEXT: "newText": "",
439 # CHECK-NEXT: "range": {
440 # CHECK-NEXT: "end": {
441 # CHECK-NEXT: "character": 0,
442 # CHECK-NEXT: "line": 2
444 # CHECK-NEXT: "start": {
445 # CHECK-NEXT: "character": 0,
446 # CHECK-NEXT: "line": 1
451 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes0",
452 # CHECK-NEXT: "newText": "#include {{.*}}bar.h{{.*}}",
453 # CHECK-NEXT: "range": {
454 # CHECK-NEXT: "end": {
455 # CHECK-NEXT: "character": 0,
456 # CHECK-NEXT: "line": 2
458 # CHECK-NEXT: "start": {
459 # CHECK-NEXT: "character": 0,
460 # CHECK-NEXT: "line": 2
465 # CHECK-NEXT: "annotationId": "AddAllMissingIncludes1",
466 # CHECK-NEXT: "newText": "#include {{.*}}foo.h{{.*}}",
467 # CHECK-NEXT: "range": {
468 # CHECK-NEXT: "end": {
469 # CHECK-NEXT: "character": 0,
470 # CHECK-NEXT: "line": 2
472 # CHECK-NEXT: "start": {
473 # CHECK-NEXT: "character": 0,
474 # CHECK-NEXT: "line": 2
479 # CHECK-NEXT: "textDocument": {
480 # CHECK-NEXT: "uri": "file://{{.*}}/simple.cpp",
481 # CHECK-NEXT: "version": 0
487 # CHECK-NEXT: "command": "clangd.applyFix",
488 # CHECK-NEXT: "title": "Apply fix: fix all includes"
492 {"jsonrpc":"2.0","id":4,"method":"shutdown"}
494 {"jsonrpc":"2.0","method":"exit"}