[gnome-builder/wip/tintou/vala-subprocess: 7/7] Provide symbol lookup



commit ddba7798180dbfcaf7d73109190ef5704990d068
Author: Corentin Noël <corentin noel collabora com>
Date:   Thu Mar 14 17:54:15 2019 +0100

    Provide symbol lookup

 src/plugins/vala-pack/lang-server/ide-utils.vala   |  65 +++++-
 .../vala-pack/lang-server/ide-vala-index.vala      |  15 +-
 .../vala-pack/lang-server/ide-vala-locator.vala    | 222 ++++++++++++++-------
 .../lang-server/ide-vala-symbol-tree.vala          |   2 +-
 4 files changed, 210 insertions(+), 94 deletions(-)
---
diff --git a/src/plugins/vala-pack/lang-server/ide-utils.vala 
b/src/plugins/vala-pack/lang-server/ide-utils.vala
index 2105cf475..e928b1533 100644
--- a/src/plugins/vala-pack/lang-server/ide-utils.vala
+++ b/src/plugins/vala-pack/lang-server/ide-utils.vala
@@ -1,22 +1,53 @@
 namespace Ide {
-       public static Ide.Symbol? vala_to_ide_symbol (Vala.CodeNode node)
+       public static Ide.Symbol? vala_to_ide_symbol (Vala.CodeNode node, bool simple_name = false)
        {
-               Vala.Symbol? symbol = vala_symbol_from_code_node (node);
-               if (symbol == null)
+               if (node is Vala.Block) {
                        return null;
+               }
+
+               critical ("%s", node.type_name);
+               Vala.Symbol? symbol = vala_symbol_from_code_node (node);
 
                Ide.SymbolKind kind = vala_symbol_kind_from_code_node (node);
                Ide.SymbolFlags flags = vala_symbol_flags_from_code_node (node);
-               string name = vala_symbol_name (symbol);
+               string? name;
+               if (symbol != null) {
+                       if (!simple_name) {
+                               name = vala_symbol_name (symbol);
+                       } else {
+                               if (symbol is Vala.CreationMethod) {
+                                       name = (symbol as Vala.CreationMethod).class_name;
+                               } else {
+                                       name = symbol.name;
+                               }
+                       }
+               } else {
+                       name = node.to_string ();
+               }
+
+               unowned Vala.SourceReference? source_reference = null;
+               if (node is Vala.MethodCall) {
+                       source_reference = ((Vala.MethodCall) node).call.symbol_reference.source_reference;
+               } else if (node is Vala.DataType) {
+                       source_reference = ((Vala.DataType) node).data_type.source_reference;
+               } else if (node is Vala.MemberAccess) {
+                       weak Vala.Symbol symbol_ref = ((Vala.MemberAccess) node).symbol_reference;
+                       if (symbol_ref != null) {
+                               source_reference = symbol_ref.source_reference;
+                       } else {
+                               source_reference = node.source_reference;
+                       }
+               } else {
+                       source_reference = node.source_reference;
+               }
 
-               var source_reference = node.source_reference;
                if (source_reference != null) {
                        var file = GLib.File.new_for_path (source_reference.file.filename);
                        var loc = new Ide.Location (file,
                                                    source_reference.begin.line - 1,
                                                    source_reference.begin.column - 1);
 
-                       return new Ide.Symbol (name, kind, flags, loc, loc);
+                       return new Ide.Symbol (name, kind, flags, loc, null);
                }
 
                return new Ide.Symbol (name, kind, flags, null, null);
@@ -46,18 +77,26 @@ namespace Ide {
                else if (node is Vala.Namespace) return Ide.SymbolKind.NAMESPACE;
                else if (node is Vala.Delegate) return Ide.SymbolKind.TEMPLATE;
                else if (node is Vala.Signal) return Ide.SymbolKind.UI_SIGNAL;
+               else if (node is Vala.MethodCall) return Ide.SymbolKind.METHOD;
 
                return Ide.SymbolKind.NONE;
        }
 
-       public static unowned string vala_symbol_name (Vala.Symbol symbol)
+       public static string? vala_symbol_name (Vala.Symbol symbol)
        {
-               unowned string name = symbol.name;
-               if (symbol is Vala.CreationMethod) {
-                       name = (symbol as Vala.CreationMethod).class_name;
+               if (symbol is Vala.Variable) {
+                       unowned Vala.Variable variable = (Vala.Variable) symbol;
+                       if (variable.variable_type != null) {
+                               return variable.variable_type.to_prototype_string () + " " + symbol.name;
+                       } else {
+                               return "var " + symbol.name;
+                       }
+               } else if (symbol is Vala.Method) {
+                       var type = new Vala.MethodType ((Vala.Method) symbol);
+                       return type.to_prototype_string ();
                }
 
-               return name;
+               return symbol.to_string ();
        }
 
        public static Ide.SymbolFlags vala_symbol_flags_from_code_node (Vala.CodeNode node)
@@ -81,6 +120,10 @@ namespace Ide {
        {
                if (node is Vala.Expression)
                        return (node as Vala.Expression).symbol_reference;
+               else if (node is Vala.MethodCall)
+                       return (node as Vala.MethodCall).call.symbol_reference;
+               else if (node is Vala.MemberAccess)
+                       return (node as Vala.MemberAccess).symbol_reference;
                else
                        return (node as Vala.Symbol);
        }
diff --git a/src/plugins/vala-pack/lang-server/ide-vala-index.vala 
b/src/plugins/vala-pack/lang-server/ide-vala-index.vala
index 150dfd596..e66739849 100644
--- a/src/plugins/vala-pack/lang-server/ide-vala-index.vala
+++ b/src/plugins/vala-pack/lang-server/ide-vala-index.vala
@@ -205,8 +205,9 @@ namespace Ide
                                        if (source_file.filename == path) {
                                                var locator = new Ide.ValaLocator ();
                                                var vala_node = locator.locate (source_file, line, column);
-                                               if (vala_node != null && vala_node is Vala.Symbol) {
-                                                       symbol = Ide.vala_to_ide_symbol (vala_node as 
Vala.Symbol);
+
+                                               if (vala_node != null) {
+                                                       symbol = Ide.vala_to_ide_symbol (vala_node);
                                                }
 
                                                break;
@@ -346,11 +347,11 @@ namespace Ide
                        }
                }
 
-               private Vala.Symbol? find_nearest_symbol (string path,
+               private Vala.CodeNode? find_nearest_symbol (string path,
                                                          uint line,
                                                          uint column)
                {
-                       Vala.Symbol? symbol = null;
+                       Vala.CodeNode? symbol = null;
                        if (add_file (GLib.File.new_for_path (path)))
                                reparse ();
 
@@ -358,8 +359,8 @@ namespace Ide
                        foreach (var source_file in code_context.get_source_files ()) {
                                if (source_file.filename == path) {
                                        var locator = new Ide.ValaLocator ();
-                                       var vala_node = locator.locate (source_file, line, column) as 
Vala.Symbol;
-                                       while (vala_node != null) {
+                                       symbol = locator.locate (source_file, line, column);
+                                       /*while (vala_node != null) {
                                                if (vala_node is Vala.Class ||
                                                        vala_node is Vala.Subroutine ||
                                                        vala_node is Vala.Namespace ||
@@ -372,7 +373,7 @@ namespace Ide
                                                        vala_node = vala_node.parent_symbol;
                                        }
 
-                                       symbol = vala_node;
+                                       symbol = vala_node;*/
                                        break;
                                }
                        }
diff --git a/src/plugins/vala-pack/lang-server/ide-vala-locator.vala 
b/src/plugins/vala-pack/lang-server/ide-vala-locator.vala
index 75e21c223..a6a9ba378 100644
--- a/src/plugins/vala-pack/lang-server/ide-vala-locator.vala
+++ b/src/plugins/vala-pack/lang-server/ide-vala-locator.vala
@@ -28,162 +28,233 @@ namespace Ide {
                                this.column = column;
                        }
 
-                       public bool inside (Vala.SourceReference src) {
-                               var begin = Location (src.begin.line, src.begin.column);
-                               var end = Location (src.end.line, src.end.column);
-
-                               return begin.before (this) && this.before(end);
-                       }
-
-                       public bool before (Location other) {
-                               if (line > other.line)
+                       public bool inside (Vala.CodeNode node) {
+                               unowned Vala.SourceReference? src = node.source_reference;
+                               if (src == null) {
                                        return false;
-                               else if (line == other.line && column > other.column)
+                               }
+
+                               unowned Vala.SourceLocation src_begin = src.begin;
+                               unowned Vala.SourceLocation src_end = src.end;
+                               critical ("[%s]: %s", node.type_name, node.to_string ());
+                               if (line > src_begin.line && line < src_end.line) {
+                                       return true;
+                               } else if (line == src_begin.line && line == src_end.line) {
+                                       return column >= src_begin.column && column <= src_end.column;
+                               } else if (line == src_begin.line) {
+                                       return column >= src_begin.column;
+                               } else if (line == src_end.line) {
+                                       return column <= src_end.column;
+                               } else {
                                        return false;
-                               return true;
+                               }
                        }
                }
 
                Location location;
                Vala.CodeNode innermost;
-               Location innermost_begin;
-               Location innermost_end;
 
                public Vala.CodeNode? locate (Vala.SourceFile file, uint line, uint column) {
+                       critical ("~~ START ~~");
                        location = Location (line, column);
                        innermost = null;
                        file.accept_children(this);
                        return innermost;
                }
 
-               bool update_location (Vala.CodeNode s) {
-                       if (!location.inside (s.source_reference))
-                               return false;
+               private bool is_closer_to_location (Vala.CodeNode node) {
+                       if (innermost == null) {
+                               return true;
+                       }
 
-                       var begin = Location (s.source_reference.begin.line, s.source_reference.begin.column);
-                       var end = Location (s.source_reference.end.line, s.source_reference.end.column);
+                       if (innermost == node) {
+                               return false;
+                       }
 
-                       if (innermost == null || (innermost_begin.before(begin) && 
end.before(innermost_end))) {
-                                       innermost = s;
-                                       innermost_begin = begin;
-                                       innermost_end = end;
-                                       return true;
+                       unowned Vala.SourceReference? node_src = node.source_reference;
+                       unowned Vala.SourceReference? innermost_src = innermost.source_reference;
+                       if (node_src.begin.line > innermost_src.begin.line || node_src.end.line < 
innermost_src.end.line) {
+                               return true;
+                       } else if (node_src.begin.line == innermost_src.begin.line && node_src.begin.column > 
innermost_src.begin.column) {
+                               return true;
+                       } else if (node_src.end.line == innermost_src.end.line && node_src.end.column < 
innermost_src.end.column) {
+                               return true;
                        }
 
                        return false;
                }
 
-               /*private bool covers_location (Vala.SourceReference source_ref) {
-                       unowned source_ref.begin
-                       if (source_ref.begin.line > location.line)
-                               return false;
+               bool update_location (Vala.CodeNode node, bool assign = true) {
+                       if (!location.inside (node)) {
+                               if (node is Vala.Subroutine) {
+                                       unowned Vala.Block body = ((Vala.Subroutine)node).body;
+                                       if (location.inside (body)) {
+                                               visit_block (body);
+                                       }
+                               }
 
-                       if (source_ref.end.line < location.line)
                                return false;
+                       }
+                       critical ("[%s] [%u.%u:%u.%u] matches location [%u.%u]", node.type_name, 
node.source_reference.begin.line, node.source_reference.begin.column, node.source_reference.end.line, 
node.source_reference.end.column, location.line, location.column);
 
-                       if (source_ref.begin.line == location.line && )
-                               return false;
+                       if (is_closer_to_location (node)) {
+                               critical ("Replacing innermost");
+                               if (assign) {
+                                       innermost = node;
+                               }
 
-                       if (source_ref.end.line < location.line)
-                               return false;
-               }*/
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public override void visit_assignment (Vala.Assignment a) {
+                       if (update_location (a, false)) {
+                               a.accept_children (this);
+                       }
+               }
 
                public override void visit_block (Vala.Block b) {
-                       if (update_location (b))
-                               b.accept_children(this);
+                       if (update_location (b, false)) {
+                               b.accept_children (this);
+                       }
                }
 
                public override void visit_namespace (Vala.Namespace ns) {
+                       // This is only the namespace declaration, source_reference is only one line long
                        update_location (ns);
-                       ns.accept_children(this);
+                       ns.accept_children (this);
                }
+
                public override void visit_class (Vala.Class cl) {
-                       /* the location of a class contains only its declaration, not its content */
-                       if (update_location (cl))
-                               return;
-                       cl.accept_children(this);
+                       // This is only the class declaration, source_reference is only one line long
+                       update_location (cl);
+                       cl.accept_children (this);
                }
+
+               public override void visit_data_type (Vala.DataType type) {
+                       if (update_location (type)) {
+                               type.accept_children (this);
+                       }
+               }
+
                public override void visit_struct (Vala.Struct st) {
-                       if (update_location (st))
-                               return;
-                       st.accept_children(this);
+                       if (update_location (st)) {
+                               st.accept_children (this);
+                       }
                }
+
                public override void visit_interface (Vala.Interface iface) {
-                       if (update_location (iface))
-                               return;
-                       iface.accept_children(this);
-               }
-               public override void visit_member_access (Vala.MemberAccess expr) {
-                       if (update_location (expr))
-                               return;
-                       expr.accept_children(this);
+                       if (update_location (iface)) {
+                               iface.accept_children(this);
+                       }
                }
+
                public override void visit_method (Vala.Method m) {
-                       if (update_location (m))
-                               return;
-                       m.accept_children(this);
+                       if (update_location (m)) {
+                               m.accept_children (this);
+                       }
                }
+
                public override void visit_method_call (Vala.MethodCall expr) {
-                       if (update_location (expr))
-                               return;
-                       expr.accept_children(this);
+                       if (update_location (expr)) {
+                               expr.accept_children (this);
+                       }
+               }
+
+               public override void visit_member_access (Vala.MemberAccess expr) {
+                       if (update_location (expr)) {
+                               expr.accept_children (this);
+                       }
                }
+
                public override void visit_creation_method (Vala.CreationMethod m) {
-                       if (update_location (m))
-                               return;
-                       m.accept_children(this);
+                       if (update_location (m)) {
+                               m.accept_children (this);
+                       }
+               }
+
+               public override void visit_object_creation_expression (Vala.ObjectCreationExpression expr) {
+                       if (update_location (expr, false)) {
+                               expr.accept_children (this);
+                       }
                }
+
                public override void visit_property (Vala.Property prop) {
-                       prop.accept_children(this);
+                       prop.accept_children (this);
                }
+
                public override void visit_property_accessor (Vala.PropertyAccessor acc) {
-                       acc.accept_children(this);
+                       if (update_location (acc)) {
+                               acc.accept_children (this);
+                       }
                }
+
                public override void visit_constructor (Vala.Constructor c) {
-                       c.accept_children(this);
+                       if (update_location (c, false)) {
+                               c.accept_children (this);
+                       }
                }
+
                public override void visit_destructor (Vala.Destructor d) {
-                       d.accept_children(this);
+                       if (update_location (d, false)) {
+                               d.accept_children (this);
+                       }
                }
+
                public override void visit_if_statement (Vala.IfStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_switch_statement (Vala.SwitchStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_switch_section (Vala.SwitchSection section) {
                        visit_block (section);
                }
+
                public override void visit_while_statement (Vala.WhileStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_do_statement (Vala.DoStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_for_statement (Vala.ForStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_foreach_statement (Vala.ForeachStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_try_statement (Vala.TryStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_catch_clause (Vala.CatchClause clause) {
-                       clause.accept_children(this);
+                       clause.accept_children (this);
                }
+
                public override void visit_lock_statement (Vala.LockStatement stmt) {
-                       stmt.accept_children(this);
+                       stmt.accept_children (this);
                }
+
                public override void visit_expression_statement (Vala.ExpressionStatement stmt) {
                        stmt.accept_children (this);
                }
+
                public override void visit_declaration_statement (Vala.DeclarationStatement stmt) {
                        stmt.accept_children (this);
                }
+
                public override void visit_local_variable (Vala.LocalVariable variable) {
                        variable.accept_children (this);
                }
+
                public override void visit_end_full_expression (Vala.Expression expr) {
                        if (expr is Vala.LambdaExpression) {
                                if ((expr as Vala.LambdaExpression).method != null)
@@ -195,17 +266,18 @@ namespace Ide {
                                }
                        }
                }
+
                public override void visit_expression (Vala.Expression expr) {
                        if (expr is Vala.LambdaExpression) {
                                if ((expr as Vala.LambdaExpression).method != null)
                                        visit_method ((expr as Vala.LambdaExpression).method);
                        }
-                       if (expr is Vala.MethodCall) {
+                       /*if (expr is Vala.MethodCall) {
                                update_location (expr);
                                foreach (Vala.Expression e in (expr as Vala.MethodCall).get_argument_list())
                                        visit_expression (e);
 
-                       }
+                       }*/
                        if (expr is Vala.Assignment) {
                                (expr as Vala.Assignment).accept_children (this);
                        }
diff --git a/src/plugins/vala-pack/lang-server/ide-vala-symbol-tree.vala 
b/src/plugins/vala-pack/lang-server/ide-vala-symbol-tree.vala
index aee2f43e4..3df417725 100644
--- a/src/plugins/vala-pack/lang-server/ide-vala-symbol-tree.vala
+++ b/src/plugins/vala-pack/lang-server/ide-vala-symbol-tree.vala
@@ -123,7 +123,7 @@ namespace Ide
                        GLib.Variant? root_variant = null;
                        var symbol = node as Vala.Symbol;
                        if (symbol != null) {
-                               Ide.Symbol? ide_symbol = Ide.vala_to_ide_symbol (symbol);
+                               Ide.Symbol? ide_symbol = Ide.vala_to_ide_symbol (symbol, true);
                                if (ide_symbol == null)
                                        return null;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]