def operation_ip(self, tree: Tree): accessor, operator, expression = tree.children self.visit(expression) identifier, *_ = accessor.children if var := getVar(self.stack, identifier): var.writes.append(VariableAccess(tree, self.stack[-1].definition))
def index_setter(self, tree: Tree): accessor, index, expression = tree.children self.visit(expression) identifier, *not_implemented = accessor.children if not_implemented: return if var := getVar(self.stack, identifier): var.writes.append(VariableAccess(tree, self.stack[-1].definition))
def control_for(self, tree: Tree): _, var, _, expression, block = tree.children self.push_context(block.line, block.column) self.stack[-1].variables.append( VariableContext(var, VariableAccess(var, self.stack[-1].definition), False, False)) self.visit(expression) [self.visit(i) for i in block.children] self.pop_context()
def function_definition(self, tree: Tree): _, _name, parameter_list, _return_type, body = tree.children self.push_context(body.line, body.column) self_type, *parameters = parameter_list.children if self_type: self.stack[-1].variables.append( VariableContext( str(self_type), VariableAccess(self_type, self.stack[-1].definition), False, False)) [self.visit(i) for i in parameters] [self.visit(i) for i in body.children] self.pop_context()
def value(self, tree: Tree): value, = tree.children # simply extract the accessor part if isinstance(value, Tree) and value.data == "array_accessor": value = value.children[0] if isinstance(value, Tree) and value.data == "accessor": identifier, *not_implemented = value.children if not not_implemented: var = getVar(self.stack, identifier) if var: var.reads.append( VariableAccess(tree, self.stack[-1].definition)) elif isinstance(value, Tree) and value.data == "function_call": accessor, *arguments = value.children [self.visit(i) for i in arguments] base_obj, *children = accessor.children if children: self._handle_variable(str(base_obj), value) elif isinstance(value, Tree): for child in value.children: if isinstance(child, Tree): self.visit(child)
def function_parameter(self, tree: Tree): name, _type = tree.children self.stack[-1].variables.append( VariableContext(name, VariableAccess(tree, self.stack[-1].definition), False, False))
def _handle_variable(self, variable_name: str, declaration: Tree): if var := getVar(self.stack, variable_name): var.writes.append( VariableAccess(declaration, self.stack[-1].definition))
identifier, *not_implemented = value.children if not not_implemented: var = getVar(self.stack, identifier) if var: var.reads.append( VariableAccess(tree, self.stack[-1].definition)) elif isinstance(value, Tree) and value.data == "function_call": accessor, *arguments = value.children [self.visit(i) for i in arguments] base_obj, *children = accessor.children if children: self._handle_variable(str(base_obj), value) elif isinstance(value, Tree): for child in value.children: if isinstance(child, Tree): self.visit(child) ######################### # Utility functions ##### ######################### def _handle_variable(self, variable_name: str, declaration: Tree): if var := getVar(self.stack, variable_name): var.writes.append( VariableAccess(declaration, self.stack[-1].definition)) else: self.stack[-1].variables.append( VariableContext( variable_name, VariableAccess(declaration, self.stack[-1].definition), False, False))