diff --git a/blueprintcompiler/decompiler.py b/blueprintcompiler/decompiler.py index 99901c1..de6c06f 100644 --- a/blueprintcompiler/decompiler.py +++ b/blueprintcompiler/decompiler.py @@ -51,9 +51,10 @@ class LineType(Enum): class DecompileCtx: - def __init__(self) -> None: + def __init__(self, parent_gir: T.Optional[GirContext] = None) -> None: + self.sub_decompiler = parent_gir is not None self._result: str = "" - self.gir = GirContext() + self.gir = parent_gir or GirContext() self._blocks_need_end: T.List[str] = [] self._last_line_type: LineType = LineType.NONE self._obj_type_stack: list[T.Optional[GirType]] = [] @@ -63,15 +64,19 @@ class DecompileCtx: @property def result(self) -> str: - import_lines = sorted( - [ - f"using {ns} {namespace.version};" - for ns, namespace in self.gir.namespaces.items() - if ns != "Gtk" - ] - ) - full_string = "\n".join(["using Gtk 4.0;", *import_lines]) + self._result - return formatter.format(full_string) + imports = "" + + if not self.sub_decompiler: + import_lines = sorted( + [ + f"using {ns} {namespace.version};" + for ns, namespace in self.gir.namespaces.items() + if ns != "Gtk" + ] + ) + imports += "\n".join(["using Gtk 4.0;", *import_lines]) + + return formatter.format(imports + self._result) def type_by_cname(self, cname: str) -> T.Optional[GirType]: if type := self.gir.get_type_by_cname(cname): @@ -131,6 +136,7 @@ class DecompileCtx: for child in self.root_node.children: if child.tag == "template": return child["class"] + return None def find_object(self, id: str) -> T.Optional[Element]: @@ -273,7 +279,7 @@ def decompile(data: str) -> str: return ctx.result -def decompile_string(data): +def decompile_string(data: str) -> str: ctx = DecompileCtx() xml = parse_string(data) @@ -417,6 +423,16 @@ def decompile_property( ctx.print(f"{name}: {translatable};") elif gir is None or gir.properties.get(name) is None: ctx.print(f"{name}: {escape_quote(cdata)};") + elif ( + gir.assignable_to(ctx.gir.get_class("BuilderListItemFactory", "Gtk")) + and name == "bytes" + ): + sub_ctx = DecompileCtx(ctx.gir) + + xml = parse_string(cdata) + decompile_element(sub_ctx, None, xml) + + ctx.print(sub_ctx.result) else: _, string = ctx.decompile_value(cdata, gir.properties.get(name).type) ctx.print(f"{name}: {string};") diff --git a/tests/samples/list_factory_dec.blp b/tests/samples/list_factory_dec.blp new file mode 100644 index 0000000..0ef0835 --- /dev/null +++ b/tests/samples/list_factory_dec.blp @@ -0,0 +1,11 @@ +using Gtk 4.0; + +ListView { + factory: BuilderListItemFactory list_item_factory { + template ListItem { + child: Label { + label: bind template.item as <$MyObject>.name; + }; + } + }; +} diff --git a/tests/samples/subscope.blp b/tests/samples/subscope.blp index 08c5959..0748089 100644 --- a/tests/samples/subscope.blp +++ b/tests/samples/subscope.blp @@ -1,8 +1,11 @@ using Gtk 4.0; +using Adw 1; Gtk.BuilderListItemFactory { template ListItem { - child: Gtk.Label label {}; + child: Adw.Bin { + Gtk.Label label {} + }; } } diff --git a/tests/samples/subscope.ui b/tests/samples/subscope.ui index 3513650..ef4e4db 100644 --- a/tests/samples/subscope.ui +++ b/tests/samples/subscope.ui @@ -11,7 +11,11 @@ corresponding .blp file and regenerate this file with blueprint-compiler. ]]> diff --git a/tests/samples/subscope_dec.blp b/tests/samples/subscope_dec.blp new file mode 100644 index 0000000..8d10855 --- /dev/null +++ b/tests/samples/subscope_dec.blp @@ -0,0 +1,12 @@ +using Gtk 4.0; +using Adw 1; + +BuilderListItemFactory { + template ListItem { + child: Adw.Bin { + Label label {} + }; + } +} + +Label label {} diff --git a/tests/test_samples.py b/tests/test_samples.py index 265a716..05dfb95 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -212,14 +212,8 @@ class TestSamples(unittest.TestCase): SKIP_DECOMPILE = [ # Not implemented yet "action_widgets", - # Not implemented yet - "gtkcolumnview", # Comments are not preserved in either direction "comments", - # Not implemented yet - "list_factory", - # Not implemented yet - "subscope", ] if sample in REQUIRE_ADW_1_4 and not self.have_adw_1_4: