Fix 'template' keyword in list item factories

This commit is contained in:
James Westman 2023-05-13 20:15:28 -05:00
parent 5a782c653b
commit 46e467bbfb
7 changed files with 30 additions and 13 deletions

View file

@ -36,6 +36,16 @@ class ValueTypeCtx:
class ScopeCtx: class ScopeCtx:
node: AstNode 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 @cached_property
def objects(self) -> T.Dict[str, Object]: def objects(self) -> T.Dict[str, Object]:
return { return {
@ -45,6 +55,8 @@ class ScopeCtx:
} }
def validate_unique_ids(self) -> None: def validate_unique_ids(self) -> None:
from .gtk_list_item_factory import ExtListItemFactory
passed = {} passed = {}
for obj in self._iter_recursive(self.node): for obj in self._iter_recursive(self.node):
if obj.tokens["id"] is None: if obj.tokens["id"] is None:
@ -52,7 +64,9 @@ class ScopeCtx:
if obj.tokens["id"] in passed: if obj.tokens["id"] in passed:
token = obj.group.tokens["id"] token = obj.group.tokens["id"]
if not isinstance(obj, Template): if not isinstance(obj, Template) and not isinstance(
obj, ExtListItemFactory
):
raise CompileError( raise CompileError(
f"Duplicate object ID '{obj.tokens['id']}'", f"Duplicate object ID '{obj.tokens['id']}'",
token.start, token.start,

View file

@ -106,7 +106,7 @@ class LiteralExpr(ExprBase):
if isinstance(self.literal.value, IdentLiteral): if isinstance(self.literal.value, IdentLiteral):
if object := self.context[ScopeCtx].objects.get(self.literal.value.ident): if object := self.context[ScopeCtx].objects.get(self.literal.value.ident):
return not isinstance(object, Template) return not object.gir_class.incomplete
return True return True

View file

@ -96,11 +96,6 @@ class Signal(AstNode):
# This happens for classes defined by the app itself # This happens for classes defined by the app itself
return 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: if self.gir_signal is None:
raise CompileError( raise CompileError(
f"Class {self.gir_class.full_name} does not contain a signal called {self.tokens['name']}", f"Class {self.gir_class.full_name} does not contain a signal called {self.tokens['name']}",

View file

@ -7,7 +7,7 @@ from .contexts import ScopeCtx
class ExtListItemFactory(AstNode): class ExtListItemFactory(AstNode):
grammar = [Keyword("template"), Optional(TypeName), ObjectContent] grammar = [UseExact("id", "template"), Optional(TypeName), ObjectContent]
@property @property
def type_name(self) -> T.Optional[TypeName]: def type_name(self) -> T.Optional[TypeName]:

View file

@ -8,7 +8,6 @@ from .xml_emitter import XmlEmitter
class XmlOutput(OutputFormat): class XmlOutput(OutputFormat):
def emit(self, ui: UI) -> str: def emit(self, ui: UI) -> str:
xml = XmlEmitter() xml = XmlEmitter()
self._ui = ui
self._emit_ui(ui, xml) self._emit_ui(ui, xml)
return xml.result return xml.result
@ -193,8 +192,11 @@ class XmlOutput(OutputFormat):
xml.put_text(value.ident) xml.put_text(value.ident)
elif isinstance(value_type, gir.Enumeration): elif isinstance(value_type, gir.Enumeration):
xml.put_text(str(value_type.members[value.ident].value)) xml.put_text(str(value_type.members[value.ident].value))
elif value.ident == "template" and self._ui.template is not None: elif (
xml.put_text(self._ui.template.gir_class.glib_type_name) value.ident == "template"
and value.context[ScopeCtx].template is not None
):
xml.put_text(value.context[ScopeCtx].template.gir_class.glib_type_name)
else: else:
xml.put_text(value.ident) xml.put_text(value.ident)
elif isinstance(value, TypeLiteral): elif isinstance(value, TypeLiteral):

View file

@ -4,7 +4,7 @@ Gtk.ListView {
factory: Gtk.BuilderListItemFactory list_item_factory { factory: Gtk.BuilderListItemFactory list_item_factory {
template ListItem { template ListItem {
child: Label { child: Label {
label: "Hello"; label: bind template.item as <$MyObject>.name;
}; };
} }
}; };

View file

@ -9,7 +9,13 @@
<template class="GtkListItem"> <template class="GtkListItem">
<property name="child"> <property name="child">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label">Hello</property> <binding name="label">
<lookup name="name" type="MyObject">
<lookup name="item" type="GtkListItem">
<constant>GtkListItem</constant>
</lookup>
</lookup>
</binding>
</object> </object>
</property> </property>
</template> </template>