From bd64b248fd94fc8ed1dd6a6d29f2e8ffc4c20bda Mon Sep 17 00:00:00 2001 From: Princeton Ferro Date: Tue, 5 May 2020 21:37:30 -0400 Subject: [PATCH] documentSymbol: evaluate range on property read This allows us to setup the document outline/tree first, and then have the ranges computed correctly. --- src/list_symbols.vala | 3 --- src/protocol.vala | 23 +++++++++++++++++++++-- src/server.vala | 12 ------------ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/list_symbols.vala b/src/list_symbols.vala index 265cc7893..8f2d99f1b 100644 --- a/src/list_symbols.vala +++ b/src/list_symbols.vala @@ -59,7 +59,6 @@ class Vls.ListSymbols : Vala.CodeVisitor { existing_sym.name = dsym.name; existing_sym.detail = dsym.detail; existing_sym.kind = dsym.kind; - existing_sym.range = dsym.range; return existing_sym; } else if (existing_sym.kind == Property && dsym.kind == Field) return existing_sym; @@ -89,7 +88,6 @@ class Vls.ListSymbols : Vala.CodeVisitor { if (current_sym != null) { // debug (@"adding $(dsym.name) to current_sym $(current_sym.name)"); current_sym.children.add (dsym); - current_sym.range = current_sym.range.union (dsym.range); } else { if (sym.parent_symbol is Vala.Namespace && sym.parent_symbol.to_string () != "(root namespace)") { @@ -100,7 +98,6 @@ class Vls.ListSymbols : Vala.CodeVisitor { parent_dsym = ns_name_to_dsym [sym.parent_symbol.get_full_name ()]; // debug (@"adding $(dsym.name) to $(parent_dsym.name)"); parent_dsym.children.add (dsym); - parent_dsym.range = parent_dsym.range.union (dsym.range); } else { // debug (@"adding $(dsym.name) to top_level_syms"); top_level_syms.add (dsym); diff --git a/src/protocol.vala b/src/protocol.vala index aabef4716..4d7af96fa 100644 --- a/src/protocol.vala +++ b/src/protocol.vala @@ -230,11 +230,20 @@ namespace LanguageServer { } class DocumentSymbol : Object, Json.Serializable { + private Vala.SourceReference? _source_reference; public string name { get; set; } public string? detail { get; set; } public SymbolKind kind { get; set; } public bool deprecated { get; set; } - public Range range { get; set; } + private Range? _initial_range; + public Range range { + owned get { + if (_initial_range == null) + _initial_range = new Range.from_sourceref (children.first ()._source_reference); + + return children.fold ((child, current_range) => current_range.union (child.range), _initial_range); + } + } public Range selectionRange { get; set; } public Gee.List children { get; private set; default = new Gee.LinkedList (); } @@ -243,10 +252,20 @@ namespace LanguageServer { * @param sym the symbol */ public DocumentSymbol.from_vala_symbol (Vala.DataType? type, Vala.Symbol sym, SymbolKind kind) { + this._initial_range = new Range.from_sourceref (sym.source_reference); + if (sym is Vala.Subroutine) { + var sub = (Vala.Subroutine) sym; + var body_sref = sub.body != null ? sub.body.source_reference : null; + // debug ("subroutine %s found (body @ %s)", sym.get_full_name (), + // body_sref != null ? body_sref.to_string () : null); + if (body_sref != null && (body_sref.begin.line < body_sref.end.line || + body_sref.begin.line == body_sref.end.line && body_sref.begin.pos <= body_sref.end.pos)) { + this._initial_range = this._initial_range.union (new Range.from_sourceref (body_sref)); + } + } this.name = sym.name; this.detail = Vls.CodeHelp.get_symbol_representation (type, sym, null); this.kind = kind; - this.range = Vls.Server.get_best_range (sym); this.selectionRange = new Range.from_sourceref (sym.source_reference); this.deprecated = sym.version.deprecated; } diff --git a/src/server.vala b/src/server.vala index 422fa0429..acc2aa668 100644 --- a/src/server.vala +++ b/src/server.vala @@ -909,18 +909,6 @@ class Vls.Server : Object { }); } - public static Range get_best_range (Vala.Symbol sym) { - var range = new Range.from_sourceref (sym.source_reference); - - if (sym is Vala.Method) { - var m = (Vala.Method) sym; - if (m.body != null && m.body.source_reference != null) - range = range.union (get_best_range (m.body)); - } - - return range; - } - public LanguageServer.MarkupContent? get_symbol_documentation (Project project, Vala.Symbol sym) { Vala.Symbol real_sym = find_real_sym (project, sym); sym = real_sym;