diff --git a/blueprintcompiler/language/contexts.py b/blueprintcompiler/language/contexts.py index 069f4de..29d95de 100644 --- a/blueprintcompiler/language/contexts.py +++ b/blueprintcompiler/language/contexts.py @@ -36,6 +36,16 @@ class ValueTypeCtx: class ScopeCtx: node: AstNode + @cached_property + def template(self): + from .ui import UI + from .gtk_list_item_factory import ExtListItemFactory + + if isinstance(self.node, UI): + return self.node.template + elif isinstance(self.node, ExtListItemFactory): + return self.node + @cached_property def objects(self) -> T.Dict[str, Object]: return { @@ -45,6 +55,8 @@ class ScopeCtx: } def validate_unique_ids(self) -> None: + from .gtk_list_item_factory import ExtListItemFactory + passed = {} for obj in self._iter_recursive(self.node): if obj.tokens["id"] is None: @@ -52,7 +64,9 @@ class ScopeCtx: if obj.tokens["id"] in passed: token = obj.group.tokens["id"] - if not isinstance(obj, Template): + if not isinstance(obj, Template) and not isinstance( + obj, ExtListItemFactory + ): raise CompileError( f"Duplicate object ID '{obj.tokens['id']}'", token.start, diff --git a/blueprintcompiler/language/expression.py b/blueprintcompiler/language/expression.py index 3f816f3..314c753 100644 --- a/blueprintcompiler/language/expression.py +++ b/blueprintcompiler/language/expression.py @@ -106,7 +106,7 @@ class LiteralExpr(ExprBase): if isinstance(self.literal.value, IdentLiteral): if object := self.context[ScopeCtx].objects.get(self.literal.value.ident): - return not isinstance(object, Template) + return not object.gir_class.incomplete return True diff --git a/blueprintcompiler/language/gobject_signal.py b/blueprintcompiler/language/gobject_signal.py index e5c71c6..6cc0c5f 100644 --- a/blueprintcompiler/language/gobject_signal.py +++ b/blueprintcompiler/language/gobject_signal.py @@ -96,11 +96,6 @@ class Signal(AstNode): # This happens for classes defined by the app itself return - if isinstance(self.parent.parent, Template): - # If the signal is part of a template, it might be defined by - # the application and thus not in gir - return - if self.gir_signal is None: raise CompileError( f"Class {self.gir_class.full_name} does not contain a signal called {self.tokens['name']}", diff --git a/blueprintcompiler/language/gtk_list_item_factory.py b/blueprintcompiler/language/gtk_list_item_factory.py index 35695df..cf1a415 100644 --- a/blueprintcompiler/language/gtk_list_item_factory.py +++ b/blueprintcompiler/language/gtk_list_item_factory.py @@ -7,7 +7,7 @@ from .contexts import ScopeCtx class ExtListItemFactory(AstNode): - grammar = [Keyword("template"), Optional(TypeName), ObjectContent] + grammar = [UseExact("id", "template"), Optional(TypeName), ObjectContent] @property def type_name(self) -> T.Optional[TypeName]: diff --git a/blueprintcompiler/outputs/xml/__init__.py b/blueprintcompiler/outputs/xml/__init__.py index 020648c..0fc2c5e 100644 --- a/blueprintcompiler/outputs/xml/__init__.py +++ b/blueprintcompiler/outputs/xml/__init__.py @@ -8,7 +8,6 @@ from .xml_emitter import XmlEmitter class XmlOutput(OutputFormat): def emit(self, ui: UI) -> str: xml = XmlEmitter() - self._ui = ui self._emit_ui(ui, xml) return xml.result @@ -193,8 +192,11 @@ class XmlOutput(OutputFormat): xml.put_text(value.ident) elif isinstance(value_type, gir.Enumeration): xml.put_text(str(value_type.members[value.ident].value)) - elif value.ident == "template" and self._ui.template is not None: - xml.put_text(self._ui.template.gir_class.glib_type_name) + elif ( + value.ident == "template" + and value.context[ScopeCtx].template is not None + ): + xml.put_text(value.context[ScopeCtx].template.gir_class.glib_type_name) else: xml.put_text(value.ident) elif isinstance(value, TypeLiteral): diff --git a/tests/samples/list_factory.blp b/tests/samples/list_factory.blp index 118aaf3..27c65f2 100644 --- a/tests/samples/list_factory.blp +++ b/tests/samples/list_factory.blp @@ -4,7 +4,7 @@ Gtk.ListView { factory: Gtk.BuilderListItemFactory list_item_factory { template ListItem { child: Label { - label: "Hello"; + label: bind template.item as <$MyObject>.name; }; } }; diff --git a/tests/samples/list_factory.ui b/tests/samples/list_factory.ui index 664de85..447a53a 100644 --- a/tests/samples/list_factory.ui +++ b/tests/samples/list_factory.ui @@ -9,7 +9,13 @@