From 948a98bc0ac23fa21d2522d501fb326977beef38 Mon Sep 17 00:00:00 2001 From: "Michael A. Wekesa" Date: Mon, 27 Nov 2023 23:59:05 +0300 Subject: [PATCH] add for checker for cmd ids orders and union types --- projects/jdwp/defs/command_sets/__init__.py | 9 +++ projects/jdwp/defs/schema.py | 2 +- .../jdwp/tools/check_command_ids_order.py | 34 +++++++++ projects/jdwp/tools/check_union_types.py | 74 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 projects/jdwp/defs/command_sets/__init__.py create mode 100644 projects/jdwp/tools/check_command_ids_order.py create mode 100644 projects/jdwp/tools/check_union_types.py diff --git a/projects/jdwp/defs/command_sets/__init__.py b/projects/jdwp/defs/command_sets/__init__.py new file mode 100644 index 0000000..03f9851 --- /dev/null +++ b/projects/jdwp/defs/command_sets/__init__.py @@ -0,0 +1,9 @@ +from projects.jdwp.defs.command_sets.virtual_machine import VirtualMachine +from projects.jdwp.defs.command_sets.reference_type import ReferenceType +from projects.jdwp.defs.command_sets.event_request import EventRequest + +ALL = [ + VirtualMachine, + ReferenceType, + EventRequest, +] diff --git a/projects/jdwp/defs/schema.py b/projects/jdwp/defs/schema.py index 3dda5dc..8f13095 100644 --- a/projects/jdwp/defs/schema.py +++ b/projects/jdwp/defs/schema.py @@ -92,7 +92,7 @@ class TaggedUnion(Generic[EnumT]): class UnionTag(Generic[EnumT]): """Union tag class type.""" - tag: IntegralType + type: IntegralType value: TypeAlias[EnumT] diff --git a/projects/jdwp/tools/check_command_ids_order.py b/projects/jdwp/tools/check_command_ids_order.py new file mode 100644 index 0000000..5c6dc78 --- /dev/null +++ b/projects/jdwp/tools/check_command_ids_order.py @@ -0,0 +1,34 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. + +from argparse import ArgumentParser +from projects.jdwp.defs.schema import CommandSet +from projects.jdwp.defs.command_sets import ALL + + +def check_command_ids(command_set: CommandSet) -> None: + try: + sorted_command_ids = [command.id for command in command_set.commands] + if sorted_command_ids != sorted(sorted_command_ids): + print(f"Command IDs in {command_set.name} are NOT in ascending order.") + exit(1) + except Exception as e: + print(f"Error checking command IDs in {command_set.name}: {e}") + exit(1) + + +def main() -> None: + parser = ArgumentParser(description="Check order of command IDs in command sets") + parser.add_argument("--command-set", type=str, help="Specific command set to check") + args = parser.parse_args() + + arg_command_set: str = args.command_set + + for command_set in ALL: + if arg_command_set: + if arg_command_set != command_set.name: + continue + check_command_ids(command_set) + + +if __name__ == "__main__": + main() diff --git a/projects/jdwp/tools/check_union_types.py b/projects/jdwp/tools/check_union_types.py new file mode 100644 index 0000000..1d4ae60 --- /dev/null +++ b/projects/jdwp/tools/check_union_types.py @@ -0,0 +1,74 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. + +from argparse import ArgumentParser +from projects.jdwp.defs.command_sets import ALL +from projects.jdwp.defs.schema import ( + Command, + CommandSet, + Struct, + TaggedUnion, + Type, + Array, + UnionTag, +) + + +def check_command_set(command_set: CommandSet) -> None: + for command in command_set.commands: + check_command(command) + + +def check_command(command: Command) -> None: + if command.out: + check_struct(command.out) + if command.reply: + check_struct(command.reply) + + +def check_struct(struct: Struct) -> None: + for field in struct.fields: + check_type(field.type) + + +def check_type(type: Type) -> None: + match type: + case Struct(): + check_struct(type) + case Array(): + check_struct(type.element_type) + case TaggedUnion(): + check_tagged_union(type) + + +def check_tagged_union(union: TaggedUnion) -> None: + tagged_union: UnionTag = union.tag.type + print(f"Checking tagged union '{union.tag.type}' with tag '{tagged_union.value}'") + for enum_value in tagged_union.value: + try: + union.cases[enum_value] + except KeyError: + print( + f"Error in tagged union '{union.tag.type}': Missing case for enum value '{enum_value}'" + ) + exit(1) + + for value in union.cases.values(): + check_struct(value) + + +def main() -> None: + parser = ArgumentParser(description="Check tagged union mappings in command sets") + parser.add_argument("--command-set", type=str, help="Specific command set to check") + args = parser.parse_args() + + arg_command_set: str = args.command_set + + for command_set in ALL: + if arg_command_set: + if arg_command_set != command_set.name: + continue + check_command_set(command_set) + + +if __name__ == "__main__": + main()