[gnome-builder/wip/slaf/xml-pack: 548/572] xml-pack: more precise node and diagnostics location
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/slaf/xml-pack: 548/572] xml-pack: more precise node and diagnostics location
- Date: Sun, 14 May 2017 21:21:25 +0000 (UTC)
commit bf0457a0b3f4213158463c7f795c4156caaef439
Author: Sebastien Lafargue <slafargue gnome org>
Date: Mon Mar 13 22:28:57 2017 +0100
xml-pack: more precise node and diagnostics location
Libxml2 give us the end of a tag.
We now compute the start and the size.
We use range for the diagnostics.
plugins/xml-pack/ide-xml-parser-generic.c | 6 +-
plugins/xml-pack/ide-xml-parser-ui.c | 24 +++---
plugins/xml-pack/ide-xml-parser.c | 51 +++++++++---
plugins/xml-pack/ide-xml-sax.c | 107 +++++++++++++++++++++++--
plugins/xml-pack/ide-xml-sax.h | 7 +-
plugins/xml-pack/ide-xml-symbol-node.c | 14 +++-
plugins/xml-pack/ide-xml-symbol-node.h | 9 ++-
plugins/xml-pack/ide-xml-tree-builder-utils.c | 6 +-
8 files changed, 177 insertions(+), 47 deletions(-)
---
diff --git a/plugins/xml-pack/ide-xml-parser-generic.c b/plugins/xml-pack/ide-xml-parser-generic.c
index 5098b03..2dea869 100644
--- a/plugins/xml-pack/ide-xml-parser-generic.c
+++ b/plugins/xml-pack/ide-xml-parser-generic.c
@@ -67,7 +67,7 @@ ide_xml_parser_generic_start_element_sax_cb (ParserState *state,
attr = collect_attributes (self, (const gchar **)attributes);
label = g_strconcat ((const gchar *)name, attr, NULL);
- node = ide_xml_symbol_node_new (label, NULL, NULL, IDE_SYMBOL_XML_ELEMENT, NULL, 0, 0);
+ node = ide_xml_symbol_node_new (label, NULL, NULL, IDE_SYMBOL_XML_ELEMENT, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
ide_xml_parser_state_processing (self, state, (const gchar *)name, node,
IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT, FALSE);
@@ -84,7 +84,7 @@ ide_xml_parser_generic_comment_sax_cb (ParserState *state,
g_assert (IDE_IS_XML_PARSER (self));
strip_name = g_strstrip (g_strdup ((const gchar *)name));
- node = ide_xml_symbol_node_new (strip_name, NULL, NULL, IDE_SYMBOL_XML_COMMENT, NULL, 0, 0);
+ node = ide_xml_symbol_node_new (strip_name, NULL, NULL, IDE_SYMBOL_XML_COMMENT, NULL, 0, 0, 0);
ide_xml_parser_state_processing (self, state, "comment", node, IDE_XML_SAX_CALLBACK_TYPE_COMMENT, FALSE);
}
@@ -98,7 +98,7 @@ ide_xml_parser_generic_cdata_sax_cb (ParserState *state,
g_assert (IDE_IS_XML_PARSER (self));
- node = ide_xml_symbol_node_new ("cdata", NULL, NULL, IDE_SYMBOL_XML_CDATA, NULL, 0, 0);
+ node = ide_xml_symbol_node_new ("cdata", NULL, NULL, IDE_SYMBOL_XML_CDATA, NULL, 0, 0, 0);
ide_xml_parser_state_processing (self, state, "cdata", node, IDE_XML_SAX_CALLBACK_TYPE_CDATA, FALSE);
}
diff --git a/plugins/xml-pack/ide-xml-parser-ui.c b/plugins/xml-pack/ide-xml-parser-ui.c
index b25a33b..12549cb 100644
--- a/plugins/xml-pack/ide-xml-parser-ui.c
+++ b/plugins/xml-pack/ide-xml-parser-ui.c
@@ -66,7 +66,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
{
value = get_attribute (attributes, "name", NULL);
node = ide_xml_symbol_node_new (value, NULL, "property",
- IDE_SYMBOL_UI_PROPERTY, NULL, 0, 0);
+ IDE_SYMBOL_UI_PROPERTY, NULL, 0, 0, 0);
is_internal = TRUE;
state->build_state = BUILD_STATE_GET_CONTENT;
}
@@ -79,7 +79,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
{
value = get_attribute (attributes, "name", NULL);
node = ide_xml_symbol_node_new (value, NULL, "attribute",
- IDE_SYMBOL_UI_MENU_ATTRIBUTE, NULL, 0, 0);
+ IDE_SYMBOL_UI_MENU_ATTRIBUTE, NULL, 0, 0, 0);
is_internal = TRUE;
state->build_state = BUILD_STATE_GET_CONTENT;
}
@@ -88,7 +88,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
{
value = get_attribute (attributes, "name", NULL);
node = ide_xml_symbol_node_new (value, NULL, "class",
- IDE_SYMBOL_UI_STYLE_CLASS, NULL, 0, 0);
+ IDE_SYMBOL_UI_STYLE_CLASS, NULL, 0, 0, 0);
is_internal = TRUE;
}
else if (ide_str_equal0 (name, "child"))
@@ -110,7 +110,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
}
node = ide_xml_symbol_node_new (string->str, NULL, "child",
- IDE_SYMBOL_UI_CHILD, NULL, 0, 0);
+ IDE_SYMBOL_UI_CHILD, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "object"))
@@ -129,7 +129,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
}
node = ide_xml_symbol_node_new (string->str, NULL, "object",
- IDE_SYMBOL_UI_OBJECT, NULL, 0, 0);
+ IDE_SYMBOL_UI_OBJECT, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "template"))
@@ -146,18 +146,18 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
g_string_append (string, value);
node = ide_xml_symbol_node_new (string->str, NULL, (const gchar *)name,
- IDE_SYMBOL_UI_TEMPLATE, NULL, 0, 0);
+ IDE_SYMBOL_UI_TEMPLATE, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "packing"))
{
node = ide_xml_symbol_node_new ("packing", NULL, "packing",
- IDE_SYMBOL_UI_PACKING, NULL, 0, 0);
+ IDE_SYMBOL_UI_PACKING, NULL, 0, 0, 0);
}
else if (ide_str_equal0 (name, "style"))
{
node = ide_xml_symbol_node_new ("style", NULL, "style",
- IDE_SYMBOL_UI_STYLE, NULL, 0, 0);
+ IDE_SYMBOL_UI_STYLE, NULL, 0, 0, 0);
}
else if (ide_str_equal0 (name, "menu"))
{
@@ -167,7 +167,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
g_string_append (string, value);
node = ide_xml_symbol_node_new (string->str, NULL, "menu",
- IDE_SYMBOL_UI_MENU, NULL, 0, 0);
+ IDE_SYMBOL_UI_MENU, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "submenu"))
@@ -178,7 +178,7 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
g_string_append (string, value);
node = ide_xml_symbol_node_new (string->str, NULL, "submenu",
- IDE_SYMBOL_UI_SUBMENU, NULL, 0, 0);
+ IDE_SYMBOL_UI_SUBMENU, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "section"))
@@ -189,13 +189,13 @@ ide_xml_parser_ui_start_element_sax_cb (ParserState *state,
g_string_append (string, value);
node = ide_xml_symbol_node_new (string->str, NULL, "section",
- IDE_SYMBOL_UI_SECTION, NULL, 0, 0);
+ IDE_SYMBOL_UI_SECTION, NULL, 0, 0, 0);
g_object_set (node, "use-markup", TRUE, NULL);
}
else if (ide_str_equal0 (name, "item"))
{
node = ide_xml_symbol_node_new ("item", NULL, "item",
- IDE_SYMBOL_UI_ITEM, NULL, 0, 0);
+ IDE_SYMBOL_UI_ITEM, NULL, 0, 0, 0);
}
ide_xml_parser_state_processing (self, state, (const gchar *)name, node,
IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT, is_internal);
diff --git a/plugins/xml-pack/ide-xml-parser.c b/plugins/xml-pack/ide-xml-parser.c
index e66c9e1..259d82e 100644
--- a/plugins/xml-pack/ide-xml-parser.c
+++ b/plugins/xml-pack/ide-xml-parser.c
@@ -104,23 +104,45 @@ ide_xml_parser_create_diagnostic (ParserState *state,
IdeXmlParser *self = (IdeXmlParser *)state->self;
IdeContext *context;
IdeDiagnostic *diagnostic;
- g_autoptr(IdeSourceLocation) loc = NULL;
+ g_autoptr(IdeSourceLocation) start_loc = NULL;
+ g_autoptr(IdeSourceLocation) end_loc = NULL;
g_autoptr(IdeFile) ifile = NULL;
- gint line;
- gint line_offset;
+ gint start_line;
+ gint start_line_offset;
+ gint end_line;
+ gint end_line_offset;
+ gsize size;
g_assert (IDE_IS_XML_PARSER (self));
context = ide_object_get_context (IDE_OBJECT (self));
- ide_xml_sax_get_position (self->sax_parser, &line, &line_offset);
+ ide_xml_sax_get_location (self->sax_parser,
+ &start_line, &start_line_offset,
+ &end_line, &end_line_offset,
+ &size);
+
ifile = ide_file_new (context, state->file);
- loc = ide_source_location_new (ifile,
- line - 1,
- line_offset - 1,
- 0);
+ start_loc = ide_source_location_new (ifile,
+ start_line - 1,
+ start_line_offset - 1,
+ 0);
+
+ if (size > 0)
+ {
+ IdeSourceRange *range;
+
+ end_loc = ide_source_location_new (ifile,
+ end_line - 1,
+ end_line_offset - 1,
+ 0);
- diagnostic = ide_diagnostic_new (severity, msg, loc);
+ range = ide_source_range_new (start_loc, end_loc);
+ diagnostic = ide_diagnostic_new (severity, msg, NULL);
+ ide_diagnostic_take_range (diagnostic, range);
+ }
+ else
+ diagnostic = ide_diagnostic_new (severity, msg, start_loc);
return diagnostic;
}
@@ -138,6 +160,7 @@ ide_xml_parser_state_processing (IdeXmlParser *self,
g_autofree gchar *popped_element_name = NULL;
gint line;
gint line_offset;
+ gsize size;
gint depth;
g_assert (IDE_IS_XML_SYMBOL_NODE (node) || node == NULL);
@@ -173,8 +196,8 @@ ide_xml_parser_state_processing (IdeXmlParser *self,
return;
}
- ide_xml_sax_get_position (self->sax_parser, &line, &line_offset);
- ide_xml_symbol_node_set_location (node, g_object_ref (state->file), line, line_offset);
+ ide_xml_sax_get_location (self->sax_parser, &line, &line_offset, NULL, NULL, &size);
+ ide_xml_symbol_node_set_location (node, g_object_ref (state->file), line, line_offset, size);
/* TODO: take end elements into account and use:
* || ABS (depth - current_depth) > 1
@@ -305,7 +328,7 @@ ide_xml_parser_internal_subset_sax_cb (ParserState *state,
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_position (self->sax_parser, &entry.schema_line, &entry.schema_col);
+ ide_xml_sax_get_location (self->sax_parser, &entry.schema_line, &entry.schema_col, NULL, NULL, NULL);
g_array_append_val (state->schemas, entry);
}
@@ -369,7 +392,7 @@ ide_xml_parser_processing_instruction_sax_cb (ParserState *state,
else
goto fail;
- ide_xml_sax_get_position (self->sax_parser, &entry.schema_line, &entry.schema_col);
+ ide_xml_sax_get_location (self->sax_parser, &entry.schema_line, &entry.schema_col, NULL, NULL,
NULL);
entry.schema_file = get_absolute_schema_file (state->file, schema_url);
g_array_append_val (state->schemas, entry);
@@ -497,7 +520,7 @@ ide_xml_parser_get_analysis_async (IdeXmlParser *self,
state->build_state = BUILD_STATE_NORMAL;
state->analysis = ide_xml_analysis_new (-1);
- state->root_node = ide_xml_symbol_node_new ("root", NULL, "root", IDE_SYMBOL_NONE, NULL, 0, 0);
+ state->root_node = ide_xml_symbol_node_new ("root", NULL, "root", IDE_SYMBOL_NONE, NULL, 0, 0, 0);
ide_xml_analysis_set_root_node (state->analysis, state->root_node);
state->parent_node = state->root_node;
diff --git a/plugins/xml-pack/ide-xml-sax.c b/plugins/xml-pack/ide-xml-sax.c
index d162fdc..051990f 100644
--- a/plugins/xml-pack/ide-xml-sax.c
+++ b/plugins/xml-pack/ide-xml-sax.c
@@ -180,20 +180,111 @@ ide_xml_sax_parse (IdeXmlSax *self,
return wellformed;
}
+static void
+get_tag_location (IdeXmlSax *self,
+ gint *line,
+ gint *line_offset,
+ gsize *size)
+{
+ xmlParserInput *input;
+ const gchar *base;
+ const gchar *current;
+ const gchar *line_start;
+ gint start_line_number;
+ gunichar ch;
+
+ g_assert (IDE_IS_XML_SAX (self));
+ g_assert (line != NULL);
+ g_assert (line_offset != NULL);
+ g_assert (size != NULL);
+
+ /* TODO: handle other types of line break */
+
+ input = self->context->input;
+ base = (const gchar *)input->base;
+ current = (const gchar *)input->cur;
+ start_line_number = xmlSAX2GetLineNumber (self->context);
+
+ if (g_utf8_get_char (current) == '\n' && current > base)
+ --current;
+
+ if (g_utf8_get_char (current) != '>')
+ {
+ *line = start_line_number;
+ *line_offset = xmlSAX2GetColumnNumber (self->context);
+ *size = 0;
+
+ return;
+ }
+
+ while (current > base)
+ {
+ ch = g_utf8_get_char (current);
+ if (ch == '<')
+ break;
+
+ if (ch == '\n')
+ --start_line_number;
+
+ current = g_utf8_prev_char (current);
+ }
+
+ line_start = current;
+ while (line_start > base)
+ {
+ ch = g_utf8_get_char (line_start);
+ if (ch == '\n')
+ {
+ ++line_start;
+ break;
+ }
+
+ line_start = g_utf8_prev_char (line_start);
+ }
+
+ *line = start_line_number;
+ *line_offset = (current - line_start) + 1;
+ *size = (const gchar *)input->cur - current;
+}
+
gboolean
-ide_xml_sax_get_position (IdeXmlSax *self,
- gint *line,
- gint *line_offset)
+ide_xml_sax_get_location (IdeXmlSax *self,
+ gint *start_line,
+ gint *start_line_offset,
+ gint *end_line,
+ gint *end_line_offset,
+ gsize *size)
{
+ gint tmp_line;
+ gint tmp_line_offset;
+ gint tmp_end_line;
+ gint tmp_end_line_offset;
+ gsize tmp_size;
+
g_return_val_if_fail (IDE_IS_XML_SAX (self), FALSE);
- g_return_val_if_fail (line != NULL, FALSE);
- g_return_val_if_fail (line_offset != NULL, FALSE);
g_return_val_if_fail (self->context != NULL, FALSE);
- *line = xmlSAX2GetLineNumber (self->context);
- *line_offset = xmlSAX2GetColumnNumber (self->context);
+ get_tag_location (self, &tmp_line, &tmp_line_offset, &tmp_size);
+
+ if (start_line != NULL)
+ *start_line = tmp_line;
+
+ if (start_line_offset != NULL)
+ *start_line_offset = tmp_line_offset;
+
+ if (size != NULL)
+ *size = tmp_size;
+
+ tmp_end_line = xmlSAX2GetLineNumber (self->context);
+ tmp_end_line_offset = xmlSAX2GetColumnNumber (self->context);
+
+ if (end_line != NULL)
+ *end_line = tmp_end_line;
+
+ if (end_line_offset != NULL)
+ *end_line_offset = tmp_end_line_offset;
- return (*line > 0 && *line_offset > 0);
+ return (tmp_end_line > 0 && tmp_end_line_offset > 0);
}
gint
diff --git a/plugins/xml-pack/ide-xml-sax.h b/plugins/xml-pack/ide-xml-sax.h
index c602c08..45a1217 100644
--- a/plugins/xml-pack/ide-xml-sax.h
+++ b/plugins/xml-pack/ide-xml-sax.h
@@ -49,9 +49,12 @@ enum _IdeXmlSaxCallbackType {
void ide_xml_sax_clear (IdeXmlSax *self);
gint ide_xml_sax_get_depth (IdeXmlSax *self);
-gboolean ide_xml_sax_get_position (IdeXmlSax *self,
+gboolean ide_xml_sax_get_location (IdeXmlSax *self,
gint *line,
- gint *line_offset);
+ gint *line_offset,
+ gint *end_line,
+ gint *end_line_offset,
+ gsize *size);
IdeXmlSax *ide_xml_sax_new (void);
gboolean ide_xml_sax_parse (IdeXmlSax *self,
const gchar *data,
diff --git a/plugins/xml-pack/ide-xml-symbol-node.c b/plugins/xml-pack/ide-xml-symbol-node.c
index 9dd8911..e41e04a 100644
--- a/plugins/xml-pack/ide-xml-symbol-node.c
+++ b/plugins/xml-pack/ide-xml-symbol-node.c
@@ -31,6 +31,7 @@ struct _IdeXmlSymbolNode
GFile *file;
gint line;
gint line_offset;
+ gsize size;
};
G_DEFINE_TYPE (IdeXmlSymbolNode, ide_xml_symbol_node, IDE_TYPE_SYMBOL_NODE)
@@ -119,7 +120,8 @@ ide_xml_symbol_node_new (const gchar *name,
IdeSymbolKind kind,
GFile *file,
gint line,
- gint line_offset)
+ gint line_offset,
+ gsize size)
{
IdeXmlSymbolNode *self;
IdeSymbolFlags flags = IDE_SYMBOL_FLAGS_NONE;
@@ -222,7 +224,8 @@ void
ide_xml_symbol_node_set_location (IdeXmlSymbolNode *self,
GFile *file,
gint line,
- gint line_offset)
+ gint line_offset,
+ gsize size)
{
g_return_if_fail (IDE_IS_XML_SYMBOL_NODE (self));
g_return_if_fail (G_IS_FILE (file) || file == NULL);
@@ -233,6 +236,7 @@ ide_xml_symbol_node_set_location (IdeXmlSymbolNode *self,
self->line = line;
self->line_offset = line_offset;
+ self->size = size;
}
/**
@@ -246,7 +250,8 @@ ide_xml_symbol_node_set_location (IdeXmlSymbolNode *self,
GFile *
ide_xml_symbol_node_get_location (IdeXmlSymbolNode *self,
gint *line,
- gint *line_offset)
+ gint *line_offset,
+ gsize *size)
{
g_return_val_if_fail (IDE_IS_XML_SYMBOL_NODE (self), NULL);
@@ -256,6 +261,9 @@ ide_xml_symbol_node_get_location (IdeXmlSymbolNode *self,
if (line_offset != NULL)
*line_offset = self->line_offset;
+ if (size != NULL)
+ *size = self->size;
+
return self->file;
}
diff --git a/plugins/xml-pack/ide-xml-symbol-node.h b/plugins/xml-pack/ide-xml-symbol-node.h
index ba113a7..b1a8e3b 100644
--- a/plugins/xml-pack/ide-xml-symbol-node.h
+++ b/plugins/xml-pack/ide-xml-symbol-node.h
@@ -35,7 +35,8 @@ IdeXmlSymbolNode *ide_xml_symbol_node_new (con
IdeSymbolKind kind,
GFile *file,
gint line,
- gint
line_offset);
+ gint
line_offset,
+ gsize size);
void ide_xml_symbol_node_take_child (IdeXmlSymbolNode *self,
IdeXmlSymbolNode *child);
void ide_xml_symbol_node_take_internal_child (IdeXmlSymbolNode *self,
@@ -43,7 +44,8 @@ void ide_xml_symbol_node_take_internal_child (Ide
const gchar *ide_xml_symbol_node_get_element_name (IdeXmlSymbolNode *self);
GFile * ide_xml_symbol_node_get_location (IdeXmlSymbolNode *self,
gint *line,
- gint
*line_offset);
+ gint
*line_offset,
+ gsize *size);
guint ide_xml_symbol_node_get_n_children (IdeXmlSymbolNode *self);
guint ide_xml_symbol_node_get_n_internal_children (IdeXmlSymbolNode *self);
IdeSymbolNode *ide_xml_symbol_node_get_nth_child (IdeXmlSymbolNode *self,
@@ -54,7 +56,8 @@ const gchar *ide_xml_symbol_node_get_value (Ide
void ide_xml_symbol_node_set_location (IdeXmlSymbolNode *self,
GFile *file,
gint line,
- gint
line_offset);
+ gint
line_offset,
+ gsize size);
void ide_xml_symbol_node_set_element_name (IdeXmlSymbolNode *self,
const gchar
*element_name);
void ide_xml_symbol_node_set_value (IdeXmlSymbolNode *self,
diff --git a/plugins/xml-pack/ide-xml-tree-builder-utils.c b/plugins/xml-pack/ide-xml-tree-builder-utils.c
index 640873e..02de297 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-utils.c
+++ b/plugins/xml-pack/ide-xml-tree-builder-utils.c
@@ -29,6 +29,7 @@ print_node (IdeXmlSymbolNode *node,
g_autofree gchar *spacer;
gint line;
gint line_offset;
+ gsize size;
g_return_if_fail (IDE_IS_XML_SYMBOL_NODE (node) || node == NULL);
@@ -39,14 +40,15 @@ print_node (IdeXmlSymbolNode *node,
}
spacer = g_strnfill (depth, '\t');
- ide_xml_symbol_node_get_location (node, &line, &line_offset);
+ ide_xml_symbol_node_get_location (node, &line, &line_offset, &size);
- printf ("%s%s (%i) at (%i,%i) %p\n",
+ printf ("%s%s (%i) at (%i,%i) size:%li %p\n",
spacer,
ide_symbol_node_get_name (IDE_SYMBOL_NODE (node)),
depth,
line,
line_offset,
+ size,
node);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]