[gnome-builder/wip/slaf/xml-symbol-resolver: 19/25] xml-pack: add diagnostics
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/slaf/xml-symbol-resolver: 19/25] xml-pack: add diagnostics
- Date: Wed, 8 Feb 2017 19:25:25 +0000 (UTC)
commit b24d9c1c3bae5d47e364bedf0f90a5b2a6453977
Author: Sebastien Lafargue <slafargue gnome org>
Date: Thu Feb 2 00:07:40 2017 +0100
xml-pack: add diagnostics
libide/diagnostics/ide-diagnostic-provider.c | 11 +-
libide/diagnostics/ide-diagnostic-provider.h | 2 +
libide/diagnostics/ide-diagnostics-manager.c | 3 +
libide/langserv/ide-langserv-diagnostic-provider.c | 1 +
plugins/clang/ide-clang-diagnostic-provider.c | 1 +
plugins/gettext/ide-gettext-diagnostic-provider.c | 1 +
.../ide-gca-diagnostic-provider.c | 1 +
plugins/xml-pack/Makefile.am | 4 +
plugins/xml-pack/ide-xml-analysis.c | 134 ++++++
plugins/xml-pack/ide-xml-analysis.h | 59 +++
plugins/xml-pack/ide-xml-diagnostic-provider.c | 139 +++++++
plugins/xml-pack/ide-xml-diagnostic-provider.h | 36 ++
plugins/xml-pack/ide-xml-sax.c | 12 +
plugins/xml-pack/ide-xml-sax.h | 5 +-
plugins/xml-pack/ide-xml-service.c | 435 ++++++++++++++------
plugins/xml-pack/ide-xml-service.h | 16 +-
plugins/xml-pack/ide-xml-symbol-resolver.c | 7 +-
plugins/xml-pack/ide-xml-tree-builder-generic.c | 6 +-
plugins/xml-pack/ide-xml-tree-builder-generic.h | 11 +-
plugins/xml-pack/ide-xml-tree-builder-ui.c | 139 ++++++-
plugins/xml-pack/ide-xml-tree-builder-ui.h | 12 +-
plugins/xml-pack/ide-xml-tree-builder.c | 37 ++-
plugins/xml-pack/ide-xml-tree-builder.h | 3 +-
plugins/xml-pack/xml-pack-plugin.c | 2 +
plugins/xml-pack/xml-pack.plugin | 2 +
25 files changed, 901 insertions(+), 178 deletions(-)
---
diff --git a/libide/diagnostics/ide-diagnostic-provider.c b/libide/diagnostics/ide-diagnostic-provider.c
index 03a4801..cf4dd7d 100644
--- a/libide/diagnostics/ide-diagnostic-provider.c
+++ b/libide/diagnostics/ide-diagnostic-provider.c
@@ -18,6 +18,7 @@
#define G_LOG_DOMAIN "ide-diagnostic-provider"
+#include "buffers/ide-buffer.h"
#include "ide-context.h"
#include "ide-debug.h"
@@ -58,9 +59,11 @@ ide_diagnostic_provider_default_init (IdeDiagnosticProviderInterface *iface)
}
+/* If the file does not match a loaded buffer, buffer is %NULL */
void
ide_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *self,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -69,9 +72,15 @@ ide_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *self,
g_return_if_fail (IDE_IS_DIAGNOSTIC_PROVIDER (self));
g_return_if_fail (IDE_IS_FILE (file));
+ g_return_if_fail (IDE_IS_BUFFER (buffer) || buffer == NULL);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- IDE_DIAGNOSTIC_PROVIDER_GET_IFACE (self)->diagnose_async (self, file, cancellable, callback, user_data);
+ IDE_DIAGNOSTIC_PROVIDER_GET_IFACE (self)->diagnose_async (self,
+ file,
+ buffer,
+ cancellable,
+ callback,
+ user_data);
IDE_EXIT;
}
diff --git a/libide/diagnostics/ide-diagnostic-provider.h b/libide/diagnostics/ide-diagnostic-provider.h
index a297618..919c765 100644
--- a/libide/diagnostics/ide-diagnostic-provider.h
+++ b/libide/diagnostics/ide-diagnostic-provider.h
@@ -35,6 +35,7 @@ struct _IdeDiagnosticProviderInterface
IdeContext *context);
void (*diagnose_async) (IdeDiagnosticProvider *self,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -46,6 +47,7 @@ struct _IdeDiagnosticProviderInterface
void ide_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *self,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/libide/diagnostics/ide-diagnostics-manager.c b/libide/diagnostics/ide-diagnostics-manager.c
index f463e5f..ab7e0d6 100644
--- a/libide/diagnostics/ide-diagnostics-manager.c
+++ b/libide/diagnostics/ide-diagnostics-manager.c
@@ -412,6 +412,7 @@ ide_diagnostics_group_diagnose_foreach (IdeExtensionSetAdapter *adapter,
IdeDiagnosticsManager *self = user_data;
IdeDiagnosticsGroup *group;
IdeContext *context;
+ g_autoptr (IdeBuffer) buffer = NULL;
g_autoptr(IdeFile) file = NULL;
IDE_ENTRY;
@@ -439,8 +440,10 @@ ide_diagnostics_group_diagnose_foreach (IdeExtensionSetAdapter *adapter,
}
#endif
+ buffer = g_weak_ref_get (&group->buffer_wr);
ide_diagnostic_provider_diagnose_async (provider,
file,
+ buffer,
NULL,
ide_diagnostics_group_diagnose_cb,
g_object_ref (self));
diff --git a/libide/langserv/ide-langserv-diagnostic-provider.c
b/libide/langserv/ide-langserv-diagnostic-provider.c
index 295c54e..a006475 100644
--- a/libide/langserv/ide-langserv-diagnostic-provider.c
+++ b/libide/langserv/ide-langserv-diagnostic-provider.c
@@ -72,6 +72,7 @@ ide_langserv_diagnostic_provider_get_diagnostics_cb (GObject *object,
static void
ide_langserv_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
diff --git a/plugins/clang/ide-clang-diagnostic-provider.c b/plugins/clang/ide-clang-diagnostic-provider.c
index 80682a0..503193a 100644
--- a/plugins/clang/ide-clang-diagnostic-provider.c
+++ b/plugins/clang/ide-clang-diagnostic-provider.c
@@ -124,6 +124,7 @@ ide_clang_diagnostic_provider_diagnose__file_find_other_cb (GObject *object
static void
ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
diff --git a/plugins/gettext/ide-gettext-diagnostic-provider.c
b/plugins/gettext/ide-gettext-diagnostic-provider.c
index e46eeec..b745a77 100644
--- a/plugins/gettext/ide-gettext-diagnostic-provider.c
+++ b/plugins/gettext/ide-gettext-diagnostic-provider.c
@@ -195,6 +195,7 @@ get_diagnostics_cb (GObject *source_object,
static void
ide_gettext_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
diff --git a/plugins/gnome-code-assistance/ide-gca-diagnostic-provider.c
b/plugins/gnome-code-assistance/ide-gca-diagnostic-provider.c
index ff36e9b..95f7384 100644
--- a/plugins/gnome-code-assistance/ide-gca-diagnostic-provider.c
+++ b/plugins/gnome-code-assistance/ide-gca-diagnostic-provider.c
@@ -404,6 +404,7 @@ cleanup:
static void
ide_gca_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
IdeFile *file,
+ IdeBuffer *buffer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
diff --git a/plugins/xml-pack/Makefile.am b/plugins/xml-pack/Makefile.am
index 78e14f9..bfda967 100644
--- a/plugins/xml-pack/Makefile.am
+++ b/plugins/xml-pack/Makefile.am
@@ -7,6 +7,10 @@ plugin_LTLIBRARIES = libxml-pack-plugin.la
dist_plugin_DATA = xml-pack.plugin
libxml_pack_plugin_la_SOURCES = \
+ ide-xml-analysis.c \
+ ide-xml-analysis.h \
+ ide-xml-diagnostic-provider.c \
+ ide-xml-diagnostic-provider.h \
ide-xml-highlighter.c \
ide-xml-highlighter.h \
ide-xml-indenter.c \
diff --git a/plugins/xml-pack/ide-xml-analysis.c b/plugins/xml-pack/ide-xml-analysis.c
new file mode 100644
index 0000000..804c564
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-analysis.c
@@ -0,0 +1,134 @@
+/* ide-xml-analysis.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-analysis.h"
+
+G_DEFINE_BOXED_TYPE (IdeXmlAnalysis, ide_xml_analysis, ide_xml_analysis_ref, ide_xml_analysis_unref)
+
+gint64
+ide_xml_analysis_get_sequence (IdeXmlAnalysis *self)
+{
+ g_return_val_if_fail (self, -1);
+
+ return self->sequence;
+}
+
+/**
+ * ide_xml_analysis_get_diagnostics:
+ * @self: A #IdeXmlAnalysis.
+ *
+ * Returns: (nullable) (transfer none): The #IdeDiagnostics contained by the analysis.
+ *
+ */
+IdeDiagnostics *
+ide_xml_analysis_get_diagnostics (IdeXmlAnalysis *self)
+{
+ g_return_val_if_fail (self, NULL);
+
+ return self->diagnostics;
+}
+
+/**
+ * ide_xml_analysis_get_diagnostics:
+ * @self: A #IdeXmlAnalysis.
+ *
+ * Returns: (nullable) (transfer none): The #IdeXmlSymbolNode root node contained by the analysis.
+ *
+ */
+IdeXmlSymbolNode *
+ide_xml_analysis_get_root_node (IdeXmlAnalysis *self)
+{
+ g_return_val_if_fail (self, NULL);
+
+ return self->root_node;
+}
+
+void
+ide_xml_analysis_set_diagnostics (IdeXmlAnalysis *self,
+ IdeDiagnostics *diagnostics)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (diagnostics != NULL);
+
+ g_clear_pointer (&self->diagnostics, ide_diagnostics_unref);
+ self->diagnostics = ide_diagnostics_ref (diagnostics);
+}
+
+void
+ide_xml_analysis_set_root_node (IdeXmlAnalysis *self,
+ IdeXmlSymbolNode *root_node)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (root_node != NULL);
+
+ g_clear_object (&self->root_node);
+ self->root_node = g_object_ref (root_node);
+}
+
+void
+ide_xml_analysis_set_sequence (IdeXmlAnalysis *self,
+ gint64 sequence)
+{
+ g_return_if_fail (self != NULL);
+
+ self->sequence = sequence;
+}
+
+IdeXmlAnalysis *
+ide_xml_analysis_new (gint64 sequence)
+{
+ IdeXmlAnalysis *self;
+
+ self = g_slice_new0 (IdeXmlAnalysis);
+ self->ref_count = 1;
+ self->sequence = sequence;
+
+ return self;
+}
+
+static void
+ide_xml_analysis_free (IdeXmlAnalysis *self)
+{
+ g_assert (self);
+ g_assert_cmpint (self->ref_count, ==, 0);
+
+ g_clear_object (&self->root_node);
+ g_clear_pointer (&self->diagnostics, ide_diagnostics_unref);
+
+ g_slice_free (IdeXmlAnalysis, self);
+}
+
+IdeXmlAnalysis *
+ide_xml_analysis_ref (IdeXmlAnalysis *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_analysis_unref (IdeXmlAnalysis *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_analysis_free (self);
+}
diff --git a/plugins/xml-pack/ide-xml-analysis.h b/plugins/xml-pack/ide-xml-analysis.h
new file mode 100644
index 0000000..ed86908
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-analysis.h
@@ -0,0 +1,59 @@
+/* ide-xml-analysis.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_ANALYSIS_H
+#define IDE_XML_ANALYSIS_H
+
+#include "diagnostics/ide-diagnostics.h"
+#include "ide-xml-symbol-node.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_XML_ANALYSIS (ide_xml_analysis_get_type())
+
+typedef struct _IdeXmlAnalysis IdeXmlAnalysis;
+
+struct _IdeXmlAnalysis
+{
+ guint ref_count;
+ IdeXmlSymbolNode *root_node;
+ IdeDiagnostics *diagnostics;
+ gint64 sequence;
+};
+
+IdeDiagnostics *ide_xml_analysis_get_diagnostics (IdeXmlAnalysis *self);
+IdeXmlSymbolNode *ide_xml_analysis_get_root_node (IdeXmlAnalysis *self);
+gint64 ide_xml_analysis_get_sequence (IdeXmlAnalysis *self);
+void ide_xml_analysis_set_diagnostics (IdeXmlAnalysis *self,
+ IdeDiagnostics *diagnostics);
+void ide_xml_analysis_set_root_node (IdeXmlAnalysis *self,
+ IdeXmlSymbolNode *root_node);
+void ide_xml_analysis_set_sequence (IdeXmlAnalysis *self,
+ gint64 sequence);
+IdeXmlAnalysis *ide_xml_analysis_new (gint64 sequence);
+IdeXmlAnalysis *ide_xml_analysis_ref (IdeXmlAnalysis *self);
+void ide_xml_analysis_unref (IdeXmlAnalysis *self);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeXmlAnalysis, ide_xml_analysis_unref)
+
+G_END_DECLS
+
+#endif /* IDE_XML_ANALYSIS_H */
+
diff --git a/plugins/xml-pack/ide-xml-diagnostic-provider.c b/plugins/xml-pack/ide-xml-diagnostic-provider.c
new file mode 100644
index 0000000..abcb11b
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-diagnostic-provider.c
@@ -0,0 +1,139 @@
+/* ide-xml-diagnostic-provider.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/>.
+ */
+
+#define G_LOG_DOMAIN "xml-diagnostic-provider"
+
+#include "ide-xml-service.h"
+
+#include "ide-xml-diagnostic-provider.h"
+
+struct _IdeXmlDiagnosticProvider
+{
+ IdeObject parent_instance;
+};
+
+static void diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (IdeXmlDiagnosticProvider, ide_xml_diagnostic_provider, IDE_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (IDE_TYPE_DIAGNOSTIC_PROVIDER, diagnostic_provider_iface_init))
+
+static void
+ide_xml_diagnostic_provider_diagnose_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeXmlService *service = (IdeXmlService *)object;
+ g_autoptr(GTask) task = user_data;
+ IdeDiagnostics *diagnostics;
+ GError *error = NULL;
+
+ IDE_ENTRY;
+
+ if (NULL == (diagnostics = ide_xml_service_get_diagnostics_finish (service, result, &error)))
+ g_task_return_error (task, error);
+ else
+ g_task_return_pointer (task,
+ ide_diagnostics_ref (diagnostics),
+ (GDestroyNotify)ide_diagnostics_unref);
+
+ IDE_EXIT;
+}
+
+static void
+ide_xml_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
+ IdeFile *file,
+ IdeBuffer *buffer,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeXmlDiagnosticProvider *self = (IdeXmlDiagnosticProvider *)provider;
+ g_autoptr(GTask) task = NULL;
+ IdeXmlService *service;
+ IdeContext *context;
+
+ IDE_ENTRY;
+
+ g_return_if_fail (IDE_IS_XML_DIAGNOSTIC_PROVIDER (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_xml_diagnostic_provider_diagnose_async);
+
+ context = ide_object_get_context (IDE_OBJECT (provider));
+ service = ide_context_get_service_typed (context, IDE_TYPE_XML_SERVICE);
+
+ ide_xml_service_get_diagnostics_async (service,
+ file,
+ buffer,
+ cancellable,
+ ide_xml_diagnostic_provider_diagnose_cb,
+ g_steal_pointer (&task));
+
+ IDE_EXIT;
+}
+
+static IdeDiagnostics *
+ide_xml_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider *provider,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+ IdeDiagnostics *ret;
+
+ IDE_ENTRY;
+
+ g_return_val_if_fail (IDE_IS_XML_DIAGNOSTIC_PROVIDER (provider), NULL);
+ g_return_val_if_fail (G_IS_TASK (task), NULL);
+
+ ret = g_task_propagate_pointer (task, error);
+
+ IDE_RETURN (ret);
+}
+
+IdeXmlDiagnosticProvider *
+ide_xml_diagnostic_provider_new (void)
+{
+ return g_object_new (IDE_TYPE_XML_DIAGNOSTIC_PROVIDER, NULL);
+}
+
+static void
+ide_xml_diagnostic_provider_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (ide_xml_diagnostic_provider_parent_class)->finalize (object);
+}
+
+static void
+ide_xml_diagnostic_provider_class_init (IdeXmlDiagnosticProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ide_xml_diagnostic_provider_finalize;
+}
+
+static void
+ide_xml_diagnostic_provider_init (IdeXmlDiagnosticProvider *self)
+{
+}
+
+static void
+diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface)
+{
+ iface->diagnose_async = ide_xml_diagnostic_provider_diagnose_async;
+ iface->diagnose_finish = ide_xml_diagnostic_provider_diagnose_finish;
+}
diff --git a/plugins/xml-pack/ide-xml-diagnostic-provider.h b/plugins/xml-pack/ide-xml-diagnostic-provider.h
new file mode 100644
index 0000000..3d65547
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-diagnostic-provider.h
@@ -0,0 +1,36 @@
+/* ide-xml-diagnostic-provider.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_DIAGNOSTIC_PROVIDER_H
+#define IDE_XML_DIAGNOSTIC_PROVIDER_H
+
+#include <glib-object.h>
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_XML_DIAGNOSTIC_PROVIDER (ide_xml_diagnostic_provider_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeXmlDiagnosticProvider, ide_xml_diagnostic_provider, IDE, XML_DIAGNOSTIC_PROVIDER,
IdeObject)
+
+IdeXmlDiagnosticProvider *ide_xml_diagnostic_provider_new (void);
+
+G_END_DECLS
+
+#endif /* IDE_XML_DIAGNOSTIC_PROVIDER_H */
+
diff --git a/plugins/xml-pack/ide-xml-sax.c b/plugins/xml-pack/ide-xml-sax.c
index 84cec95..c65163e 100644
--- a/plugins/xml-pack/ide-xml-sax.c
+++ b/plugins/xml-pack/ide-xml-sax.c
@@ -125,6 +125,18 @@ ide_xml_sax_set_callback (IdeXmlSax *self,
handler->entityDecl = callback;
break;
+ case IDE_XML_SAX_CALLBACK_TYPE_WARNING:
+ handler->warning = callback;
+ break;
+
+ case IDE_XML_SAX_CALLBACK_TYPE_ERROR:
+ handler->error = callback;
+ break;
+
+ case IDE_XML_SAX_CALLBACK_TYPE_FATAL_ERROR:
+ handler->fatalError = callback;
+ break;
+
default:
g_assert_not_reached ();
}
diff --git a/plugins/xml-pack/ide-xml-sax.h b/plugins/xml-pack/ide-xml-sax.h
index cf5bf2f..7cb7259 100644
--- a/plugins/xml-pack/ide-xml-sax.h
+++ b/plugins/xml-pack/ide-xml-sax.h
@@ -38,7 +38,10 @@ enum _IdeXmlSaxCallbackType {
IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT,
IDE_XML_SAX_CALLBACK_TYPE_END_DOCUMENT,
IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT,
- IDE_XML_SAX_CALLBACK_TYPE_ENTITY
+ IDE_XML_SAX_CALLBACK_TYPE_ENTITY,
+ IDE_XML_SAX_CALLBACK_TYPE_WARNING,
+ IDE_XML_SAX_CALLBACK_TYPE_ERROR,
+ IDE_XML_SAX_CALLBACK_TYPE_FATAL_ERROR,
};
void ide_xml_sax_clear (IdeXmlSax *self);
diff --git a/plugins/xml-pack/ide-xml-service.c b/plugins/xml-pack/ide-xml-service.c
index 140c3d2..c8654b7 100644
--- a/plugins/xml-pack/ide-xml-service.c
+++ b/plugins/xml-pack/ide-xml-service.c
@@ -23,6 +23,7 @@
#include <gtksourceview/gtksource.h>
#include <math.h>
+#include "ide-xml-analysis.h"
#include "ide-xml-tree-builder.h"
#include "ide-xml-service.h"
@@ -33,9 +34,9 @@ gboolean _ide_buffer_get_loading (IdeBuffer *self);
struct _IdeXmlService
{
- IdeObject parent_instance;
+ IdeObject parent_instance;
- EggTaskCache *trees;
+ EggTaskCache *analyses;
IdeXmlTreeBuilder *tree_builder;
GCancellable *cancellable;
};
@@ -52,18 +53,17 @@ ide_xml_service_build_tree_cb2 (GObject *object,
{
IdeXmlTreeBuilder *tree_builder = (IdeXmlTreeBuilder *)object;
g_autoptr(GTask) task = user_data;
- IdeXmlSymbolNode *root_node;
+ g_autoptr(IdeXmlAnalysis) analysis = NULL;
GError *error = NULL;
g_assert (IDE_IS_XML_TREE_BUILDER (tree_builder));
g_assert (G_IS_TASK (result));
g_assert (G_IS_TASK (task));
- root_node = ide_xml_tree_builder_build_tree_finish (tree_builder, result, &error);
- if (root_node == NULL)
+ if (NULL == (analysis = ide_xml_tree_builder_build_tree_finish (tree_builder, result, &error)))
g_task_return_error (task, error);
else
- g_task_return_pointer (task, root_node, g_object_unref);
+ g_task_return_pointer (task, g_steal_pointer (&analysis), (GDestroyNotify)ide_xml_analysis_unref);
}
static void
@@ -79,13 +79,13 @@ ide_xml_service_build_tree_cb (EggTaskCache *cache,
IDE_ENTRY;
+ g_assert (EGG_IS_TASK_CACHE (cache));
g_assert (IDE_IS_XML_SERVICE (self));
- g_assert (key != NULL);
- g_assert (IDE_IS_FILE ((IdeFile *)key));
+ g_assert (IDE_IS_FILE (ifile));
g_assert (G_IS_TASK (task));
- gfile = ide_file_get_file (ifile);
- if (!gfile || !(path = g_file_get_path (gfile)))
+ if (NULL == (gfile = ide_file_get_file (ifile)) ||
+ NULL == (path = g_file_get_path (gfile)))
{
g_task_return_new_error (task,
G_IO_ERROR,
@@ -94,7 +94,6 @@ ide_xml_service_build_tree_cb (EggTaskCache *cache,
return;
}
- printf ("tree path:%s\n", path);
ide_xml_tree_builder_build_tree_async (self->tree_builder,
gfile,
g_task_get_cancellable (task),
@@ -105,42 +104,23 @@ ide_xml_service_build_tree_cb (EggTaskCache *cache,
}
static void
-ide_xml_service_buffer_saved (IdeXmlService *self,
- IdeBuffer *buffer,
- IdeBufferManager *buffer_manager)
-{
- IDE_ENTRY;
-
- g_assert (IDE_IS_XML_SERVICE (self));
- g_assert (IDE_IS_BUFFER (buffer));
- g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
-
- printf ("buffer saved:%p\n", buffer);
-
- IDE_EXIT;
-}
-
-static void
-ide_xml_service_get_root_node_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ide_xml_service_get_analysis_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
EggTaskCache *cache = (EggTaskCache *)object;
g_autoptr(GTask) task = user_data;
- IdeXmlSymbolNode *ret;
+ g_autoptr(IdeXmlAnalysis) analysis = NULL;
GError *error = NULL;
g_assert (EGG_IS_TASK_CACHE (cache));
g_assert (G_IS_TASK (result));
g_assert (G_IS_TASK (task));
- if (!(ret = egg_task_cache_get_finish (cache, result, &error)))
+ if (NULL == (analysis = egg_task_cache_get_finish (cache, result, &error)))
g_task_return_error (task, error);
else
- {
- printf ("new tree:%p\n", ret);
- g_task_return_pointer (task, ret, g_object_unref);
- }
+ g_task_return_pointer (task, g_steal_pointer (&analysis), (GDestroyNotify)ide_xml_analysis_unref);
}
typedef struct
@@ -157,88 +137,48 @@ ide_xml_service__buffer_loaded_cb (IdeBuffer *buffer,
TaskState *state)
{
IdeXmlService *self = (IdeXmlService *)state->self;
- g_autoptr(GTask) task = state->task;
g_assert (IDE_IS_XML_SERVICE (self));
- g_assert (G_IS_TASK (task));
+ g_assert (G_IS_TASK (state->task));
g_assert (state->cancellable == NULL || G_IS_CANCELLABLE (state->cancellable));
g_assert (IDE_IS_FILE (state->ifile));
g_assert (IDE_IS_BUFFER (state->buffer));
- printf ("buffer loaded\n");
-
- egg_task_cache_get_async (self->trees,
+ egg_task_cache_get_async (self->analyses,
state->ifile,
TRUE,
state->cancellable,
- ide_xml_service_get_root_node_cb,
- g_steal_pointer (&task));
+ ide_xml_service_get_analysis_cb,
+ g_steal_pointer (&state->task));
g_object_unref (state->buffer);
g_object_unref (state->ifile);
g_slice_free (TaskState, state);
}
-/**
- * ide_xml_service_get_root_node_async:
- *
- * This function is used to asynchronously retrieve the root node for
- * a particular file.
- *
- * If the root node is up to date, then no parsing will occur and the
- * existing root node will be used.
- *
- * If the root node is out of date, then the source file(s) will be
- * parsed asynchronously.
- *
- * The xml service is meant to be used with buffers, that is,
- * by extension, loaded views.
- */
-void
-ide_xml_service_get_root_node_async (IdeXmlService *self,
- IdeFile *file,
- IdeBuffer *buffer,
- gint64 min_serial,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static void
+ide_xml_service_get_analysis_async (IdeXmlService *self,
+ IdeFile *ifile,
+ IdeBuffer *buffer,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- IdeXmlSymbolNode *cached;
g_autoptr(GTask) task = NULL;
IdeContext *context;
IdeBufferManager *manager;
GFile *gfile;
- g_return_if_fail (IDE_IS_XML_SERVICE (self));
- g_return_if_fail (IDE_IS_FILE (file));
- g_return_if_fail (IDE_IS_BUFFER (buffer));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+ g_assert (IDE_IS_XML_SERVICE (self));
+ g_assert (IDE_IS_FILE (ifile));
+ g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
task = g_task_new (self, cancellable, callback, user_data);
context = ide_object_get_context (IDE_OBJECT (self));
-
- if (min_serial == 0)
- {
- IdeUnsavedFiles *unsaved_files;
-
- unsaved_files = ide_context_get_unsaved_files (context);
- min_serial = ide_unsaved_files_get_sequence (unsaved_files);
- }
-
- /*
- * If we have a cached unit, and it is new enough, then re-use it.
- */
- if ((cached = egg_task_cache_peek (self->trees, file)) &&
- (ide_xml_symbol_node_get_serial (cached) >= min_serial))
- {
- printf ("get cached tree:%p\n", cached);
- g_task_return_pointer (task, g_object_ref (cached), g_object_unref);
- return;
- }
-
- printf ("egg_task_cache_get_async\n");
manager = ide_context_get_buffer_manager (context);
- gfile = ide_file_get_file (file);
+ gfile = ide_file_get_file (ifile);
+
if (!ide_buffer_manager_has_file (manager, gfile))
{
TaskState *state;
@@ -257,7 +197,7 @@ ide_xml_service_get_root_node_async (IdeXmlService *self,
state->self = self;
state->task = g_steal_pointer (&task);
state->cancellable = cancellable;
- state->ifile = g_object_ref (file);
+ state->ifile = g_object_ref (ifile);
state->buffer = g_object_ref (buffer);
g_signal_connect (buffer,
@@ -266,14 +206,119 @@ ide_xml_service_get_root_node_async (IdeXmlService *self,
state);
}
else
- egg_task_cache_get_async (self->trees,
- file,
+ egg_task_cache_get_async (self->analyses,
+ ifile,
TRUE,
cancellable,
- ide_xml_service_get_root_node_cb,
+ ide_xml_service_get_analysis_cb,
g_steal_pointer (&task));
}
+IdeXmlAnalysis *
+ide_xml_service_get_analysis_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 (task), NULL);
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static void
+ide_xml_service_get_root_node_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeXmlService *self = (IdeXmlService *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(IdeXmlAnalysis) analysis = NULL;
+ IdeXmlSymbolNode *root_node;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_XML_SERVICE (self));
+ g_assert (G_IS_TASK (result));
+ g_assert (G_IS_TASK (task));
+
+ if (NULL == (analysis = ide_xml_service_get_analysis_finish (self, result, &error)))
+ g_task_return_error (task, error);
+ else
+ {
+ root_node = g_object_ref (ide_xml_analysis_get_root_node (analysis));
+ g_task_return_pointer (task, root_node, g_object_unref);
+ }
+}
+
+/**
+ * ide_xml_service_get_root_node_async:
+ *
+ * This function is used to asynchronously retrieve the root node for
+ * a particular file.
+ *
+ * If the root node is up to date, then no parsing will occur and the
+ * existing root node will be used.
+ *
+ * If the root node is out of date, then the source file(s) will be
+ * parsed asynchronously.
+ *
+ * The xml service is meant to be used with buffers, that is,
+ * by extension, loaded views.
+ */
+void
+ide_xml_service_get_root_node_async (IdeXmlService *self,
+ IdeFile *ifile,
+ IdeBuffer *buffer,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ IdeXmlAnalysis *cached;
+
+ 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));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+
+ /*
+ * If we have a cached analysis with a valid root_node,
+ * and it is new enough, then re-use it.
+ */
+ if (NULL != (cached = egg_task_cache_peek (self->analyses, ifile)))
+ {
+ IdeContext *context;
+ IdeUnsavedFiles *unsaved_files;
+ IdeUnsavedFile *uf;
+ IdeXmlSymbolNode *root_node;
+ GFile *gfile;
+
+ gfile = ide_file_get_file (ifile);
+ context = ide_object_get_context (IDE_OBJECT (self));
+ unsaved_files = ide_context_get_unsaved_files (context);
+
+ if (NULL != (uf = ide_unsaved_files_get_unsaved_file (unsaved_files, gfile)) &&
+ ide_xml_analysis_get_sequence (cached) == ide_unsaved_file_get_sequence (uf))
+ {
+ root_node = g_object_ref (ide_xml_analysis_get_root_node (cached));
+ g_assert (IDE_IS_XML_SYMBOL_NODE (root_node));
+
+ g_task_return_pointer (task, root_node, g_object_unref);
+ return;
+ }
+ }
+
+ ide_xml_service_get_analysis_async (self,
+ ifile,
+ buffer,
+ cancellable,
+ ide_xml_service_get_root_node_cb,
+ g_steal_pointer (&task));
+}
+
/**
* ide_xml_service_get_root_node_finish:
*
@@ -291,6 +336,121 @@ ide_xml_service_get_root_node_finish (IdeXmlService *self,
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_get_diagnostics_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeXmlService *self = (IdeXmlService *)object;
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(IdeXmlAnalysis) analysis = NULL;
+ IdeDiagnostics *diagnostics;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_XML_SERVICE (self));
+ g_assert (G_IS_TASK (result));
+ g_assert (G_IS_TASK (task));
+
+ if (NULL == (analysis = ide_xml_service_get_analysis_finish (self, result, &error)))
+ g_task_return_error (task, error);
+ else
+ {
+ diagnostics = ide_diagnostics_ref (ide_xml_analysis_get_diagnostics (analysis));
+ g_task_return_pointer (task, diagnostics, (GDestroyNotify)ide_diagnostics_unref);
+ }
+}
+
+/**
+ * ide_xml_service_get_diagnostics_async:
+ *
+ * This function is used to asynchronously retrieve the diagnostics
+ * for a particular file.
+ *
+ * If the analysis is up to date, then no parsing will occur and the
+ * existing diagnostics will be used.
+ *
+ * If the analysis is out of date, then the source file(s) will be
+ * parsed asynchronously.
+ *
+ * The xml service is meant to be used with buffers, that is,
+ * by extension, loaded views.
+ */
+void
+ide_xml_service_get_diagnostics_async (IdeXmlService *self,
+ IdeFile *ifile,
+ IdeBuffer *buffer,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ IdeXmlAnalysis *cached;
+
+ 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);
+
+ /*
+ * If we have a cached analysis with some diagnostics,
+ * and it is new enough, then re-use it.
+ */
+ if (NULL != (cached = egg_task_cache_peek (self->analyses, ifile)))
+ {
+ IdeContext *context;
+ IdeUnsavedFiles *unsaved_files;
+ IdeUnsavedFile *uf;
+ IdeDiagnostics *diagnostics;
+ GFile *gfile;
+
+ gfile = ide_file_get_file (ifile);
+ context = ide_object_get_context (IDE_OBJECT (self));
+ unsaved_files = ide_context_get_unsaved_files (context);
+
+ if (NULL != (uf = ide_unsaved_files_get_unsaved_file (unsaved_files, gfile)) &&
+ ide_xml_analysis_get_sequence (cached) == ide_unsaved_file_get_sequence (uf))
+ {
+ diagnostics = ide_diagnostics_ref (ide_xml_analysis_get_diagnostics (cached));
+ g_assert (diagnostics != NULL);
+
+ g_task_return_pointer (task, diagnostics, (GDestroyNotify)ide_diagnostics_unref);
+ return;
+ }
+ }
+
+ ide_xml_service_get_analysis_async (self,
+ ifile,
+ buffer,
+ cancellable,
+ ide_xml_service_get_diagnostics_cb,
+ g_steal_pointer (&task));
+}
+
+/**
+ * ide_xml_service_get_diagnostics_finish:
+ *
+ * Completes an asychronous request to get the diagnostics for a given file.
+ * See ide_xml_service_get_diagnostics_async() for more information.
+ *
+ * Returns: (transfer full): An #IdeDiagnostics or %NULL on failure.
+ */
+IdeDiagnostics *
+ide_xml_service_get_diagnostics_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);
}
@@ -300,28 +460,18 @@ ide_xml_service_context_loaded (IdeService *service)
{
IdeXmlService *self = (IdeXmlService *)service;
IdeContext *context;
- IdeBufferManager *buffer_manager;
IDE_ENTRY;
g_assert (IDE_IS_XML_SERVICE (self));
context = ide_object_get_context (IDE_OBJECT (self));
- buffer_manager = ide_context_get_buffer_manager (context);
-
- g_signal_connect_object (buffer_manager,
- "buffer-saved",
- G_CALLBACK (ide_xml_service_buffer_saved),
- self,
- G_CONNECT_SWAPPED);
if (self->tree_builder == NULL)
self->tree_builder = g_object_new (IDE_TYPE_XML_TREE_BUILDER,
"context", context,
NULL);
- /* TODO: schedule caching of open views trees */
-
IDE_EXIT;
}
@@ -330,20 +480,20 @@ ide_xml_service_start (IdeService *service)
{
IdeXmlService *self = (IdeXmlService *)service;
- g_return_if_fail (IDE_IS_XML_SERVICE (self));
+ g_assert (IDE_IS_XML_SERVICE (self));
- self->trees = egg_task_cache_new ((GHashFunc)ide_file_hash,
- (GEqualFunc)ide_file_equal,
- g_object_ref,
- g_object_unref,
- g_object_ref,
- g_object_unref,
- DEFAULT_EVICTION_MSEC,
- ide_xml_service_build_tree_cb,
- self,
- NULL);
-
- egg_task_cache_set_name (self->trees, "xml trees cache");
+ self->analyses = egg_task_cache_new ((GHashFunc)ide_file_hash,
+ (GEqualFunc)ide_file_equal,
+ g_object_ref,
+ g_object_unref,
+ (GBoxedCopyFunc)ide_xml_analysis_ref,
+ (GBoxedFreeFunc)ide_xml_analysis_unref,
+ DEFAULT_EVICTION_MSEC,
+ ide_xml_service_build_tree_cb,
+ self,
+ NULL);
+
+ egg_task_cache_set_name (self->analyses, "xml analysis cache");
}
static void
@@ -351,13 +501,13 @@ ide_xml_service_stop (IdeService *service)
{
IdeXmlService *self = (IdeXmlService *)service;
- g_return_if_fail (IDE_IS_XML_SERVICE (self));
+ g_assert (IDE_IS_XML_SERVICE (self));
if (self->cancellable && !g_cancellable_is_cancelled (self->cancellable))
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
- g_clear_object (&self->trees);
+ g_clear_object (&self->analyses);
}
static void
@@ -367,10 +517,8 @@ ide_xml_service_finalize (GObject *object)
IDE_ENTRY;
- ide_xml_service_stop (IDE_SERVICE (self));
-
- if (self->tree_builder != NULL)
- g_clear_object (&self->tree_builder);
+ ide_xml_service_stop (IDE_SERVICE (self));
+ g_clear_object (&self->tree_builder);
G_OBJECT_CLASS (ide_xml_service_parent_class)->finalize (object);
@@ -418,14 +566,41 @@ _ide_xml_service_register_type (GTypeModule *module)
*/
IdeXmlSymbolNode *
ide_xml_service_get_cached_root_node (IdeXmlService *self,
- GFile *file)
+ GFile *gfile)
{
+ IdeXmlAnalysis *analysis;
IdeXmlSymbolNode *cached;
g_return_val_if_fail (IDE_IS_XML_SERVICE (self), NULL);
- g_return_val_if_fail (IDE_IS_FILE (file), NULL);
+ g_return_val_if_fail (IDE_IS_FILE (gfile), NULL);
+
+ if (NULL != (analysis = egg_task_cache_peek (self->analyses, gfile)) &&
+ NULL != (cached = ide_xml_analysis_get_root_node (analysis)))
+ return g_object_ref (cached);
+
+ return NULL;
+}
+
+/**
+ * ide_xml_service_get_cached_diagnostics:
+ *
+ * Gets the #IdeDiagnostics for the corresponding file.
+ *
+ * Returns: (transfer NULL): A #IdeDiagnostics.
+ */
+IdeDiagnostics *
+ide_xml_service_get_cached_diagnostics (IdeXmlService *self,
+ GFile *gfile)
+{
+ IdeXmlAnalysis *analysis;
+ IdeDiagnostics *cached;
+
+ g_return_val_if_fail (IDE_IS_XML_SERVICE (self), NULL);
+ g_return_val_if_fail (IDE_IS_FILE (gfile), NULL);
- cached = egg_task_cache_peek (self->trees, file);
+ if (NULL != (analysis = egg_task_cache_peek (self->analyses, gfile)) &&
+ NULL != (cached = ide_xml_analysis_get_diagnostics (analysis)))
+ return ide_diagnostics_ref (cached);
- return cached ? g_object_ref (cached) : NULL;
+ return NULL;
}
diff --git a/plugins/xml-pack/ide-xml-service.h b/plugins/xml-pack/ide-xml-service.h
index d0bdd17..1897155 100644
--- a/plugins/xml-pack/ide-xml-service.h
+++ b/plugins/xml-pack/ide-xml-service.h
@@ -30,12 +30,22 @@ 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 *file);
+ 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 *file,
+ IdeFile *ifile,
IdeBuffer *buffer,
- gint64 min_serial,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
diff --git a/plugins/xml-pack/ide-xml-symbol-resolver.c b/plugins/xml-pack/ide-xml-symbol-resolver.c
index ad375b1..40f6559 100644
--- a/plugins/xml-pack/ide-xml-symbol-resolver.c
+++ b/plugins/xml-pack/ide-xml-symbol-resolver.c
@@ -49,6 +49,7 @@ ide_xml_symbol_resolver_lookup_symbol_async (IdeSymbolResolver *resolver,
g_assert (location != NULL);
task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_source_tag (task, ide_xml_symbol_resolver_lookup_symbol_async);
g_task_return_new_error (task,
G_IO_ERROR,
@@ -78,7 +79,7 @@ ide_xml_symbol_resolver_get_symbol_tree_cb (GObject *object,
{
IdeXmlService *service = (IdeXmlService *)object;
g_autoptr(GTask) task = user_data;
- IdeXmlSymbolNode *root_node;
+ g_autoptr(IdeXmlSymbolNode) root_node = NULL;
IdeXmlSymbolTree *symbol_tree;
GError *error = NULL;
@@ -124,18 +125,16 @@ ide_xml_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver *resolver,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+ g_task_set_source_tag (task, ide_xml_symbol_resolver_get_symbol_tree_async);
ifile = g_object_new (IDE_TYPE_FILE,
"file", file,
"context", context,
NULL);
- printf ("=> ask symbol tree for:%s\n", g_file_get_path (file));
-
ide_xml_service_get_root_node_async (service,
ifile,
buffer,
- 0,
cancellable,
ide_xml_symbol_resolver_get_symbol_tree_cb,
g_object_ref (task));
diff --git a/plugins/xml-pack/ide-xml-tree-builder-generic.c b/plugins/xml-pack/ide-xml-tree-builder-generic.c
index 7ed2f72..211e3a3 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-generic.c
+++ b/plugins/xml-pack/ide-xml-tree-builder-generic.c
@@ -36,7 +36,7 @@ create_node_from_reader (XmlReader *reader)
file, line, line_offset);
}
-IdeXmlSymbolNode *
+IdeXmlAnalysis *
ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
IdeXmlSax *parser,
GFile *file,
@@ -44,7 +44,7 @@ ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
gsize size)
{
IdeXmlStack *stack;
- IdeXmlSymbolNode *root_node = NULL;
+ IdeXmlAnalysis *analysis = NULL;
IdeXmlSymbolNode *parent_node;
IdeXmlSymbolNode *current_node;
IdeXmlSymbolNode *previous_node = NULL;
@@ -111,5 +111,5 @@ ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
/* stack_destroy (stack); */
- return root_node;
+ return analysis;
}
diff --git a/plugins/xml-pack/ide-xml-tree-builder-generic.h b/plugins/xml-pack/ide-xml-tree-builder-generic.h
index 70b57c3..c30bf27 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-generic.h
+++ b/plugins/xml-pack/ide-xml-tree-builder-generic.h
@@ -21,6 +21,7 @@
#include <glib.h>
+#include "ide-xml-analysis.h"
#include "ide-xml-sax.h"
#include "ide-xml-symbol-node.h"
#include "ide-xml-tree-builder.h"
@@ -28,11 +29,11 @@
G_BEGIN_DECLS
-IdeXmlSymbolNode *ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
- IdeXmlSax *parser,
- GFile *file,
- const gchar *data,
- gsize size);
+IdeXmlAnalysis *ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
+ IdeXmlSax *parser,
+ GFile *file,
+ const gchar *data,
+ gsize size);
G_END_DECLS
diff --git a/plugins/xml-pack/ide-xml-tree-builder-ui.c b/plugins/xml-pack/ide-xml-tree-builder-ui.c
index dcf921e..32a9777 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-ui.c
+++ b/plugins/xml-pack/ide-xml-tree-builder-ui.c
@@ -35,6 +35,8 @@ typedef struct _ParserState
IdeXmlSax *parser;
IdeXmlStack *stack;
GFile *file;
+ IdeXmlAnalysis *analysis;
+ GPtrArray *diagnostics_array;
IdeXmlSymbolNode *root_node;
IdeXmlSymbolNode *parent_node;
IdeXmlSymbolNode *current_node;
@@ -45,9 +47,12 @@ typedef struct _ParserState
static void
parser_state_free (ParserState *state)
{
+ g_clear_pointer (&state->analysis, ide_xml_analysis_unref);
+ g_clear_pointer (&state->diagnostics_array, g_ptr_array_unref);
g_clear_object (&state->stack);
g_clear_object (&state->file);
g_clear_object (&state->parser);
+ g_clear_object (&state->root_node);
}
static void
@@ -58,7 +63,7 @@ state_processing (ParserState *state,
gboolean is_internal)
{
IdeXmlSymbolNode *parent_node;
- IdeXmlSymbolNode *popped_node;
+ IdeXmlSymbolNode *popped_node G_GNUC_UNUSED;
g_autofree gchar *popped_element_name = NULL;
gint line;
gint line_offset;
@@ -157,7 +162,7 @@ start_element_sax_cb (ParserState *state,
const xmlChar **attributes)
{
IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
- g_autoptr (GString) string = NULL;
+ g_autoptr(GString) string = NULL;
g_autofree gchar *label = NULL;
const gchar *value = NULL;
IdeXmlSymbolNode *node = NULL;
@@ -328,6 +333,97 @@ end_element_sax_cb (ParserState *state,
state_processing (state, (const gchar *)name, NULL, IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT, FALSE);
}
+static IdeDiagnostic *
+create_diagnostic (ParserState *state,
+ const gchar *msg,
+ IdeDiagnosticSeverity severity)
+{
+ IdeContext *context;
+ IdeDiagnostic *diagnostic;
+ g_autoptr(IdeSourceLocation) loc = NULL;
+ g_autoptr(IdeFile) ifile = NULL;
+ gint line;
+ gint line_offset;
+
+ context = ide_object_get_context (IDE_OBJECT (state->self));
+
+ ide_xml_sax_get_position (state->parser, &line, &line_offset);
+ ifile = ide_file_new (context, state->file);
+ loc = ide_source_location_new (ifile,
+ line - 1,
+ line_offset - 1,
+ 0);
+
+ diagnostic = ide_diagnostic_new (severity, msg, loc);
+
+ return diagnostic;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static void
+warning_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_WARNING);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+static void
+error_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_ERROR);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+static void
+fatal_error_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_FATAL);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+#pragma GCC diagnostic pop
+
static void
characters_sax_cb (ParserState *state,
const xmlChar *name,
@@ -375,7 +471,7 @@ node_post_processing_collect_style_classes (IdeXmlTreeBuilder *self,
IdeXmlSymbolNode *node)
{
IdeXmlSymbolNode *child;
- g_autoptr (GString) label = NULL;
+ g_autoptr(GString) label = NULL;
gint n_children;
g_assert (IDE_IS_XML_SYMBOL_NODE (node));
@@ -407,14 +503,17 @@ node_post_processing_add_label (IdeXmlTreeBuilder *self,
IdeXmlSymbolNode *node)
{
const gchar *value;
- g_autoptr (GString) name = NULL;
+ g_autoptr(GString) name = NULL;
g_autofree gchar *label = NULL;
g_assert (IDE_IS_XML_SYMBOL_NODE (node));
if (NULL != (value = get_menu_attribute_value (node, "label")))
{
- name = g_string_new (NULL);
+ g_object_get (node, "name", &label, NULL);
+ name = g_string_new (label);
+ g_free (label);
+
label = ide_xml_tree_builder_get_color_tag (self, "label", COLOR_TAG_LABEL, TRUE, TRUE, TRUE);
g_string_append (name, label);
@@ -452,16 +551,16 @@ ide_xml_tree_builder_post_processing (IdeXmlTreeBuilder *self,
if (ide_str_equal0 (element_name, "style"))
node_post_processing_collect_style_classes (self, node);
- else if (ide_str_equal0 (element_name, "item"))
- node_post_processing_add_label (self, node);
- else if (ide_str_equal0 (element_name, "submenu"))
+ else if (ide_str_equal0 (element_name, "item") ||
+ ide_str_equal0 (element_name, "submenu") ||
+ ide_str_equal0 (element_name, "section"))
node_post_processing_add_label (self, node);
}
return TRUE;
}
-IdeXmlSymbolNode *
+IdeXmlAnalysis *
ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
IdeXmlSax *parser,
GFile *file,
@@ -469,7 +568,8 @@ ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
gsize length)
{
ParserState *state;
- IdeXmlSymbolNode *root_node;
+ IdeXmlAnalysis *analysis;
+ g_autoptr(IdeDiagnostics) diagnostics = NULL;
g_autofree gchar *uri = NULL;
g_return_val_if_fail (IDE_IS_XML_SAX (parser), NULL);
@@ -482,6 +582,7 @@ ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
state->parser = g_object_ref (parser);
state->stack = ide_xml_stack_new ();
state->file = g_object_ref (file);
+ state->diagnostics_array = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_diagnostic_unref);
state->build_state = BUILD_STATE_NORMAL;
ide_xml_sax_clear (parser);
@@ -489,16 +590,26 @@ ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT, end_element_sax_cb);
ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_CHAR, characters_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_WARNING, warning_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_ERROR, error_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_FATAL_ERROR, fatal_error_sax_cb);
+
+ state->analysis = ide_xml_analysis_new (-1);
state->root_node = ide_xml_symbol_node_new ("root", NULL, "root", IDE_SYMBOL_NONE, NULL, 0, 0);
+ ide_xml_analysis_set_root_node (state->analysis, state->root_node);
+
state->parent_node = state->root_node;
ide_xml_stack_push (state->stack, "root", state->root_node, NULL, 0);
uri = g_file_get_uri (file);
ide_xml_sax_parse (parser, data, length, uri, state);
- root_node = state->root_node;
- parser_state_free (state);
+ ide_xml_tree_builder_post_processing (self, state->root_node);
- ide_xml_tree_builder_post_processing (self, root_node);
- return root_node;
+ analysis = g_steal_pointer (&state->analysis);
+ diagnostics = ide_diagnostics_new (g_steal_pointer (&state->diagnostics_array));
+ ide_xml_analysis_set_diagnostics (analysis, diagnostics);
+
+ parser_state_free (state);
+ return analysis;
}
diff --git a/plugins/xml-pack/ide-xml-tree-builder-ui.h b/plugins/xml-pack/ide-xml-tree-builder-ui.h
index 1bb71c2..b570f5b 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-ui.h
+++ b/plugins/xml-pack/ide-xml-tree-builder-ui.h
@@ -20,7 +20,9 @@
#define IDE_XML_TREE_BUILDER_UI_H
#include <glib.h>
+#include <ide.h>
+#include "ide-xml-analysis.h"
#include "ide-xml-sax.h"
#include "ide-xml-symbol-node.h"
#include "ide-xml-tree-builder.h"
@@ -28,11 +30,11 @@
G_BEGIN_DECLS
-IdeXmlSymbolNode *ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
- IdeXmlSax *parser,
- GFile *file,
- const gchar *data,
- gsize length);
+IdeXmlAnalysis *ide_xml_tree_builder_ui_create (IdeXmlTreeBuilder *self,
+ IdeXmlSax *parser,
+ GFile *file,
+ const gchar *data,
+ gsize length);
G_END_DECLS
diff --git a/plugins/xml-pack/ide-xml-tree-builder.c b/plugins/xml-pack/ide-xml-tree-builder.c
index dd8aedc..78d90d5 100644
--- a/plugins/xml-pack/ide-xml-tree-builder.c
+++ b/plugins/xml-pack/ide-xml-tree-builder.c
@@ -67,6 +67,7 @@ typedef struct{
IdeXmlSax *parser;
GBytes *content;
GFile *file;
+ gint64 sequence;
} BuilderState;
static void
@@ -81,11 +82,15 @@ G_DEFINE_TYPE (IdeXmlTreeBuilder, ide_xml_tree_builder, IDE_TYPE_OBJECT)
static GBytes *
ide_xml_tree_builder_get_file_content (IdeXmlTreeBuilder *self,
- GFile *file)
+ GFile *file,
+ gint64 *sequence)
{
IdeContext *context;
IdeBufferManager *manager;
+ IdeUnsavedFiles *unsaved_files;
+ IdeUnsavedFile *uf;
IdeBuffer *buffer;
+ gint64 sequence_tmp = -1;
GBytes *content = NULL;
g_assert (IDE_IS_XML_TREE_BUILDER (self));
@@ -94,10 +99,17 @@ ide_xml_tree_builder_get_file_content (IdeXmlTreeBuilder *self,
context = ide_object_get_context (IDE_OBJECT (self));
manager = ide_context_get_buffer_manager (context);
- printf ("found buffer:%p\n", ide_buffer_manager_find_buffer (manager, file));
-
if (NULL != (buffer = ide_buffer_manager_find_buffer (manager, file)))
- content = ide_buffer_get_content (buffer);
+ {
+ content = ide_buffer_get_content (buffer);
+
+ unsaved_files = ide_context_get_unsaved_files (context);
+ if (NULL != (uf = ide_unsaved_files_get_unsaved_file (unsaved_files, file)))
+ sequence_tmp = ide_unsaved_file_get_sequence (uf);
+ }
+
+ if (sequence != NULL)
+ *sequence = sequence_tmp;
return content;
}
@@ -135,7 +147,7 @@ build_tree_worker (GTask *task,
{
IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)source_object;
BuilderState *state = (BuilderState *)task_data;
- IdeXmlSymbolNode *root_node = NULL;
+ IdeXmlAnalysis *analysis = NULL;
const gchar *data;
gsize size;
@@ -147,11 +159,11 @@ build_tree_worker (GTask *task,
data = g_bytes_get_data (state->content, &size);
if (ide_xml_tree_builder_file_is_ui (state->file, data, size))
- root_node = ide_xml_tree_builder_ui_create (self, state->parser, state->file, data, size);
+ analysis = ide_xml_tree_builder_ui_create (self, state->parser, state->file, data, size);
else
- root_node = ide_xml_tree_builder_generic_create (self, state->parser, state->file, data, size);
+ analysis = ide_xml_tree_builder_generic_create (self, state->parser, state->file, data, size);
- if (root_node == NULL)
+ if (analysis == NULL)
{
g_task_return_new_error (task,
G_IO_ERROR,
@@ -160,7 +172,8 @@ build_tree_worker (GTask *task,
return;
}
- g_task_return_pointer (task, root_node, g_object_unref);
+ ide_xml_analysis_set_sequence (analysis, state->sequence);
+ g_task_return_pointer (task, analysis, (GDestroyNotify)ide_xml_analysis_unref);
}
void
@@ -173,6 +186,7 @@ ide_xml_tree_builder_build_tree_async (IdeXmlTreeBuilder *self,
g_autoptr(GTask) task = NULL;
BuilderState *state;
GBytes *content = NULL;
+ gint64 sequence;
g_return_if_fail (IDE_IS_XML_TREE_BUILDER (self));
g_return_if_fail (G_IS_FILE (file));
@@ -181,7 +195,7 @@ ide_xml_tree_builder_build_tree_async (IdeXmlTreeBuilder *self,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, ide_xml_tree_builder_build_tree_async);
- if (NULL == (content = ide_xml_tree_builder_get_file_content (self, file)))
+ if (NULL == (content = ide_xml_tree_builder_get_file_content (self, file, &sequence)))
{
g_task_return_new_error (task,
G_IO_ERROR,
@@ -194,12 +208,13 @@ ide_xml_tree_builder_build_tree_async (IdeXmlTreeBuilder *self,
state->parser = ide_xml_sax_new ();
state->content = content;
state->file = g_object_ref (file);
+ state->sequence = sequence;
g_task_set_task_data (task, state, (GDestroyNotify)builder_state_free);
g_task_run_in_thread (task, build_tree_worker);
}
-IdeXmlSymbolNode *
+IdeXmlAnalysis *
ide_xml_tree_builder_build_tree_finish (IdeXmlTreeBuilder *self,
GAsyncResult *result,
GError **error)
diff --git a/plugins/xml-pack/ide-xml-tree-builder.h b/plugins/xml-pack/ide-xml-tree-builder.h
index 3a968d0..d903dab 100644
--- a/plugins/xml-pack/ide-xml-tree-builder.h
+++ b/plugins/xml-pack/ide-xml-tree-builder.h
@@ -19,6 +19,7 @@
#ifndef IDE_XML_TREE_BUILDER_H
#define IDE_XML_TREE_BUILDER_H
+#include "ide-xml-analysis.h"
#include "ide-xml-symbol-node.h"
#include <glib-object.h>
@@ -46,7 +47,7 @@ void ide_xml_tree_builder_build_tree_async (IdeXmlTreeBuil
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-IdeXmlSymbolNode *ide_xml_tree_builder_build_tree_finish (IdeXmlTreeBuilder *self,
+IdeXmlAnalysis *ide_xml_tree_builder_build_tree_finish (IdeXmlTreeBuilder *self,
GAsyncResult *result,
GError **error);
gchar *ide_xml_tree_builder_get_color_tag (IdeXmlTreeBuilder *self,
diff --git a/plugins/xml-pack/xml-pack-plugin.c b/plugins/xml-pack/xml-pack-plugin.c
index 2732265..8d69507 100644
--- a/plugins/xml-pack/xml-pack-plugin.c
+++ b/plugins/xml-pack/xml-pack-plugin.c
@@ -18,6 +18,7 @@
#include <libpeas/peas.h>
+#include "ide-xml-diagnostic-provider.h"
#include "ide-xml-highlighter.h"
#include "ide-xml-indenter.h"
#include "ide-xml-service.h"
@@ -36,6 +37,7 @@ peas_register_types (PeasObjectModule *module)
_ide_xml_symbol_resolver_register_type (G_TYPE_MODULE (module));
_ide_xml_service_register_type (G_TYPE_MODULE (module));
+ peas_object_module_register_extension_type (module, IDE_TYPE_DIAGNOSTIC_PROVIDER,
IDE_TYPE_XML_DIAGNOSTIC_PROVIDER);
peas_object_module_register_extension_type (module, IDE_TYPE_HIGHLIGHTER, IDE_TYPE_XML_HIGHLIGHTER);
peas_object_module_register_extension_type (module, IDE_TYPE_INDENTER, IDE_TYPE_XML_INDENTER);
peas_object_module_register_extension_type (module, IDE_TYPE_SYMBOL_RESOLVER,
IDE_TYPE_XML_SYMBOL_RESOLVER);
diff --git a/plugins/xml-pack/xml-pack.plugin b/plugins/xml-pack/xml-pack.plugin
index f1b03f4..20a6d9b 100644
--- a/plugins/xml-pack/xml-pack.plugin
+++ b/plugins/xml-pack/xml-pack.plugin
@@ -11,3 +11,5 @@ X-Symbol-Resolver-Languages=xml,html
X-Symbol-Resolver-Languages-Priority=0
X-Highlighter-Languages=xml,html
X-Highlighter-Languages-Priority=0
+X-Diagnostic-Provider-Languages=xml,html
+X-Diagnostic-Provider-Languages-Priority=0
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]