Private
Public Access
0
0
Files
manual_slop/scripts/transform_render_methods.py
T

93 lines
2.8 KiB
Python

from __future__ import annotations
import ast
import sys
import os
import re
def transform_file(file_path: str) -> None:
"""
Refactors App._render_xxx methods to module-level functions for hot-reloading.
Now correctly renames 'self' to 'app' inside function bodies.
"""
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
tree = ast.parse(content)
class VariableRenamer(ast.NodeTransformer):
def visit_Name(self, node: ast.Name) -> ast.Name:
if node.id == "self":
node.id = "app"
return node
class RenderTransformer(ast.NodeTransformer):
def __init__(self):
self.new_functions = []
def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
if node.name != "App": return node
new_body = []
for item in node.body:
if isinstance(item, ast.FunctionDef) and item.name.startswith("_render_") and item.name != "_render_window_if_open":
func_name = item.name.lstrip("_")
# Transform body: rename 'self' to 'app'
renamer = VariableRenamer()
new_body_nodes = [renamer.visit(b) for b in item.body]
new_func = ast.FunctionDef(
name=func_name,
args=item.args,
body=new_body_nodes,
decorator_list=item.decorator_list,
returns=item.returns
)
if new_func.args.args and new_func.args.args[0].arg == "self":
new_func.args.args[0].arg = "app"
self.new_functions.append(new_func)
# Create delegation wrapper in class
wrapper_body = [
ast.Expr(
value=ast.Call(
func=ast.Name(id=func_name, ctx=ast.Load()),
args=[ast.Name(id="self", ctx=ast.Load())] + [ast.Name(id=a.arg, ctx=ast.Load()) for a in item.args.args[1:]],
keywords=[ast.keyword(arg=kw.arg, value=ast.Name(id=kw.arg, ctx=ast.Load())) for kw in item.args.kwonlyargs]
)
)
]
item.body = wrapper_body
new_body.append(item)
else:
new_body.append(item)
node.body = new_body
return node
transformer = RenderTransformer()
new_tree = transformer.visit(tree)
for func in transformer.new_functions:
new_tree.body.append(func)
ast.fix_missing_locations(new_tree)
if hasattr(ast, "unparse"):
raw_output = ast.unparse(new_tree)
lines = raw_output.splitlines()
new_lines = []
for line in lines:
match = re.match(r"^( +)(.*)", line)
if match:
spaces, rest = match.groups()
new_indent = " " * (len(spaces) // 4)
new_lines.append(new_indent + rest)
else:
new_lines.append(line)
final_content = "\n".join(new_lines)
with open(file_path, "w", encoding="utf-8") as f:
f.write(final_content)
print(f"Successfully transformed {file_path} with 1-space indentation and 'self'->'app' migration.")
else:
print("ast.unparse not available.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python scripts/transform_render_methods.py <file_path>")
else:
transform_file(sys.argv[1])