cssprovider: Change section handling

Instead of building a full tree of sections that then nobody cares
about, just create sections as necessary for when we use it in the
inspector.
This commit is contained in:
Benjamin Otte 2019-04-10 16:37:52 +02:00
parent a475d72d47
commit 46143492a2
5 changed files with 63 additions and 147 deletions

View File

@ -5092,12 +5092,13 @@ GtkCssParserWarning
<SUBSECTION> <SUBSECTION>
GtkCssLocation GtkCssLocation
GtkCssSection GtkCssSection
gtk_css_section_new
gtk_css_section_ref
gtk_css_section_unref
gtk_css_section_get_file gtk_css_section_get_file
gtk_css_section_get_parent gtk_css_section_get_parent
gtk_css_section_get_start_location gtk_css_section_get_start_location
gtk_css_section_get_end_location gtk_css_section_get_end_location
gtk_css_section_ref
gtk_css_section_unref
<SUBSECTION Standard> <SUBSECTION Standard>
GTK_TYPE_CSS_PROVIDER GTK_TYPE_CSS_PROVIDER
GTK_CSS_PROVIDER GTK_CSS_PROVIDER

View File

@ -103,7 +103,6 @@ struct _GtkCssScanner
{ {
GtkCssProvider *provider; GtkCssProvider *provider;
GtkCssParser *parser; GtkCssParser *parser;
GtkCssSection *section;
GtkCssScanner *parent; GtkCssScanner *parent;
GSList *state; GSList *state;
}; };
@ -309,8 +308,6 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
static void static void
gtk_css_scanner_destroy (GtkCssScanner *scanner) gtk_css_scanner_destroy (GtkCssScanner *scanner)
{ {
if (scanner->section)
gtk_css_section_unref (scanner->section);
g_object_unref (scanner->provider); g_object_unref (scanner->provider);
gtk_css_parser_unref (scanner->parser); gtk_css_parser_unref (scanner->parser);
@ -331,7 +328,7 @@ gtk_css_provider_emit_error (GtkCssProvider *provider,
const GError *error) const GError *error)
{ {
gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (provider), gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (provider),
scanner ? scanner->section : NULL, NULL /* FIXME */,
error); error);
} }
@ -343,14 +340,20 @@ gtk_css_scanner_parser_error (GtkCssParser *parser,
gpointer user_data) gpointer user_data)
{ {
GtkCssScanner *scanner = user_data; GtkCssScanner *scanner = user_data;
GtkCssSection *section;
gtk_css_provider_emit_error (scanner->provider, scanner, error); section = gtk_css_section_new (gtk_css_parser_get_file (parser),
start,
end);
gtk_css_style_provider_emit_error (GTK_STYLE_PROVIDER (scanner->provider), section, error);
gtk_css_section_unref (section);
} }
static GtkCssScanner * static GtkCssScanner *
gtk_css_scanner_new (GtkCssProvider *provider, gtk_css_scanner_new (GtkCssProvider *provider,
GtkCssScanner *parent, GtkCssScanner *parent,
GtkCssSection *section,
GFile *file, GFile *file,
GBytes *bytes) GBytes *bytes)
{ {
@ -361,8 +364,6 @@ gtk_css_scanner_new (GtkCssProvider *provider,
g_object_ref (provider); g_object_ref (provider);
scanner->provider = provider; scanner->provider = provider;
scanner->parent = parent; scanner->parent = parent;
if (section)
scanner->section = gtk_css_section_ref (section);
scanner->parser = gtk_css_parser_new_for_bytes (bytes, scanner->parser = gtk_css_parser_new_for_bytes (bytes,
file, file,
@ -390,34 +391,6 @@ gtk_css_scanner_would_recurse (GtkCssScanner *scanner,
return FALSE; return FALSE;
} }
static void
gtk_css_scanner_push_section (GtkCssScanner *scanner)
{
GtkCssSection *section;
section = gtk_css_section_new_for_parser (scanner->section,
scanner->parser);
if (scanner->section)
gtk_css_section_unref (scanner->section);
scanner->section = section;
}
static void
gtk_css_scanner_pop_section (GtkCssScanner *scanner)
{
GtkCssSection *parent;
parent = gtk_css_section_get_parent (scanner->section);
if (parent)
gtk_css_section_ref (parent);
_gtk_css_section_end (scanner->section);
gtk_css_section_unref (scanner->section);
scanner->section = parent;
}
static void static void
gtk_css_provider_init (GtkCssProvider *css_provider) gtk_css_provider_init (GtkCssProvider *css_provider)
{ {
@ -772,13 +745,8 @@ parse_import (GtkCssScanner *scanner)
{ {
GFile *file; GFile *file;
gtk_css_scanner_push_section (scanner);
if (!gtk_css_parser_try_at_keyword (scanner->parser, "import")) if (!gtk_css_parser_try_at_keyword (scanner->parser, "import"))
{ return FALSE;
gtk_css_scanner_pop_section (scanner);
return FALSE;
}
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_STRING)) if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_STRING))
{ {
@ -836,8 +804,6 @@ parse_import (GtkCssScanner *scanner)
g_clear_object (&file); g_clear_object (&file);
gtk_css_scanner_pop_section (scanner);
return TRUE; return TRUE;
} }
@ -848,26 +814,17 @@ parse_color_definition (GtkCssScanner *scanner)
GtkCssValue *color; GtkCssValue *color;
char *name; char *name;
gtk_css_scanner_push_section (scanner);
if (!gtk_css_parser_try_at_keyword (scanner->parser, "define-color")) if (!gtk_css_parser_try_at_keyword (scanner->parser, "define-color"))
{ return FALSE;
gtk_css_scanner_pop_section (scanner);
return FALSE;
}
name = gtk_css_parser_consume_ident (scanner->parser); name = gtk_css_parser_consume_ident (scanner->parser);
if (name == NULL) if (name == NULL)
{ return TRUE;
gtk_css_scanner_pop_section (scanner);
return TRUE;
}
color = _gtk_css_color_value_parse (scanner->parser); color = _gtk_css_color_value_parse (scanner->parser);
if (color == NULL) if (color == NULL)
{ {
g_free (name); g_free (name);
gtk_css_scanner_pop_section (scanner);
return TRUE; return TRUE;
} }
@ -880,14 +837,11 @@ parse_color_definition (GtkCssScanner *scanner)
GTK_CSS_PARSER_ERROR, GTK_CSS_PARSER_ERROR,
GTK_CSS_PARSER_ERROR_SYNTAX, GTK_CSS_PARSER_ERROR_SYNTAX,
"Missing semicolon at end of color definition"); "Missing semicolon at end of color definition");
gtk_css_scanner_pop_section (scanner);
return TRUE; return TRUE;
} }
g_hash_table_insert (priv->symbolic_colors, name, color); g_hash_table_insert (priv->symbolic_colors, name, color);
gtk_css_scanner_pop_section (scanner);
return TRUE; return TRUE;
} }
@ -898,20 +852,12 @@ parse_keyframes (GtkCssScanner *scanner)
GtkCssKeyframes *keyframes; GtkCssKeyframes *keyframes;
char *name; char *name;
gtk_css_scanner_push_section (scanner);
if (!gtk_css_parser_try_at_keyword (scanner->parser, "keyframes")) if (!gtk_css_parser_try_at_keyword (scanner->parser, "keyframes"))
{ return FALSE;
gtk_css_scanner_pop_section (scanner);
return FALSE;
}
name = gtk_css_parser_consume_ident (scanner->parser); name = gtk_css_parser_consume_ident (scanner->parser);
if (name == NULL) if (name == NULL)
{ return FALSE;
gtk_css_scanner_pop_section (scanner);
return FALSE;
}
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF)) if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
{ {
@ -920,7 +866,6 @@ parse_keyframes (GtkCssScanner *scanner)
GTK_CSS_PARSER_ERROR, GTK_CSS_PARSER_ERROR,
GTK_CSS_PARSER_ERROR_SYNTAX, GTK_CSS_PARSER_ERROR_SYNTAX,
"Expected '{' for keyframes"); "Expected '{' for keyframes");
gtk_css_scanner_pop_section (scanner);
return FALSE; return FALSE;
} }
@ -939,8 +884,6 @@ parse_keyframes (GtkCssScanner *scanner)
"expected '}' after declarations"); "expected '}' after declarations");
} }
gtk_css_scanner_pop_section (scanner);
return TRUE; return TRUE;
} }
@ -968,23 +911,16 @@ parse_selector_list (GtkCssScanner *scanner)
{ {
GSList *selectors = NULL; GSList *selectors = NULL;
gtk_css_scanner_push_section (scanner);
do { do {
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser); GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
if (select == NULL) if (select == NULL)
{ return NULL;
gtk_css_scanner_pop_section (scanner);
return NULL;
}
selectors = g_slist_prepend (selectors, select); selectors = g_slist_prepend (selectors, select);
} }
while (gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COMMA)); while (gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COMMA));
gtk_css_scanner_pop_section (scanner);
return selectors; return selectors;
} }
@ -995,14 +931,12 @@ parse_declaration (GtkCssScanner *scanner,
GtkStyleProperty *property; GtkStyleProperty *property;
char *name; char *name;
gtk_css_scanner_push_section (scanner);
gtk_css_parser_start_semicolon_block (scanner->parser, GTK_CSS_TOKEN_EOF); gtk_css_parser_start_semicolon_block (scanner->parser, GTK_CSS_TOKEN_EOF);
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF)) if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
{ {
gtk_css_parser_warn_syntax (scanner->parser, "Empty declaration"); gtk_css_parser_warn_syntax (scanner->parser, "Empty declaration");
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
@ -1010,7 +944,6 @@ parse_declaration (GtkCssScanner *scanner,
if (name == NULL) if (name == NULL)
{ {
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
@ -1018,6 +951,7 @@ parse_declaration (GtkCssScanner *scanner,
if (property) if (property)
{ {
GtkCssSection *section;
GtkCssValue *value; GtkCssValue *value;
if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON)) if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON))
@ -1025,20 +959,15 @@ parse_declaration (GtkCssScanner *scanner,
gtk_css_parser_error_syntax (scanner->parser, "Expected ':'"); gtk_css_parser_error_syntax (scanner->parser, "Expected ':'");
g_free (name); g_free (name);
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
gtk_css_scanner_push_section (scanner);
value = _gtk_style_property_parse_value (property, value = _gtk_style_property_parse_value (property,
scanner->parser); scanner->parser);
if (value == NULL) if (value == NULL)
{ {
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
@ -1050,11 +979,18 @@ parse_declaration (GtkCssScanner *scanner,
GTK_CSS_PARSER_ERROR_SYNTAX, GTK_CSS_PARSER_ERROR_SYNTAX,
"Junk at end of value for %s", property->name); "Junk at end of value for %s", property->name);
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
if (gtk_keep_css_sections)
{
section = gtk_css_section_new (gtk_css_parser_get_file (scanner->parser),
gtk_css_parser_get_block_location (scanner->parser),
gtk_css_parser_get_end_location (scanner->parser));
}
else
section = NULL;
if (GTK_IS_CSS_SHORTHAND_PROPERTY (property)) if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
{ {
GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property); GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
@ -1065,14 +1001,15 @@ parse_declaration (GtkCssScanner *scanner,
GtkCssStyleProperty *child = _gtk_css_shorthand_property_get_subproperty (shorthand, i); GtkCssStyleProperty *child = _gtk_css_shorthand_property_get_subproperty (shorthand, i);
GtkCssValue *sub = _gtk_css_array_value_get_nth (value, i); GtkCssValue *sub = _gtk_css_array_value_get_nth (value, i);
gtk_css_ruleset_add (ruleset, child, _gtk_css_value_ref (sub), scanner->section); gtk_css_ruleset_add (ruleset, child, _gtk_css_value_ref (sub), section);
} }
_gtk_css_value_unref (value); _gtk_css_value_unref (value);
} }
else if (GTK_IS_CSS_STYLE_PROPERTY (property)) else if (GTK_IS_CSS_STYLE_PROPERTY (property))
{ {
gtk_css_ruleset_add (ruleset, GTK_CSS_STYLE_PROPERTY (property), value, scanner->section);
gtk_css_ruleset_add (ruleset, GTK_CSS_STYLE_PROPERTY (property), value, section);
} }
else else
{ {
@ -1080,8 +1017,7 @@ parse_declaration (GtkCssScanner *scanner,
_gtk_css_value_unref (value); _gtk_css_value_unref (value);
} }
g_clear_pointer (&section, gtk_css_section_unref);
gtk_css_scanner_pop_section (scanner);
} }
else else
{ {
@ -1091,7 +1027,6 @@ parse_declaration (GtkCssScanner *scanner,
g_free (name); g_free (name);
gtk_css_parser_end_block (scanner->parser); gtk_css_parser_end_block (scanner->parser);
gtk_css_scanner_pop_section (scanner);
} }
static void static void
@ -1110,14 +1045,11 @@ parse_ruleset (GtkCssScanner *scanner)
GSList *selectors; GSList *selectors;
GtkCssRuleset ruleset = { 0, }; GtkCssRuleset ruleset = { 0, };
gtk_css_scanner_push_section (scanner);
selectors = parse_selector_list (scanner); selectors = parse_selector_list (scanner);
if (selectors == NULL) if (selectors == NULL)
{ {
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY); gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
gtk_css_parser_skip (scanner->parser); gtk_css_parser_skip (scanner->parser);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
@ -1131,7 +1063,6 @@ parse_ruleset (GtkCssScanner *scanner)
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free); g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY); gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
gtk_css_parser_skip (scanner->parser); gtk_css_parser_skip (scanner->parser);
gtk_css_scanner_pop_section (scanner);
return; return;
} }
@ -1143,7 +1074,6 @@ parse_ruleset (GtkCssScanner *scanner)
css_provider_commit (scanner->provider, selectors, &ruleset); css_provider_commit (scanner->provider, selectors, &ruleset);
gtk_css_ruleset_clear (&ruleset); gtk_css_ruleset_clear (&ruleset);
gtk_css_scanner_pop_section (scanner);
} }
static void static void
@ -1158,8 +1088,6 @@ parse_statement (GtkCssScanner *scanner)
static void static void
parse_stylesheet (GtkCssScanner *scanner) parse_stylesheet (GtkCssScanner *scanner)
{ {
gtk_css_scanner_push_section (scanner);
while (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF)) while (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
{ {
if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_CDO) || if (gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_CDO) ||
@ -1171,8 +1099,6 @@ parse_stylesheet (GtkCssScanner *scanner)
parse_statement (scanner); parse_statement (scanner);
} }
gtk_css_scanner_pop_section (scanner);
} }
static int static int
@ -1248,13 +1174,10 @@ gtk_css_provider_load_internal (GtkCssProvider *css_provider,
{ {
GBytes *tmp_bytes = g_bytes_new_static ("", 0); GBytes *tmp_bytes = g_bytes_new_static ("", 0);
scanner = gtk_css_scanner_new (css_provider, scanner = gtk_css_scanner_new (css_provider,
NULL,
NULL, NULL,
file, file,
tmp_bytes); tmp_bytes);
g_bytes_unref (tmp_bytes); g_bytes_unref (tmp_bytes);
gtk_css_scanner_push_section (scanner);
} }
else else
scanner = parent; scanner = parent;
@ -1267,11 +1190,7 @@ gtk_css_provider_load_internal (GtkCssProvider *css_provider,
load_error->message); load_error->message);
if (parent == NULL) if (parent == NULL)
{ gtk_css_scanner_destroy (scanner);
gtk_css_scanner_pop_section (scanner);
gtk_css_scanner_destroy (scanner);
}
} }
} }
@ -1279,7 +1198,6 @@ gtk_css_provider_load_internal (GtkCssProvider *css_provider,
{ {
scanner = gtk_css_scanner_new (css_provider, scanner = gtk_css_scanner_new (css_provider,
parent, parent,
parent ? parent->section : NULL,
file, file,
bytes); bytes);

View File

@ -28,42 +28,43 @@ struct _GtkCssSection
GtkCssSection *parent; GtkCssSection *parent;
GFile *file; GFile *file;
GtkCssLocation start_location; GtkCssLocation start_location;
GtkCssParser *parser; /* parser if section isn't finished parsing yet or %NULL */
GtkCssLocation end_location; /* end location if parser is %NULL */ GtkCssLocation end_location; /* end location if parser is %NULL */
}; };
G_DEFINE_BOXED_TYPE (GtkCssSection, gtk_css_section, gtk_css_section_ref, gtk_css_section_unref) G_DEFINE_BOXED_TYPE (GtkCssSection, gtk_css_section, gtk_css_section_ref, gtk_css_section_unref)
/**
* gtk_css_section_new: (constructor)
* @file: (nullable) (transfer none): The file this section refers to
* @start: The start location
* @end: The end location
*
* Creates a new #GtkCssSection referring to the section
* in the given @file from the @start location to the
* @end location.
*
* Returns: a new #GtkCssSection
**/
GtkCssSection * GtkCssSection *
gtk_css_section_new_for_parser (GtkCssSection *parent, gtk_css_section_new (GFile *file,
GtkCssParser *parser) const GtkCssLocation *start,
const GtkCssLocation *end)
{ {
GtkCssSection *section; GtkCssSection *result;
gtk_internal_return_val_if_fail (parser != NULL, NULL); gtk_internal_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
gtk_internal_return_val_if_fail (start != NULL, NULL);
gtk_internal_return_val_if_fail (end != NULL, NULL);
section = g_slice_new0 (GtkCssSection); result = g_slice_new0 (GtkCssSection);
section->ref_count = 1; result->ref_count = 1;
if (parent) if (file)
section->parent = gtk_css_section_ref (parent); result->file = g_object_ref (file);
section->file = gtk_css_parser_get_file (parser); result->start_location = *start;
if (section->file) result->end_location = *end;
g_object_ref (section->file);
section->parser = parser;
section->start_location = *gtk_css_parser_get_start_location (section->parser);
return section; return result;
}
void
_gtk_css_section_end (GtkCssSection *section)
{
gtk_internal_return_if_fail (section != NULL);
gtk_internal_return_if_fail (section->parser != NULL);
section->end_location = *gtk_css_parser_get_end_location (section->parser);
section->parser = NULL;
} }
/** /**
@ -180,9 +181,6 @@ gtk_css_section_get_end_location (const GtkCssSection *section)
{ {
gtk_internal_return_val_if_fail (section != NULL, NULL); gtk_internal_return_val_if_fail (section != NULL, NULL);
if (section->parser)
return gtk_css_parser_get_end_location (section->parser);
return &section->end_location; return &section->end_location;
} }

View File

@ -37,6 +37,10 @@ typedef struct _GtkCssSection GtkCssSection;
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GType gtk_css_section_get_type (void) G_GNUC_CONST; GType gtk_css_section_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkCssSection * gtk_css_section_new (GFile *file,
const GtkCssLocation *start,
const GtkCssLocation *end);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL
GtkCssSection * gtk_css_section_ref (GtkCssSection *section); GtkCssSection * gtk_css_section_ref (GtkCssSection *section);
GDK_AVAILABLE_IN_ALL GDK_AVAILABLE_IN_ALL

View File

@ -24,11 +24,6 @@
G_BEGIN_DECLS G_BEGIN_DECLS
GtkCssSection * gtk_css_section_new_for_parser (GtkCssSection *parent,
GtkCssParser *parser);
void _gtk_css_section_end (GtkCssSection *section);
void _gtk_css_section_print (const GtkCssSection *section, void _gtk_css_section_print (const GtkCssSection *section,
GString *string); GString *string);
char * _gtk_css_section_to_string (const GtkCssSection *section); char * _gtk_css_section_to_string (const GtkCssSection *section);