[gnome-builder/wip/slaf/xml-pack: 34/56] xml-pack: parse schemas in the service



commit 6dff271ad3cd37f5623129649140004c35bfbf25
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Mon May 22 19:14:18 2017 +0200

    xml-pack: parse schemas in the service
    
    Lot of refactoring here because in the process
    we move SchemaEntry to IdeXmlSchemaCacheEntry
    to unify the schema holder object.

 plugins/xml-pack/ide-xml-analysis.c                |   12 +-
 plugins/xml-pack/ide-xml-analysis.h                |    6 +-
 plugins/xml-pack/ide-xml-parser-private.h          |    2 +-
 plugins/xml-pack/ide-xml-parser.c                  |   45 +++++-----
 plugins/xml-pack/ide-xml-schema-cache-entry.c      |   10 ++
 plugins/xml-pack/ide-xml-schema-cache-entry.h      |   34 ++++++-
 plugins/xml-pack/ide-xml-service.c                 |   99 ++++++++++++++++++--
 .../xml-pack/ide-xml-tree-builder-utils-private.h  |    3 +-
 plugins/xml-pack/ide-xml-tree-builder-utils.c      |    2 +-
 plugins/xml-pack/ide-xml-tree-builder.c            |   67 ++++++++------
 plugins/xml-pack/ide-xml-validator.c               |   32 +++---
 plugins/xml-pack/ide-xml-validator.h               |   26 +----
 12 files changed, 225 insertions(+), 113 deletions(-)
---
diff --git a/plugins/xml-pack/ide-xml-analysis.c b/plugins/xml-pack/ide-xml-analysis.c
index 25b14cd..2440af5 100644
--- a/plugins/xml-pack/ide-xml-analysis.c
+++ b/plugins/xml-pack/ide-xml-analysis.c
@@ -59,12 +59,12 @@ ide_xml_analysis_get_root_node (IdeXmlAnalysis *self)
 
 /**
  * ide_xml_analysis_get_schemas:
- * @self: A #GArray.
+ * @self: A #GPtrArray.
  *
- * Returns: (nullable) (transfer none): The schemas entries #GArray contained by the analysis.
+ * Returns: (nullable) (transfer none): The schemas entries #GPtrArray contained by the analysis.
  *
  */
-GArray *
+GPtrArray *
 ide_xml_analysis_get_schemas (IdeXmlAnalysis *self)
 {
   g_return_val_if_fail (self, NULL);
@@ -96,14 +96,14 @@ ide_xml_analysis_set_root_node (IdeXmlAnalysis   *self,
 
 void
 ide_xml_analysis_set_schemas (IdeXmlAnalysis *self,
-                              GArray         *schemas)
+                              GPtrArray      *schemas)
 {
   g_return_if_fail (self != NULL);
 
-  g_clear_pointer (&self->schemas, g_array_unref);
+  g_clear_pointer (&self->schemas, g_ptr_array_unref);
 
   if (schemas != NULL)
-    self->schemas = g_array_ref (schemas);
+    self->schemas = g_ptr_array_ref (schemas);
 }
 
 void
diff --git a/plugins/xml-pack/ide-xml-analysis.h b/plugins/xml-pack/ide-xml-analysis.h
index a306ccc..2d74ed4 100644
--- a/plugins/xml-pack/ide-xml-analysis.h
+++ b/plugins/xml-pack/ide-xml-analysis.h
@@ -35,14 +35,14 @@ struct _IdeXmlAnalysis
   guint             ref_count;
   IdeXmlSymbolNode *root_node;
   IdeDiagnostics   *diagnostics;
-  GArray           *schemas;
+  GPtrArray        *schemas;       // array of IdeXmlSchemaCacheEntry
   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);
