def visit_Call(self, node): callvisitor = topics_in_file.FuncCallVisitor() callvisitor.visit(node.func) # moveToPose if self.move_to_pose_cmd in callvisitor.name: # save value to self.pose_cmd_frame_dict process_node_arg(self.pose_cmd_frame_dict, callvisitor.name.split('.')[0], node, 1, self.scopes) self.generic_visit(node)
def visit_Call(self, node): callvisitor = topics_in_file.FuncCallVisitor() callvisitor.visit(node.func) if callvisitor.name in self.msgTypeList: #################### ### Instantiation ## #################### # Twist msg if 'Twist' in callvisitor.name and len(node.args) == 2: self.save_vel_instantiation(node.args) self.generic_visit(node)
def save_vel_instantiation(self, node_args_list): attribute_field = ['x','y','z'] # for twist msg if isinstance(node_args_list[0], ast.Call): # instantiate with Vector3 callvisitor_twist_linear = topics_in_file.FuncCallVisitor() callvisitor_twist_linear.visit(node_args_list[0].func) for idx, ast_value_obj in enumerate(node_args_list[0].args): # lienar x, y, z self.out_of_bound_list.extend(check_and_save_attribute_and_value_to_dict(None, ast_value_obj, self.var_names_list, self.msg_fields_dict, \ scope=self.scopes[0], attribute_list=['linear', attribute_field[idx]], limits_dict=self.limits_dict,\ call_func_list=self.possible_subcall_func_list, call_func_hist=['Twist', [0, 'Vector3'], idx])) # TODO: get line number and replace later? if isinstance(node_args_list[1], ast.Call): # instantiate with Vector3 callvisitor_twist_angular = topics_in_file.FuncCallVisitor() callvisitor_twist_angular.visit(node_args_list[1].func) for idx, ast_value_obj in enumerate(node_args_list[1].args): # angular x, y, z self.out_of_bound_list.extend(check_and_save_attribute_and_value_to_dict(None, ast_value_obj, self.var_names_list, self.msg_fields_dict, \ scope=self.scopes[0], attribute_list=['angular', attribute_field[idx]], limits_dict=self.limits_dict,\ call_func_list=self.possible_subcall_func_list, call_func_hist=['Twist', [1, 'Vector3'], idx]))
def attribute_in_var_names_list(ast_attribute_obj, var_names_list): """ This function checks if part of a given attribute is in the var_names_list. It splits the attribute and returns a list if that's the case. """ attributevisitor = topics_in_file.FuncCallVisitor() attributevisitor.visit(ast_attribute_obj) parameters_logger.log(2, "Attribute name: {0}".format(attributevisitor.name)) # check if part of attribute is a msgType Object if any([x in attributevisitor.name for x in var_names_list]): parameters_logger.log(2, "Save Parameter: TRUE in var_names_list:{0}".format(var_names_list)) attribute_name_list = attributevisitor.name.replace(x+'.','').split('.') return True, attribute_name_list else: parameters_logger.log(2, "Save Parameter: FALSE in var_names_list:{0}".format(var_names_list)) return False, []
def process_node_arg(target_dict, dict_key, node, arg_idx, scopes): if isinstance(node.args[arg_idx], ast.Str): target_dict[dict_key] = node.args[arg_idx].s #original elif isinstance(node.args[arg_idx],ast.Name): if scopes[0].find(node.args[arg_idx].id): target_dict[dict_key] = node.args[arg_idx].id #original else: moveit_logger.warning('Cannot find variable:{0} in scopes!'.format(node.args[arg_idx].id)) elif isinstance(node.args[arg_idx],ast.Attribute): attr_value_visitor = topics_in_file.FuncCallVisitor() attr_value_visitor.visit(node.args[arg_idx]) attr_name = attr_value_visitor.name if scopes[0].find(attr_name): target_dict[dict_key] = scopes[0].find(attr_name) #original elif isinstance(node.args[0],ast.Add): pass
def visit_Assign(self, node): # FIXIT: skips Subscript objects, cannot use codegen #if isinstance(node.targets[0], ast.Subscript): # continue #moveit_logger.log(2, codegen.to_source(node)) moveit_logger.log(2, "------") moveit_logger.log(2, "node targets:{0}, node value: {1}".format(node.targets, node.value)) # save variables 'a = 1' to scope (Name -> Num) if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.Num): self.scopes[0].add(node.targets[0].id, node.value.n) # save variables 'a = [1,2,3]' to scope (Name -> List) elif len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.List)\ and (isinstance(node.value.ctx, ast.Load) or isinstance(node.value.ctx, ast.Store)): listVisitor = topics_in_file.ListVisitor(self.scopes[0]) listVisitor.visit(node.value) self.scopes[0].add(node.targets[0].id, listVisitor._name) # save variables 'a = "hello" to scope (Name -> str) elif len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.Str): self.scopes[0].add(node.targets[0].id, node.value.s) # check if it is MoveGroupInterface Instantiation elif isinstance(node.value, ast.Call): callvisitor = topics_in_file.FuncCallVisitor() callvisitor.visit(node.value.func) if callvisitor.name in self.interface_list: # store name to look for in the tree namevisitor = topics_in_file.FuncCallVisitor() namevisitor.visit(node.targets[0]) # save value to self.interface_dict process_node_arg(self.interface_dict, namevisitor.name, node.value, 0, self.scopes) # assign target is an attribute (Attribute -> ???) elif isinstance(node.targets[0], ast.Attribute): moveit_logger.debug('NEEDS TO BE DONE: assign target is a Attribute. node target[0]: {0}'.format(node.targets[0])) # assign target is a tuple (Tuple -> ???) elif isinstance(node.targets[0], ast.Tuple): moveit_logger.debug('NEEDS TO BE DONE: assign target is a Tuple. node target[0]: {0}'.format(node.targets[0])) # assign target is a list elif isinstance(node.value, ast.ListComp): moveit_logger.debug('NEEDS TO BE DONE: assign target is a listComp. node target[0]: {0}'.format(node.targets[0])) else: if len(node.targets) == 1: moveit_logger.debug("This assignment is not handled: target: {0}, value: {1}".format(\ type(node.targets[0]), type(node.value))) else: moveit_logger.debug("This assignment is not handled: target: {0}, value: {1}".format(\ type(node.targets), type(node.value)))
def visit_Assign(self, node): # FIXIT: skips Subscript objects, cannot use codegen #if isinstance(node.targets[0], ast.Subscript): # continue #parameters_logger.log(2, codegen.to_source(node)) parameters_logger.log(2, "------") parameters_logger.log(2, "node targets:{0}, node value: {1}".format(node.targets, node.value)) # save variables 'a = 1' to scope (Name -> Num) if len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.Num): self.scopes[0].add(node.targets[0].id, node.value.n) # save variables 'a = [1,2,3]' to scope (Name -> List) elif len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.List)\ and (isinstance(node.value.ctx, ast.Load) or isinstance(node.value.ctx, ast.Store)): listVisitor = topics_in_file.ListVisitor(self.scopes[0]) listVisitor.visit(node.value) self.scopes[0].add(node.targets[0].id, listVisitor._name) # save variables 'a = "hello" to scope (Name -> str) elif len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) \ and isinstance(node.value, ast.Str): self.scopes[0].add(node.targets[0].id, node.value.s) # check if it is initializing a msgType object (new Func Obj with msg_type) elif isinstance(node.value, ast.Call): callvisitor = topics_in_file.FuncCallVisitor() callvisitor.visit(node.value.func) if callvisitor.name in self.msgTypeList: # store name to look for in the tree namevisitor = topics_in_file.FuncCallVisitor() namevisitor.visit(node.targets[0]) if namevisitor.name not in self.var_names_list: self.var_names_list.append(namevisitor.name) parameters_logger.debug(node.value.args) #################### ### Instantiation ## #################### # Twist msg if 'Twist' in callvisitor.name and len(node.value.args) == 2: self.save_vel_instantiation(node.value.args) # assign target is an attribute (Attribute -> ???) elif isinstance(node.targets[0], ast.Attribute): # check if first part of attribute is a msgType Object self.out_of_bound_list.extend(check_and_save_attribute_and_value_to_dict(node.targets[0], node.value, self.var_names_list, \ self.msg_fields_dict, self.scopes[0], limits_dict=self.limits_dict,\ call_func_list=self.possible_subcall_func_list)) # assign target is a tuple (Tuple -> ???) elif isinstance(node.targets[0], ast.Tuple): for idx, item in enumerate(node.targets[0].elts): if isinstance(item, ast.Attribute): # check if first part of attribute is a msgType Object self.out_of_bound_list.extend(check_and_save_attribute_and_value_to_dict(item, node.value.elts[idx], self.var_names_list, \ self.msg_fields_dict, self.scopes[0],limits_dict=self.limits_dict,\ call_func_list=self.possible_subcall_func_list)) # assign target is a list elif isinstance(node.value, ast.ListComp): parameters_logger.debug('NEEDS TO BE DONE: assign target is a listComp. node target[0]: {0}'.format(node.targets[0])) else: if len(node.targets) == 1: parameters_logger.debug("This assignment is not handled: target: {0}, value: {1}".format(\ type(node.targets[0]), type(node.value))) else: parameters_logger.debug("This assignment is not handled: target: {0}, value: {1}".format(\ type(node.targets), type(node.value))) # TODO: what if the value is an equation self.generic_visit(node)
def check_and_save_attribute_and_value_to_dict(ast_attribute_obj, ast_value_obj, var_names_list, msg_fields_dict, \ scope=None, attribute_list=[], limits_dict={}, call_func_list=[], call_func_hist=None): """ This function updates msg_fields_dict if attribute(ast_attribute_obj) matches variables in var_names_list. The value of the assignment comes from ast_value_obj or scope ast_attribute_obj: object on the left side of the assignment ast_value_obj: object on the right side of the assignment var_names_list: variables that are associated with the msg type of interest msg_fields_dict: dictionary storing all possible values for the msg type of interest scope: previously saved variables attribute_list: a.b to ['a','b'], can be feed into the function to bypass 'attribute_in_var_names_list' limit_dict: a dictionary of value obj limits call_func_list: valid func call that we will save parameters e.g.:['JointTrajectoryPoint'] call_func_hist: history of related function call to the variable: e.g.: Twist(Vector3(-,1,-),....) -> ['Twist', [0, 'Vector3'], 1] for parameter replacement later """ out_of_bound_list = [] result = False if attribute_list: result = True if not result: result, attribute_list = attribute_in_var_names_list(ast_attribute_obj, var_names_list) parameters_logger.debug('result:{0}, attribute_list:{1}'.format(result, attribute_list)) # TODO: maybe we want the full list instead? including the name? if result: # get all fields and save to dict if isinstance(ast_value_obj, ast.Num): dict_insert(msg_fields_dict, attribute_list, ast_value_obj.n) # check limits if limits_dict: out_of_bound_tuple = check_limits_wrapper(attribute_list, ast_value_obj.n, limits_dict) if out_of_bound_tuple: out_of_bound_list.append(out_of_bound_tuple + (ast_value_obj.n, call_func_hist)) elif isinstance(ast_value_obj, ast.Name) and scope: if scope.find(ast_value_obj.id): dict_insert(msg_fields_dict, attribute_list, ast_value_obj.id) #dict_insert(msg_fields_dict, attribute_list, scope.find(ast_value_obj.id)) # check limits if limits_dict: for value in scope.find(ast_value_obj.id): out_of_bound_tuple = check_limits_wrapper(attribute_list, value, limits_dict) if out_of_bound_tuple: out_of_bound_list.append(out_of_bound_tuple + (ast_value_obj.id, call_func_hist)) elif isinstance(ast_value_obj, ast.List) and scope: parameters_logger.debug('List elts: {0}, ctx: {1}'.format(ast_value_obj.elts, ast_value_obj.ctx)) for ast_elts_obj in ast_value_obj.elts: #recursive for different fields check_and_save_attribute_and_value_to_dict(None, ast_elts_obj, var_names_list, msg_fields_dict, \ scope=scope, attribute_list=attribute_list, limits_dict=limits_dict, call_func_list=call_func_list, call_func_hist=call_func_hist) elif isinstance(ast_value_obj, ast.Call) and scope: callvisitor = topics_in_file.FuncCallVisitor() callvisitor.visit(ast_value_obj.func) # check if the function cal is valid for consideration if not call_func_list or callvisitor.name in call_func_list: for ast_args_obj in ast_value_obj.args: pass # only dealing with keywords now for ast_keywords_obj in ast_value_obj.keywords: check_and_save_attribute_and_value_to_dict(None, ast_keywords_obj.value, var_names_list, msg_fields_dict, \ scope=scope, attribute_list=attribute_list + [ast_keywords_obj.arg], limits_dict=limits_dict,\ call_func_list=call_func_list, call_func_hist=call_func_hist) parameters_logger.debug("Call Func name:{0}, Args:{1}, Keywords:{2}".format(\ callvisitor.name, ast_value_obj.args, ast_value_obj.keywords)) else: if not scope: parameters_logger.warning('scope is None!') else: parameters_logger.warning('not sure what to do with this: {0}'.format(type(ast_value_obj))) return out_of_bound_list