[gnome-builder/gnome-builder-3-18] vala: add a simple symbol tree for vala
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/gnome-builder-3-18] vala: add a simple symbol tree for vala
- Date: Tue, 13 Oct 2015 07:25:01 +0000 (UTC)
commit 87723c0c0dab89ca18c1f235a57d69243491cf93
Author: Christian Hergert <christian hergert me>
Date: Sat Sep 26 04:36:38 2015 -0700
vala: add a simple symbol tree for vala
Not very optimized, and I noticed that libvala is leaking like crazy.
We have a lot to do here.
Also, it seems the symbol tree is broke for searching non-toplevels.
plugins/vala-pack/Makefile.am | 1 +
plugins/vala-pack/ide-vala-index.vala | 35 +++++
plugins/vala-pack/ide-vala-source-file.vala | 2 +-
plugins/vala-pack/ide-vala-symbol-resolver.vala | 9 +-
plugins/vala-pack/ide-vala-symbol-tree.vala | 154 +++++++++++++++++++++++
5 files changed, 198 insertions(+), 3 deletions(-)
---
diff --git a/plugins/vala-pack/Makefile.am b/plugins/vala-pack/Makefile.am
index f83fccc..a7caeaa 100644
--- a/plugins/vala-pack/Makefile.am
+++ b/plugins/vala-pack/Makefile.am
@@ -18,6 +18,7 @@ libvala_pack_plugin_la_SOURCES = \
ide-vala-locator.vala \
ide-vala-source-file.vala \
ide-vala-symbol-resolver.vala \
+ ide-vala-symbol-tree.vala \
vala-pack-plugin.vala \
$(NULL)
diff --git a/plugins/vala-pack/ide-vala-index.vala b/plugins/vala-pack/ide-vala-index.vala
index a90b1ad..76fedf6 100644
--- a/plugins/vala-pack/ide-vala-index.vala
+++ b/plugins/vala-pack/ide-vala-index.vala
@@ -326,6 +326,41 @@ namespace Ide
return symbol;
}
+
+ public async Ide.SymbolTree? get_symbol_tree (GLib.File file,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error
+ {
+ Ide.SymbolTree? ret = null;
+
+ Ide.ThreadPool.push (Ide.ThreadPoolKind.COMPILER, () => {
+ lock (this.code_context) {
+ Vala.CodeContext.push (this.code_context);
+
+ if (!this.source_files.contains (file)) {
+ this.add_file (file);
+ this.reparse ();
+ }
+
+ var source_file = this.source_files [file];
+ if (source_file.dirty) {
+ this.reparse ();
+ }
+
+ var tree_builder = new Ide.ValaSymbolTreeVisitor ();
+ source_file.accept_children (tree_builder);
+ ret = tree_builder.build_tree ();
+
+ Vala.CodeContext.pop ();
+
+ GLib.Idle.add (this.get_symbol_tree.callback);
+ }
+ });
+
+ yield;
+
+ return ret;
+ }
}
}
diff --git a/plugins/vala-pack/ide-vala-source-file.vala b/plugins/vala-pack/ide-vala-source-file.vala
index f0eff3e..2a62294 100644
--- a/plugins/vala-pack/ide-vala-source-file.vala
+++ b/plugins/vala-pack/ide-vala-source-file.vala
@@ -45,7 +45,7 @@ namespace Ide
public class ValaSourceFile: Vala.SourceFile
{
ArrayList<Ide.Diagnostic> diagnostics;
- Ide.File file;
+ internal Ide.File file;
public ValaSourceFile (Vala.CodeContext context,
Vala.SourceFileType type,
diff --git a/plugins/vala-pack/ide-vala-symbol-resolver.vala b/plugins/vala-pack/ide-vala-symbol-resolver.vala
index 8c740ef..f498a0a 100644
--- a/plugins/vala-pack/ide-vala-symbol-resolver.vala
+++ b/plugins/vala-pack/ide-vala-symbol-resolver.vala
@@ -28,7 +28,12 @@ namespace Ide
GLib.Cancellable? cancellable)
throws GLib.Error
{
- return null;
+ var context = this.get_context ();
+ var service = (Ide.ValaService)context.get_service_typed (typeof (Ide.ValaService));
+ var index = service.index;
+ var symbol_tree = yield index.get_symbol_tree (file, cancellable);
+
+ return symbol_tree;
}
public async Ide.Symbol? lookup_symbol_async (Ide.SourceLocation location,
@@ -48,7 +53,7 @@ namespace Ide
if (symbol != null) {
var kind = Ide.SymbolKind.FUNCTION;
- var flags = Ide.SymbolFlags.SYMBOL_FLAGS_NONE;
+ var flags = Ide.SymbolFlags.NONE;
var source_reference = symbol.source_reference;
if (source_reference != null) {
diff --git a/plugins/vala-pack/ide-vala-symbol-tree.vala b/plugins/vala-pack/ide-vala-symbol-tree.vala
new file mode 100644
index 0000000..0f68ced
--- /dev/null
+++ b/plugins/vala-pack/ide-vala-symbol-tree.vala
@@ -0,0 +1,154 @@
+/* ide-vala-symbol-tree.vala
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using GLib;
+using Ide;
+using Vala;
+
+namespace Ide
+{
+ public class ValaSymbolTreeVisitor: Vala.CodeVisitor
+ {
+ HashMap<Vala.CodeNode?,ArrayList<Vala.CodeNode>> table;
+ GLib.Queue<ArrayList<Vala.CodeNode>> queue;
+
+ public ValaSymbolTreeVisitor ()
+ {
+ this.table = new HashMap<Vala.CodeNode?,ArrayList<Vala.CodeNode>> ();
+ this.queue = new GLib.Queue<ArrayList<Vala.CodeNode>> ();
+
+ var root = new ArrayList<Vala.CodeNode> ();
+ this.table [null] = root;
+ this.queue.push_head (root);
+ }
+
+ public Ide.SymbolTree? build_tree ()
+ {
+ return new Ide.ValaSymbolTree (this.table);
+ }
+
+ void visit_generic (Vala.CodeNode node)
+ {
+ var current = this.queue.peek_head ();
+ current.add (node);
+
+ var list = new ArrayList<Vala.CodeNode> ();
+ this.queue.push_head (list);
+
+ this.table [node] = list;
+
+ node.accept_children (this);
+
+ this.queue.pop_head ();
+ }
+
+ public override void visit_class (Vala.Class node) { this.visit_generic (node); }
+ public override void visit_method (Vala.Method node) { this.visit_generic (node); }
+ public override void visit_local_variable (Vala.LocalVariable node) { this.visit_generic
(node); }
+ public override void visit_interface (Vala.Interface node) { this.visit_generic (node); }
+ public override void visit_struct (Vala.Struct node) { this.visit_generic (node); }
+ public override void visit_creation_method (Vala.CreationMethod node) { this.visit_generic
(node); }
+ public override void visit_property (Vala.Property node) { this.visit_generic (node); }
+ public override void visit_property_accessor (Vala.PropertyAccessor node) {
this.visit_generic (node); }
+ public override void visit_constructor (Vala.Constructor node) { this.visit_generic (node); }
+ public override void visit_destructor (Vala.Destructor node) { this.visit_generic (node); }
+
+ public override void visit_block (Vala.Block node) { node.accept_children (this); }
+ public override void visit_source_file (Vala.SourceFile source_file) {
source_file.accept_children (this); }
+ }
+
+ public class ValaSymbolTree : GLib.Object, Ide.SymbolTree
+ {
+ HashMap<Vala.CodeNode?,ArrayList<Vala.CodeNode>> table;
+
+ public ValaSymbolTree (HashMap<Vala.CodeNode?,ArrayList<Vala.CodeNode>> table)
+ {
+ this.table = table;
+
+ debug ("Tree created with %u rows", table.size);
+ }
+
+ ArrayList<Vala.CodeNode>? find (Ide.SymbolNode? node)
+ {
+ Ide.ValaSymbolNode? symbol_node = (Ide.ValaSymbolNode)node;
+ Vala.CodeNode? key = null;
+
+ if (symbol_node != null) {
+ if (!this.table.contains (symbol_node.node))
+ return null;
+ key = symbol_node.node;
+ }
+
+ return this.table [key];
+ }
+
+ public uint get_n_children (Ide.SymbolNode? node)
+ {
+ var list = find (node);
+
+ if (list == null)
+ debug ("Failed to find child! %p", node);
+ else
+ debug ("node has %u children.", list.size);
+
+ return list != null ? list.size : 0;
+ }
+
+ public Ide.SymbolNode? get_nth_child (Ide.SymbolNode? node, uint nth)
+ {
+ var list = find (node);
+
+ if (list != null && list.size > nth)
+ return new Ide.ValaSymbolNode (list [(int)nth]);
+
+ return null;
+ }
+ }
+
+ public class ValaSymbolNode : Ide.SymbolNode
+ {
+ public Vala.CodeNode? node;
+
+ public ValaSymbolNode (Vala.CodeNode node)
+ {
+ this.node = node;
+
+ this.name = (node as Vala.Symbol).name;
+ this.kind = Ide.SymbolKind.NONE;
+ this.flags = Ide.SymbolFlags.NONE;
+
+ if (node is Vala.Method)
+ this.kind = Ide.SymbolKind.FUNCTION;
+ else if (node is Vala.Class)
+ this.kind = Ide.SymbolKind.CLASS;
+ else if (node is Vala.Struct)
+ this.kind = Ide.SymbolKind.STRUCT;
+ }
+
+ public override Ide.SourceLocation? get_location ()
+ {
+ var source_reference = this.node.source_reference;
+ var file = (source_reference.file as Ide.ValaSourceFile).file;
+
+ return new Ide.SourceLocation (file,
+ source_reference.begin.line - 1,
+ source_reference.begin.column - 1,
+ 0);
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]