mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
decompiler: Support sub-templates
Support GtkBuilderListItemFactory syntax by decompiling the nested XML, rather than preserving it as a string literal.
This commit is contained in:
parent
25d9826aea
commit
21d5ce86e9
6 changed files with 60 additions and 20 deletions
|
@ -51,9 +51,10 @@ class LineType(Enum):
|
||||||
|
|
||||||
|
|
||||||
class DecompileCtx:
|
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._result: str = ""
|
||||||
self.gir = GirContext()
|
self.gir = parent_gir or GirContext()
|
||||||
self._blocks_need_end: T.List[str] = []
|
self._blocks_need_end: T.List[str] = []
|
||||||
self._last_line_type: LineType = LineType.NONE
|
self._last_line_type: LineType = LineType.NONE
|
||||||
self._obj_type_stack: list[T.Optional[GirType]] = []
|
self._obj_type_stack: list[T.Optional[GirType]] = []
|
||||||
|
@ -63,15 +64,19 @@ class DecompileCtx:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def result(self) -> str:
|
def result(self) -> str:
|
||||||
import_lines = sorted(
|
imports = ""
|
||||||
[
|
|
||||||
f"using {ns} {namespace.version};"
|
if not self.sub_decompiler:
|
||||||
for ns, namespace in self.gir.namespaces.items()
|
import_lines = sorted(
|
||||||
if ns != "Gtk"
|
[
|
||||||
]
|
f"using {ns} {namespace.version};"
|
||||||
)
|
for ns, namespace in self.gir.namespaces.items()
|
||||||
full_string = "\n".join(["using Gtk 4.0;", *import_lines]) + self._result
|
if ns != "Gtk"
|
||||||
return formatter.format(full_string)
|
]
|
||||||
|
)
|
||||||
|
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]:
|
def type_by_cname(self, cname: str) -> T.Optional[GirType]:
|
||||||
if type := self.gir.get_type_by_cname(cname):
|
if type := self.gir.get_type_by_cname(cname):
|
||||||
|
@ -131,6 +136,7 @@ class DecompileCtx:
|
||||||
for child in self.root_node.children:
|
for child in self.root_node.children:
|
||||||
if child.tag == "template":
|
if child.tag == "template":
|
||||||
return child["class"]
|
return child["class"]
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_object(self, id: str) -> T.Optional[Element]:
|
def find_object(self, id: str) -> T.Optional[Element]:
|
||||||
|
@ -273,7 +279,7 @@ def decompile(data: str) -> str:
|
||||||
return ctx.result
|
return ctx.result
|
||||||
|
|
||||||
|
|
||||||
def decompile_string(data):
|
def decompile_string(data: str) -> str:
|
||||||
ctx = DecompileCtx()
|
ctx = DecompileCtx()
|
||||||
|
|
||||||
xml = parse_string(data)
|
xml = parse_string(data)
|
||||||
|
@ -417,6 +423,16 @@ def decompile_property(
|
||||||
ctx.print(f"{name}: {translatable};")
|
ctx.print(f"{name}: {translatable};")
|
||||||
elif gir is None or gir.properties.get(name) is None:
|
elif gir is None or gir.properties.get(name) is None:
|
||||||
ctx.print(f"{name}: {escape_quote(cdata)};")
|
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:
|
else:
|
||||||
_, string = ctx.decompile_value(cdata, gir.properties.get(name).type)
|
_, string = ctx.decompile_value(cdata, gir.properties.get(name).type)
|
||||||
ctx.print(f"{name}: {string};")
|
ctx.print(f"{name}: {string};")
|
||||||
|
|
11
tests/samples/list_factory_dec.blp
Normal file
11
tests/samples/list_factory_dec.blp
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
using Gtk 4.0;
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
Gtk.BuilderListItemFactory {
|
Gtk.BuilderListItemFactory {
|
||||||
template ListItem {
|
template ListItem {
|
||||||
child: Gtk.Label label {};
|
child: Adw.Bin {
|
||||||
|
Gtk.Label label {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,11 @@ corresponding .blp file and regenerate this file with blueprint-compiler.
|
||||||
<interface>
|
<interface>
|
||||||
<template class="GtkListItem">
|
<template class="GtkListItem">
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkLabel" id="label"></object>
|
<object class="AdwBin">
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="label"></object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
</property>
|
</property>
|
||||||
</template>
|
</template>
|
||||||
</interface>]]></property>
|
</interface>]]></property>
|
||||||
|
|
12
tests/samples/subscope_dec.blp
Normal file
12
tests/samples/subscope_dec.blp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
BuilderListItemFactory {
|
||||||
|
template ListItem {
|
||||||
|
child: Adw.Bin {
|
||||||
|
Label label {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label label {}
|
|
@ -212,14 +212,8 @@ class TestSamples(unittest.TestCase):
|
||||||
SKIP_DECOMPILE = [
|
SKIP_DECOMPILE = [
|
||||||
# Not implemented yet
|
# Not implemented yet
|
||||||
"action_widgets",
|
"action_widgets",
|
||||||
# Not implemented yet
|
|
||||||
"gtkcolumnview",
|
|
||||||
# Comments are not preserved in either direction
|
# Comments are not preserved in either direction
|
||||||
"comments",
|
"comments",
|
||||||
# Not implemented yet
|
|
||||||
"list_factory",
|
|
||||||
# Not implemented yet
|
|
||||||
"subscope",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if sample in REQUIRE_ADW_1_4 and not self.have_adw_1_4:
|
if sample in REQUIRE_ADW_1_4 and not self.have_adw_1_4:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue