| # 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 List, Tuple, Iterable, Dict |
| |
| from difl.ir import * |
| from difl.changes import Change, DeclAdded, DeclRemoved |
| from difl.enums import enum_changes |
| from difl.protocol import protocol_changes |
| from difl.struct import struct_changes |
| from difl.table import table_changes |
| from difl.intersection import intersect_changes |
| from difl.comparator import Comparator |
| |
| |
| def libraries_changes(before: Libraries, after: Libraries, |
| comparator: Comparator) -> List[Change]: |
| # Only analyze libraries that exist before and after |
| return intersect_changes( |
| before, |
| after, |
| library_changes, |
| comparator, |
| include_decl_added_and_decl_removed=False) |
| |
| |
| def declaration_changes(before: Declaration, after: Declaration, |
| comparator: Comparator) -> List[Change]: |
| if isinstance(before, Enum) and isinstance(after, Enum): |
| return enum_changes(before, after, comparator) |
| if isinstance(before, Struct) and isinstance(after, Struct): |
| return struct_changes(before, after, comparator) |
| if isinstance(before, Table) and isinstance(after, Table): |
| return table_changes(before, after, comparator) |
| if isinstance(before, Protocol) and isinstance(after, Protocol): |
| return protocol_changes(before, after, comparator) |
| |
| if type(before) != type(after): |
| # TODO: create DeclarationTypeChanged or something |
| #print('TYPE CHANGED %r %r' % (before, after)) |
| return [] |
| |
| # TODO: support other declaration types |
| #print('UNHANDLED DECLARATION: %r %r' % (before, after)) |
| return [] |
| |
| |
| def library_changes(before: Library, after: Library, |
| comparator: Comparator) -> List[Change]: |
| changes: List[Change] = [] |
| |
| for name in after.declaration_order: |
| after_decl = after.declarations[name] |
| before_decl = before.declarations.get(name) |
| if before_decl is None: |
| changes.append(DeclAdded(before=None, after=after_decl)) |
| continue |
| changes.extend( |
| declaration_changes(before_decl, after_decl, comparator)) |
| for name, before_decl in before.declarations.items(): |
| if name not in after.declarations: |
| changes.append(DeclRemoved(before=before_decl, after=None)) |
| return changes |