[gnome-builder/wip/slaf/xml-pack: 551/572] xml-pack: get location infos from cursor



commit 0d5923b5d669d7c4903711632e87acbb77ec462c
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Sun Apr 2 23:03:23 2017 +0200

    xml-pack: get location infos from cursor

 plugins/xml-pack/Makefile.am        |    2 +
 plugins/xml-pack/ide-xml-parser.c   |   24 ++++++---
 plugins/xml-pack/ide-xml-position.c |   75 +++++++++++++++++++++++++
 plugins/xml-pack/ide-xml-position.h |   58 ++++++++++++++++++++
 plugins/xml-pack/ide-xml-service.c  |  102 +++++++++++++++++++++++++++++++++++
 plugins/xml-pack/ide-xml-service.h  |   58 ++++++++++++--------
 6 files changed, 288 insertions(+), 31 deletions(-)
---
diff --git a/plugins/xml-pack/Makefile.am b/plugins/xml-pack/Makefile.am
index 6c22e0a..0f6aca1 100644
--- a/plugins/xml-pack/Makefile.am
+++ b/plugins/xml-pack/Makefile.am
@@ -22,6 +22,8 @@ libxml_pack_plugin_la_SOURCES =              \
        ide-xml-parser-generic.h             \
        ide-xml-parser-ui.c                  \
        ide-xml-parser-ui.h                  \
+       ide-xml-position.c                   \
+       ide-xml-position.h                   \
        ide-xml-sax.c                        \
        ide-xml-sax.h                        \
        ide-xml-service.c                    \
diff --git a/plugins/xml-pack/ide-xml-parser.c b/plugins/xml-pack/ide-xml-parser.c
index 74ffd3c..6611c59 100644
--- a/plugins/xml-pack/ide-xml-parser.c
+++ b/plugins/xml-pack/ide-xml-parser.c
@@ -187,16 +187,24 @@ ide_xml_parser_state_processing (IdeXmlParser          *self,
         }
       else if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT)
         {
-          /* TODO: compare current with popped */
-          if (ide_xml_stack_is_empty (self->stack))
+          while (TRUE)
             {
-              g_warning ("Xml nodes stack empty\n");
-              return;
-            }
+              if (ide_xml_stack_is_empty (self->stack))
+                {
+                  g_warning ("Xml nodes stack empty\n");
+                  return;
+                }
 
-          popped_node = ide_xml_stack_pop (self->stack, &popped_element_name, &parent_node, &depth);
-          state->parent_node = parent_node;
-          g_assert (state->parent_node != NULL);
+              popped_node = ide_xml_stack_pop (self->stack, &popped_element_name, &parent_node, &depth);
+              if (ide_str_equal0 (popped_element_name, element_name))
+                {
+                  ide_xml_symbol_node_set_end_tag_location (popped_node, line, line_offset, size);
+                  state->parent_node = parent_node;
+                  g_assert (state->parent_node != NULL);
+
+                  break;
+                }
+            }
         }
 
       state->current_depth = depth;