-GArray             *ide_xml_analysis_get_schemas         (IdeXmlAnalysis   *self);
+GPtrArray          *ide_xml_analysis_get_schemas         (IdeXmlAnalysis   *self);
 void                ide_xml_analysis_set_diagnostics     (IdeXmlAnalysis   *self,
                                                           IdeDiagnostics   *diagnostics);
 void                ide_xml_analysis_set_root_node       (IdeXmlAnalysis   *self,
@@ -50,7 +50,7 @@ void                ide_xml_analysis_set_root_node       (IdeXmlAnalysis   *self
 void                ide_xml_analysis_set_sequence        (IdeXmlAnalysis   *self,
                                                           gint64            sequence);
 void                ide_xml_analysis_set_schemas         (IdeXmlAnalysis   *self,
-                                                          GArray           *schemas);
+                                                          GPtrArray        *schemas);
 IdeXmlAnalysis     *ide_xml_analysis_new                 (gint64            sequence);
 IdeXmlAnalysis     *ide_xml_analysis_ref                 (IdeXmlAnalysis   *self);
 void                ide_xml_analysis_unref               (IdeXmlAnalysis   *self);
diff --git a/plugins/xml-pack/ide-xml-parser-private.h b/plugins/xml-pack/ide-xml-parser-private.h
index f6ead64..d93eadb 100644
--- a/plugins/xml-pack/ide-xml-parser-private.h
+++ b/plugins/xml-pack/ide-xml-parser-private.h
@@ -74,7 +74,7 @@ typedef struct _ParserState
   const gchar      **attributes;
   BuildState         build_state;
   gint               current_depth;
-  GArray            *schemas;
+  GPtrArray         *schemas;
   gint64             sequence;
 } ParserState;
 
diff --git a/plugins/xml-pack/ide-xml-parser.c b/plugins/xml-pack/ide-xml-parser.c
index 02eaf13..a0662fb 100644
--- a/plugins/xml-pack/ide-xml-parser.c
+++ b/plugins/xml-pack/ide-xml-parser.c
@@ -17,15 +17,16 @@
  */
 
 #include <glib/gi18n.h>
+#include <glib-object.h>
 
 #include "ide-xml-parser.h"
 #include "ide-xml-parser-generic.h"
 #include "ide-xml-parser-ui.h"
 #include "ide-xml-parser-private.h"
 #include "ide-xml-sax.h"
+#include "ide-xml-schema-cache-entry.h"
 #include "ide-xml-stack.h"
 #include "ide-xml-tree-builder-utils-private.h"
