346895de48188d80d1e7417b30f1264526b0b1a1
[roobuilder] / src / Lsp.vala
1 /* protocol.vala
2  *
3  * Copyright 2017-2019 Ben Iofel <ben@iofel.me>
4  * Copyright 2017-2020 Princeton Ferro <princetonferro@gmail.com>
5  * Copyright 2020 Sergii Fesenko <s.fesenko@outlook.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation, either version 2.1 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 namespace Lsp {
22     /**
23      * Defines how the host (editor) should sync document changes to the language server.
24      */
25     [CCode (default_value = "LSP_TEXT_DOCUMENT_SYNC_KIND_Unset")]
26     public enum TextDocumentSyncKind {
27         Unset = -1,
28         /**
29          * Documents should not be synced at all.
30          */
31         None = 0,
32         /**
33          * Documents are synced by always sending the full content of the document.
34          */
35         Full = 1,
36         /**
37          * Documents are synced by sending the full content on open. After that only incremental
38          * updates to the document are sent.
39          */
40         Incremental = 2
41     }
42
43     public  enum DiagnosticSeverity {
44         Unset = 0,
45         /**
46          * Reports an error.
47          */
48         Error = 1,
49         /**
50          * Reports a warning.
51          */
52         Warning = 2,
53         /**
54          * Reports an information.
55          */
56         Information = 3,
57         /**
58          * Reports a hint.
59          */
60         Hint = 4
61         
62     }
63
64     public  class Position : Object, Gee.Comparable<Position> {
65         
66         public Position(uint line, uint chr)
67         {
68                 this.line = line;
69                 this.character = chr;
70         }
71         /**
72          * Line position in a document (zero-based).
73          */
74         public uint line { get; set; default = -1; }
75
76         /**
77          * Character offset on a line in a document (zero-based). Assuming that the line is
78          * represented as a string, the `character` value represents the gap between the
79          * `character` and `character + 1`.
80          *
81          * If the character value is greater than the line length it defaults back to the
82          * line length.
83          */
84         public uint character { get; set; default = -1; }
85
86         public int compare_to (Position other) {
87              
88             return line > other.line ? 1 :
89                 (line == other.line ?
90                  (character > other.character ? 1 :
91                   (character == other.character ? 0 : -1)) : -1);
92         }
93         public bool equals(Position o) {
94                 return o.line == this.line && o.character == this.character;
95         }
96                 
97         public string to_string () {
98             return @"$line:$character";
99         }
100
101         public Position.from_libvala (Vala.SourceLocation sloc) {
102             line = sloc.line - 1;
103             character = sloc.column;
104         }
105
106         public Position dup () {
107             return this.translate ();
108         }
109
110         public Position translate (int dl = 0, int dc = 0) {
111             return new Position () {
112                 line = this.line + dl,
113                 character = this.character + dc
114             };
115         }
116     }
117
118     public class Range : Object, Gee.Hashable<Range>, Gee.Comparable<Range> {
119         
120         public Range.simple(uint line, uint pos) {
121                 var p =  new Position () {
122                 line = line,
123                 character = pos
124             };
125                 this.start = p;
126                 this.end = p;
127                 
128         }
129         /**
130          * The range's start position.
131          */
132         public Position start { get; set; }
133
134         /**
135          * The range's end position.
136          */
137         public Position end { get; set; }
138
139         private string? filename;
140
141         public string to_string () { return (filename != null ? @"$filename:" : "") + @"$start -> $end"; }
142
143         public Range.from_pos (Position pos) {
144             this.start = pos;
145             this.end = pos.dup ();
146         }
147
148         public Range.from_sourceref (Vala.SourceReference sref) {
149             this.start = new Position.from_libvala (sref.begin);
150             this.end = new Position.from_libvala (sref.end);
151             this.start.character -= 1;
152             this.filename = sref.file.filename;
153         }
154
155         public uint hash () {
156             return this.to_string ().hash ();
157         }
158
159         public bool equal_to (Range other) { return this.to_string () == other.to_string (); }
160                 public bool equals (Range o) {
161                         return this.filename == o.filename && this.start.equals(o.start) && this.end.equals(o.end);
162                 }
163
164         public int compare_to (Range other) {
165             return start.compare_to (other.start);
166         }
167
168         /**
169          * Return a new range that includes `this` and `other`.
170          */
171         public Range union (Range other) {
172             var range = new Range () {
173                 start = start.compare_to (other.start) < 0 ? start : other.start,
174                 end = end.compare_to (other.end) < 0 ? other.end : end,
175             };
176             if (filename == other.filename)
177                 range.filename = filename;
178             return range;
179         }
180
181         public bool contains (Position pos) {
182                 
183             var ret =  start.compare_to (pos) <= 0 && pos.compare_to (end) <= 0;
184            // GLib.debug( "range contains %d  (%d-%d) %s", (int)pos.line, (int)start.line, (int)end.line, ret ? "Y" : "N");
185             return ret;
186         }
187        
188     }
189
190     public class Diagnostic : Object {
191         
192         public Diagnostic.simple ( int line, int character, string message)
193         {
194                 this.message = message;
195                 this.severity = DiagnosticSeverity.Error;
196                 this.range =  new Range.simple(line, character );
197                 
198                 
199         
200         }
201         /**
202          * The range at which the message applies.
203          */
204         public Range range { get; set; }
205
206         /**
207          * The diagnostic's severity. Can be omitted. If omitted it is up to the
208          * client to interpret diagnostics as error, warning, info or hint.
209          */
210         public DiagnosticSeverity severity { get; set; }
211
212         /**
213          * The diagnostic's code. Can be omitted.
214          */
215         public string? code { get; set; }
216
217         /**
218          * A human-readable string describing the source of this
219          * diagnostic, e.g. 'typescript' or 'super lint'.
220          */
221         public string? source { get; set; }
222
223         /**
224          * The diagnostic's message.
225          */
226         public string message { get; set; }
227         
228         
229         public string category {
230                 get { 
231                         switch(this.severity) {
232
233                                 case DiagnosticSeverity.Error : 
234                                         return "ERR";
235                                 case DiagnosticSeverity.Warning : 
236                                         return this.message.contains("deprecated") ? "DEPR" : "WARN";
237                                 default : 
238                                         return "WARN";
239                         }
240                 }
241                 private set {}
242                 
243         }
244         public bool equals(Lsp.Diagnostic o) {
245                 var ret = this.range.equals(o.range) && this.severity == o.severity && this.message == o.message;
246                 //GLib.debug("compare %s  (%s == %s)", ret ? "YES" : "NO", this.to_string(), o.to_string()); 
247                 
248                 
249                 return ret;
250         }
251         public string to_string()
252         {
253                 return "%s : %d - %s".printf(this.category, (int) this.range.start.line , this.message);
254         }
255         
256     }
257
258     /**
259      * An event describing a change to a text document. If range and rangeLength are omitted
260      * the new text is considered to be the full content of the document.
261      */
262     public class TextDocumentContentChangeEvent : Object {
263         public Range? range    { get; set; }
264         public int rangeLength { get; set; }
265         public string text     { get; set; }
266     }
267
268     public enum MessageType {
269         /**
270          * An error message.
271          */
272         Error = 1,
273         /**
274          * A warning message.
275          */
276         Warning = 2,
277         /**
278          * An information message.
279          */
280         Info = 3,
281         /**
282          * A log message.
283          */
284         Log = 4
285     }
286
287     public class TextDocumentIdentifier : Object {
288         public string uri { get; set; }
289     }
290
291     public class VersionedTextDocumentIdentifier : TextDocumentIdentifier {
292         /**
293          * The version number of this document. If a versioned text document identifier
294          * is sent from the server to the client and the file is not open in the editor
295          * (the server has not received an open notification before) the server can send
296          * `null` to indicate that the version is known and the content on disk is the
297          * master (as speced with document content ownership).
298          *
299          * The version number of a document will increase after each change, including
300          * undo/redo. The number doesn't need to be consecutive.
301          */
302         public int version { get; set; default = -1; }
303     }
304
305     public class TextDocumentPositionParams : Object {
306         public TextDocumentIdentifier textDocument { get; set; }
307         public Position position { get; set; }
308     }
309
310     public class ReferenceParams : TextDocumentPositionParams {
311         public class ReferenceContext : Object {
312             public bool includeDeclaration { get; set; }
313         }
314         public ReferenceContext? context { get; set; }
315     }
316
317     public class Location : Object {
318         public string uri { get; set; }
319         public Range range { get; set; }
320
321         public Location.from_sourceref (Vala.SourceReference sref) {
322             this (sref.file.filename, new Range.from_sourceref (sref));
323         }
324
325         public Location (string filename, Range range) {
326             this.uri = File.new_for_commandline_arg (filename).get_uri ();
327             this.range = range;
328         }
329     }
330
331     [CCode (default_value = "LSP_DOCUMENT_HIGHLIGHT_KIND_Text")]
332     public enum DocumentHighlightKind {
333         Text = 1,
334         Read = 2,
335         Write = 3
336     }
337
338     public class DocumentHighlight : Object {
339         public Range range { get; set; }
340         public DocumentHighlightKind kind { get; set; }
341     }
342
343     public class DocumentSymbolParams: Object {
344         public TextDocumentIdentifier textDocument { get; set; }
345     }
346
347     public class DocumentSymbol : Object, Json.Serializable {
348                 private Vala.SourceReference? _source_reference;
349                 public string name { get; set; }
350                 public string detail { get; set; default = ""; }
351                 public SymbolKind kind { get; set; }
352                 public bool deprecated { get; set; }
353
354                 public Range range { get; set; } 
355                 public Range selectionRange { get; set; }
356                 public GLib.ListStore children { get;  set; default = new GLib.ListStore(typeof(DocumentSymbol)); }
357                 public string? parent_name;
358
359                 private DocumentSymbol () {}
360
361         /**
362          * @param type the data type containing this symbol, if there was one (not available for Namespaces, for example)
363          * @param sym the symbol
364          */
365          /*
366         public DocumentSymbol.from_vala_symbol (Vala.DataType? type, Vala.Symbol sym, SymbolKind kind) {
367             this.parent_name = sym.parent_symbol != null ? sym.parent_symbol.name : null;
368             this._initial_range = new Range.from_sourceref (sym.source_reference);
369             if (sym is Vala.Subroutine) {
370                 var sub = (Vala.Subroutine) sym;
371                 var body_sref = sub.body != null ? sub.body.source_reference : null;
372                 // debug ("subroutine %s found (body @ %s)", sym.get_full_name (),
373                 //         body_sref != null ? body_sref.to_string () : null);
374                 if (body_sref != null && (body_sref.begin.line < body_sref.end.line ||
375                                 val = GLib.Value (typeof(Gee.ArrayList));                          body_sref.begin.line == body_sref.end.line && body_sref.begin.pos <= body_sref.end.pos)) {
376                     this._initial_range = this._initial_range.union (new Range.from_sourceref (body_sref));
377                 }
378             }
379             this.name = sym.name;
380             this.detail = Vls.CodeHelp.get_symbol_representation (type, sym, null, false);
381             this.kind = kind;
382             this.selectionRange = new Range.from_sourceref (sym.source_reference);
383             this.deprecated = sym.version.deprecated;
384         }
385         */
386         public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
387             base.set_property (pspec.get_name (), value);
388         }
389
390         public new Value Json.Serializable.get_property (ParamSpec pspec) {
391             Value val = Value (pspec.value_type);
392             base.get_property (pspec.get_name (), ref val);
393             return val;
394         }
395
396         public unowned ParamSpec? find_property (string name) {
397             return this.get_class ().find_property (name);
398         }
399
400         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
401            // if (property_name != "children")
402                 return default_serialize_property (property_name, value, pspec);
403             /*var node = new Json.Node (Json.NodeType.ARRAY);
404             node.init_array (new Json.Array ());
405             var array = node.get_array ();
406             foreach (var child in children)
407                 array.add_element (Json.gobject_serialize (child));
408             return node;
409             */
410         }
411
412         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) 
413             {
414                 GLib.debug("deserialise property %s" , property_name);
415                 if (property_name != "children") {
416                     return default_deserialize_property (property_name, out value, pspec, property_node);
417                 }
418             value = GLib.Value (typeof(GLib.ListStore));
419                 if (property_node.get_node_type () != Json.NodeType.ARRAY) {
420                     GLib.debug ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
421                     return false;
422                 }
423                         GLib.debug("got child length of %d", (int) property_node.get_array ().get_length());
424                 var arguments = new GLib.ListStore(typeof(DocumentSymbol));
425
426                 property_node.get_array ().foreach_element ((array, index, element) => {
427                     
428                         var add= Json.gobject_deserialize ( typeof (DocumentSymbol),  array.get_element(index)) as DocumentSymbol;
429                                 arguments.append( add);
430
431                    
432                 });
433
434                 value.set_object (arguments);
435                 return true;
436            }
437            public string symbol_icon { 
438                         
439                         owned get {
440                                 return this.kind.icon(); 
441                         }
442                 }
443                  
444                 public string tooltip {
445                         owned get {
446                                 GLib.debug("%s : %s", this.name, this.detail);
447                                 //var detail = this.detail == "" ? (this.kind.to_string() + ": " + this.name) : this.detail;
448                                  return GLib.Markup.escape_text(this.detail + "\nline: " + this.range.start.line.to_string());
449                                 
450                         }
451                 }
452                 public string sort_key {
453                         owned get { 
454                                 return this.kind.sort_key().to_string() + "=" + this.name;
455                         }
456                 }
457                 
458                 public DocumentSymbol? containsLine(int line)
459                 {
460                         if (!this.range.contains(new Position.new_line(line))) {
461                                 return null;
462                         }
463
464                         for(var i = 0; i < this.children.get_n_items();i++) {
465                                 var el = (DocumentSymbol)this.children.get_item(i);
466                                 var ret = el.containsLine(line);
467                                 if (ret != null) {
468                                         return ret;
469                                 }
470                         }
471                         return this;
472                         
473                 }
474                 public bool equals(DocumentSymbol sym) {
475                         return this.name == sym.name && this.kind == sym.kind &&  sym.range.equals(this.range);
476                 }
477            
478            
479     }
480
481     public class SymbolInformation : Object {
482         public string name { get; set; }
483         public SymbolKind kind { get; set; }
484         public Location location { get; set; }
485         public string? containerName { get; set; }
486
487         public SymbolInformation.from_document_symbol (DocumentSymbol dsym, string uri) {
488             this.name = dsym.name;
489             this.kind = dsym.kind;
490           //  this.location = new Location (uri, dsym.range);
491             this.containerName = dsym.parent_name;
492         }
493     }
494
495     [CCode (default_value = "LSP_SYMBOL_KIND_Variable")]
496     public enum SymbolKind {
497         File = 1,
498         Module = 2,
499         Namespace = 3,
500         Package = 4,
501         Class = 5,
502         Method = 6,
503         Property = 7,
504         Field = 8,
505         Constructor = 9,
506         Enum = 10,
507         Interface = 11,
508         Function = 12,
509         Variable = 13,
510         Constant = 14,
511         String = 15,
512         Number = 16,
513         Boolean = 17,
514         Array = 18,
515         Object = 19,
516         Key = 20,
517         Null = 21,
518         EnumMember = 22,
519         Struct = 23,
520         Event = 24,
521         Operator = 25,
522         TypeParameter = 26;
523         
524         public string icon () { 
525                                 
526                         switch (this) {
527                                 
528                                 // case         SymbolKind.Text: return "completion-snippet-symbolic";
529                                 case    SymbolKind.Method: return "lang-method-symbolic";
530                                 case    SymbolKind.Function: return "lang-function-symbolic";
531                                 case    SymbolKind.Constructor: return "lang-method-symbolic";
532                                 case    SymbolKind.Field: return "lang-struct-field-symbolic";
533                                 case    SymbolKind.Variable: return "lang-variable-symbolic";
534                                 case    SymbolKind.Class: return "lang-class-symbolic";
535                                 case    SymbolKind.Interface: return "lang-class-symbolic";
536                                 case    SymbolKind.Module: return "lang-namespace-symbolic";
537                                 case    SymbolKind.Property:return "lang-struct-field-symbolic";
538                                 //case  SymbolKind.Unit: return "lang-variable-symbolic";
539                                 //case  SymbolKind.Value: return "lang-variable-symbolic";
540                                 case    SymbolKind.Enum: return "lang-enum-symbolic";
541                                 //case  SymbolKind.Keyword: return "completion-word-symbolic";
542                                 //case  SymbolKind.Snippet: return "completion-snippet-symbolic";
543
544                                 //case  SymbolKind.Color: return "lang-typedef-symbolic";
545                                 case    SymbolKind.File:return "lang-typedef-symbolic";
546                                 //case  SymbolKind.Reference: return "lang-typedef-symbolic";
547                                 //case  SymbolKind.Folder:return "lang-typedef-symbolic";
548                                 case    SymbolKind.EnumMember: return "lang-typedef-symbolic";
549                                 case    SymbolKind.Constant:return "lang-typedef-symbolic";
550                                 case    SymbolKind.Struct: return "lang-struct-symbolic";
551                                 case    SymbolKind.Event:return "lang-typedef-symbolic";
552                                 case    SymbolKind.Operator:return "lang-typedef-symbolic";
553                                 case    SymbolKind.TypeParameter:return "lang-typedef-symbolic";
554                         
555                                 default: 
556                                  return "completion-snippet-symbolic";
557                                                 
558                         }
559                 }
560                 public int sort_key() { 
561                          
562                         switch (this) {
563                                 case Enum : return 1;
564                                 case Class: return 2;
565                                 
566                                 case Constructor : return 1;
567                                 case Method : return 2;
568                                 case Field : return 3;
569                                 case Property : return 3;
570                                 
571                                 default:
572                                         return 5;
573                         }       
574                 
575                 
576                 
577                 }
578         
579     }
580
581         public class CompletionList : Object, Json.Serializable {
582         public bool isIncomplete { get; set; }
583         public Gee.List<CompletionItem> items { get; private set; default = new Gee.LinkedList<CompletionItem> (); }
584
585         public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
586             base.set_property (pspec.get_name (), value);
587         }
588
589         public new Value Json.Serializable.get_property (ParamSpec pspec) {
590             Value val = Value(pspec.value_type);
591             base.get_property (pspec.get_name (), ref val);
592             return val;
593         }
594
595         public unowned ParamSpec? find_property (string name) {
596             return this.get_class ().find_property (name);
597         }
598
599         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
600             if (property_name != "items")
601                 return default_serialize_property (property_name, value, pspec);
602             var node = new Json.Node (Json.NodeType.ARRAY);
603             node.init_array (new Json.Array ());
604             var array = node.get_array ();
605             foreach (var child in items)
606                 array.add_element (Json.gobject_serialize (child));
607             return node;
608         }
609
610         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
611             error ("deserialization not supported");
612         }
613     }
614
615     [CCode (default_value = "LSP_COMPLETION_TRIGGER_KIND_Invoked")]
616     public enum CompletionTriggerKind {
617         /**
618              * Completion was triggered by typing an identifier (24x7 code
619              * complete), manual invocation (e.g Ctrl+Space) or via API.
620              */
621         Invoked = 1,
622
623         /**
624              * Completion was triggered by a trigger character specified by
625              * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
626              */
627         TriggerCharacter = 2,
628
629         /**
630              * Completion was re-triggered as the current completion list is incomplete.
631              */
632         TriggerForIncompleteCompletions = 3
633     }
634
635     public class CompletionContext : Object {
636         public CompletionTriggerKind triggerKind { get; set;}
637         public string? triggerCharacter { get; set; }
638     }
639
640     public class CompletionParams : TextDocumentPositionParams {
641         /**
642          * The completion context. This is only available if the client specifies
643          * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
644          */
645         public CompletionContext? context { get; set; }
646     }
647
648     public enum CompletionItemTag {
649         // Render a completion as obsolete, usually using a strike-out.
650         Deprecated = 1,
651     }
652
653     [CCode (default_value = "LSP_INSERT_TEXT_FORMAT_PlainText")]
654     public enum InsertTextFormat {
655         /**
656          * The primary text to be inserted is treated as a plain string.
657          */
658         PlainText = 1,
659
660         /**
661          * The primary text to be inserted is treated as a snippet.
662          *
663          * A snippet can define tab stops and placeholders with `$1`, `$2`
664          * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
665          * the end of the snippet. Placeholders with equal identifiers are linked,
666          * that is typing in one will update others too.
667          */
668         Snippet = 2,
669     }
670
671     public class CompletionItem : Object, Gee.Hashable<CompletionItem>, Json.Serializable {
672         public string label { get; set; }
673         public CompletionItemKind kind { get; set; }
674         public string detail { get; set; }
675         public MarkupContent? documentation { get; set; }
676         public bool deprecated { get; set; }
677         public Gee.List<CompletionItemTag> tags { get; private set; default = new Gee.ArrayList<CompletionItemTag> (); }
678         public string? insertText { get; set; }
679         public InsertTextFormat insertTextFormat { get; set; default = InsertTextFormat.PlainText; }
680         private uint _hash;
681
682         private CompletionItem () {}
683
684         public CompletionItem.keyword (string keyword, string? insert_text = null, string? documentation = null) {
685             this.label = keyword;
686             this.kind = CompletionItemKind.Keyword;
687             this.insertText = insert_text;
688             if (insert_text != null && (insert_text.contains ("$0") || insert_text.contains ("${0")))
689                 this.insertTextFormat = InsertTextFormat.Snippet;
690             if (documentation != null)
691                 this.documentation = new MarkupContent.from_plaintext (documentation);
692             this._hash = @"$label $kind".hash ();
693         }
694
695         /**
696          * A completion suggestion from an existing Vala symbol.
697          * 
698          * @param instance_type the parent data type of data type of the expression where this symbol appears, or null
699          * @param sym the symbol itself
700          * @param scope the scope to display this in
701          * @param kind the kind of completion to display
702          * @param documentation the documentation to display
703          * @param label_override if non-null, override the displayed symbol name with this
704          */
705          /*
706         public CompletionItem.from_symbol (Vala.DataType? instance_type, Vala.Symbol sym, Vala.Scope? scope,
707             CompletionItemKind kind,
708             Vls.DocComment? documentation, string? label_override = null) {
709             this.label = label_override ?? sym.name;
710             this.kind = kind;
711             this.detail = Vls.CodeHelp.get_symbol_representation (instance_type, sym, scope, true, null, label_override, false);
712             this._hash = @"$label $kind".hash ();
713
714             if (documentation != null)
715                 this.documentation = new MarkupContent.from_markdown (documentation.body);
716
717             var version = sym.get_attribute ("Version");
718             if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
719                 this.tags.add (CompletionItemTag.Deprecated);
720                 this.deprecated = true;
721             }public
722         }
723                 */
724         /**
725          * A completion suggestion from a data type and a synthetic symbol name.
726          *
727          * @param symbol_type       the data type of the symbol
728          * @param symbol_name       the name of the synthetic symbol
729          * @param scope             the scope that this completion item is displayed in, or null
730          * @param kind              the type of completion to display
731          * @param documentation     the documentation for this symbol, or null
732          */
733          /*
734         public CompletionItem.from_synthetic_symbol (Vala.DataType symbol_type, string symbol_name, Vala.Scope? scope,
735                                                      CompletionItemKind kind, Vls.DocComment? documentation) {
736             this.label = symbol_name;
737             this.kind = kind;
738             this.detail = @"$(Vls.CodeHelp.get_symbol_representation (symbol_type, null, scope, true, null, null, false)) $symbol_name";
739             this._hash = @"$label $kind".hash ();
740
741             if (documentation != null)
742                 this.documentation = new MarkupContent.from_markdown (documentation.body);
743         }
744         */
745                 /*
746         public CompletionItem.from_unimplemented_symbol (Vala.Symbol sym, 
747                                                          string label, CompletionItemKind kind,
748                                                          string insert_text,
749                                                          Vls.DocComment? documentation) {
750             this.label = label;
751             this.kind = kind;
752             this.insertText = insert_text;
753             if (insert_text.contains ("$0") || insert_text.contains ("${0"))
754                 this.insertTextFormat = InsertTextFormat.Snippet;
755             this._hash = @"$label $kind".hash ();
756             if (documentation != null)
757                 this.documentation = new MarkupContent.from_markdown (documentation.body);
758         }
759         */
760
761         public uint hash () {
762             return this._hash;
763         }
764
765         public bool equal_to (CompletionItem other) {
766             return other.label == this.label && other.kind == this.kind;
767         }
768
769         public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
770             base.set_property (pspec.get_name (), value);
771         }
772
773         public new Value Json.Serializable.get_property (ParamSpec pspec) {
774             Value val = Value(pspec.value_type);
775             base.get_property (pspec.get_name (), ref val);
776             return val;
777         }
778
779         public unowned ParamSpec? find_property (string name) {
780             return this.get_class ().find_property (name);
781         }
782
783         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
784             if (property_name != "tags")
785                 return default_serialize_property (property_name, value, pspec);
786
787             var node = new Json.Node (Json.NodeType.ARRAY);
788             node.init_array (new Json.Array ());
789             var array = node.get_array ();
790             foreach (var tag in this.tags) {
791                 array.add_int_element (tag);
792             }
793
794             return node;
795         }
796         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) 
797         {
798                 if (property_name != "tags") {
799                 return default_deserialize_property (property_name, out value, pspec, property_node);
800             }
801             value = GLib.Value (typeof(Gee.ArrayList));
802             if (property_node.get_node_type () != Json.NodeType.ARRAY) {
803                 warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
804                 return false;
805             }
806
807             var arguments = new Gee.ArrayList<CompletionItemTag>();
808
809             property_node.get_array ().foreach_element ((array, index, element) => {
810                 try {
811                     arguments.add ((CompletionItemTag) Json.gvariant_deserialize (element, null).get_int32() );
812                 } catch (Error e) {
813                     warning ("argument %u to command could not be deserialized: %s", index, e.message);
814                 }
815             });
816
817             value.set_object (arguments);
818             return true;
819        }
820     }
821
822     public class MarkupContent : Object {
823         public string kind { get; set; }
824         public string value { get; set; }
825
826         private MarkupContent () {}
827
828         /**
829          * Create a MarkupContent with plain text.
830          */
831         public MarkupContent.from_plaintext (string doc) {
832             this.kind = "plaintext";
833             this.value = doc;
834         }
835
836         /**
837          * Create a MarkupContent with markdown text.
838          */
839         public MarkupContent.from_markdown (string doc) {
840             this.kind = "markdown";
841             this.value = doc;
842         }
843     }
844     
845     [CCode (default_value = "LSP_COMPLETION_ITEM_KIND_Text")]
846     public enum CompletionItemKind {
847         Text = 1,
848         Method = 2,
849         Function = 3,
850         Constructor = 4,
851         Field = 5,
852         Variable = 6,
853         Class = 7,
854         Interface = 8,
855         Module = 9,
856         Property = 10,
857         Unit = 11,
858         Value = 12,
859         Enum = 13,
860         Keyword = 14,
861         Snippet = 15,
862         Color = 16,
863         File = 17,
864         Reference = 18,
865         Folder = 19,
866         EnumMember = 20,
867         Constant = 21,
868         Struct = 22,
869         Event = 23,
870         Operator = 24,
871         TypeParameter = 25
872     }
873     
874     /**
875      * Capabilities of the client/editor for `textDocument/documentSymbol`
876      */
877     public class DocumentSymbolCapabilities : Object {
878         public bool hierarchicalDocumentSymbolSupport { get; set; }
879     }
880
881     /**
882      * Capabilities of the client/editor for `textDocument/rename`
883      */
884     public class RenameClientCapabilities : Object {
885         public bool prepareSupport { get; set; }
886     }
887
888     /**
889      * Capabilities of the client/editor pertaining to language features.
890      */
891     public class TextDocumentClientCapabilities : Object {
892         public DocumentSymbolCapabilities documentSymbol { get; set; default = new DocumentSymbolCapabilities ();}
893         public RenameClientCapabilities rename { get; set; default = new RenameClientCapabilities (); }
894     }
895
896     /**
897      * Capabilities of the client/editor.
898      */
899     public class ClientCapabilities : Object {
900         public TextDocumentClientCapabilities textDocument { get; set; default = new TextDocumentClientCapabilities (); }
901     }
902
903     public class InitializeParams : Object {
904         public int processId { get; set; }
905         public string? rootPath { get; set; }
906         public string? rootUri { get; set; }
907         public ClientCapabilities capabilities { get; set; default = new ClientCapabilities (); }
908     }
909
910     public class SignatureInformation : Object, Json.Serializable {
911         public string label { get; set; }
912         public MarkupContent documentation { get; set; }
913
914         public Gee.List<ParameterInformation> parameters { get; private set; default = new Gee.LinkedList<ParameterInformation> (); }
915
916         public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
917             base.set_property (pspec.get_name (), value);
918         }
919
920         public new Value Json.Serializable.get_property (ParamSpec pspec) {
921             Value val = Value(pspec.value_type);
922             base.get_property (pspec.get_name (), ref val);
923             return val;
924         }
925
926         public unowned ParamSpec? find_property (string name) {
927             return this.get_class ().find_property (name);
928         }
929
930         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
931             if (property_name != "parameters")
932                 return default_serialize_property (property_name, value, pspec);
933             var node = new Json.Node (Json.NodeType.ARRAY);
934             node.init_array (new Json.Array ());
935             var array = node.get_array ();
936             foreach (var child in parameters)
937                 array.add_element (Json.gobject_serialize (child));
938             return node;
939         }
940
941         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
942             error ("deserialization not supported");
943         }
944     }
945
946     public class SignatureHelp : Object, Json.Serializable {
947         public Gee.Collection<SignatureInformation> signatures { get; set; default = new Gee.ArrayList<SignatureInformation> (); }
948         public int activeSignature { get; set; }
949         public int activeParameter { get; set; }
950
951         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
952             if (property_name != "signatures")
953                 return default_serialize_property (property_name, value, pspec);
954
955             var node = new Json.Node (Json.NodeType.ARRAY);
956             node.init_array (new Json.Array ());
957             var array = node.get_array ();
958             foreach (var child in signatures)
959                 array.add_element (Json.gobject_serialize (child));
960             return node;
961         }
962
963         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
964             error ("deserialization not supported");
965         }
966     }
967
968     public class ParameterInformation : Object {
969         public string label { get; set; }
970         public MarkupContent documentation { get; set; }
971     }
972
973    public  class MarkedString : Object {
974                 public MarkedString(string language, string value) 
975                 {
976                         this.language = language;
977                         this.value = value;
978                         GLib.debug("new marked string %s : %s", language, value);
979                 }
980         public string language { get; set; }
981         public string value { get; set; }
982     }
983
984     public class Hover : Object, Json.Serializable {
985         public Gee.List<MarkedString> contents { get; set; default = new Gee.ArrayList<MarkedString> (); }
986         public Range range { get; set; }
987
988         public new void Json.Serializable.set_property (ParamSpec pspec, Value value) {
989             base.set_property (pspec.get_name (), value);
990         }
991
992         public new Value Json.Serializable.get_property (ParamSpec pspec) {
993             Value val = Value(pspec.value_type);
994             base.get_property (pspec.get_name (), ref val);
995             return val;
996         }
997
998         public unowned ParamSpec? find_property (string name) {
999             return this.get_class ().find_property (name);
1000         }
1001
1002         public Json.Node serialize_property (string property_name, Value value, ParamSpec pspec) {
1003             if (property_name != "contents")
1004                 return default_serialize_property (property_name, value, pspec);
1005             var node = new Json.Node (Json.NodeType.ARRAY);
1006             node.init_array (new Json.Array ());
1007             var array = node.get_array ();
1008             foreach (var child in contents) {
1009                 if (child.language != null)
1010                     array.add_element (Json.gobject_serialize (child));
1011                 else
1012                     array.add_element (new Json.Node (Json.NodeType.VALUE).init_string (child.value));
1013             }
1014             return node;
1015         }
1016
1017         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) 
1018         {
1019             if (property_name == "contents") {
1020                 value = GLib.Value (typeof(Gee.ArrayList));
1021                         if (property_node.get_node_type () != Json.NodeType.ARRAY) {
1022                             warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
1023                             return false;
1024                         }
1025                                 var contents = new Gee.ArrayList<MarkedString>();
1026
1027                         property_node.get_array ().foreach_element ((array, index, element) => {
1028                                 try {
1029                                                 var add = new MarkedString(
1030                                                         array.get_object_element(index).get_string_member("language"),
1031                                                         array.get_object_element(index).get_string_member("value")
1032                                                 );
1033                              
1034                                 contents.add ( add );
1035                             } catch (Error e) {
1036                                 warning ("argument %u to command could not be deserialized: %s", index, e.message);
1037                             }
1038                         });
1039                 value.set_object (contents);
1040                         return true;
1041             } 
1042             
1043             return default_deserialize_property (property_name, out value, pspec, property_node);
1044         }
1045     }
1046
1047     /**
1048      * A textual edit applicable to a text document.
1049      */
1050     public class TextEdit : Object {
1051         /**
1052          * The range of the text document to be manipulated. To insert
1053          * text into a document create a range where ``start === end``.
1054          */
1055         public Range range { get; set; }
1056
1057         /**
1058          * The string to be inserted. For delete operations use an
1059          * empty string.
1060          */
1061         public string newText { get; set; }
1062
1063         public TextEdit (Range range, string new_text = "") {
1064             this.range = range;
1065             this.newText = new_text;
1066         }
1067     }
1068
1069     /** 
1070      * Describes textual changes on a single text document. The text document is
1071      * referred to as a {@link VersionedTextDocumentIdentifier} to allow clients to
1072      * check the text document version before an edit is applied. A
1073      * {@link TextDocumentEdit} describes all changes on a version ``Si`` and after they are
1074      * applied move the document to version ``Si+1``. So the creator of a
1075      * {@link TextDocumentEdit} doesn’t need to sort the array of edits or do any kind
1076      * of ordering. However the edits must be non overlapping.
1077      */
1078     public class TextDocumentEdit : Object, Json.Serializable {
1079         /**
1080          * The text document to change.
1081          */
1082         public VersionedTextDocumentIdentifier textDocument { get; set; }
1083
1084         /**
1085          * The edits to be applied.
1086          */
1087         public Gee.ArrayList<TextEdit> edits { get; set; default = new Gee.ArrayList<TextEdit> (); }
1088
1089         public TextDocumentEdit (VersionedTextDocumentIdentifier text_document) {
1090             this.textDocument = text_document;
1091         }
1092
1093         public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1094             if (property_name != "edits")
1095                 return default_serialize_property (property_name, value, pspec);
1096             
1097             var node = new Json.Node (Json.NodeType.ARRAY);
1098             node.init_array (new Json.Array ());
1099             var array = node.get_array ();
1100             foreach (var text_edit in edits) {
1101                 array.add_element (Json.gobject_serialize (text_edit));
1102             }
1103             return node;
1104         }
1105
1106         public bool deserialize_property (string property_name, out GLib.Value value, GLib.ParamSpec pspec, Json.Node property_node) {
1107             error ("deserialization not supported");
1108         }
1109     }
1110
1111     public abstract class CommandLike : Object, Json.Serializable {
1112         /**
1113          * The identifier of the actual command handler.
1114          */
1115         public string command { get; set; }
1116
1117         /**
1118          * Arguments that the command handler should be invoked with.
1119          */
1120         public Array<Variant>? arguments { get; set; }
1121
1122         public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1123             if (property_name != "arguments" || arguments == null)
1124                 return default_serialize_property (property_name, value, pspec);
1125
1126             var array = new Json.Array ();
1127             for (int i = 0; i < arguments.length; i++)
1128                 array.add_element (Json.gvariant_serialize (arguments.index (i)));
1129
1130             var node = new Json.Node (Json.NodeType.ARRAY);
1131             node.set_array (array);
1132             return node;
1133         }
1134
1135         public bool deserialize_property (string property_name, out GLib.Value value, GLib.ParamSpec pspec, Json.Node property_node) 
1136         {
1137             if (property_name == "arguments") {
1138                 value = GLib.Value (typeof(Array));
1139                 if (property_node.get_node_type () != Json.NodeType.ARRAY) {
1140                     warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
1141                     return false;
1142                 }
1143
1144                 var arguments = new Array<Variant> ();
1145
1146                 property_node.get_array ().foreach_element ((array, index, element) => {
1147                     try {
1148                         arguments.append_val (Json.gvariant_deserialize (element, null));
1149                     } catch (Error e) {
1150                         warning ("argument %u to command could not be deserialized: %s", index, e.message);
1151                     }
1152                 });
1153
1154                 value.set_boxed (arguments);
1155                 return true;
1156             } else if (property_name == "command") {
1157                 // workaround for json-glib < 1.5.2 (Ubuntu 20.04 / eOS 6)
1158                 if (property_node.get_value_type () != typeof (string)) {
1159                     value = "";
1160                     warning ("unexpected property node type for 'commands' %s", property_node.get_node_type ().to_string ());
1161                     return false;
1162                 }
1163
1164                 value = property_node.get_string ();
1165                 return true;
1166             } else {
1167                 return default_deserialize_property (property_name, out value, pspec, property_node);
1168             }
1169         }
1170     }
1171
1172     public class ExecuteCommandParams : CommandLike {
1173     }
1174
1175     /**
1176      * Represents a reference to a command. Provides a title which will be used
1177      * to represent a command in the UI. Commands are identified by a string
1178      * identifier. The recommended way to handle commands is to implement their
1179      * execution on the server side if the client and server provides the
1180      * corresponding capabilities. Alternatively the tool extension code could
1181      * handle the command. The protocol currently doesn’t specify a set of
1182      * well-known commands.
1183      */
1184     public class Command : CommandLike {
1185         /**
1186          * The title of the command, like `save`.
1187          */
1188         public string title { get; set; }
1189     }
1190
1191     /**
1192      * A code lens represents a command that should be shown along with
1193      * source text, like the number of references, a way to run tests, etc.
1194      *
1195      * A code lens is _unresolved_ when no command is associated to it. For
1196      * performance reasons the creation of a code lens and resolving should be done
1197      * in two stages.
1198      */
1199     public class CodeLens : Object {
1200         /**
1201          * The range in which this code lens is valid. Should only span a single
1202          * line.
1203          */
1204         public Range range { get; set; }
1205
1206         /**
1207          * The command this code lens represents.
1208          */
1209         public Command? command { get; set; }
1210     }
1211     
1212     public class DocumentRangeFormattingParams : Object {
1213         public TextDocumentIdentifier textDocument { get; set; }
1214         public Range? range { get; set; }
1215         public FormattingOptions options { get; set; }
1216     }
1217
1218     public class FormattingOptions : Object {
1219         public uint tabSize { get; set; }
1220         public bool insertSpaces { get; set; }
1221         public bool trimTrailingWhitespace { get; set; }
1222         public bool insertFinalNewline { get; set; }
1223         public bool trimFinalNewlines { get; set; }
1224     }
1225
1226     public class CodeActionParams : Object {
1227         public TextDocumentIdentifier textDocument { get; set; }
1228         public Range range { get; set; }
1229         public CodeActionContext context { get; set; }
1230     }
1231
1232
1233     public class CodeActionContext : Object, Json.Serializable {
1234         public Gee.List<Diagnostic> diagnostics { get; set; default = new Gee.ArrayList<Diagnostic> (); }
1235         public string[]? only { get; set; }
1236 /*
1237         public bool deserialize_property (string property_name, out Value value, ParamSpec pspec, Json.Node property_node) {
1238             if (property_name != "diagnostics")
1239                 return default_deserialize_property (property_name, out value, pspec, property_node);
1240             var diags = new Gee.ArrayList<Diagnostic> ();
1241             property_node.get_array ().foreach_element ((array, index, element) => {
1242                 try {
1243                     diags.add (Vls.Util.parse_variant<Diagnostic> (Json.gvariant_deserialize (element, null)));
1244                 } catch (Error e) {
1245                     warning ("argument %u could not be deserialized: %s", index, e.message);
1246                 }
1247             });
1248             value = diags;
1249             return true;
1250         }
1251         */
1252     }
1253
1254
1255         public class Diagnostics : Object, Json.Serializable 
1256         {
1257                 public Diagnostics()
1258                 {
1259                         this.diagnostics = new Gee.ArrayList<Diagnostic>((a,b) => {
1260                                 return a.equals(b);
1261                         });
1262                 }
1263                 
1264                 public string uri { get; set; }
1265
1266                 public int version  { get; set; default = 0; }
1267         public Gee.ArrayList<Diagnostic>? diagnostics { get; set; }
1268                  
1269                 public string filename { 
1270                         owned get {
1271                                 return File.new_for_uri (this.uri).get_path();
1272                         }
1273                         private set {}
1274                 }
1275                 
1276                 public bool deserialize_property (string property_name, out GLib.Value val, GLib.ParamSpec pspec, Json.Node property_node) {
1277                         if (property_name == "diagnostics") {
1278                 val = GLib.Value (typeof(Gee.ArrayList));
1279                                 var diags =  new Gee.ArrayList<Diagnostic> ((a,b) => {
1280                                         return a.equals(b);
1281                                 });
1282                                 if (property_node.get_node_type () != Json.NodeType.ARRAY) {
1283                                         val.set_object(diags);
1284                                         warning ("unexpected property node type for 'arguments' %s", property_node.get_node_type ().to_string ());
1285                                         return false;
1286                                 }
1287
1288                                 
1289
1290                                 property_node.get_array ().foreach_element ((array, index, element) => {
1291                                          
1292                                                 diags.add (Json.gobject_deserialize (typeof (Lsp.Diagnostic), element) as Diagnostic );
1293                                          
1294                                                 //warning ("argument %u to command could not be deserialized: %s", index, e.message);
1295                                          
1296                                 });
1297                                 val.set_object(diags);
1298                                  
1299                                 return true;
1300                         }   
1301                          
1302                         return default_deserialize_property (property_name, out val, pspec, property_node);
1303                          
1304                 }
1305
1306                 
1307         }
1308
1309
1310    public  class CodeAction : Object, Json.Serializable {
1311         public string title { get; set; }
1312         public string? kind { get; set; }
1313         public Gee.Collection<Diagnostic>? diagnostics { get; set; }
1314         public bool isPreferred { get; set; }
1315         public WorkspaceEdit? edit { get; set; }
1316         public Command? command { get; set; }
1317         public Object? data { get; set; }
1318
1319         protected void add_diagnostic (Diagnostic diag) {
1320             if (diagnostics == null)
1321                 diagnostics = new Gee.ArrayList<Diagnostic> ();
1322             diagnostics.add (diag);
1323         }
1324
1325         public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1326             if (property_name != "diagnostics")
1327                 return default_serialize_property (property_name, value, pspec);
1328
1329             var array = new Json.Array ();
1330             if (diagnostics != null)
1331                 foreach (var text_edit in diagnostics)
1332                     array.add_element (Json.gobject_serialize (text_edit));
1333             return new Json.Node.alloc ().init_array (array);
1334         }
1335     }
1336
1337     public class WorkspaceEdit : Object, Json.Serializable {
1338         public Gee.List<TextDocumentEdit>? documentChanges { get; set; }
1339
1340         public Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1341             if (property_name != "documentChanges")
1342                 return default_serialize_property (property_name, value, pspec);
1343
1344             var node = new Json.Node (Json.NodeType.ARRAY);
1345             node.init_array (new Json.Array ());
1346             if (documentChanges != null) {
1347                 var array = node.get_array ();
1348                 foreach (var text_edit in documentChanges) {
1349                     array.add_element (Json.gobject_serialize (text_edit));
1350                 }
1351             }
1352             return node;
1353         }
1354     }
1355
1356     [Flags]
1357     public enum SymbolTags {
1358         NONE,
1359         DEPRECATED
1360     }
1361
1362     public class CallHierarchyItem : Object, Json.Serializable {
1363         public string name { get; set; }
1364         public SymbolKind kind { get; set; }
1365         public SymbolTags tags { get; set; }
1366         public string? detail { get; set; }
1367         public string uri { get; set; }
1368         public Range range { get; set; }
1369         public Range selectionRange { get; set; }
1370
1371         public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1372             if (property_name != "tags")
1373                 return default_serialize_property (property_name, value, pspec);
1374             var array = new Json.Array ();
1375             if (SymbolTags.DEPRECATED in tags)
1376                 array.add_int_element (SymbolTags.DEPRECATED);
1377             return new Json.Node.alloc ().init_array (array);
1378         }
1379 /*
1380         public CallHierarchyItem.from_symbol (Vala.Symbol symbol) {
1381             this.name = symbol.get_full_name ();
1382             if (symbol is Vala.Method) {
1383                 if (symbol.parent_symbol is Vala.Namespace)
1384                     this.kind = SymbolKind.Function;
1385                 else
1386                     this.kind = SymbolKind.Method;
1387             } else if (symbol is Vala.Signal) {
1388                 this.kind = SymbolKind.Event;
1389             } else if (symbol is Vala.Constructor) {
1390                 this.kind = SymbolKind.Constructor;
1391             } else {
1392                 this.kind = SymbolKind.Method;
1393             }
1394             var version = symbol.get_attribute ("Version");
1395             if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
1396                 this.tags |= SymbolTags.DEPRECATED;
1397             }
1398             this.detail = Vls.CodeHelp.get_symbol_representation (null, symbol, null, true);
1399             this.uri = File.new_for_commandline_arg (symbol.source_reference.file.filename).get_uri ();
1400             this.range = new Range.from_sourceref (symbol.source_reference);
1401             if (symbol.comment != null)
1402                 this.range = new Range.from_sourceref (symbol.comment.source_reference).union (this.range);
1403             if (symbol is Vala.Subroutine && ((Vala.Subroutine)symbol).body != null)
1404                 this.range = new Range.from_sourceref (((Vala.Subroutine)symbol).body.source_reference).union (this.range);
1405             this.selectionRange = new Range.from_sourceref (symbol.source_reference);
1406         }
1407         */
1408     }
1409
1410     public class CallHierarchyIncomingCall : Json.Serializable, Object {
1411         /**
1412          * The method that calls the query method.
1413          */
1414         public CallHierarchyItem from { get; set; }
1415
1416         /**
1417          * The ranges at which the query method is called by `from`.
1418          */
1419         public Gee.ArrayList<Range> fromRanges { get; set; default = new Gee.ArrayList<Range> (); }
1420
1421         public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1422             if (property_name == "from")
1423                 return default_serialize_property (property_name, value, pspec);
1424             var array = new Json.Array ();
1425             foreach (var range in fromRanges)
1426                 array.add_element (Json.gobject_serialize (range));
1427             return new Json.Node.alloc ().init_array (array);
1428         }
1429     }
1430
1431     public class CallHierarchyOutgoingCall : Json.Serializable, Object {
1432         /**
1433          * The method that the query method calls.
1434          */
1435         public CallHierarchyItem to { get; set; }
1436
1437         /**
1438          * The ranges at which the method is called by the query method.
1439          */
1440         public Gee.ArrayList<Range> fromRanges { get; set; default = new Gee.ArrayList<Range> (); }
1441
1442         public override Json.Node serialize_property (string property_name, GLib.Value value, GLib.ParamSpec pspec) {
1443             if (property_name == "to")
1444                 return default_serialize_property (property_name, value, pspec);
1445             var array = new Json.Array ();
1446             foreach (var range in fromRanges)
1447                 array.add_element (Json.gobject_serialize (range));
1448             return new Json.Node.alloc ().init_array (array);
1449         }
1450     }
1451
1452     public class InlayHintParams : Json.Serializable, Object {
1453         public TextDocumentIdentifier textDocument { get; set; }
1454         public Range range { get; set; }
1455     }
1456
1457     public enum InlayHintKind {
1458         UNSET,
1459         TYPE,
1460         PARAMETER
1461     }
1462
1463     public class InlayHint : Object {
1464         public Position position { get; set; }
1465         public string label { get; set; }
1466         public InlayHintKind kind { get; set; }
1467         public string? tooltip { get; set; }
1468         public bool paddingLeft { get; set; }
1469         public bool paddingRight { get; set; }
1470     }
1471
1472    public  class TypeHierarchyItem : Object, Json.Serializable {
1473         /**
1474          * The name of this item
1475          */
1476         public string name { get; set; }
1477
1478         /**
1479          * The kind of this item
1480          */
1481         public SymbolKind kind { get; set; }
1482
1483         /**
1484          * Tags for this item
1485          */
1486         public SymbolTags tags { get; set; }
1487
1488         /**
1489          * More detail for this item, e.g. the signature of a function.
1490          */
1491         public string? detail { get; set; }
1492
1493         /**
1494          * The resource identifier of this item.
1495          */
1496         public string uri { get; set; }
1497
1498         /**
1499          * The range enclosing this symbol not including leading/trailing
1500          * whitespace, but everything else, e.g. comments and code.
1501          */
1502         public Range range { get; set; }
1503
1504         /**
1505          * The range that should be selected and revealed when this symbol
1506          * is being picked, e.g. the name of a function. Must be contained
1507          * by {@link TypeHierarchyItem.range}
1508          */
1509         public Range selectionRange { get; set; }
1510
1511         private TypeHierarchyItem () {}
1512 /*
1513         public TypeHierarchyItem.from_symbol (Vala.TypeSymbol symbol) {
1514             this.name = symbol.get_full_name ();
1515             if (symbol is Vala.Class)
1516                 this.kind = SymbolKind.Class;
1517             else if (symbol is Vala.Delegate)
1518                 this.kind = SymbolKind.Interface;
1519             else if (symbol is Vala.Enum)
1520                 this.kind = SymbolKind.Enum;
1521             else if (symbol is Vala.ErrorCode)
1522                 this.kind = SymbolKind.EnumMember;
1523             else if (symbol is Vala.ErrorDomain)
1524                 this.kind = SymbolKind.Enum;
1525             else if (symbol is Vala.Interface)
1526                 this.kind = SymbolKind.Interface;
1527             else if (symbol is Vala.Struct)
1528                 this.kind = SymbolKind.Struct;
1529             else if (symbol is Vala.TypeParameter)
1530                 this.kind = SymbolKind.TypeParameter;
1531             else {
1532                 this.kind = SymbolKind.Module;
1533                 warning ("unexpected symbol kind in type hierarchy: `%s'", symbol.type_name);
1534             }
1535
1536             var version = symbol.get_attribute ("Version");
1537             if (version != null && (version.get_bool ("deprecated") || version.get_string ("deprecated_since") != null)) {
1538                 this.tags |= SymbolTags.DEPRECATED;
1539             }
1540             this.detail = Vls.CodeHelp.get_symbol_representation (null, symbol, null, true);
1541             this.uri = File.new_for_commandline_arg (symbol.source_reference.file.filename).get_uri ();
1542             this.range = new Range.from_sourceref (symbol.source_reference);
1543             this.selectionRange = this.range;
1544
1545             // widen range to include all members
1546             if (symbol is Vala.ObjectTypeSymbol) {
1547                 foreach (var member in ((Vala.ObjectTypeSymbol)symbol).get_members ()) {
1548                     if (member.source_reference != null)
1549                         this.range = this.range.union (new Range.from_sourceref (member.source_reference));
1550                 }
1551             } else if (symbol is Vala.Enum) {
1552                 foreach (var member in ((Vala.Enum)symbol).get_values ()) {
1553                     if (member.source_reference != null)
1554                         this.range = this.range.union (new Range.from_sourceref (member.source_reference));
1555                 }
1556                 foreach (var method in ((Vala.Enum)symbol).get_methods ()) {
1557                     if (method.source_reference != null)
1558                         this.range = this.range.union (new Range.from_sourceref (method.source_reference));
1559                 }
1560             } else if (symbol is Vala.ErrorDomain) {
1561                 foreach (var member in ((Vala.ErrorDomain)symbol).get_codes ()) {
1562                     if (member.source_reference != null)
1563                         this.range = this.range.union (new Range.from_sourceref (member.source_reference));
1564                 }
1565                 foreach (var method in ((Vala.ErrorDomain)symbol).get_methods ()) {
1566                     if (method.source_reference != null)
1567                         this.range = this.range.union (new Range.from_sourceref (method.source_reference));
1568                 }
1569             } else if (symbol is Vala.Struct) {
1570                 foreach (var field in ((Vala.Struct)symbol).get_fields ()) {
1571                     if (field.source_reference != null)
1572                         this.range = this.range.union (new Range.from_sourceref (field.source_reference));
1573                 }
1574                 foreach (var method in ((Vala.Struct)symbol).get_methods ()) {
1575                     if (method.source_reference != null)
1576                         this.range = this.range.union (new Range.from_sourceref (method.source_reference));
1577                 }
1578             }
1579         }
1580         */
1581     }
1582 }