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