-#include "ide-xml-validator.h"
 
 typedef struct _ColorTag
 {
@@ -377,15 +378,16 @@ ide_xml_parser_internal_subset_sax_cb (ParserState   *state,
                                        const xmlChar *system_id)
 {
   IdeXmlParser *self = (IdeXmlParser *)state->self;
-  SchemaEntry entry = {0};
+  IdeXmlSchemaCacheEntry *entry;
 
   g_assert (IDE_IS_XML_PARSER (self));
 
   printf ("internal subset:%s external_id:%s system_id:%s\n", name, external_id, system_id);
 
-  entry.schema_kind = SCHEMA_KIND_DTD;
-  ide_xml_sax_get_location (self->sax_parser, &entry.schema_line, &entry.schema_col, NULL, NULL, NULL, NULL);
-  g_array_append_val (state->schemas, entry);
+  entry = ide_xml_schema_cache_entry_new ();
+  entry->kind = SCHEMA_KIND_DTD;
+  ide_xml_sax_get_location (self->sax_parser, &entry->line, &entry->col, NULL, NULL, NULL, NULL);
+  g_ptr_array_add (state->schemas, entry);
 }
 
 void
@@ -432,7 +434,8 @@ ide_xml_parser_processing_instruction_sax_cb (ParserState   *state,
   IdeDiagnostic *diagnostic;
   g_autofree gchar *schema_url = NULL;
   const gchar *extension;
-  SchemaEntry entry = {0};
+  IdeXmlSchemaCacheEntry *entry;
+  IdeXmlSchemaKind kind;
 
   g_assert (IDE_IS_XML_PARSER (self));
 
@@ -442,15 +445,22 @@ ide_xml_parser_processing_instruction_sax_cb (ParserState   *state,
         {
           ++extension;
           if (ide_str_equal0 (extension, "rng"))
-            entry.schema_kind = SCHEMA_KIND_RNG;
+            kind = SCHEMA_KIND_RNG;
           else if (ide_str_equal0 (extension, "xsd"))
-            entry.schema_kind = SCHEMA_KIND_XML_SCHEMA;
+            kind = SCHEMA_KIND_XML_SCHEMA;
           else
             goto fail;
 
-          ide_xml_sax_get_location (self->sax_parser, &entry.schema_line, &entry.schema_col, NULL, NULL, 
NULL, NULL);
-          entry.schema_file = get_absolute_schema_file (state->file, schema_url);
-          g_array_append_val (state->schemas, entry);
+          entry = ide_xml_schema_cache_entry_new ();
+          entry->kind = kind;
+
+          ide_xml_sax_get_location (self->sax_parser, &entry->line, &entry->col, NULL, NULL, NULL, NULL);
+          entry->file = get_absolute_schema_file (state->file, schema_url);
+
+          /* Needed to pass the kind to the service schema fetcher */
+          g_object_set_data (G_OBJECT (entry->file), "kind", GUINT_TO_POINTER (entry->kind));
+
+          g_ptr_array_add (state->schemas, entry);
 
           return;
         }
@@ -536,16 +546,6 @@ ide_xml_parser_get_analysis_worker (GTask        *task,
   g_task_return_pointer (task, analysis, (GDestroyNotify)ide_xml_analysis_unref);
 }
 
-static void
-schemas_free (gpointer *data)
-{
-  SchemaEntry *entry = (SchemaEntry *)data;
-
-  g_clear_object (&entry->schema_file);
-  g_clear_pointer (&entry->schema_content, g_bytes_unref);
-  g_clear_pointer (&entry->error_message, g_free);
-}
-
 void
 ide_xml_parser_get_analysis_async (IdeXmlParser        *self,
                                    GFile               *file,
@@ -570,8 +570,7 @@ ide_xml_parser_get_analysis_async (IdeXmlParser        *self,
   state->content = g_bytes_ref (content);
   state->sequence = sequence;
   state->diagnostics_array = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_diagnostic_unref);
-  state->schemas = g_array_new (TRUE, TRUE, sizeof (SchemaEntry));
-  g_array_set_clear_func (state->schemas, (GDestroyNotify)schemas_free);
+  state->schemas = g_ptr_array_new_with_free_func (g_object_unref);
 
   state->build_state = BUILD_STATE_NORMAL;
 
diff --git a/plugins/xml-pack/ide-xml-schema-cache-entry.c b/plugins/xml-pack/ide-xml-schema-cache-entry.c
index 3cd3a5e..c09f05e 100644
--- a/plugins/xml-pack/ide-xml-schema-cache-entry.c
+++ b/plugins/xml-pack/ide-xml-schema-cache-entry.c
@@ -66,6 +66,15 @@ ide_xml_schema_cache_entry_copy (IdeXmlSchemaCacheEntry *self)
   if (self->error_message != NULL)
     copy->error_message = g_strdup (self->error_message);
 
+  if (self->file != NULL)
+    copy->file = g_object_ref (self->file);
+
+  copy->kind = self->kind;
+  copy->state = self->state;
+  copy->line = self->line;
+  copy->col = self->col;
+  copy->mtime = self->mtime;
+
   return copy;
 }
 
@@ -76,6 +85,7 @@ ide_xml_schema_cache_entry_free (IdeXmlSchemaCacheEntry *self)
   g_assert_cmpint (self->ref_count, ==, 0);
 
   g_clear_pointer (&self->content, g_bytes_unref);
+  g_clear_object (&self->file);
   g_clear_pointer (&self->error_message, g_free);
 
   g_slice_free (IdeXmlSchemaCacheEntry, self);
diff --git a/plugins/xml-pack/ide-xml-schema-cache-entry.h b/plugins/xml-pack/ide-xml-schema-cache-entry.h
index 93a52ca..78ca0a4 100644
--- a/plugins/xml-pack/ide-xml-schema-cache-entry.h
+++ b/plugins/xml-pack/ide-xml-schema-cache-entry.h
@@ -19,7 +19,10 @@
 #ifndef IDE_XML_SCHEMA_CACHE_ENTRY_H
 #define IDE_XML_SCHEMA_CACHE_ENTRY_H
 
-#include <glib-object.h>
+#include <gio/gio.h>
+#include <glib.h>
+
+#include "ide-xml-schema.h"
 
 G_BEGIN_DECLS
 
@@ -27,12 +30,37 @@ G_BEGIN_DECLS
 
 typedef struct _IdeXmlSchemaCacheEntry IdeXmlSchemaCacheEntry;
 
+typedef enum
+{
+  SCHEMA_KIND_NONE,
+  SCHEMA_KIND_DTD,
+  SCHEMA_KIND_RNG,
+  SCHEMA_KIND_XML_SCHEMA,
+} IdeXmlSchemaKind;
+
+typedef enum
+{
+  SCHEMA_STATE_NONE,
+  SCHEMA_STATE_WRONG_FILE_TYPE,
+  SCHEMA_STATE_CANT_LOAD,
+  SCHEMA_STATE_CANT_VALIDATE,
+  SCHEMA_STATE_CANT_PARSE,
+  SCHEMA_STATE_PARSED
+} IdeXmlSchemaState;
+
 struct _IdeXmlSchemaCacheEntry
 {
   guint ref_count;
 
-  GBytes *content;
-  gchar  *error_message;
+  GFile             *file;
+  GBytes            *content;
+  IdeXmlSchema      *schema;
+  gchar             *error_message;
+  IdeXmlSchemaKind   kind;
+  IdeXmlSchemaState  state;
+  gint32             line;
+  gint32             col;
+  guint64            mtime;
 };
 
 IdeXmlSchemaCacheEntry     *ide_xml_schema_cache_entry_new           (void);
diff --git a/plugins/xml-pack/ide-xml-service.c b/plugins/xml-pack/ide-xml-service.c
index 06d5700..b070567 100644
--- a/plugins/xml-pack/ide-xml-service.c
+++ b/plugins/xml-pack/ide-xml-service.c
@@ -24,6 +24,7 @@
 #include <math.h>
 
 #include "ide-xml-analysis.h"
+#include "ide-xml-rng-parser.h"
 #include "ide-xml-schema-cache-entry.h"
 #include "ide-xml-tree-builder.h"
 #include "ide-xml-types.h"
@@ -106,32 +107,99 @@ ide_xml_service_build_tree_cb (DzlTaskCache  *cache,
   IDE_EXIT;
 }
 
+typedef struct
+{
+  IdeXmlService          *self;
+  GTask                  *task;
+  IdeXmlSchemaCacheEntry *cache_entry;
+} SchemaState;
+
+/* Parse schema phase */
 static void
-ide_xml_service_load_schema_cb2 (GObject      *object,
+ide_xml_service_load_schema_cb3 (GObject      *object,
                                  GAsyncResult *result,
                                  gpointer      user_data)
 {
   GFile *file = (GFile *)object;
-  g_autoptr(GTask) task = user_data;
+  SchemaState *state = (SchemaState *)user_data;
+  GTask *task;
+  IdeXmlSchema *schema;
+  g_autoptr (IdeXmlRngParser) rng_parser = NULL;
   IdeXmlSchemaCacheEntry *cache_entry;
+  IdeXmlSchemaKind kind;
   GError *error = NULL;
   gchar *content;
   gsize len;
 
   g_assert (G_IS_FILE (file));
   g_assert (G_IS_TASK (result));
-  g_assert (G_IS_TASK (task));
+  g_assert (state != NULL);
 
-  cache_entry = ide_xml_schema_cache_entry_new ();
+  task = state->task;
+  cache_entry = state->cache_entry;
+  kind = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (file), "kind"));
 
   if (!g_file_load_contents_finish (file, result, &content, &len, NULL, &error))
-    cache_entry->error_message = g_strdup (error->message);
+    {
+      cache_entry->error_message = g_strdup (error->message);
+      cache_entry->state = SCHEMA_STATE_CANT_LOAD;
+    }
   else
-    cache_entry->content = g_bytes_new_take (content, len);
+    {
+      cache_entry->content = g_bytes_new_take (content, len);
+      if (kind == SCHEMA_KIND_RNG)
+        {
+          rng_parser = ide_xml_rng_parser_new ();
+          if (NULL != (schema = ide_xml_rng_parser_parse (rng_parser, content, len, file)))
+            {
+              cache_entry->schema = schema;
+              cache_entry->state = SCHEMA_STATE_PARSED;
+            }
+          else
+            {
+              /* TODO: get parse error ? */
+              g_clear_pointer (&cache_entry->content, g_bytes_unref);
+              cache_entry->state = SCHEMA_STATE_CANT_PARSE;
+            }
+        }
+      else
+        {
+          /* TODO: set error message */
+          g_clear_pointer (&cache_entry->content, g_bytes_unref);
+          cache_entry->state = SCHEMA_STATE_WRONG_FILE_TYPE;
+        }
+    }
 
+  g_object_unref (state->task);
+  g_slice_free (SchemaState, state);
   g_task_return_pointer (task, cache_entry, (GDestroyNotify)ide_xml_schema_cache_entry_unref);
 }
 
+/* Get content phase */
+static void
+ide_xml_service_load_schema_cb2 (GObject      *object,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  GFile *file = (GFile *)object;
+  SchemaState *state = (SchemaState *)user_data;
+  g_autoptr (GFileInfo) file_info = NULL;
+  GError *error = NULL;
+
+  g_assert (G_IS_FILE (file));
+  g_assert (G_IS_TASK (result));
+  g_assert (state != NULL);
+
+  if (NULL != (file_info = g_file_query_info_finish (file, result, &error)))
+    state->cache_entry->mtime = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+
+  g_file_load_contents_async (file,
+                              g_task_get_cancellable (state->task),
+                              ide_xml_service_load_schema_cb3,
+                              state);
+}
+
+/* Get mtime phase */
 static void
 ide_xml_service_load_schema_cb (DzlTaskCache  *cache,
                                 gconstpointer  key,
@@ -140,6 +208,7 @@ ide_xml_service_load_schema_cb (DzlTaskCache  *cache,
 {
   IdeXmlService *self = user_data;
   GFile *file = (GFile *)key;
+  SchemaState *state;
 
   IDE_ENTRY;
 
@@ -148,10 +217,20 @@ ide_xml_service_load_schema_cb (DzlTaskCache  *cache,
   g_assert (G_IS_TASK (task));
   g_assert (G_IS_FILE (file));
 
-  g_file_load_contents_async (file,
-                              g_task_get_cancellable (task),
-                              ide_xml_service_load_schema_cb2,
-                              g_object_ref (task));
+  state = g_slice_new0 (SchemaState);
+  state->self = self;
+  state->task = g_object_ref (task);
+  state->cache_entry = ide_xml_schema_cache_entry_new ();
+
+  state->cache_entry->file = g_object_ref (file);
+
+  g_file_query_info_async (file,
+                           G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                           G_FILE_QUERY_INFO_NONE,
+                           G_PRIORITY_DEFAULT,
+                           g_task_get_cancellable (state->task),
+                           ide_xml_service_load_schema_cb2,
+                           state);
 
   IDE_EXIT;
 }
diff --git a/plugins/xml-pack/ide-xml-tree-builder-utils-private.h 
b/plugins/xml-pack/ide-xml-tree-builder-utils-private.h
index ba7ccce..ad43c2f 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-utils-private.h
+++ b/plugins/xml-pack/ide-xml-tree-builder-utils-private.h
@@ -21,12 +21,13 @@
 #include <glib.h>
 #include <ide.h>
 
+#include "ide-xml-schema-cache-entry.h"
 #include "ide-xml-symbol-node.h"
 #include "ide-xml-validator.h"
 
 G_BEGIN_DECLS
 
-const gchar  *get_schema_kind_string     (SchemaKind          kind);
+const gchar  *get_schema_kind_string     (IdeXmlSchemaKind    kind);
 gchar        *get_schema_url             (const gchar        *data);
 const gchar  *list_get_attribute         (const guchar      **attributes,
                                           const gchar        *name);
diff --git a/plugins/xml-pack/ide-xml-tree-builder-utils.c b/plugins/xml-pack/ide-xml-tree-builder-utils.c
index 607de2c..4bcf1e1 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-utils.c
+++ b/plugins/xml-pack/ide-xml-tree-builder-utils.c
@@ -104,7 +104,7 @@ get_schema_url (const gchar *data)
 }
 
 const gchar *
-get_schema_kind_string (SchemaKind kind)
+get_schema_kind_string (IdeXmlSchemaKind kind)
 {
   if (kind == SCHEMA_KIND_NONE)
     return "No schema";
diff --git a/plugins/xml-pack/ide-xml-tree-builder.c b/plugins/xml-pack/ide-xml-tree-builder.c
index 2232d4c..a344ab3 100644
--- a/plugins/xml-pack/ide-xml-tree-builder.c
+++ b/plugins/xml-pack/ide-xml-tree-builder.c
@@ -23,7 +23,9 @@
 #include <string.h>
 
 #include "ide-xml-parser.h"
+#include "ide-xml-rng-parser.h"
 #include "ide-xml-sax.h"
+#include "ide-xml-schema.h"
 #include "ide-xml-service.h"
 #include "ide-xml-schema-cache-entry.h"
 #include "ide-xml-tree-builder-utils-private.h"
@@ -117,7 +119,7 @@ typedef struct _FetchSchemasState
 {
   IdeXmlTreeBuilder *self;
   GTask             *task;
-  GArray            *schemas;
+  GPtrArray         *schemas;
   guint              index;
 } FetchSchemasState;
 
@@ -125,7 +127,7 @@ static void
 fetch_schema_state_free (FetchSchemasState *state)
 {
   g_object_unref (state->self);
-  g_array_unref (state->schemas);
+  g_ptr_array_unref (state->schemas);
 
   g_slice_free (FetchSchemasState, state);
 }
@@ -140,7 +142,7 @@ fetch_schemas_cb (GObject      *object,
   g_autoptr (IdeXmlSchemaCacheEntry) cache_entry = NULL;
   GTask *task = state->task;
   guint count;
-  SchemaEntry *entry;
+  IdeXmlSchemaCacheEntry *entry;
   GError *error = NULL;
 
   g_assert (DZL_IS_TASK_CACHE (schemas_cache));
@@ -148,13 +150,20 @@ fetch_schemas_cb (GObject      *object,
   g_assert (G_IS_TASK (task));
 
   cache_entry = dzl_task_cache_get_finish (schemas_cache, result, &error);
-  entry = &g_array_index (state->schemas, SchemaEntry, state->index);
+  entry = g_ptr_array_index (state->schemas, state->index);
 
   if (cache_entry->content != NULL)
-    entry->schema_content = g_bytes_ref (cache_entry->content);
-  else
+    entry->content = g_bytes_ref (cache_entry->content);
+
+  if (cache_entry->error_message != NULL)
     entry->error_message = g_strdup (cache_entry->error_message);
 
+  if (cache_entry->schema != NULL)
+    entry->schema = ide_xml_schema_ref (cache_entry->schema);
+
+  entry->state = cache_entry->state;
+  entry->mtime = cache_entry->mtime;
+
   fetch_schema_state_free (state);
   count = GPOINTER_TO_UINT (g_task_get_task_data (task));
   --count;
@@ -169,7 +178,7 @@ fetch_schemas_cb (GObject      *object,
 
 static gboolean
 fetch_schemas_async (IdeXmlTreeBuilder   *self,
-                     GArray              *schemas,
+                     GPtrArray           *schemas,
                      GCancellable        *cancellable,
                      GAsyncReadyCallback  callback,
                      gpointer             user_data)
@@ -197,17 +206,17 @@ fetch_schemas_async (IdeXmlTreeBuilder   *self,
 
   for (gint i = 0; i < schemas->len; ++i)
     {
-      SchemaEntry *entry;
+      IdeXmlSchemaCacheEntry *entry;
       FetchSchemasState *state;
 
-      entry = &g_array_index (schemas, SchemaEntry, i);
+      entry = g_ptr_array_index (schemas, i);
       /* Check if it's an internal schema */
-      if (entry->schema_file == NULL)
+      if (entry->file == NULL)
         continue;
 
       state = g_slice_new0 (FetchSchemasState);
       state->self = g_object_ref (self);
-      state->schemas = g_array_ref (schemas);
+      state->schemas = g_ptr_array_ref (schemas);
       state->task = task;
 
       ++count;
@@ -217,13 +226,13 @@ fetch_schemas_async (IdeXmlTreeBuilder   *self,
       state->index = i;
       /* TODO: peek schemas if it's already in cache */
       dzl_task_cache_get_async (schemas_cache,
-                                entry->schema_file,
+                                entry->file,
                                 FALSE,
                                 cancellable,
                                 fetch_schemas_cb,
                                 state);
 
-      printf ("fetching schema URL:%s\n", g_file_get_uri (entry->schema_file));
+      printf ("fetching schema URL:%s\n", g_file_get_uri (entry->file));
     }
 
   if (!has_external_schemas)
@@ -255,11 +264,11 @@ ide_xml_tree_builder_build_tree_cb2 (GObject      *object,
   TreeBuilderState *state;
   IdeContext *context;
   g_autoptr(GTask) task = user_data;
-  g_autoptr (GArray) schemas = NULL;
+  g_autoptr (GPtrArray) schemas = NULL;
   const gchar *doc_data;
   xmlDoc *doc;
   gsize doc_size;
-  SchemaKind kind;
+  IdeXmlSchemaKind kind;
   GError *error = NULL;
 
   g_assert (G_IS_TASK (result));
@@ -276,31 +285,30 @@ ide_xml_tree_builder_build_tree_cb2 (GObject      *object,
 
   state = g_task_get_task_data (task);
   schemas = ide_xml_analysis_get_schemas (state->analysis);
-  ide_xml_analysis_set_schemas (state->analysis, NULL);
-
   context = ide_object_get_context (IDE_OBJECT (self));
 
   doc_data = g_bytes_get_data (state->content, &doc_size);
   if (NULL != (doc = xmlParseMemory (doc_data, doc_size)))
     {
       doc->URL = (guchar *)g_file_get_uri (state->file);
+
       for (gint i = 0; i < schemas->len; ++i)
         {
-          SchemaEntry *entry;
+          IdeXmlSchemaCacheEntry *entry;
           const gchar *schema_data;
           gsize schema_size;
           g_autoptr (IdeDiagnostics) diagnostics = NULL;
           g_autoptr (IdeDiagnostic) diagnostic = NULL;
           gboolean schema_ret;
 
-          entry = &g_array_index (schemas, SchemaEntry, i);
-          kind = entry->schema_kind;
+          entry = g_ptr_array_index (schemas, i);
+          kind = entry->kind;
 
           if (kind == SCHEMA_KIND_RNG || kind == SCHEMA_KIND_XML_SCHEMA)
             {
-              if (entry->schema_content != NULL)
+              if (entry->content != NULL)
                 {
-                  schema_data = g_bytes_get_data (entry->schema_content, &schema_size);
+                  schema_data = g_bytes_get_data (entry->content, &schema_size);
                   schema_ret = ide_xml_validator_set_schema (self->validator,
                                                              kind,
                                                              schema_data,
@@ -313,8 +321,8 @@ ide_xml_tree_builder_build_tree_cb2 (GObject      *object,
                   diagnostic = create_diagnostic (context,
                                                   entry->error_message,
                                                   state->file,
-                                                  entry->schema_line,
-                                                  entry->schema_col,
+                                                  entry->line,
+                                                  entry->col,
                                                   IDE_DIAGNOSTIC_ERROR);
                   ide_diagnostics_add (state->analysis->diagnostics, diagnostic);
                   continue;
@@ -332,13 +340,13 @@ ide_xml_tree_builder_build_tree_cb2 (GObject      *object,
               g_autofree gchar *uri = NULL;
               g_autofree gchar *msg = NULL;
 
-              uri = g_file_get_uri (entry->schema_file);
+              uri = g_file_get_uri (entry->file);
               msg = g_strdup_printf ("Can't parse the schema: '%s'", uri);
               diagnostic = create_diagnostic (context,
                                               msg,
                                               state->file,
-                                              entry->schema_line,
-                                              entry->schema_col,
+                                              entry->line,
+                                              entry->col,
                                               IDE_DIAGNOSTIC_ERROR);
               ide_diagnostics_add (state->analysis->diagnostics, diagnostic);
               continue;
@@ -347,7 +355,10 @@ ide_xml_tree_builder_build_tree_cb2 (GObject      *object,
           if (ide_xml_validator_validate (self->validator, doc, &diagnostics))
             printf ("validated\n");
           else
-            printf ("NOT validated\n");
+            {
+              printf ("NOT validated\n");
+              entry->state = SCHEMA_STATE_CANT_VALIDATE;
+            }
 
           ide_diagnostics_merge (state->analysis->diagnostics, diagnostics);
         }
diff --git a/plugins/xml-pack/ide-xml-validator.c b/plugins/xml-pack/ide-xml-validator.c
index ab52518..0e4f825 100644
--- a/plugins/xml-pack/ide-xml-validator.c
+++ b/plugins/xml-pack/ide-xml-validator.c
@@ -29,28 +29,28 @@
 
 struct _IdeXmlValidator
 {
-  IdeObject      parent_instance;
+  IdeObject         parent_instance;
 
-  GPtrArray     *diagnostics_array;
-  xmlDtd        *dtd;
-  xmlRelaxNG    *rng;
-  xmlSchema     *xml_schema;
+  GPtrArray        *diagnostics_array;
+  xmlDtd           *dtd;
+  xmlRelaxNG       *rng;
+  xmlSchema        *xml_schema;
 
-  SchemaKind     kind;
-  guint          dtd_use_subsets : 1;
+  IdeXmlSchemaKind  kind;
+  guint             dtd_use_subsets : 1;
 };
 
 typedef struct _ValidState
 {
-  IdeXmlValidator *self;
-  SchemaKind       kind;
-  xmlValidCtxt    *dtd_valid_context;
-  xmlDoc          *doc;
+  IdeXmlValidator  *self;
+  IdeXmlSchemaKind  kind;
+  xmlValidCtxt     *dtd_valid_context;
+  xmlDoc           *doc;
 } ValidState;
 
 G_DEFINE_TYPE (IdeXmlValidator, ide_xml_validator, IDE_TYPE_OBJECT)
 
-SchemaKind
+IdeXmlSchemaKind
 ide_xml_validator_get_kind (IdeXmlValidator *self)
 {
   g_return_val_if_fail (IDE_IS_XML_VALIDATOR (self), SCHEMA_KIND_NONE);
@@ -214,10 +214,10 @@ end:
  * subsets (internal/external) will be used for the validation.
  */
 gboolean
-ide_xml_validator_set_schema (IdeXmlValidator *self,
-                              SchemaKind       kind,
-                              const gchar     *data,
-                              gsize            size)
+ide_xml_validator_set_schema (IdeXmlValidator  *self,
+                              IdeXmlSchemaKind  kind,
+                              const gchar      *data,
+                              gsize             size)
 {
   xmlDoc *dtd_doc;
   xmlRelaxNGParserCtxt *rng_parser;
diff --git a/plugins/xml-pack/ide-xml-validator.h b/plugins/xml-pack/ide-xml-validator.h
index a01b5f8..3e3b9ff 100644
--- a/plugins/xml-pack/ide-xml-validator.h
+++ b/plugins/xml-pack/ide-xml-validator.h
@@ -20,37 +20,21 @@
 #define IDE_XML_VALIDATOR_H
 
 #include <glib-object.h>
-#include <ide.h>
 #include <libxml/parser.h>
 
+#include <ide.h>
+#include "ide-xml-schema-cache-entry.h"
+
 G_BEGIN_DECLS
 
 #define IDE_TYPE_XML_VALIDATOR (ide_xml_validator_get_type())
 
 G_DECLARE_FINAL_TYPE (IdeXmlValidator, ide_xml_validator, IDE, XML_VALIDATOR, IdeObject)
 
-typedef enum
-{
-  SCHEMA_KIND_NONE,
-  SCHEMA_KIND_DTD,
-  SCHEMA_KIND_RNG,
-  SCHEMA_KIND_XML_SCHEMA,
-} SchemaKind;
-
-typedef struct _SchemaEntry
-{
-  GFile      *schema_file;
-  GBytes     *schema_content;
-  gchar      *error_message;
-  SchemaKind  schema_kind;
-  gint32      schema_line;
-  gint32      schema_col;
-} SchemaEntry;
-
 IdeXmlValidator       *ide_xml_validator_new        (IdeContext       *context);
-SchemaKind             ide_xml_validator_get_kind   (IdeXmlValidator  *self);
+IdeXmlSchemaKind       ide_xml_validator_get_kind   (IdeXmlValidator  *self);
 gboolean               ide_xml_validator_set_schema (IdeXmlValidator  *self,
-                                                     SchemaKind        kind,
+                                                     IdeXmlSchemaKind  kind,
                                                      const gchar      *data,
                                                      gsize             size);
 


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