1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.protocol.interfaces.text_document;
22 
23 import dls.protocol.definitions;
24 import dls.protocol.interfaces.client : TextDocumentRegistrationOptions;
25 import std.json : JSONValue;
26 
27 class DidOpenTextDocumentParams
28 {
29     import dls.util.constructor : Constructor;
30 
31     TextDocumentItem textDocument;
32 
33     mixin Constructor!DidOpenTextDocumentParams;
34 }
35 
36 class DidChangeTextDocumentParams
37 {
38     import dls.util.constructor : Constructor;
39 
40     VersionedTextDocumentIdentifier textDocument;
41     TextDocumentContentChangeEvent[] contentChanges;
42 
43     mixin Constructor!DidChangeTextDocumentParams;
44 }
45 
46 class TextDocumentContentChangeEvent
47 {
48     import std.typecons : Nullable;
49 
50     Nullable!Range range;
51     Nullable!size_t rangeLength;
52     string text;
53 }
54 
55 class TextDocumentChangeRegistrationOptions : TextDocumentRegistrationOptions
56 {
57     import dls.protocol.interfaces.general : TextDocumentSyncKind;
58 
59     TextDocumentSyncKind syncKind;
60 
61     this(TextDocumentSyncKind syncKind = TextDocumentSyncKind.init)
62     {
63         this.syncKind = syncKind;
64     }
65 }
66 
67 private class ParamsBase
68 {
69     import dls.util.constructor : Constructor;
70 
71     TextDocumentIdentifier textDocument;
72 
73     mixin Constructor!ParamsBase;
74 }
75 
76 class WillSaveTextDocumentParams : ParamsBase
77 {
78     TextDocumentSaveReason reason;
79 }
80 
81 enum TextDocumentSaveReason : uint
82 {
83     manual = 1,
84     afterDelay = 2,
85     focusOut = 3
86 }
87 
88 class DidSaveTextDocumentParams : ParamsBase
89 {
90     import std.typecons : Nullable;
91 
92     Nullable!string text;
93 }
94 
95 class TextDocumentSaveRegistrationOptions : TextDocumentRegistrationOptions
96 {
97     import std.typecons : Nullable;
98 
99     Nullable!bool includeText;
100 
101     this(Nullable!bool includeText = Nullable!bool.init)
102     {
103         this.includeText = includeText;
104     }
105 }
106 
107 alias DidCloseTextDocumentParams = ParamsBase;
108 
109 class PublishDiagnosticsParams
110 {
111     DocumentUri uri;
112     Diagnostic[] diagnostics;
113 
114     this(DocumentUri uri = DocumentUri.init, Diagnostic[] diagnostics = Diagnostic[].init)
115     {
116         this.uri = uri;
117         this.diagnostics = diagnostics;
118     }
119 }
120 
121 class CompletionParams : TextDocumentPositionParams
122 {
123     import std.typecons : Nullable;
124 
125     Nullable!CompletionContext context;
126 }
127 
128 class CompletionContext
129 {
130     import std.typecons : Nullable;
131 
132     CompletionTriggerKind triggerKind;
133     Nullable!string triggerCharacter;
134 }
135 
136 enum CompletionTriggerKind : uint
137 {
138     invoked = 1,
139     triggerCharacter = 2,
140     triggerForIncompleteCompletions = 3
141 }
142 
143 class CompletionList
144 {
145     bool isIncomplete;
146     CompletionItem[] items;
147 
148     this(bool isIncomplete = bool.init, CompletionItem[] items = CompletionItem[].init)
149     {
150         this.isIncomplete = isIncomplete;
151         this.items = items;
152     }
153 }
154 
155 enum InsertTextFormat : uint
156 {
157     plainText = 1,
158     snippet = 2
159 }
160 
161 class CompletionItem
162 {
163     import std.typecons : Nullable;
164 
165     string label;
166     Nullable!CompletionItemKind kind;
167     Nullable!string detail;
168     Nullable!MarkupContent documentation;
169     Nullable!bool deprecated_;
170     Nullable!bool preselect;
171     Nullable!string sortText;
172     Nullable!string filterText;
173     Nullable!string insertText;
174     Nullable!InsertTextFormat insertTextFormat;
175     Nullable!TextEdit textEdit;
176     Nullable!(TextEdit[]) additionalTextEdits;
177     Nullable!(string[]) commitCharacters;
178     Nullable!Command command;
179     Nullable!JSONValue data;
180 
181     this(string label = string.init, Nullable!CompletionItemKind kind = Nullable!CompletionItemKind.init,
182             Nullable!string detail = Nullable!string.init,
183             Nullable!MarkupContent documentation = Nullable!MarkupContent.init,
184             Nullable!bool deprecated_ = Nullable!bool.init, Nullable!string sortText = Nullable!string.init,
185             Nullable!string filterText = Nullable!string.init, Nullable!string insertText = Nullable!string.init,
186             Nullable!InsertTextFormat insertTextFormat = Nullable!InsertTextFormat.init,
187             Nullable!TextEdit textEdit = Nullable!TextEdit.init,
188             Nullable!(TextEdit[]) additionalTextEdits = Nullable!(TextEdit[])
189             .init, Nullable!(string[]) commitCharacters = Nullable!(string[])
190             .init, Nullable!Command command = Nullable!Command.init,
191             Nullable!JSONValue data = Nullable!JSONValue.init)
192     {
193         this.label = label;
194         this.kind = kind;
195         this.detail = detail;
196         this.documentation = documentation;
197         this.deprecated_ = deprecated_;
198         this.sortText = sortText;
199         this.filterText = filterText;
200         this.insertText = insertText;
201         this.insertTextFormat = insertTextFormat;
202         this.textEdit = textEdit;
203         this.additionalTextEdits = additionalTextEdits;
204         this.commitCharacters = commitCharacters;
205         this.command = command;
206         this.data = data;
207     }
208 }
209 
210 enum CompletionItemKind : uint
211 {
212     text = 1,
213     method = 2,
214     function_ = 3,
215     constructor = 4,
216     field = 5,
217     variable = 6,
218     class_ = 7,
219     interface_ = 8,
220     module_ = 9,
221     property = 10,
222     unit = 11,
223     value = 12,
224     enum_ = 13,
225     keyword = 14,
226     snippet = 15,
227     color = 16,
228     file = 17,
229     reference = 18,
230     folder = 19,
231     enumMember = 20,
232     constant = 21,
233     struct_ = 22,
234     event = 23,
235     operator = 24,
236     typeParameter = 25
237 }
238 
239 class CompletionRegistrationOptions : TextDocumentRegistrationOptions
240 {
241     import std.typecons : Nullable;
242 
243     Nullable!(string[]) triggerCharacters;
244     Nullable!bool resolveProvider;
245 
246     this(Nullable!(string[]) triggerCharacters = Nullable!(string[]).init,
247             Nullable!bool resolveProvider = Nullable!bool.init)
248     {
249         this.triggerCharacters = triggerCharacters;
250         this.resolveProvider = resolveProvider;
251     }
252 }
253 
254 class Hover
255 {
256     import std.typecons : Nullable;
257 
258     MarkupContent contents;
259     Nullable!Range range;
260 
261     this(MarkupContent contents = MarkupContent.init, Nullable!Range range = Nullable!Range.init)
262     {
263         this.contents = contents;
264         this.range = range;
265     }
266 }
267 
268 class SignatureHelp
269 {
270     import std.typecons : Nullable;
271 
272     SignatureInformation[] signatures;
273     Nullable!double activeSignature;
274     Nullable!double activeParameter;
275 
276     this(SignatureInformation[] signatures = SignatureInformation[].init,
277             Nullable!double activeSignature = Nullable!double.init,
278             Nullable!double activeParameter = Nullable!double.init)
279     {
280         this.signatures = signatures;
281         this.activeSignature = activeSignature;
282         this.activeParameter = activeParameter;
283     }
284 }
285 
286 private class InformationBase
287 {
288     import std.typecons : Nullable;
289 
290     string label;
291     Nullable!string documentation;
292 }
293 
294 class SignatureInformation : InformationBase
295 {
296     import std.typecons : Nullable;
297 
298     Nullable!(ParameterInformation[]) parameters;
299 
300     this(Nullable!(ParameterInformation[]) parameters = Nullable!(ParameterInformation[]).init)
301     {
302         this.parameters = parameters;
303     }
304 }
305 
306 alias ParameterInformation = InformationBase;
307 
308 class SignatureHelpRegistrationOptions : TextDocumentRegistrationOptions
309 {
310     import std.typecons : Nullable;
311 
312     Nullable!(string[]) triggerCharacters;
313 
314     this(Nullable!(string[]) triggerCharacters = Nullable!(string[]).init)
315     {
316         this.triggerCharacters = triggerCharacters;
317     }
318 }
319 
320 class ReferenceParams : TextDocumentPositionParams
321 {
322     import dls.util.constructor : Constructor;
323 
324     ReferenceContext context;
325 
326     mixin Constructor!ReferenceParams;
327 }
328 
329 class ReferenceContext
330 {
331     bool includeDeclaration;
332 }
333 
334 class DocumentHighlight
335 {
336     import std.typecons : Nullable;
337 
338     Range range;
339     Nullable!DocumentHighlightKind kind;
340 
341     this(Range range = new Range(),
342             Nullable!DocumentHighlightKind kind = Nullable!DocumentHighlightKind.init)
343     {
344         this.range = range;
345         this.kind = kind;
346     }
347 }
348 
349 enum DocumentHighlightKind : uint
350 {
351     text = 1,
352     read = 2,
353     write = 3
354 }
355 
356 alias DocumentSymbolParams = ParamsBase;
357 
358 class DocumentSymbol
359 {
360     import std.typecons : Nullable;
361 
362     string name;
363     Nullable!string detail;
364     SymbolKind kind;
365     Nullable!bool deprecated_;
366     Range range;
367     Range selectionRange;
368     Nullable!(DocumentSymbol[]) children;
369 
370     this(string name = string.init, Nullable!string detail = Nullable!string.init,
371             SymbolKind kind = SymbolKind.init, Nullable!bool deprecated_ = Nullable!bool.init,
372             Range range = new Range(), Range selectionRange = new Range(),
373             Nullable!(DocumentSymbol[]) children = Nullable!(DocumentSymbol[]).init)
374     {
375         this.name = name;
376         this.detail = detail;
377         this.kind = kind;
378         this.deprecated_ = deprecated_;
379         this.range = range;
380         this.selectionRange = selectionRange;
381         this.children = children;
382     }
383 }
384 
385 class SymbolInformation
386 {
387     import std.typecons : Nullable;
388 
389     string name;
390     SymbolKind kind;
391     Location location;
392     Nullable!string containerName;
393 
394     this(string name = string.init, SymbolKind kind = SymbolKind.init,
395             Location location = new Location(),
396             Nullable!string containerName = Nullable!string.init)
397     {
398         this.name = name;
399         this.kind = kind;
400         this.location = location;
401         this.containerName = containerName;
402     }
403 }
404 
405 enum SymbolKind : uint
406 {
407     file = 1,
408     module_ = 2,
409     namespace = 3,
410     package_ = 4,
411     class_ = 5,
412     method = 6,
413     property = 7,
414     field = 8,
415     constructor = 9,
416     enum_ = 10,
417     interface_ = 11,
418     function_ = 12,
419     variable = 13,
420     constant = 14,
421     string_ = 15,
422     number = 16,
423     boolean = 17,
424     array = 18,
425     object = 19,
426     key = 20,
427     null_ = 21,
428     enumMember = 22,
429     struct_ = 23,
430     event = 24,
431     operator = 25,
432     typeParameter = 26
433 }
434 
435 class CodeActionParams : ParamsBase
436 {
437     import dls.util.constructor : Constructor;
438 
439     Range range;
440     CodeActionContext context;
441 
442     mixin Constructor!CodeActionParams;
443 }
444 
445 enum CodeActionKind : string
446 {
447     quickfix = "quickfix",
448     refactor = "refactor",
449     refactorExtract = "refactor.extract",
450     refactorInline = "refactor.inline",
451     source = "source",
452     sourceOrganizeImports = "source.organizeImports"
453 }
454 
455 class CodeActionContext
456 {
457     import std.typecons : Nullable;
458 
459     Diagnostic[] diagnostics;
460     Nullable!(CodeActionKind[]) only;
461 }
462 
463 class CodeAction
464 {
465     import std.typecons : Nullable;
466 
467     string title;
468     Nullable!CodeActionKind kind;
469     Nullable!(Diagnostic[]) diagnostics;
470     Nullable!WorkspaceEdit edit;
471     Nullable!Command command;
472 
473     this(string title = string.init, Nullable!CodeActionKind kind = Nullable!CodeActionKind.init,
474             Nullable!(Diagnostic[]) diagnostics = Nullable!(Diagnostic[]).init,
475             Nullable!WorkspaceEdit edit = Nullable!WorkspaceEdit.init,
476             Nullable!Command command = Nullable!Command.init)
477     {
478         this.title = title;
479         this.kind = kind;
480         this.diagnostics = diagnostics;
481         this.edit = edit;
482         this.command = command;
483     }
484 }
485 
486 alias CodeActionRegistrationOptions = JSONValue;
487 
488 alias CodeLensParams = ParamsBase;
489 
490 class CodeLens
491 {
492     import std.typecons : Nullable;
493 
494     Range range;
495     Nullable!Command command;
496     Nullable!JSONValue data;
497 
498     this(Range range = new Range(), Nullable!Command command = Nullable!Command.init,
499             Nullable!JSONValue data = Nullable!JSONValue.init)
500     {
501         this.range = range;
502         this.command = command;
503         this.data = data;
504     }
505 }
506 
507 class CodeLensRegistrationOptions : TextDocumentRegistrationOptions
508 {
509     import std.typecons : Nullable;
510 
511     Nullable!bool resolveProvider;
512 
513     this(Nullable!bool resolveProvider = Nullable!bool.init)
514     {
515         this.resolveProvider = resolveProvider;
516     }
517 }
518 
519 alias DocumentLinkParams = ParamsBase;
520 
521 class DocumentLink
522 {
523     import std.typecons : Nullable;
524 
525     Range range;
526     Nullable!DocumentUri target;
527 
528     this(Range range = new Range(), Nullable!DocumentUri target = Nullable!DocumentUri.init)
529     {
530         this.range = range;
531         this.target = target;
532     }
533 }
534 
535 class DocumentLinkRegistrationOptions : TextDocumentRegistrationOptions
536 {
537     import std.typecons : Nullable;
538 
539     Nullable!bool resolveProvider;
540 
541     this(Nullable!bool resolveProvider = Nullable!bool.init)
542     {
543         this.resolveProvider = resolveProvider;
544     }
545 }
546 
547 class DocumentColorParams
548 {
549     import dls.util.constructor : Constructor;
550 
551     TextDocumentIdentifier textDocument;
552 
553     mixin Constructor!DocumentColorParams;
554 }
555 
556 class ColorInformation
557 {
558     Range range;
559     Color color;
560 
561     this(Range range = new Range(), Color color = new Color())
562     {
563         this.range = range;
564         this.color = color;
565     }
566 }
567 
568 class Color
569 {
570     float red;
571     float green;
572     float blue;
573     float alpha;
574 
575     this(float red = 0, float green = 0, float blue = 0, float alpha = 0)
576     {
577         this.red = red;
578         this.green = green;
579         this.blue = blue;
580         this.alpha = alpha;
581     }
582 }
583 
584 class ColorPresentationParams
585 {
586     import dls.util.constructor : Constructor;
587 
588     TextDocumentIdentifier textDocument;
589     Color color;
590     Range range;
591 
592     mixin Constructor!ColorPresentationParams;
593 }
594 
595 class ColorPresentation
596 {
597     import std.typecons : Nullable;
598 
599     string label;
600     Nullable!TextEdit textEdit;
601     Nullable!(TextEdit[]) additionalTextEdits;
602 
603     this(string label = string.init, Nullable!TextEdit textEdit = Nullable!TextEdit.init,
604             Nullable!(TextEdit[]) additionalTextEdits = Nullable!(TextEdit[]).init)
605     {
606         this.label = label;
607         this.textEdit = textEdit;
608         this.additionalTextEdits = additionalTextEdits;
609     }
610 }
611 
612 class DocumentFormattingParams : ParamsBase
613 {
614     import dls.util.constructor : Constructor;
615 
616     FormattingOptions options;
617 
618     mixin Constructor!DocumentFormattingParams;
619 }
620 
621 class FormattingOptions
622 {
623     size_t tabSize;
624     bool insertSpaces;
625 }
626 
627 class DocumentRangeFormattingParams : DocumentFormattingParams
628 {
629     import dls.util.constructor : Constructor;
630 
631     Range range;
632 
633     mixin Constructor!DocumentRangeFormattingParams;
634 }
635 
636 class DocumentOnTypeFormattingParams : DocumentFormattingParams
637 {
638     import dls.util.constructor : Constructor;
639 
640     Position position;
641     string ch;
642 
643     mixin Constructor!DocumentOnTypeFormattingParams;
644 }
645 
646 class DocumentOnTypeFormattingRegistrationOptions : TextDocumentRegistrationOptions
647 {
648     import std.typecons : Nullable;
649 
650     string firstTriggerCharacter;
651     Nullable!(string[]) moreTriggerCharacter;
652 
653     this(string firstTriggerCharacter = string.init,
654             Nullable!(string[]) moreTriggerCharacter = Nullable!(string[]).init)
655     {
656         this.firstTriggerCharacter = firstTriggerCharacter;
657         this.moreTriggerCharacter = moreTriggerCharacter;
658     }
659 }
660 
661 class RenameParams : ParamsBase
662 {
663     import dls.util.constructor : Constructor;
664 
665     Position position;
666     string newName;
667 
668     mixin Constructor!RenameParams;
669 }
670 
671 class RenameRegistrationOptions : TextDocumentRegistrationOptions
672 {
673     import std.typecons : Nullable;
674 
675     Nullable!bool prepareProvider;
676 }
677 
678 alias FoldingRangeParams = ParamsBase;
679 
680 enum FoldingRangeKind : string
681 {
682     comments = "comments",
683     imports = "imports",
684     region = "region"
685 }
686 
687 class FoldingRange
688 {
689     import std.typecons : Nullable;
690 
691     size_t startLine;
692     Nullable!size_t startCharacter;
693     size_t endLine;
694     Nullable!size_t endCharacter;
695     Nullable!FoldingRangeKind kind;
696 }