[gnome-builder/wip/tingping/gjs-indexer: 2/2] gjs-symbols: Implement code indexer



commit 9534960e501eb01f98456175dd074a7d8d8c1cb4
Author: Patrick Griffis <tingping tingping se>
Date:   Mon Sep 11 22:28:15 2017 -0400

    gjs-symbols: Implement code indexer

 plugins/gjs-symbols/gjs_symbols.plugin |    2 +
 plugins/gjs-symbols/gjs_symbols.py     |   70 +++++++++++++++++++++++++++++--
 2 files changed, 67 insertions(+), 5 deletions(-)
---
diff --git a/plugins/gjs-symbols/gjs_symbols.plugin b/plugins/gjs-symbols/gjs_symbols.plugin
index e014098..7384d57 100644
--- a/plugins/gjs-symbols/gjs_symbols.plugin
+++ b/plugins/gjs-symbols/gjs_symbols.plugin
@@ -8,3 +8,5 @@ Copyright=Copyright © 2017 Patrick Griffis
 Builtin=true
 X-Symbol-Resolver-Languages=js
 X-Symbol-Resolver-Languages-Priority=0
+X-Code-Indexer-Languages=js
+X-Code-Indexer-Languages-Priority=0
diff --git a/plugins/gjs-symbols/gjs_symbols.py b/plugins/gjs-symbols/gjs_symbols.py
index 474e1bf..59a7b16 100644
--- a/plugins/gjs-symbols/gjs_symbols.py
+++ b/plugins/gjs-symbols/gjs_symbols.py
@@ -38,11 +38,14 @@ class JsSymbolNode(Ide.SymbolNode):
     def __len__(self):
         return len(self.children)
 
+    def __bool__(self):
+        return True
+
     def __getitem__(self, key):
         return self.children[key]
 
     def __iter__(self):
-        return self.children
+        return iter(self.children)
 
     def __repr__(self):
         return '<JsSymbolNode {} ({})'.format(self.props.name, self.props.kind)
@@ -169,9 +172,8 @@ class GjsSymbolProvider(Ide.Object, Ide.SymbolResolver):
     def __init__(self):
         super().__init__()
 
-    def _get_launcher(self, file_):
-        context = self.get_context()
-
+    @staticmethod
+    def _get_launcher(context, file_):
         file_path = file_.get_path()
         script = JS_SCRIPT %file_path
         unsaved_file = context.get_unsaved_files().get_unsaved_file(file_)
@@ -198,7 +200,7 @@ class GjsSymbolProvider(Ide.Object, Ide.SymbolResolver):
 
     def do_get_symbol_tree_async(self, file_, buffer_, cancellable, callback, user_data=None):
         task = Gio.Task.new(self, cancellable, callback)
-        launcher = self._get_launcher(file_)
+        launcher = self._get_launcher(self.get_context(), file_)
 
         threading.Thread(target=self._get_tree_thread, args=(task, launcher, file_),
                          name='gjs-symbols-thread').start()
@@ -247,3 +249,61 @@ class GjsSymbolProvider(Ide.Object, Ide.SymbolResolver):
         return None
 
 
+class JsCodeIndexEntries(GObject.Object, Ide.CodeIndexEntries):
+    def __init__(self, entries):
+        super().__init__()
+        self.entries = entries
+        self.entry_iter = None
+
+    def do_get_next_entry(self):
+        if self.entry_iter is None:
+            self.entry_iter = iter(self.entries)
+        try:
+            return next(self.entry_iter)
+        except StopIteration:
+            self.entry_iter = None
+            return None
+
+
+class GjsCodeIndexer(Ide.Object, Ide.CodeIndexer):
+    def __init__(self):
+        super().__init__()
+
+    def do_index_file(self, file_, build_flags, cancellable):
+        launcher = GjsSymbolProvider._get_launcher(self.get_context(), file_)
+        proc = launcher.spawn()
+        success, stdout, stderr = proc.communicate_utf8(None, None)
+
+        if not success:
+            return None
+
+        ide_file = Ide.File(file=file_, context=self.get_context())
+        try:
+            root_node = JsSymbolTree._node_from_dict(json.loads(stdout), ide_file)
+        except (json.JSONDecodeError, UnicodeDecodeError) as e:
+            raise GLib.Error('Failed to decode gjs json: {}'.format(e))
+        except (IndexError, KeyError) as e:
+            raise GLib.Error('Failed to extract information from ast: {}'.format(e))
+
+        entries = []
+        # TODO: Avoid recreating the same data
+        for node in root_node:
+            entry = Ide.CodeIndexEntry(
+                key=node.props.file.get_path() + '|' + node.props.name, # Some unique value..
+                name='f ' + node.props.name, # The Clang backend seems to hardcode these?
+                kind=node.props.kind, # Ide.SymbolKind.FUNCTION,
+                flags=node.props.flags, # | Ide.SymbolFlags.IS_DEFINITION,
+                begin_line=node.props.line,
+                begin_line_offset=node.props.col,
+            )
+            entries.append(entry)
+        return JsCodeIndexEntries(entries)
+
+    def do_generate_key_async(self, location, cancellable, callback, user_data=None):
+        print('generate key')
+        task = Gio.Task.new(self, cancellable, callback)
+        task.return_boolean(False)
+
+    def do_generate_key_finish(self, result):
+        if result.propagate_boolean():
+            return ''


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