def combine_states(self, left, right): state = State(left.name, [left], left.type, 'branch', self.locate(), read=left.read, set=left.set, over=left.over, over_position=left.over_position) if right is None: state.read = 'no' if left.read == 'no' else 'maybe' state.set = 'no' if left.set == 'no' else 'maybe' state.over = 'no' if left.over == 'no' else 'maybe' else: if not are_types_equal(left.type, right.type): self.report_issue("Type changes", { 'name': left.name, 'old': left.type, 'new': right.type }) state.read = Tifa.match_rso(left.read, right.read) state.set = Tifa.match_rso(left.set, right.set) state.over = Tifa.match_rso(left.over, right.over) if left.over == 'no': state.over_position = right.over_position state.trace.append(right) return state
def combine_states(self, left, right): """ Args: left: right: Returns: """ state = State(left.name, [left], left.type, 'branch', self.locate(), read=left.read, set=left.set, over=left.over, over_position=left.over_position) if right is None: state.read = 'no' if left.read == 'no' else 'maybe' state.set = 'no' if left.set == 'no' else 'maybe' state.over = 'no' if left.over == 'no' else 'maybe' else: if not are_types_equal(left.type, right.type): self._issue(type_changes(self.locate(), left.name, left.type, right.type)) state.read = self.match_rso(left.read, right.read) state.set = self.match_rso(left.set, right.set) state.over = self.match_rso(left.over, right.over) if left.over == 'no': state.over_position = right.over_position state.trace.append(right) return state
def store_variable(self, name, store_type, position=None, force_create=False): """ Update the variable with the given name to now have the new type. Args: name (str): The unqualified name of the variable. The variable will be assumed to be in the current scope. store_type (Type): The new type of this variable. position: The location that this store occurred at Returns: State: The new state of the variable. """ if position is None: position = self.locate() full_name = self._scope_chain_str(name) current_path = self.path_chain[0] variable = self.find_variable_scope(name) if not variable.exists or force_create: # Create a new instance of the variable on the current path new_state = State(name, [], store_type, 'store', position, read='no', set='yes', over='no') self.name_map[current_path][full_name] = new_state else: new_state = self.trace_state(variable.state, "store", position) if not variable.in_scope: self._issue( write_out_of_scope(self.locate(), name, report=self.report)) # Type change? if not are_types_equal(store_type, variable.state.type): self._issue( type_changes(position, name, variable.state.type, store_type)) new_state.type = store_type # Overwritten? if variable.state.set == 'yes' and variable.state.read == 'no': new_state.over_position = position new_state.over = 'yes' else: new_state.set = 'yes' new_state.read = 'no' self.name_map[current_path][full_name] = new_state # If this is a class scope... current_scope = self.scope_chain[0] if current_scope in self.class_scopes: self.class_scopes[current_scope].add_attr(name, new_state.type) return new_state
def store_variable(self, name, type, position=None): ''' Update the variable with the given name to now have the new type. Args: name (str): The unqualified name of the variable. The variable will be assumed to be in the current scope. type (Type): The new type of this variable. Returns: State: The new state of the variable. ''' if position is None: position = self.locate() full_name = self._scope_chain_str(name) current_path = self.path_chain[0] variable = self.find_variable_scope(name) if not variable.exists: # Create a new instance of the variable on the current path new_state = State(name, [], type, 'store', position, read='no', set='yes', over='no') self.name_map[current_path][full_name] = new_state else: new_state = self.trace_state(variable.state, "store", position) if not variable.in_scope: self.report_issue("Write out of scope", {'name': name}) # Type change? if not are_types_equal(type, variable.state.type): self.report_issue( "Type changes", { 'name': name, 'old': variable.state.type, 'new': type, 'position': position }) new_state.type = type # Overwritten? if variable.state.set == 'yes' and variable.state.read == 'no': new_state.over_position = position new_state.over = 'yes' else: new_state.set = 'yes' new_state.read = 'no' self.name_map[current_path][full_name] = new_state return new_state
def store_variable(self, name, type, position=None): """ Update the variable with the given name to now have the new type. Args: name (str): The unqualified name of the variable. The variable will be assumed to be in the current scope. type (Type): The new type of this variable. Returns: State: The new state of the variable. """ if position is None: position = self.locate() full_name = self._scope_chain_str(name) current_path = self.path_chain[0] variable = self.find_variable_scope(name) if not variable.exists: # Create a new instance of the variable on the current path new_state = State(name, [], type, 'store', position, read='no', set='yes', over='no') self.name_map[current_path][full_name] = new_state else: new_state = self.trace_state(variable.state, "store", position) if not variable.in_scope: self.report_issue("Write out of scope", {'name': name}) # Type change? if not are_types_equal(type, variable.state.type): self.report_issue("Type changes", {'name': name, 'old': variable.state.type, 'new': type, 'position': position}) new_state.type = type # Overwritten? if variable.state.set == 'yes' and variable.state.read == 'no': new_state.over_position = position new_state.over = 'yes' else: new_state.set = 'yes' new_state.read = 'no' self.name_map[current_path][full_name] = new_state # If this is a class scope... current_scope = self.scope_chain[0] if current_scope in self.class_scopes: self.class_scopes[current_scope].add_attr(name, new_state.type) return new_state
def combine_states(self, left, right): state = State(left.name, [left], left.type, 'branch', self.locate(), read=left.read, set=left.set, over=left.over, over_position=left.over_position) if right is None: state.read = 'no' if left.read == 'no' else 'maybe' state.set = 'no' if left.set == 'no' else 'maybe' state.over = 'no' if left.over == 'no' else 'maybe' else: if not are_types_equal(left.type, right.type): self.report_issue("Type changes", {'name': left.name, 'old': left.type, 'new': right.type}) state.read = Tifa.match_rso(left.read, right.read) state.set = Tifa.match_rso(left.set, right.set) state.over = Tifa.match_rso(left.over, right.over) if left.over == 'no': state.over_position = right.over_position state.trace.append(right) return state