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