From ebfcdb893d9338fe742a08c4fad011e69245f0ba Mon Sep 17 00:00:00 2001 From: CRoot Date: Tue, 9 Dec 2025 22:58:46 +0800 Subject: [PATCH 1/4] Add AST tree replacement class Support for replacing the current node during Visitor traversal. --- luaparser/ast.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/luaparser/ast.py b/luaparser/ast.py index 03cb44c..3328069 100644 --- a/luaparser/ast.py +++ b/luaparser/ast.py @@ -94,6 +94,41 @@ def default(self, o): def to_pretty_json(root: Node) -> str: return json.dumps(root, cls=JSONEncoder, indent=4) +class ASTReplaceVisitor: + def visit(self, root): + if root is None: + return + node_stack = [(root, None)] + + while len(node_stack) > 0: + node, parent = node_stack.pop() + + if isinstance(node, astnodes.Node): + name = "visit_" + node.__class__.__name__ + tree_visitor = getattr(self, name, None) + if tree_visitor: + new_node = tree_visitor(node) + if new_node != None: + for key in parent.__dict__.keys(): + if key == 'values' or key == 'args': + obj_list = getattr(parent, key, None) + for i, item in enumerate(obj_list): + # print(item) + if item is node: + obj_list[i] = new_node + + elif getattr(parent, key, None) is node: + setattr(parent, key, new_node) + + children = [ + attr for attr in node.__dict__.keys() if not attr.startswith("_") + ] + for child in reversed(children): + node_stack.append((node.__dict__[child], node)) + + elif isinstance(node, list): + for n in reversed(node): + node_stack.append((n, parent)) class ASTVisitor: def visit(self, root): From f88f69a606781ca0fb7d736f92e16ca07c5a16dd Mon Sep 17 00:00:00 2001 From: CRoot Date: Wed, 10 Dec 2025 09:28:02 +0800 Subject: [PATCH 2/4] Repair incomplete type matching --- luaparser/ast.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/luaparser/ast.py b/luaparser/ast.py index 3328069..21442e9 100644 --- a/luaparser/ast.py +++ b/luaparser/ast.py @@ -110,15 +110,16 @@ def visit(self, root): new_node = tree_visitor(node) if new_node != None: for key in parent.__dict__.keys(): - if key == 'values' or key == 'args': + # if key == 'values' or key == 'args': obj_list = getattr(parent, key, None) - for i, item in enumerate(obj_list): - # print(item) - if item is node: - obj_list[i] = new_node - - elif getattr(parent, key, None) is node: - setattr(parent, key, new_node) + if isinstance(obj_list, list): + for i, item in enumerate(obj_list): + # print(item) + if item is node: + obj_list[i] = new_node + + elif getattr(parent, key, None) is node: + setattr(parent, key, new_node) children = [ attr for attr in node.__dict__.keys() if not attr.startswith("_") From 15e1b1061d5ef0ce329ee7ac6db578ddb36ce127 Mon Sep 17 00:00:00 2001 From: CRoot Date: Wed, 10 Dec 2025 09:31:17 +0800 Subject: [PATCH 3/4] Optimize the code --- luaparser/ast.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/luaparser/ast.py b/luaparser/ast.py index 21442e9..fd03ef2 100644 --- a/luaparser/ast.py +++ b/luaparser/ast.py @@ -111,14 +111,14 @@ def visit(self, root): if new_node != None: for key in parent.__dict__.keys(): # if key == 'values' or key == 'args': - obj_list = getattr(parent, key, None) - if isinstance(obj_list, list): + obj = getattr(parent, key, None) + if isinstance(obj, list): for i, item in enumerate(obj_list): # print(item) if item is node: obj_list[i] = new_node - elif getattr(parent, key, None) is node: + elif obj is node: setattr(parent, key, new_node) children = [ From 8c49d0bcf32dad3983cd37ffc1beea45ca2f4c7b Mon Sep 17 00:00:00 2001 From: CRoot Date: Wed, 10 Dec 2025 09:31:38 +0800 Subject: [PATCH 4/4] Optimize the code. --- luaparser/ast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/luaparser/ast.py b/luaparser/ast.py index fd03ef2..79ea0be 100644 --- a/luaparser/ast.py +++ b/luaparser/ast.py @@ -113,10 +113,10 @@ def visit(self, root): # if key == 'values' or key == 'args': obj = getattr(parent, key, None) if isinstance(obj, list): - for i, item in enumerate(obj_list): + for i, item in enumerate(obj): # print(item) if item is node: - obj_list[i] = new_node + obj[i] = new_node elif obj is node: setattr(parent, key, new_node)