| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from typing import Sequence, TypeVar, Generic, List, Tuple, Callable, Dict |
| |
| from difl.ir import Declaration |
| from difl.changes import Change, DeclAdded, DeclRemoved |
| from difl.comparator import Comparator |
| |
| D = TypeVar('D', bound=Declaration) |
| |
| |
| def intersect_changes( |
| before: Sequence[D], |
| after: Sequence[D], |
| compare: Callable[[D, D, Comparator], List[Change]], |
| comparator: Comparator, |
| include_decl_added_and_decl_removed=True) -> List[Change]: |
| # dictionaries of declarations by name |
| before_by_name = {d.name: d for d in before} |
| after_by_name = {d.name: d for d in after} |
| # immutable sets of declaration names |
| before_names = frozenset(before_by_name.keys()) |
| after_names = frozenset(after_by_name.keys()) |
| |
| changes: List[Change] = [] |
| |
| if include_decl_added_and_decl_removed: |
| for decl in [after_by_name[n] for n in after_names - before_names]: |
| changes.append(DeclAdded(before=None, after=decl)) |
| for decl in [before_by_name[n] for n in before_names - after_names]: |
| changes.append(DeclRemoved(before=decl, after=None)) |
| for before_decl, after_decl in [ |
| (before_by_name[n], after_by_name[n]) |
| for n in before_names.intersection(after_names) |
| ]: |
| changes.extend(compare(before_decl, after_decl, comparator)) |
| |
| return changes |