From 60f91734216c478fcc1f9c67c82cc53d00b0b5ad Mon Sep 17 00:00:00 2001 From: James Westman Date: Sat, 13 May 2023 16:49:12 -0500 Subject: [PATCH] Add type to BuilderListItemFactory extension Makes it a little clearer how it works. --- .../language/gtk_list_item_factory.py | 29 ++++++++++++++++++- tests/sample_errors/list_factory.blp | 5 ++++ tests/sample_errors/list_factory.err | 1 + tests/sample_errors/subscope.blp | 2 +- tests/samples/list_factory.blp | 2 +- tests/samples/subscope.blp | 2 +- tests/test_samples.py | 1 + 7 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 tests/sample_errors/list_factory.blp create mode 100644 tests/sample_errors/list_factory.err diff --git a/blueprintcompiler/language/gtk_list_item_factory.py b/blueprintcompiler/language/gtk_list_item_factory.py index 9aab904..35695df 100644 --- a/blueprintcompiler/language/gtk_list_item_factory.py +++ b/blueprintcompiler/language/gtk_list_item_factory.py @@ -2,11 +2,19 @@ from .gobject_object import ObjectContent, validate_parent_type from ..parse_tree import Keyword from ..ast_utils import AstNode, validate from .common import * +from .types import TypeName from .contexts import ScopeCtx class ExtListItemFactory(AstNode): - grammar = [Keyword("template"), ObjectContent] + grammar = [Keyword("template"), Optional(TypeName), ObjectContent] + + @property + def type_name(self) -> T.Optional[TypeName]: + if len(self.children[TypeName]) == 1: + return self.children[TypeName][0] + else: + return None @property def gir_class(self): @@ -21,6 +29,25 @@ class ExtListItemFactory(AstNode): "sub-templates", ) + @validate() + def type_is_list_item(self): + if self.type_name is not None: + if self.type_name.glib_type_name != "GtkListItem": + raise CompileError(f"Only Gtk.ListItem is allowed as a type here") + + @validate("template") + def type_name_upgrade(self): + if self.type_name is None: + raise UpgradeWarning( + "Expected type name after 'template' keyword", + actions=[ + CodeAction( + "Add ListItem type to template block (introduced in blueprint 0.8.0)", + "template ListItem", + ) + ], + ) + @context(ScopeCtx) def scope_ctx(self) -> ScopeCtx: return ScopeCtx(node=self) diff --git a/tests/sample_errors/list_factory.blp b/tests/sample_errors/list_factory.blp new file mode 100644 index 0000000..bf0cbb1 --- /dev/null +++ b/tests/sample_errors/list_factory.blp @@ -0,0 +1,5 @@ +using Gtk 4.0; + +BuilderListItemFactory { + template Label {} +} \ No newline at end of file diff --git a/tests/sample_errors/list_factory.err b/tests/sample_errors/list_factory.err new file mode 100644 index 0000000..adfd57b --- /dev/null +++ b/tests/sample_errors/list_factory.err @@ -0,0 +1 @@ +4,3,17,Only Gtk.ListItem is allowed as a type here \ No newline at end of file diff --git a/tests/sample_errors/subscope.blp b/tests/sample_errors/subscope.blp index 59d3a9f..d90a350 100644 --- a/tests/sample_errors/subscope.blp +++ b/tests/sample_errors/subscope.blp @@ -1,7 +1,7 @@ using Gtk 4.0; BuilderListItemFactory { - template { + template ListItem { child: label; } } diff --git a/tests/samples/list_factory.blp b/tests/samples/list_factory.blp index ead74c3..118aaf3 100644 --- a/tests/samples/list_factory.blp +++ b/tests/samples/list_factory.blp @@ -2,7 +2,7 @@ using Gtk 4.0; Gtk.ListView { factory: Gtk.BuilderListItemFactory list_item_factory { - template { + template ListItem { child: Label { label: "Hello"; }; diff --git a/tests/samples/subscope.blp b/tests/samples/subscope.blp index a14591b..03643f4 100644 --- a/tests/samples/subscope.blp +++ b/tests/samples/subscope.blp @@ -1,7 +1,7 @@ using Gtk 4.0; Gtk.BuilderListItemFactory { - template { + template ListItem { child: Gtk.Label label {}; } } diff --git a/tests/test_samples.py b/tests/test_samples.py index 66faef1..bf26640 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -267,6 +267,7 @@ class TestSamples(unittest.TestCase): self.assert_sample_error("invalid_bool") self.assert_sample_error("layout_in_non_widget") self.assert_sample_error("legacy_template") + self.assert_sample_error("list_factory") self.assert_sample_error("menu_no_id") self.assert_sample_error("menu_toplevel_attribute") self.assert_sample_error("no_import_version")