11import ast
2+
3+ from ngcsimlib ._src .context .contextAwareObjectMeta import ContextAwareObjectMeta
24from ngcsimlib ._src .global_state .manager import global_state_manager
35from ngcsimlib ._src .logger import warn , error
46from ngcsimlib ._src .compartment .compartment import Compartment
@@ -14,9 +16,11 @@ def __init__(self, obj, method, subMethod=False):
1416 self .method = method
1517 self .current_args = set ()
1618 self .needed_keys = set ()
17- self .needed_methods = {}
1819 self .subMethod = subMethod
20+
21+ self .needed_methods = {}
1922 self .needed_globals = {}
23+ self .auxiliary_ast = {}
2024
2125 def visit_Return (self , node ):
2226 if self .subMethod :
@@ -46,8 +50,7 @@ def visit_FunctionDef(self, node):
4650
4751
4852 node .decorator_list = new_decorators
49-
50- node .name = self .obj .name + "_" + node .name
53+ node .name = self .obj .context_path .replace (":" , "_" ) + "_" + node .name
5154 self .generic_visit (node )
5255
5356 if not self .subMethod :
@@ -74,21 +77,47 @@ def visit_Attribute(self, node):
7477
7578 return ast .fix_missing_locations (new_node )
7679
80+ if hasattr (stateVal , '_is_compilable' ) and isinstance (type (stateVal ), ContextAwareObjectMeta ):
81+ return node
82+
7783 if callable (stateVal ):
78- method_name = f"{ self .obj .name } _{ node .attr } "
84+ method_name = f"{ self .obj .context_path . replace ( ':' , '_' ) } _{ node .attr } "
7985 new_node = ast .copy_location (ast .Name (id = method_name , ctx = node .ctx ), node )
8086 self .needed_methods [method_name ] = node .attr
8187 return ast .fix_missing_locations (new_node )
8288
83- attr_name = f"{ self .obj .name } _{ node .attr } "
89+ attr_name = f"{ self .obj .context_path . replace ( ':' , '_' ) } _{ node .attr } "
8490 new_node = ast .copy_location (ast .Name (id = attr_name , ctx = node .ctx ), node )
8591 self .needed_globals [attr_name ] = stateVal
8692 return ast .fix_missing_locations (new_node )
8793
8894 return node
8995
9096 def visit_Call (self , node ):
97+
9198 node = self .generic_visit (node )
99+
100+ if isinstance (node .func , ast .Attribute ) and isinstance (node .func .value , ast .Attribute ) \
101+ and isinstance (node .func .value .value , ast .Name ) and node .func .value .value .id == "self" :
102+ attr = getattr (self .obj , node .func .value .attr )
103+ if not isinstance (type (attr ), ContextAwareObjectMeta ):
104+ return node
105+
106+ subAttr = getattr (attr , node .func .attr )
107+ if not hasattr (subAttr , "compiled" ):
108+ error ("Attempting to use a method of a subcomponent that is not compiled/compilable" )
109+
110+ method_id = f"{ attr .context_path .replace (':' , '_' )} _{ node .func .attr } "
111+ subAst = subAttr .compiled .ast
112+ subAst .body [0 ].body = subAst .body [0 ].body [:- 1 ]
113+
114+ self .auxiliary_ast [method_id ] = subAst
115+ self .auxiliary_ast .update (subAttr .compiled .auxiliary_ast )
116+ self .needed_globals .update (subAttr .compiled .extra_globals )
117+
118+ node .func = ast .Name (id = method_id , ctx = ast .Load ())
119+ node .args = [ast .Name (id = 'ctx' , ctx = ast .Load ())] + node .args
120+
92121 if isinstance (node .func , ast .Attribute ) and node .func .attr == "get" :
93122 return node .func .value
94123
@@ -97,19 +126,6 @@ def visit_Call(self, node):
97126
98127 return node
99128
100- # def visit_Assign(self, node):
101- # for target in node.targets:
102- # if isinstance(target, ast.Name):
103- # target.id = f"{self.obj.name}_{target.id}"
104- # self.local_vars.add(target.id)
105- # return self.generic_visit(node)
106- #
107- #
108- # def visit_Name(self, node):
109- # # if node.id in self.local_vars:
110- # # node.id = f"{self.obj.name}_{node.id}"
111- # return node
112-
113129 def visit_Expr (self , node ):
114130 node = self .generic_visit (node )
115131 if isinstance (node .value , ast .Call ):
0 commit comments