diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-08-08 18:13:00 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2024-08-15 23:59:08 +0300 |
commit | 50c92cc7e2924009ecab3e4004448b01d687707c (patch) | |
tree | c22b49816a3c79dae4727780962aa0928df42b52 /utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py | |
parent | d3bf27180ef1d91b86b7b87a2378e559eaff5455 (diff) |
meson: Move all code generation scripts to utils/codegen/
We have multiple code generation scripts in utils/, mixed with other
miscellaneous utilities, as well as a larger code base based on mojom in
utils/ipc/. To make code sharing easier between the generator scripts,
without creating a mess in the utils/ directory, move all the code
generation code to utils/codegen/.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Diffstat (limited to 'utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py')
-rwxr-xr-x | utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py b/utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py deleted file mode 100755 index 35cd1cfd..00000000 --- a/utils/ipc/mojo/public/tools/mojom/check_stable_mojom_compatibility.py +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -"""Verifies backward-compatibility of mojom type changes. - -Given a set of pre- and post-diff mojom file contents, and a root directory -for a project, this tool verifies that any changes to [Stable] mojom types are -backward-compatible with the previous version. - -This can be used e.g. by a presubmit check to prevent developers from making -breaking changes to stable mojoms.""" - -import argparse -import io -import json -import os -import os.path -import sys - -from mojom.generate import module -from mojom.generate import translate -from mojom.parse import parser - -# pylint: disable=raise-missing-from - - -class ParseError(Exception): - pass - - -def _ValidateDelta(root, delta): - """Parses all modified mojoms (including all transitive mojom dependencies, - even if unmodified) to perform backward-compatibility checks on any types - marked with the [Stable] attribute. - - Note that unlike the normal build-time parser in mojom_parser.py, this does - not produce or rely on cached module translations, but instead parses the full - transitive closure of a mojom's input dependencies all at once. - """ - - translate.is_running_backwards_compatibility_check_hack = True - - # First build a map of all files covered by the delta - affected_files = set() - old_files = {} - new_files = {} - for change in delta: - # TODO(crbug.com/953884): Use pathlib once we're migrated fully to Python 3. - filename = change['filename'].replace('\\', '/') - affected_files.add(filename) - if change['old']: - old_files[filename] = change['old'] - if change['new']: - new_files[filename] = change['new'] - - # Parse and translate all mojoms relevant to the delta, including transitive - # imports that weren't modified. - unmodified_modules = {} - - def parseMojom(mojom, file_overrides, override_modules): - if mojom in unmodified_modules or mojom in override_modules: - return - - contents = file_overrides.get(mojom) - if contents: - modules = override_modules - else: - modules = unmodified_modules - with io.open(os.path.join(root, mojom), encoding='utf-8') as f: - contents = f.read() - - try: - ast = parser.Parse(contents, mojom) - except Exception as e: - raise ParseError('encountered exception {0} while parsing {1}'.format( - e, mojom)) - - # Files which are generated at compile time can't be checked by this script - # (at the moment) since they may not exist in the output directory. - generated_files_to_skip = { - ('third_party/blink/public/mojom/runtime_feature_state/' - 'runtime_feature.mojom'), - ('third_party/blink/public/mojom/origin_trial_feature/' - 'origin_trial_feature.mojom'), - } - - ast.import_list.items = [ - x for x in ast.import_list.items - if x.import_filename not in generated_files_to_skip - ] - - for imp in ast.import_list: - if (not file_overrides.get(imp.import_filename) - and not os.path.exists(os.path.join(root, imp.import_filename))): - # Speculatively construct a path prefix to locate the import_filename - mojom_path = os.path.dirname(os.path.normpath(mojom)).split(os.sep) - test_prefix = '' - for path_component in mojom_path: - test_prefix = os.path.join(test_prefix, path_component) - test_import_filename = os.path.join(test_prefix, imp.import_filename) - if os.path.exists(os.path.join(root, test_import_filename)): - imp.import_filename = test_import_filename - break - parseMojom(imp.import_filename, file_overrides, override_modules) - - # Now that the transitive set of dependencies has been imported and parsed - # above, translate each mojom AST into a Module so that all types are fully - # defined and can be inspected. - all_modules = {} - all_modules.update(unmodified_modules) - all_modules.update(override_modules) - modules[mojom] = translate.OrderedModule(ast, mojom, all_modules) - - old_modules = {} - for mojom in old_files: - parseMojom(mojom, old_files, old_modules) - new_modules = {} - for mojom in new_files: - parseMojom(mojom, new_files, new_modules) - - # At this point we have a complete set of translated Modules from both the - # pre- and post-diff mojom contents. Now we can analyze backward-compatibility - # of the deltas. - # - # Note that for backward-compatibility checks we only care about types which - # were marked [Stable] before the diff. Types newly marked as [Stable] are not - # checked. - def collectTypes(modules): - types = {} - for m in modules.values(): - for kinds in (m.enums, m.structs, m.unions, m.interfaces): - for kind in kinds: - types[kind.qualified_name] = kind - return types - - old_types = collectTypes(old_modules) - new_types = collectTypes(new_modules) - - # Collect any renamed types so they can be compared accordingly. - renamed_types = {} - for name, kind in new_types.items(): - old_name = kind.attributes and kind.attributes.get('RenamedFrom') - if old_name: - renamed_types[old_name] = name - - for qualified_name, kind in old_types.items(): - if not kind.stable: - continue - - new_name = renamed_types.get(qualified_name, qualified_name) - if new_name not in new_types: - raise Exception( - 'Stable type %s appears to be deleted by this change. If it was ' - 'renamed, please add a [RenamedFrom] attribute to the new type. This ' - 'can be deleted by a subsequent change.' % qualified_name) - - checker = module.BackwardCompatibilityChecker() - try: - if not checker.IsBackwardCompatible(new_types[new_name], kind): - raise Exception( - 'Stable type %s appears to have changed in a way which ' - 'breaks backward-compatibility. Please fix!\n\nIf you ' - 'believe this assessment to be incorrect, please file a ' - 'Chromium bug against the "Internals>Mojo>Bindings" ' - 'component.' % qualified_name) - except Exception as e: - raise Exception( - 'Stable type %s appears to have changed in a way which ' - 'breaks backward-compatibility: \n\n%s.\nPlease fix!\n\nIf you ' - 'believe this assessment to be incorrect, please file a ' - 'Chromium bug against the "Internals>Mojo>Bindings" ' - 'component.' % (qualified_name, e)) - - -def Run(command_line, delta=None): - """Runs the tool with the given command_line. Normally this will read the - change description from stdin as a JSON-encoded list, but tests may pass a - delta directly for convenience.""" - arg_parser = argparse.ArgumentParser( - description='Verifies backward-compatibility of mojom type changes.', - epilog=""" -This tool reads a change description from stdin and verifies that all modified -[Stable] mojom types will retain backward-compatibility. The change description -must be a JSON-encoded list of objects, each with a "filename" key (path to a -changed mojom file, relative to ROOT); an "old" key whose value is a string of -the full file contents before the change, or null if the file is being added; -and a "new" key whose value is a string of the full file contents after the -change, or null if the file is being deleted.""") - arg_parser.add_argument( - '--src-root', - required=True, - action='store', - metavar='ROOT', - help='The root of the source tree in which the checked mojoms live.') - - args, _ = arg_parser.parse_known_args(command_line) - if not delta: - delta = json.load(sys.stdin) - _ValidateDelta(args.src_root, delta) - - -if __name__ == '__main__': - Run(sys.argv[1:]) |