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