Hook AST
Hook AST is a module allow users to hook each node of the AST and inspect the content.
To load this module you should write each hook on a file not load automatically and load it manually only when the plugin is loaded like the following example:
@ModuleStaticCmd("gen_hook", "generate hook", str, "+")
class GenHook:
"""
Class Generate Hook
To use:
--gen_hook <class>.<func>
"""
def __init__(self, package, tmp_dir, args):
load_module("GenHook", "GenHook_node")
for arg in args.gen_hook:
hooks = arg.split('.')
GenHook_node.ClassToHook.add_class(hooks[0])
GenHook_node.FuncToHook.add_func(hooks[1])
Output.add_printer_callback("tree", "gen_hook", "hook", mprint)
return None
Function add_printer_callback adds a custom printer to display your result. The function given as parameters take as an argument a list of objects given when you add a result of the function add_tree_mod.
The following code shows an example of custom print function:
def mprint(arg : list) -> str:
pad = "." * (48 - len(arg[0]))
return f"{arg[0]} {pad} {arg[1]} : {arg[2]}"
To hook a node you should use a decorator like the following example:
@Node("ClassDeclaration", "in")
class ClassDeclaration:
@classmethod
def call(cls, r, self):
for i in range(0, len(r["gen_hook_class"])):
if self.elt.name == ClassToHook.get_name()[i]:
r["gen_hook_class"][i] = True
return r
To add a result to print use function add_tree_mod like the following example:
@Node("Literal", "in")
class Literal:
@classmethod
def call(cls, r, self):
self.node_graph.Color = "red"
for k, names in SeekLiteral.get():
for name in names:
if re.search(name, self.elt.value):
self.node_graph.Color = "green"
Output.add_tree_mod("seek_literal", k,
[self.elt.value,
r["Filename"], self.elt._position],
r['instance'])
return r