def bad_matches(self, var, other_type, node): """Match a Variable against a type. Return views that don't match. Args: var: A cfg.Variable, containing instances. other_type: An instance of AtomicAbstractValue. node: A cfg.CFGNode. The position in the CFG from which we "observe" the match. Returns: A list of all the views of var that didn't match. """ bad = [] views = abstract.get_views([var], node, filter_strict=True) skip_future = None while True: try: view = views.send(skip_future) except StopIteration: break if self.match_var_against_type(var, other_type, {}, node, view) is None: bad.append(view) # To get complete error messages, we need to collect all bad views, so # we can't skip any. skip_future = False else: skip_future = True return bad
def _instantiate_and_match(self, left, other_type, subst, node, view): """Instantiate and match an abstract value.""" instance = left.instantiate(node) for new_view in abstract.get_views([instance], node): # When new_view and view have entries in common, we want to use the # entries from the old view. new_view.update(view) new_subst = self.match_var_against_type(instance, other_type, subst, node, new_view) if new_subst is not None: return new_subst return None
def bad_matches(self, var, other_type, node): """Match a Variable against a type. Return views that don't match. Args: var: A cfg.Variable, containing instances. other_type: An instance of AtomicAbstractValue. node: A cfg.CFGNode. The position in the CFG from which we "observe" the match. Returns: A list of all the views of var that didn't match. """ bad = [] for view in abstract.get_views([var], node, filter_strict=True): if self.match_var_against_type(var, other_type, {}, node, view) is None: bad.append(view) return bad
def _instantiate_and_match(self, left, other_type, subst, node, view, container=None): """Instantiate and match an abstract value.""" instance = left.instantiate(node, container=container) new_substs = [] for new_view in abstract.get_views([instance], node): # When new_view and view have entries in common, we want to use the # entries from the old view. new_view.update(view) new_subst = self.match_var_against_type( instance, other_type, subst, node, new_view) if new_subst is not None: new_substs.append(new_subst) if new_substs: return self._merge_substs(subst, new_substs) else: return None
def _match_var(self, left, right): var = self.vm.program.NewVariable() var.AddBinding(left, [], self.vm.root_cfg_node) for view in abstract.get_views([var], self.vm.root_cfg_node): yield self.vm.matcher.match_var_against_type( var, right, {}, self.vm.root_cfg_node, view)