From 65d4612b51bc26681c1548cc367a2a8694869036 Mon Sep 17 00:00:00 2001 From: James Westman Date: Sat, 24 Aug 2024 13:24:27 -0500 Subject: [PATCH] decompiler: Support action widgets --- .../language/gtkbuilder_child.py | 15 ++++++---- blueprintcompiler/language/response_id.py | 29 +++++++++++++++++++ tests/test_samples.py | 2 -- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/blueprintcompiler/language/gtkbuilder_child.py b/blueprintcompiler/language/gtkbuilder_child.py index 3f19fa5..b0563ba 100644 --- a/blueprintcompiler/language/gtkbuilder_child.py +++ b/blueprintcompiler/language/gtkbuilder_child.py @@ -22,7 +22,7 @@ from functools import cached_property from .common import * from .gobject_object import Object -from .response_id import ExtResponse +from .response_id import ExtResponse, decompile_response_type ALLOWED_PARENTS: T.List[T.Tuple[str, str]] = [ ("Gtk", "Buildable"), @@ -127,10 +127,15 @@ class Child(AstNode): ) -@decompiler("child") -def decompile_child(ctx, gir, type=None, internal_child=None): - if type is not None: +@decompiler("child", element=True) +def decompile_child(ctx, gir, element): + if type := element["type"]: + if type == "action": + if decompiled := decompile_response_type(ctx.parent_node, element): + ctx.print(decompiled) + return + ctx.print(f"[{type}]") - elif internal_child is not None: + elif internal_child := element["internal-child"]: ctx.print(f"[internal-child {internal_child}]") return gir diff --git a/blueprintcompiler/language/response_id.py b/blueprintcompiler/language/response_id.py index 7de197c..8c0c807 100644 --- a/blueprintcompiler/language/response_id.py +++ b/blueprintcompiler/language/response_id.py @@ -123,3 +123,32 @@ class ExtResponse(AstNode): object = self.parent_by_type(Child).object return object.id + + +def decompile_response_type(parent_element, child_element): + obj_id = None + for obj in child_element.children: + if obj.tag == "object": + obj_id = obj["id"] + break + + if obj_id is None: + return None + + for child in parent_element.children: + if child.tag == "action-widgets": + for action_widget in child.children: + if action_widget.cdata == obj_id: + response_id = action_widget["response"] + is_default = ( + " default" if decompile.truthy(action_widget["default"]) else "" + ) + return f"[action response={response_id}{is_default}]" + + return None + + +@decompiler("action-widgets", skip_children=True) +def decompile_action_widgets(ctx, gir): + # This is handled in the decompiler and decompile_response_type above + pass diff --git a/tests/test_samples.py b/tests/test_samples.py index 05dfb95..1d1e17f 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -210,8 +210,6 @@ class TestSamples(unittest.TestCase): SKIP_COMPILE = ["translator_comments"] SKIP_DECOMPILE = [ - # Not implemented yet - "action_widgets", # Comments are not preserved in either direction "comments", ]