diff --git a/plugins/xml-pack/ide-xml-position.c b/plugins/xml-pack/ide-xml-position.c
new file mode 100644
index 0000000..55d1fe9
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-position.c
@@ -0,0 +1,75 @@
+/* ide-xml-position.c
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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/>.
+ */
+
+#include "ide-xml-position.h"
+
+G_DEFINE_BOXED_TYPE (IdeXmlPosition, ide_xml_position, ide_xml_position_ref, ide_xml_position_unref)
+
+IdeXmlPosition *
+ide_xml_position_new (void)
+{
+  IdeXmlPosition *self;
+
+  self = g_slice_new0 (IdeXmlPosition);
+  self->ref_count = 1;
+
+  return self;
+}
+
+IdeXmlPosition *
+ide_xml_position_copy (IdeXmlPosition *self)
+{
+  IdeXmlPosition *copy;
+
+  g_return_val_if_fail (self, NULL);
+  g_return_val_if_fail (self->ref_count, NULL);
+
+  copy = ide_xml_position_new ();
+
+  return copy;
+}
+
+static void
+ide_xml_position_free (IdeXmlPosition *self)
+{
+  g_assert (self);
+  g_assert_cmpint (self->ref_count, ==, 0);
+
+  g_slice_free (IdeXmlPosition, self);
+}
+
+IdeXmlPosition *
+ide_xml_position_ref (IdeXmlPosition *self)
+{
+  g_return_val_if_fail (self, NULL);
+  g_return_val_if_fail (self->ref_count, NULL);
+
+  g_atomic_int_inc (&self->ref_count);
+
+  return self;
+}
+
+void
+ide_xml_position_unref (IdeXmlPosition *self)
+{
+  g_return_if_fail (self);
+  g_return_if_fail (self->ref_count);
+
+  if (g_atomic_int_dec_and_test (&self->ref_count))
+    ide_xml_position_free (self);
+}
diff --git a/plugins/xml-pack/ide-xml-position.h b/plugins/xml-pack/ide-xml-position.h
new file mode 100644
index 0000000..441256b
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-position.h
@@ -0,0 +1,58 @@
+/* ide-xml-position.h
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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/>.
+ */
+
+#ifndef IDE_XML_POSITION_H
+#define IDE_XML_POSITION_H
+
+#include <glib-object.h>
+
+#include "ide-xml-symbol-node.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_XML_POSITION (ide_xml_position_get_type())
+
+typedef enum
+{
+  IDE_XML_POSITION_KIND_IN_START_TAG,
+  IDE_XML_POSITION_KIND_IN_END_TAG,
+  IDE_XML_POSITION_KIND_IN_CONTENT
+} IdeXmlPositionKind;
+
+typedef struct _IdeXmlPosition IdeXmlPosition;
+
+struct _IdeXmlPosition
+{
+  IdeXmlSymbolNode   *root_node;
+  IdeXmlSymbolNode   *node;
+  IdeXmlSymbolNode   *parent_node;
+  IdeXmlPositionKind  kind;
+
+  guint               ref_count;
+};
+
+IdeXmlPosition     *ide_xml_position_new   (void);
+IdeXmlPosition     *ide_xml_position_copy  (IdeXmlPosition *self);
+IdeXmlPosition     *ide_xml_position_ref   (IdeXmlPosition *self);
+void                ide_xml_position_unref (IdeXmlPosition *self);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeXmlPosition, ide_xml_position_unref)
+
+G_END_DECLS
+
+#endif /* IDE_XML_POSITION_H */
diff --git a/plugins/xml-pack/ide-xml-service.c b/plugins/xml-pack/ide-xml-service.c
index 02d6b57..3099f12 100644
--- a/plugins/xml-pack/ide-xml-service.c
+++ b/plugins/xml-pack/ide-xml-service.c
@@ -528,6 +528,108 @@ ide_xml_service_context_loaded (IdeService *service)
   IDE_EXIT;
 }
 
+typedef struct
+{
+  GTask         *task;
+  GCancellable  *cancellable;
+  IdeFile       *ifile;
+  IdeBuffer     *buffer;
+  gint           line;
+  gint           line_offset;
+} PositionState;
+
+static void
+position_state_free (PositionState *state)
+{
+  g_assert (state != NULL);
+
+  g_object_unref (state->ifile);
+  g_object_unref (state->buffer);
+}
+
+static void
+ide_xml_service_get_position_from_cursor_cb (GObject      *object,
+                                             GAsyncResult *result,
+                                             gpointer      user_data)
+{
+  IdeXmlService *service = (IdeXmlService *)object;
+  PositionState *state = (PositionState *)user_data;
+  g_autoptr(GTask) task = state->task;
+  g_autoptr(IdeXmlSymbolNode) root_node = NULL;
+  IdeXmlPosition *position;
+  GError *error = NULL;
+
+  IDE_ENTRY;
+
+  g_assert (G_IS_TASK (task));
+  g_assert (IDE_IS_XML_SERVICE (service));
+
+  root_node = ide_xml_service_get_root_node_finish (service, result, &error);
+  if (root_node != NULL)
+    {
+      /* find the correspoonding node */
+      g_task_return_pointer (task, position, g_object_unref);
+    }
+  else
+    g_task_return_error (task, error);
+
+  position_state_free (state);
+
+  IDE_EXIT;
+}
+
+void
+ide_xml_service_get_position_from_cursor_async (IdeXmlService       *self,
+                                                IdeFile             *ifile,
+                                                IdeBuffer           *buffer,
+                                                gint                 line,
+                                                gint                 line_offset,
+                                                GCancellable        *cancellable,
+                                                GAsyncReadyCallback  callback,
+                                                gpointer             user_data)
+{
+  PositionState *state;
+  g_autoptr(GTask) task = NULL;
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_XML_SERVICE (self));
+  g_return_if_fail (IDE_IS_FILE (ifile));
+  g_return_if_fail (IDE_IS_BUFFER (buffer) || buffer == NULL);
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  state = g_slice_new0 (PositionState);
+  state->task = g_steal_pointer (&task);
+  state->cancellable = cancellable;
+  state->ifile = g_object_ref (ifile);
+  state->buffer = g_object_ref (buffer);
+
+  ide_xml_service_get_root_node_async (self,
+                                       ifile,
+                                       buffer,
+                                       cancellable,
+                                       ide_xml_service_get_position_from_cursor_cb,
+                                       g_object_ref (task));
+
+  IDE_EXIT;
+}
+
+IdeXmlPosition *
+ide_xml_service_get_position_from_cursor_finish (IdeXmlService  *self,
+                                                 GAsyncResult   *result,
+                                                 GError        **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_return_val_if_fail (IDE_IS_XML_SERVICE (self), NULL);
+  g_return_val_if_fail (G_IS_TASK (result), NULL);
+  g_return_val_if_fail (error != NULL, NULL);
+
+  return g_task_propagate_pointer (task, error);
+}
+
 static void
 ide_xml_service_start (IdeService *service)
 {
diff --git a/plugins/xml-pack/ide-xml-service.h b/plugins/xml-pack/ide-xml-service.h
index 19309ba..0939c7b 100644
--- a/plugins/xml-pack/ide-xml-service.h
+++ b/plugins/xml-pack/ide-xml-service.h
@@ -22,6 +22,7 @@
 #include <gtksourceview/gtksource.h>
 #include <egg-task-cache.h>
 
+#include "ide-xml-position.h"
 #include "ide-xml-symbol-node.h"
 #include <ide.h>
 
@@ -31,29 +32,40 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeXmlService, ide_xml_service, IDE, XML_SERVICE, IdeObject)
 
-IdeDiagnostics     *ide_xml_service_get_cached_diagnostics    (IdeXmlService        *self,
-                                                               GFile                *gfile);
-IdeXmlSymbolNode   *ide_xml_service_get_cached_root_node      (IdeXmlService        *self,
-                                                               GFile                *gfile);
-IdeDiagnostics     *ide_xml_service_get_diagnostics_finish    (IdeXmlService        *self,
-                                                               GAsyncResult         *result,
-                                                               GError              **error);
-void                ide_xml_service_get_diagnostics_async     (IdeXmlService        *self,
-                                                               IdeFile              *ifile,
-                                                               IdeBuffer            *buffer,
-                                                               GCancellable         *cancellable,
-                                                               GAsyncReadyCallback   callback,
-                                                               gpointer              user_data);
-void                ide_xml_service_get_root_node_async       (IdeXmlService        *self,
-                                                               IdeFile              *ifile,
-                                                               IdeBuffer            *buffer,
-                                                               GCancellable         *cancellable,
-                                                               GAsyncReadyCallback   callback,
-                                                               gpointer              user_data);
-IdeXmlSymbolNode   *ide_xml_service_get_root_node_finish      (IdeXmlService        *self,
-                                                               GAsyncResult         *result,
-                                                               GError              **error);
-EggTaskCache       *ide_xml_service_get_schemas_cache         (IdeXmlService        *self);
+IdeDiagnostics     *ide_xml_service_get_cached_diagnostics             (IdeXmlService        *self,
+                                                                        GFile                *gfile);
+IdeXmlSymbolNode   *ide_xml_service_get_cached_root_node               (IdeXmlService        *self,
+                                                                        GFile                *gfile);
+IdeDiagnostics     *ide_xml_service_get_diagnostics_finish             (IdeXmlService        *self,
+                                                                        GAsyncResult         *result,
+                                                                        GError              **error);
+void                ide_xml_service_get_diagnostics_async              (IdeXmlService        *self,
+                                                                        IdeFile              *ifile,
+                                                                        IdeBuffer            *buffer,
+                                                                        GCancellable         *cancellable,
+                                                                        GAsyncReadyCallback   callback,
+                                                                        gpointer              user_data);
+void                ide_xml_service_get_position_from_cursor_async     (IdeXmlService        *self,
+                                                                        IdeFile              *ifile,
+                                                                        IdeBuffer            *buffer,
+                                                                        gint                  line,
+                                                                        gint                  line_offset,
+                                                                        GCancellable         *cancellable,
+                                                                        GAsyncReadyCallback   callback,
+                                                                        gpointer              user_data);
+IdeXmlPosition     *ide_xml_service_get_position_from_cursor_finish    (IdeXmlService        *self,
+                                                                        GAsyncResult         *result,
+                                                                        GError              **error);
+void                ide_xml_service_get_root_node_async                (IdeXmlService        *self,
+                                                                        IdeFile              *ifile,
+                                                                        IdeBuffer            *buffer,
+                                                                        GCancellable         *cancellable,
+                                                                        GAsyncReadyCallback   callback,
+                                                                        gpointer              user_data);
+IdeXmlSymbolNode   *ide_xml_service_get_root_node_finish               (IdeXmlService        *self,
+                                                                        GAsyncResult         *result,
+                                                                        GError              **error);
+EggTaskCache       *ide_xml_service_get_schemas_cache                  (IdeXmlService        *self);
 
 G_END_DECLS
 


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