From 60dc679878847a2b7bcf667b44cdf86fd1a5d789 Mon Sep 17 00:00:00 2001 From: Andres Toom Date: Thu, 10 Oct 2024 14:44:23 +0300 Subject: [PATCH] Add style check for unsigned integers specified as range integers Ref. eng/recordflux/RecordFlux#1775 --- CHANGELOG.md | 7 + rflx/model/type_decl.py | 38 +++++- tests/compilation/integration_test.py | 29 +++-- tests/data/models.py | 39 ++---- tests/data/specs.py | 2 +- tests/integration/cli_test.py | 2 +- tests/integration/pyrflx_test.py | 2 +- tests/integration/specification_model_test.py | 68 +++++----- tests/tools/check_doc_test.py | 4 +- tests/unit/graph_test.py | 12 +- tests/unit/ls/server_test.py | 4 +- tests/unit/model/cache_test.py | 12 +- tests/unit/model/message_test.py | 43 +++--- tests/unit/model/model_test.py | 21 ++- tests/unit/model/type_decl_test.py | 24 +++- tests/unit/pyrflx/typevalue_test.py | 25 ++-- tests/unit/specification/parser_test.py | 122 ++++++++---------- tests/unit/specification/style_test.py | 12 +- tests/verification/integration_test.py | 10 +- 19 files changed, 240 insertions(+), 236 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e33563abc..101c57cff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Style check for unsigned integer syntax (eng/recordflux/RecordFlux#1775) + ## [0.25.0] - 2024-11-05 ### Added @@ -612,6 +618,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.1.0] - 2019-05-14 +[Unreleased]: https://github.com/AdaCore/RecordFlux/compare/v0.25.0...HEAD [0.25.0]: https://github.com/AdaCore/RecordFlux/compare/v0.24.0...v0.25.0 [0.24.0]: https://github.com/AdaCore/RecordFlux/compare/v0.23.0...v0.24.0 [0.23.0]: https://github.com/AdaCore/RecordFlux/compare/v0.22.0...v0.23.0 diff --git a/rflx/model/type_decl.py b/rflx/model/type_decl.py index c8a3f6e84..de1fb357b 100644 --- a/rflx/model/type_decl.py +++ b/rflx/model/type_decl.py @@ -104,13 +104,14 @@ def constraints( class Integer(Scalar): - def __init__( + def __init__( # noqa: PLR0913 self, identifier: StrID, first: expr.Expr, last: expr.Expr, size: expr.Expr, location: Location = NO_LOCATION, + allow_full_unsigned: bool = False, ) -> None: super().__init__(identifier, size, location) @@ -204,6 +205,29 @@ def simplify(expression: expr.Expr) -> expr.Expr: ), ) + if ( + not allow_full_unsigned + and int(first_num) == 0 + and int(last_num) == 2 ** int(size_num) - 1 + ): + assert self.location is not None + self.error.push( + ErrorEntry( + "unsigned integer syntax preferable", + Severity.ERROR, + self.location, + annotations=( + [ + Annotation( + f'use "type {self.name} is unsigned {int(size_num)}" instead', + Severity.HELP, + self.location, + ), + ] + ), + ), + ) + self.error.propagate() self._first_expr = first @@ -318,7 +342,8 @@ def __init__( location=size.location, ), size, - location, + location=location, + allow_full_unsigned=True, ) def __str__(self) -> str: @@ -695,7 +720,14 @@ def checked( skip_verification: bool = False, # noqa: ARG002 workers: int = 1, # noqa: ARG002 ) -> Integer: - return Integer(self.identifier, self.first, self.last, self.size, self.location) + return Integer( + self.identifier, + self.first, + self.last, + self.size, + location=self.location, + allow_full_unsigned=False, + ) @dataclass diff --git a/tests/compilation/integration_test.py b/tests/compilation/integration_test.py index b086c0ca9..85a4e1140 100644 --- a/tests/compilation/integration_test.py +++ b/tests/compilation/integration_test.py @@ -49,7 +49,7 @@ def test_type_name_equals_package_name(definition: str, tmp_path: Path) -> None: spec = """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Test is {}; @@ -181,7 +181,7 @@ def test_sequence_with_imported_element_type_scalar(tmp_path: Path) -> None: p.parse_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; end Test; """, ) @@ -225,7 +225,8 @@ def test_sequence_with_imported_element_type_message(tmp_path: Path) -> None: @pytest.mark.parametrize( "type_definition", [ - "range 0 .. 2 ** 63 - 1 with Size => 63", + "unsigned 63", + "range 1 .. 2 ** 63 - 1 with Size => 63", "range 2 ** 8 .. 2 ** 48 with Size => 63", "(A, B, C) with Size => 63", "(A, B, C) with Always_Valid, Size => 63", @@ -249,7 +250,7 @@ def test_message_fixed_size_sequence(tmp_path: Path) -> None: """\ package Test is - type E is range 0 .. 2 ** 8 - 1 with Size => 8; + type E is unsigned 8; type S is sequence of E; @@ -291,7 +292,7 @@ def test_message_with_optional_field_based_on_message_size(tmp_path: Path) -> No """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -321,7 +322,7 @@ def test_size_attribute(tmp_path: Path, aspects: str) -> None: f"""\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -341,7 +342,7 @@ def test_message_size_calculation(tmp_path: Path) -> None: """\ package Test is - type T is range 0 .. 2 ** 16 - 1 with Size => 16; + type T is unsigned 16; type Message is message @@ -364,7 +365,7 @@ def test_transitive_type_use(tmp_path: Path) -> None: """\ package Test is - type U8 is range 0 .. 2 ** 8 - 1 with Size => 8; + type U8 is unsigned 8; type M1 is message @@ -436,7 +437,7 @@ def test_refinement_with_self(tmp_path: Path) -> None: type Tag is (T1 => 1, T2 => 2) with Size => 8; - type Length is range 0 .. 2 ** 8 - 1 with Size => 8; + type Length is unsigned 8; type Message is message @@ -463,7 +464,7 @@ def test_message_expression_value_outside_type_range(tmp_path: Path) -> None: spec = """\ package Test is - type Length is range 0 .. 2 ** 8 - 1 with Size => 8; + type Length is unsigned 8; type Packet is message @@ -484,7 +485,7 @@ def test_message_field_conditions_on_corresponding_fields(tmp_path: Path) -> Non spec = """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -507,7 +508,7 @@ def test_message_field_conditions_on_subsequent_fields(tmp_path: Path) -> None: spec = """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -601,7 +602,7 @@ def test_state_machine_type_conversion_in_message_size_calculation(tmp_path: Pat spec = """\ package Test is - type Length is range 0 .. 2 ** 8 - 1 with Size => 8; + type Length is unsigned 8; type Elems is range 0 .. 1 with Size => 8; type Data is @@ -646,7 +647,7 @@ def test_state_machine_move_content_of_opaque_field(tmp_path: Path) -> None: spec = """\ package Test is - type Payload_Size is range 0 .. 2 ** 16 - 1 with Size => 16; + type Payload_Size is unsigned 16; type M1 is message diff --git a/tests/data/models.py b/tests/data/models.py index a1ce06742..1ff24f3bb 100644 --- a/tests/data/models.py +++ b/tests/data/models.py @@ -49,6 +49,7 @@ State, StateMachine, Transition, + UnsignedInteger, ) @@ -77,11 +78,9 @@ def tlv_tag() -> Enumeration: @lru_cache -def tlv_length() -> Integer: - return Integer( +def tlv_length() -> UnsignedInteger: + return UnsignedInteger( ID("TLV::Length", location=Location((1, 1))), - Number(0), - Sub(Pow(Number(2), Number(16)), Number(1)), Number(16), location=Location((1, 1)), ) @@ -160,21 +159,17 @@ def tlv_with_checksum_tag() -> Enumeration: @lru_cache -def tlv_with_checksum_length() -> Integer: - return Integer( +def tlv_with_checksum_length() -> UnsignedInteger: + return UnsignedInteger( "TLV_With_Checksum::Length", - Number(0), - Sub(Pow(Number(2), Number(16)), Number(1)), Number(16), ) @lru_cache -def tlv_with_checksum_checksum() -> Integer: - return Integer( +def tlv_with_checksum_checksum() -> UnsignedInteger: + return UnsignedInteger( "TLV_With_Checksum::Checksum", - Number(0), - Sub(Pow(Number(2), Number(16)), Number(1)), Number(16), ) @@ -261,10 +256,8 @@ def null_message_in_tlv_message_model() -> Model: @lru_cache def ethernet_address() -> Integer: - return Integer( + return UnsignedInteger( "Ethernet::Address", - Number(0), - Sub(Pow(Number(2), Number(48)), Number(1)), Number(48), ) @@ -286,10 +279,8 @@ def ethernet_tpid() -> Integer: @lru_cache def ethernet_tci() -> Integer: - return Integer( + return UnsignedInteger( "Ethernet::TCI", - Number(0), - Sub(Pow(Number(2), Number(16)), Number(1)), Number(16), ) @@ -446,10 +437,8 @@ def enumeration_model() -> Model: @lru_cache def sequence_length() -> Integer: - return Integer( + return UnsignedInteger( "Sequence::Length", - Number(0), - Sub(Pow(Number(2), Number(8)), Number(1)), Number(8), ) @@ -752,20 +741,16 @@ def universal_message_type() -> Enumeration: @lru_cache def universal_length() -> Integer: - return Integer( + return UnsignedInteger( "Universal::Length", - Number(0), - Sub(Pow(Number(2), Number(16)), Number(1)), Number(16), ) @lru_cache def universal_value() -> Integer: - return Integer( + return UnsignedInteger( "Universal::Value", - Number(0), - Sub(Pow(Number(2), Number(8)), Number(1)), Number(8), ) diff --git a/tests/data/specs.py b/tests/data/specs.py index 653abcb4f..508cf2854 100644 --- a/tests/data/specs.py +++ b/tests/data/specs.py @@ -1,7 +1,7 @@ DEFINITE_MESSAGE_WITH_BUILTIN_TYPE_SPEC = """\ package Test is - type Length is range 0 .. 2 ** 7 - 1 with Size => 7; + type Length is unsigned 7; type Message is message diff --git a/tests/integration/cli_test.py b/tests/integration/cli_test.py index d138d87e9..e879341aa 100644 --- a/tests/integration/cli_test.py +++ b/tests/integration/cli_test.py @@ -36,7 +36,7 @@ def test_parse_no_subsequent_errors_caused_by_style_errors(tmp_path: Path) -> No """\ package B is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message diff --git a/tests/integration/pyrflx_test.py b/tests/integration/pyrflx_test.py index 12c69cccf..1bab26057 100644 --- a/tests/integration/pyrflx_test.py +++ b/tests/integration/pyrflx_test.py @@ -610,7 +610,7 @@ def test_simplification_of_div_expressions() -> None: """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Test is message diff --git a/tests/integration/specification_model_test.py b/tests/integration/specification_model_test.py index c333bd1de..1fe7e6303 100644 --- a/tests/integration/specification_model_test.py +++ b/tests/integration/specification_model_test.py @@ -16,13 +16,13 @@ OPAQUE, Enumeration, Field, - Integer, Link, Message, Model, State, StateMachine, Transition, + UnsignedInteger, declaration as decl, statement as stmt, ) @@ -81,7 +81,7 @@ def test_message_field_first_conflict() -> None: """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message @@ -107,7 +107,7 @@ def test_message_field_size_conflict() -> None: """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message @@ -209,7 +209,7 @@ def test_refinement_invalid_field() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message Foo : T; @@ -248,7 +248,7 @@ def test_model_name_conflict_messages() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message Foo : T; @@ -290,7 +290,7 @@ def test_model_name_conflict_derivations() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type Foo is message Foo : T; @@ -308,7 +308,7 @@ def test_model_name_conflict_state_machines() -> None: assert_error_string( """\ package Test is - type X is range 0 .. 2 ** 8 - 1 with Size => 8; + type X is unsigned 8; generic machine X is @@ -330,7 +330,7 @@ def test_model_illegal_first_aspect_on_initial_link() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message null @@ -348,7 +348,7 @@ def test_model_errors_in_type_and_state_machine() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 65 - 1 with Size => 65; + type T is unsigned 65; generic machine S is @@ -357,7 +357,7 @@ def test_model_errors_in_type_and_state_machine() -> None: end Test; """, r"^" - r':2:25: error: last of "T" exceeds limit \(2\*\*63 - 1\)\n' + r':2:23: error: last of "T" exceeds limit \(2\*\*63 - 1\)\n' r":4:4: error: empty states" r"$", ) @@ -368,7 +368,7 @@ def test_message_with_two_size_fields() -> None: p.parse_string( """\ package Test is - type Length is range 0 .. 2 ** 8 - 1 with Size => 8; + type Length is unsigned 8; type Packet is message Length_1 : Length; @@ -389,7 +389,7 @@ def test_message_same_field_and_type_name_with_different_size() -> None: """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -409,7 +409,7 @@ def test_invalid_implicit_size() -> None: """\ package Test is - type Kind is range 0 .. 2 ** 16 - 1 with Size => 16; + type Kind is unsigned 16; type M is message @@ -437,7 +437,7 @@ def test_invalid_use_of_message_type_with_implicit_size() -> None: """\ package Test is - type T is range 0 .. 2 ** 16 - 1 with Size => 16; + type T is unsigned 16; type Inner is message @@ -489,7 +489,7 @@ def test_invalid_message_with_field_after_field_with_implicit_size() -> None: """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message @@ -578,10 +578,8 @@ def test_consistency_specification_parsing_generation(tmp_path: Path) -> None: expr.Number(8), always_valid=False, ) - length = Integer( + length = UnsignedInteger( "Test::Length", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(16)), expr.Number(1)), expr.Number(16), ) message = Message( @@ -669,10 +667,8 @@ def test_consistency_specification_parsing_generation(tmp_path: Path) -> None: ], [BOOLEAN, OPAQUE, tag, length, message], ) - t = Integer( + t = UnsignedInteger( "Test::T", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(16)), expr.Number(1)), expr.Number(16), ) model = Model([BOOLEAN, OPAQUE, tag, length, message, state_machine, t]) @@ -792,9 +788,9 @@ def test_rfi_files(tmp_path: Path, rfi_content: str, match_error: str) -> None: package Test is type Message_Type is (MT_Null => 0, MT_Data => 1) with Size => 8; - type Length is range 0 .. 2 ** 16 - 1 with Size => 16; + type Length is unsigned 16; - type Value is range 0 .. 255 with Size => 8; + type Value is unsigned 8; type Message is message @@ -1009,7 +1005,7 @@ def test_message_negative_field_size(tmp_path: Path, capfd: pytest.CaptureFixtur textwrap.dedent( """\ package Test is - type I is range 0 .. 2 ** 32 - 1 with Size => 32; + type I is unsigned 32; type M is message F1 : I @@ -1539,7 +1535,7 @@ def test_type_range_last_exceeds_limit( textwrap.dedent( """\ package Test is - type T is range 0 .. 2 ** 64 - 1 with Size => 64; + type T is range 1 .. 2 ** 64 - 1 with Size => 64; end Test; """, ), @@ -1555,7 +1551,7 @@ def test_type_range_last_exceeds_limit( error: last of "T" exceeds limit (2**63 - 1) --> {file_path}:2:25 | - 2 | type T is range 0 .. 2 ** 64 - 1 with Size => 64; + 2 | type T is range 1 .. 2 ** 64 - 1 with Size => 64; | ^^^^^^^^^^^ | """, @@ -1764,7 +1760,7 @@ def test_invalid_refinement_base(tmp_path: Path, capfd: pytest.CaptureFixture[st textwrap.dedent( """\ package Test is - type I is range 0 .. 255 with Size => 8; + type I is unsigned 8; type I2 is new I; end Test; """, @@ -1782,7 +1778,7 @@ def test_invalid_refinement_base(tmp_path: Path, capfd: pytest.CaptureFixture[st error: invalid derivation --> {tmp_file}:3:9 | - 2 | type I is range 0 .. 255 with Size => 8; + 2 | type I is unsigned 8; | - note: base type must be a message 3 | type I2 is new I; | ^^ @@ -1905,7 +1901,7 @@ def test_condition_is_always_true( textwrap.dedent( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message A : T @@ -1930,8 +1926,8 @@ def test_condition_is_always_true( error: condition is always true --> {file_path}:7:19 | - 2 | type T is range 0 .. 255 with Size => 8; - | ---------------------------------- note: unsatisfied "A <= 255" + 2 | type T is unsigned 8; + | --------------- note: unsatisfied "A <= 255" 3 | type M is ... 6 | then B @@ -2002,7 +1998,7 @@ def test_aggregate_type_in_condition( textwrap.dedent( """\ package Test is - type I is range 0 .. 255 with Size => 8; + type I is unsigned 8; type M (A : I) is message X : Boolean @@ -2177,7 +2173,7 @@ def test_reserved_word_link_condition( textwrap.dedent( f"""\ package Test is - type I is range 0 .. 255 with Size => 8; + type I is unsigned 8; type M (A : Boolean) is message X : Boolean @@ -2227,7 +2223,7 @@ def test_size_aspect_defined_twice_in_message_field( textwrap.dedent( """\ package Test is - type I is range 0 .. 255 with Size => 8; + type I is unsigned 8; type M is message One : I @@ -2251,8 +2247,8 @@ def test_size_aspect_defined_twice_in_message_field( error: fixed size field "One" does not permit a size aspect --> {file_path}:6:26 | - 2 | type I is range 0 .. 255 with Size => 8; - | - note: associated type size \ + 2 | type I is unsigned 8; + | - note: associated type size \ defined here 3 | type M is 4 | message diff --git a/tests/tools/check_doc_test.py b/tests/tools/check_doc_test.py index c909be4a2..c84054f1f 100644 --- a/tests/tools/check_doc_test.py +++ b/tests/tools/check_doc_test.py @@ -252,7 +252,7 @@ def test_invalid_rflx_spec_style() -> None: package Protocol is -- Invalid indentation - type Len is range 0 .. 2 ** 8 - 1 with Size => 8; + type Len is unsigned 8; end Protocol; Some more text... @@ -347,7 +347,7 @@ def test_valid_rflx_spec() -> None: .. code:: rflx package Protocol is - type Len is range 0 .. 2 ** 8 - 1 with Size => 8; + type Len is unsigned 8; type Values is (E1, E2, E3) with Size => 16; end Protocol; diff --git a/tests/unit/graph_test.py b/tests/unit/graph_test.py index e735f7d98..d120a32cd 100644 --- a/tests/unit/graph_test.py +++ b/tests/unit/graph_test.py @@ -3,7 +3,7 @@ import pytest from pydotplus import Dot, InvocationException # type: ignore[attr-defined] -from rflx.expr import FALSE, TRUE, Equal, Greater, Less, Number, Pow, Sub, Variable +from rflx.expr import FALSE, TRUE, Equal, Greater, Less, Number, Variable from rflx.graph import create_message_graph, create_state_machine_graph, write_graph from rflx.identifier import ID from rflx.model import ( @@ -11,12 +11,12 @@ FINAL, INITIAL, Field, - Integer, Link, Message, State, StateMachine, Transition, + UnsignedInteger, declaration as decl, statement as stmt, ) @@ -31,7 +31,7 @@ def assert_graph(graph: Dot, expected: str, tmp_path: Path) -> None: def test_graph_object() -> None: - f_type = Integer("P::T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + f_type = UnsignedInteger("P::T", Number(32)) m = Message( ID("P::M", Location((1, 1))), structure=[ @@ -82,7 +82,7 @@ def test_empty_message_graph(tmp_path: Path) -> None: def test_dot_graph(tmp_path: Path) -> None: - f_type = Integer("P::T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + f_type = UnsignedInteger("P::T", Number(32)) m = Message( ID("P::M", Location((1, 1))), structure=[ @@ -117,7 +117,7 @@ def test_dot_graph(tmp_path: Path) -> None: def test_dot_graph_with_condition(tmp_path: Path) -> None: - f_type = Integer("P::T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + f_type = UnsignedInteger("P::T", Number(32)) m = Message( ID("P::M", Location((1, 1))), structure=[ @@ -157,7 +157,7 @@ def test_dot_graph_with_condition(tmp_path: Path) -> None: def test_dot_graph_with_double_edge(tmp_path: Path) -> None: - f_type = Integer("P::T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + f_type = UnsignedInteger("P::T", Number(32)) m = Message( ID("P::M", Location((1, 1))), structure=[ diff --git a/tests/unit/ls/server_test.py b/tests/unit/ls/server_test.py index 1aa939673..9bea9c58f 100644 --- a/tests/unit/ls/server_test.py +++ b/tests/unit/ls/server_test.py @@ -249,7 +249,7 @@ def test_verify(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: document = tmp_path / "test.rflx" document.write_text( - "package Test is type T is range 0 .. 2 ** 64 - 1 with Size => 64; end Test;", + "package Test is type T is unsigned 64; end Test;", ) document_uri = document.absolute().as_uri() @@ -268,7 +268,7 @@ def test_verify(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: document.absolute().as_uri(), [ Diagnostic( - Range(Position(0, 37), Position(0, 48)), + Range(Position(0, 35), Position(0, 37)), 'last of "T" exceeds limit (2**63 - 1)', DiagnosticSeverity.Error, ), diff --git a/tests/unit/model/cache_test.py b/tests/unit/model/cache_test.py index 1c4a0a9ef..8845bbdb3 100644 --- a/tests/unit/model/cache_test.py +++ b/tests/unit/model/cache_test.py @@ -45,10 +45,8 @@ def test_verified(tmp_path: Path) -> None: model.Link(model.Field("A"), model.FINAL, location=Location((2, 2))), ], { - model.Field(ID("A", location=Location((1, 1)))): model.Integer( + model.Field(ID("A", location=Location((1, 1)))): model.UnsignedInteger( "P::T", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(8)), expr.Number(1)), expr.Number(8), ), }, @@ -62,10 +60,8 @@ def test_verified(tmp_path: Path) -> None: model.Link(model.Field("B"), model.FINAL, location=Location((2, 2))), ], { - model.Field(ID("B", location=Location((1, 1)))): model.Integer( + model.Field(ID("B", location=Location((1, 1)))): model.UnsignedInteger( "P::T", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(8)), expr.Number(1)), expr.Number(8), ), }, @@ -79,10 +75,8 @@ def test_verified(tmp_path: Path) -> None: model.Link(model.Field("A"), model.FINAL, location=Location((2, 2))), ], { - model.Field(ID("A", location=Location((1, 1)))): model.Integer( + model.Field(ID("A", location=Location((1, 1)))): model.UnsignedInteger( "P::T", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(16)), expr.Number(1)), expr.Number(16), ), }, diff --git a/tests/unit/model/message_test.py b/tests/unit/model/message_test.py index 442dfa5af..312cd7517 100644 --- a/tests/unit/model/message_test.py +++ b/tests/unit/model/message_test.py @@ -61,6 +61,7 @@ UncheckedDerivedMessage, UncheckedMessage, UncheckedRefinement, + UnsignedInteger, type_decl, ) from rflx.model.message import ByteOrder, annotate_path @@ -293,7 +294,7 @@ def test_missing_type() -> None: def test_illegal_first_aspect_at_initial_link() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = type_decl.UnsignedInteger("P::T", Number(1)) structure = [ Link(INITIAL, Field("X"), first=Number(2, location=Location((10, 20)))), @@ -333,7 +334,7 @@ def test_name_conflict_field_enum() -> None: def test_duplicate_link() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = type_decl.UnsignedInteger("P::T", Number(1)) x = Field(ID("X", location=Location((1, 5)))) structure = [ @@ -355,7 +356,7 @@ def test_duplicate_link() -> None: def test_multiple_duplicate_links() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = UnsignedInteger("P::T", Number(1)) x = Field(ID("X", location=Location((1, 5)))) y = Field(ID("Y", location=Location((2, 5)))) @@ -430,7 +431,7 @@ def test_unreachable_field() -> None: def test_cycle() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = UnsignedInteger("P::T", Number(1)) structure = [ Link(INITIAL, Field(ID("X")), location=Location((3, 5))), Link(Field(ID("X")), Field(ID("Y")), location=Location((4, 5))), @@ -453,7 +454,7 @@ def test_cycle() -> None: def test_direct_cycle() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = UnsignedInteger("P::T", Number(1)) x = Field(ID("X")) y = Field(ID("Y")) @@ -476,7 +477,7 @@ def test_direct_cycle() -> None: def test_nested_cycle() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = UnsignedInteger("P::T", Number(1)) a = Field(ID("A")) b = Field(ID("B")) c = Field(ID("C")) @@ -517,7 +518,7 @@ def test_nested_cycle() -> None: def test_two_cycles() -> None: - t = Integer("P::T", Number(0), Number(1), Number(1)) + t = UnsignedInteger("P::T", Number(1)) a = Field(ID("A")) b = Field(ID("B")) c = Field(ID("C")) @@ -913,7 +914,7 @@ def test_undefined_variable( operation: abc.Callable[[Expr, Expr], Expr], condition: tuple[Expr, Expr], ) -> None: - mod_type = Integer("P::MT", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + mod_type = UnsignedInteger("P::MT", Number(32)) enum_type = Enumeration( "P::ET", [("Val1", Number(0)), ("Val2", Number(1))], @@ -941,7 +942,7 @@ def test_undefined_variable( def test_undefined_variable_boolean_condition_value() -> None: - mod_type = Integer("P::MT", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + mod_type = UnsignedInteger("P::MT", Number(32)) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), condition=Variable("X", location=Location((10, 20)))), @@ -957,7 +958,7 @@ def test_undefined_variable_boolean_condition_value() -> None: def test_undefined_variable_size() -> None: - mod_type = Integer("P::MT", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + mod_type = UnsignedInteger("P::MT", Number(32)) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), size=Variable("Field_Size", location=Location((10, 20)))), @@ -973,7 +974,7 @@ def test_undefined_variable_size() -> None: def test_undefined_variable_first() -> None: - mod_type = Integer("P::MT", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + mod_type = UnsignedInteger("P::MT", Number(32)) structure = [ Link(INITIAL, Field("F1")), Link(Field("F1"), Field("F2"), size=Variable("Field_First", location=Location((10, 20)))), @@ -1015,7 +1016,7 @@ def test_undefined_variables() -> None: def test_subsequent_variable() -> None: f1 = Field(ID("F1", location=Location((1, 1)))) f2 = Field(ID("F2", location=Location((2, 2)))) - t = Integer("P::T", Number(0), Sub(Pow(Number(2), Number(32)), Number(1)), Number(32)) + t = UnsignedInteger("P::T", Number(32)) structure = [ Link(INITIAL, f1), Link(f1, f2, Equal(Variable("F2", location=Location((1024, 57))), Number(42))), @@ -1191,7 +1192,7 @@ def test_invalid_relation_to_aggregate() -> None: @pytest.mark.parametrize("lower", [Number(0), Number(1)]) def test_invalid_element_in_relation_to_aggregate(lower: Number) -> None: - integer = Integer("P::Integer", lower, Number(255), Number(8)) + integer = Integer("P::Integer", lower, Number(255), Number(8), allow_full_unsigned=True) structure = [ Link(INITIAL, Field(ID("F1", location=Location((1, 2))))), Link( @@ -1324,7 +1325,7 @@ def test_field_size_is_aggregate() -> None: Link(Field(ID("G", location=Location((4, 1)))), FINAL, location=Location((4, 2))), ] - i = Integer("P::I", Number(0), Number(1), Number(1)) + i = UnsignedInteger("P::I", Number(1)) types = {Field("F"): i, Field("G"): OPAQUE} assert_message_model_error( @@ -1419,10 +1420,8 @@ def test_opaque_not_byte_aligned_dynamic() -> None: ], { Field(ID("L1", location=Location((1, 3)))): models.integer(), - Field(ID("L2", location=Location((2, 6)))): Integer( + Field(ID("L2", location=Location((2, 6)))): UnsignedInteger( "P::T", - Number(0), - Number(3), Number(2), ), Field(ID("O1", location=Location((3, 5)))): OPAQUE, @@ -2414,8 +2413,8 @@ def test_incongruent_overlay() -> None: Link(Field("F3"), Field("F4"), location=Location((4, 4))), Link(Field("F4"), FINAL, location=Location((5, 5))), ] - u8 = Integer("P::U8", Number(0), Sub(Pow(Number(2), Number(8)), Number(1)), Number(8)) - u16 = Integer("P::U16", Number(0), Sub(Pow(Number(2), Number(16)), Number(1)), Number(16)) + u8 = UnsignedInteger("P::U8", Number(8)) + u16 = UnsignedInteger("P::U16", Number(16)) types = { Field(ID("F1", location=Location((1, 1)))): u8, Field(ID("F2", location=Location((2, 2)))): u8, @@ -6381,10 +6380,8 @@ def test_refinement_type_error_in_condition() -> None: Link(Field(ID("P", location=Location((3, 3)))), FINAL, location=Location((3, 3))), ], { - Field(ID("L", location=Location((1, 1)))): Integer( + Field(ID("L", location=Location((1, 1)))): UnsignedInteger( "P::T", - Number(0), - Number(255), Number(8), ), Field(ID("P", location=Location((2, 2)))): OPAQUE, @@ -6963,7 +6960,7 @@ def test_message_refinement_with_scalar() -> None: refinement.checked( [ Message("P::Foo", [], {}), - Integer(ID("P::Bar"), Number(0), Number(255), size=Number(8)), + UnsignedInteger(ID("P::Bar"), size=Number(8)), ], ) diff --git a/tests/unit/model/model_test.py b/tests/unit/model/model_test.py index be8baaaf1..d555eedf0 100644 --- a/tests/unit/model/model_test.py +++ b/tests/unit/model/model_test.py @@ -29,6 +29,7 @@ TypeDecl, UncheckedMessage, UncheckedModel, + UnsignedInteger, type_decl, ) from rflx.model.cache import Digest @@ -51,17 +52,13 @@ def test_illegal_redefinition_of_builtin_type() -> None: [ BOOLEAN, OPAQUE, - Integer( + UnsignedInteger( ID("P::Boolean"), - Number(0), - Number(255), Number(8), location=Location((1, 2)), ), - Integer( + UnsignedInteger( ID("P::Opaque"), - Number(0), - Number(255), Number(8), location=Location((3, 4)), ), @@ -81,7 +78,7 @@ def test_name_conflict_types() -> None: ): Model( [ - Integer(ID("P::T"), Number(0), Number(255), Number(8), location=Location((10, 20))), + UnsignedInteger(ID("P::T"), Number(8), location=Location((10, 20))), Integer(ID("P::T"), Number(1), Number(100), Number(8), location=Location((11, 30))), ], ) @@ -172,8 +169,8 @@ def test_name_conflict_between_literal_and_type() -> None: Number(8), always_valid=False, ), - Integer("P::Foo", Number(0), Number(255), Number(8), Location((4, 16))), - Integer("P::Bar", Number(0), Number(255), Number(8), Location((5, 16))), + UnsignedInteger("P::Foo", Number(8), Location((4, 16))), + UnsignedInteger("P::Bar", Number(8), Location((5, 16))), ], ) @@ -455,7 +452,7 @@ def test_write_specification_file_multiple_packages_missing_deps(tmp_path: Path) def test_write_specification_files_line_too_long(tmp_path: Path) -> None: - t = Integer("P::" + "T" * 120, Number(0), Number(255), Number(8)) + t = UnsignedInteger("P::" + "T" * 120, Number(8)) Model([t]).write_specification_files(tmp_path) expected_path = tmp_path / Path("p.rflx") assert list(tmp_path.glob("*.rflx")) == [expected_path] @@ -659,10 +656,8 @@ def test_unchecked_model_checked( ), ( [ - type_decl.UncheckedInteger( + type_decl.UncheckedUnsignedInteger( ID("P::T", Location((1, 1))), - Number(0), - Number(255), Number(8), Location((1, 2)), ), diff --git a/tests/unit/model/type_decl_test.py b/tests/unit/model/type_decl_test.py index bcbc8cca6..3043c2c54 100644 --- a/tests/unit/model/type_decl_test.py +++ b/tests/unit/model/type_decl_test.py @@ -22,6 +22,7 @@ UncheckedInteger, UncheckedSequence, UncheckedTypeDecl, + UnsignedInteger, ) from rflx.rapidflux import Location, RecordFluxError from tests.data import models @@ -29,7 +30,7 @@ def test_type_name() -> None: - t = Integer("Package::Type_Name", Number(0), Number(255), Number(8)) + t = UnsignedInteger("Package::Type_Name", Number(8)) assert t.name == "Type_Name" assert t.package == ID("Package") with pytest.raises( @@ -321,6 +322,23 @@ def test_integer_invalid_out_of_bounds() -> None: ) +def test_integer_can_be_unsigned() -> None: + with pytest.raises( + RecordFluxError, + match=( + r"^:10:5: error: unsigned integer syntax preferable\n" + r':10:5: help: use "type T is unsigned 6" instead$' + ), + ): + Integer( + "P::T", + Number(0, location=Location((10, 3))), + Number(63, location=Location((10, 4))), + Number(6, location=Location((10, 6))), + Location((10, 5)), + ) + + def test_enumeration_size() -> None: assert_equal( Enumeration( @@ -650,10 +668,8 @@ def test_sequence_unsupported_element_type() -> None: ): Sequence( "P::A", - Integer( + UnsignedInteger( "P::B", - Number(0), - Sub(Pow(Number(2), Number(4)), Number(1)), Number(4), Location((3, 4)), ), diff --git a/tests/unit/pyrflx/typevalue_test.py b/tests/unit/pyrflx/typevalue_test.py index 3540e2709..b85f6b379 100644 --- a/tests/unit/pyrflx/typevalue_test.py +++ b/tests/unit/pyrflx/typevalue_test.py @@ -18,6 +18,7 @@ Opaque, Sequence, TypeDecl, + UnsignedInteger, ) from rflx.pyrflx import ( Bitstring, @@ -385,7 +386,7 @@ def test_message_value_parse_from_bitstring( tlv_message_value: MessageValue, enum_value: EnumValue, ) -> None: - intval = IntegerValue(Integer("Test::Int", expr.Number(0), expr.Number(255), expr.Number(8))) + intval = IntegerValue(UnsignedInteger("Test::Int", expr.Number(8))) intval.parse(b"\x02") assert intval.value == 2 enum_value.parse(b"\x01") @@ -653,13 +654,13 @@ def fixture_sequence_type_foo_value(sequence_type_package: Package) -> MessageVa def test_sequence_scalars(sequence_type_foo_value: MessageValue) -> None: a = IntegerValue( - Integer("Sequence_Type::Byte_One", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Sequence_Type::Byte_One", expr.Number(8)), ) b = IntegerValue( - Integer("Sequence_Type::Byte_Two", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Sequence_Type::Byte_Two", expr.Number(8)), ) c = IntegerValue( - Integer("Sequence_Type::Byte_Three", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Sequence_Type::Byte_Three", expr.Number(8)), ) a.assign(5) b.assign(6) @@ -672,20 +673,20 @@ def test_sequence_scalars(sequence_type_foo_value: MessageValue) -> None: def test_sequence_preserve_value(enum_value: EnumValue) -> None: - intval = IntegerValue(Integer("Test::Int", expr.Number(0), expr.Number(255), expr.Number(8))) + intval = IntegerValue(UnsignedInteger("Test::Int", expr.Number(8))) intval.assign(1) enum_value.assign("One") type_sequence = SequenceValue( Sequence( "Test::Sequence", - Integer("Test::Mod_Int", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Test::Mod_Int", expr.Number(8)), ), ) type_sequence.assign([intval]) assert type_sequence.value == [intval] with pytest.raises( PyRFLXError, - match="^error: cannot assign EnumValue to a sequence of Integer$", + match="^error: cannot assign EnumValue to a sequence of UnsignedInteger$", ): type_sequence.assign([enum_value]) assert type_sequence.value == [intval] @@ -713,16 +714,16 @@ def test_sequence_assign_invalid( type_sequence = SequenceValue( Sequence( "Test::Sequence", - Integer("Test::Mod_Int", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Test::Mod_Int", expr.Number(8)), ), ) msg_sequence = SequenceValue(Sequence("Test::MsgSequence", tlv_message_value._type)) - intval = IntegerValue(Integer("Test::Int", expr.Number(0), expr.Number(255), expr.Number(8))) + intval = IntegerValue(UnsignedInteger("Test::Int", expr.Number(8))) enum_value.assign("One") with pytest.raises( PyRFLXError, - match="^error: cannot assign EnumValue to a sequence of Integer$", + match="^error: cannot assign EnumValue to a sequence of UnsignedInteger$", ): type_sequence.assign([enum_value]) @@ -1402,7 +1403,7 @@ def test_parameterized_message_invalid_type(parameterized_package: Package) -> N def test_json_serialization() -> None: integer_value = IntegerValue( - Integer("Test::Int", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Test::Int", expr.Number(8)), ) integer_value.assign(128) assert integer_value.as_json() == 128 @@ -1421,7 +1422,7 @@ def test_json_serialization() -> None: sequence_value = SequenceValue( Sequence( "Test::Sequence", - Integer("Test::Int", expr.Number(0), expr.Number(255), expr.Number(8)), + UnsignedInteger("Test::Int", expr.Number(8)), ), ) sequence_value.assign([integer_value, integer_value, integer_value]) diff --git a/tests/unit/specification/parser_test.py b/tests/unit/specification/parser_test.py index 46bf43397..837f5f898 100644 --- a/tests/unit/specification/parser_test.py +++ b/tests/unit/specification/parser_test.py @@ -20,10 +20,10 @@ OPAQUE, Enumeration, Field, - Integer, Link, Message, State, + UnsignedInteger, declaration as decl, statement as stmt, ) @@ -44,7 +44,7 @@ parse_unsigned_type, ) -T = Integer("Test::T", expr.Number(0), expr.Number(255), expr.Number(8)) +T = UnsignedInteger("Test::T", expr.Number(8)) # Generated from the Ada 202x LRM source code (http://ada-auth.org/arm-files/ARM_SRC.zip) retrieved # on 2022-09-16 using the following command: @@ -1527,7 +1527,7 @@ def test_parse_type_derivation_spec() -> None: assert_ast_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type Foo is message N : T; @@ -1544,14 +1544,8 @@ def test_parse_type_derivation_spec() -> None: { "_kind": "TypeDecl", "definition": { - "_kind": "RangeTypeDef", - "first": {"_kind": "NumericLiteral", "_value": "0"}, - "size": { - "_kind": "Aspect", - "identifier": {"_kind": "UnqualifiedID", "_value": "Size"}, - "value": {"_kind": "NumericLiteral", "_value": "8"}, - }, - "last": {"_kind": "NumericLiteral", "_value": "255"}, + "_kind": "UnsignedTypeDef", + "size": {"_kind": "NumericLiteral", "_value": "8"}, }, "identifier": {"_kind": "UnqualifiedID", "_value": "T"}, "parameters": None, @@ -2227,7 +2221,7 @@ def test_parse_error_unexpected_exception_in_parser(monkeypatch: pytest.MonkeyPa p.parse_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; end Test; """, ) @@ -2295,7 +2289,7 @@ def test_parse_error_message_undefined_message_field() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message Foo : T @@ -2312,7 +2306,7 @@ def test_parse_error_invalid_location_expression() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message Foo : T @@ -2353,7 +2347,7 @@ def test_parse_error_refinement_undefined_sdu() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message Foo : T; @@ -2380,7 +2374,7 @@ def test_parse_error_derivation_unsupported_type() -> None: assert_error_string( """\ package Test is - type Foo is range 0 .. 255 with Size => 8; + type Foo is unsigned 8; type Bar is new Foo; end Test; """, @@ -2395,7 +2389,7 @@ def test_parse_error_multiple_initial_node_edges() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message null @@ -2414,7 +2408,7 @@ def test_parse_error_multiple_initial_nodes() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message null @@ -2435,7 +2429,7 @@ def test_parse_error_reserved_word_in_type_name(keyword: str) -> None: assert_error_string( f"""\ package Test is - type {keyword.title()} is range 0 .. 255 with Size => 8; + type {keyword.title()} is unsigned 8; end Test; """, rf'^:2:9: error: reserved word "{keyword.title()}" used as identifier$', @@ -2447,7 +2441,7 @@ def test_parse_error_reserved_word_in_message_field(keyword: str) -> None: assert_error_string( f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message {keyword.title()} : T; @@ -2501,7 +2495,7 @@ def test_parse_error_illegal_identifier_in_type_name(identifier: str) -> None: assert_error_string( f"""\ package Test is - type {identifier} is range 0 .. 255 with Size => 8; + type {identifier} is unsigned 8; end Test; """, r"^" @@ -2517,7 +2511,7 @@ def test_parse_error_illegal_identifier_in_message_field(identifier: str) -> Non assert_error_string( f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type PDU is message {identifier} : T; @@ -2615,13 +2609,8 @@ def test_create_model_message_type_message() -> None: ] simple_types = { - model.Field(ID("Bar", location=Location((1, 1)))): model.Integer( + model.Field(ID("Bar", location=Location((1, 1)))): model.UnsignedInteger( "Message_Type::T", - expr.Number(0), - expr.Sub( - expr.Pow(expr.Number(2), expr.Number(8)), - expr.Number(1), - ), expr.Number(8), ), model.Field(ID("Baz", location=Location((1, 1)))): model.Opaque(), @@ -2664,13 +2653,8 @@ def test_create_model_message_type_message() -> None: types = { **simple_types, - model.Field(ID("Foo", location=Location((1, 1)))): model.Integer( + model.Field(ID("Foo", location=Location((1, 1)))): model.UnsignedInteger( "Message_Type::T", - expr.Number(0), - expr.Sub( - expr.Pow(expr.Number(2), expr.Number(8)), - expr.Number(1), - ), expr.Number(8), ), } @@ -2696,10 +2680,8 @@ def test_create_model_message_type_message() -> None: def test_create_model_message_in_message() -> None: - length = model.Integer( + length = model.UnsignedInteger( "Message_In_Message::Length", - expr.Number(0), - expr.Sub(expr.Pow(expr.Number(2), expr.Number(16)), expr.Number(1)), expr.Number(16), ) @@ -2783,7 +2765,7 @@ def test_create_model_ethernet_frame() -> None: def test_create_model_type_derivation_message() -> None: - t = model.Integer("Test::T", expr.Number(0), expr.Number(255), expr.Number(8)) + t = model.UnsignedInteger("Test::T", expr.Number(8)) structure = [ model.Link(model.INITIAL, model.Field("Baz"), location=Location((1, 1))), @@ -2803,7 +2785,7 @@ def test_create_model_type_derivation_message() -> None: assert_messages_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type Foo is message Baz : T; @@ -2859,7 +2841,7 @@ def test_create_model_message_locations() -> None: p.parse_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -2911,7 +2893,7 @@ def test_create_model_sequence_with_imported_element_type() -> None: p.parse_string( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; end Test; """, ) @@ -2927,10 +2909,8 @@ def test_create_model_sequence_with_imported_element_type() -> None: sequences = [t for t in m.types if isinstance(t, model.Sequence)] assert len(sequences) == 1 assert sequences[0].identifier == ID("Sequence_Test::T") - assert sequences[0].element_type == model.Integer( + assert sequences[0].element_type == model.UnsignedInteger( "Test::T", - expr.Number(0), - expr.Number(255), expr.Number(8), ) @@ -2940,7 +2920,7 @@ def test_create_model_checksum() -> None: p.parse_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -2976,7 +2956,7 @@ def test_create_model_checksum() -> None: ( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -2991,7 +2971,7 @@ def test_create_model_checksum() -> None: ( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -3006,7 +2986,7 @@ def test_create_model_checksum() -> None: ( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -3020,7 +3000,7 @@ def test_create_model_checksum() -> None: ( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -3069,7 +3049,7 @@ def test_message_field_condition(spec: str) -> None: f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; {spec} end Test; """, @@ -3127,7 +3107,7 @@ def test_message_field_first(spec: str) -> None: assert_messages_string( f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; {spec} end Test; """, @@ -3177,7 +3157,7 @@ def test_message_field_size(spec: str) -> None: f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; {spec} end Test; @@ -3220,7 +3200,7 @@ def test_message_field_condition_and_aspects(link: str, field_b: str) -> None: assert_messages_string( f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message A : T @@ -3263,7 +3243,7 @@ def test_parameterized_messages() -> None: """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M (P : T) is message @@ -3416,7 +3396,7 @@ def test_parse_error_invalid_arguments_for_parameterized_messages( f"""\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M_P (P : T) is message @@ -3490,7 +3470,7 @@ def test_parse_error_invalid_parameterized_type(spec: str) -> None: assert_error_string( f"""\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F : T; @@ -3506,7 +3486,7 @@ def test_parse_error_undefined_parameter() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M (P : X) is message F : T; @@ -3521,7 +3501,7 @@ def test_parse_error_name_conflict_between_parameters() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M (P : T; P : T) is message F : T @@ -3541,7 +3521,7 @@ def test_parse_error_name_conflict_between_field_and_parameter() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M (P : T) is message P : T; @@ -3574,7 +3554,7 @@ def test_parse_error_duplicate_spec_stdin_file() -> None: p.parse_string( """\ package Message_Type is - type T is range 0 .. 2 ** 32 - 1 with Size => 32; + type T is unsigned 32; type M is message F : T; @@ -3636,7 +3616,7 @@ def test_parse_reserved_word_in_link_condition(keyword: str) -> None: assert_error_string( f"""\ package Test is - type I is range 0 .. 255 with Size => 8; + type I is unsigned 8; type M (A : Boolean) is message X : Boolean @@ -3656,7 +3636,7 @@ def test_parse_error_duplicate_message_aspect() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message A : T; @@ -3676,7 +3656,7 @@ def test_parse_error_duplicate_channel_decl_aspect() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Message is message A : T; @@ -3705,7 +3685,7 @@ def test_parse_error_unsupported_binding() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Message is message A : T; @@ -3772,7 +3752,7 @@ def test_parse_error_duplicate_message_checksum_aspect() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -3790,7 +3770,7 @@ def test_parse_error_duplicate_message_byte_order_aspect() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message F1 : T; @@ -3809,7 +3789,7 @@ def test_parse_error_duplicate_state_desc() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Message is message A : T; @@ -3838,7 +3818,7 @@ def test_parse_error_duplicate_transition_desc() -> None: assert_error_string( """\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type Message is message A : T; @@ -3994,7 +3974,7 @@ def test_parse_error_math_expression_in_bool_context(expression: str, message: s assert_error_string( f"""\ package Test is - type T is range 0 .. 2 ** 8 - 1 with Size => 8; + type T is unsigned 8; type M is message A : T @@ -4035,7 +4015,7 @@ def test_parse_error_short_form_condition() -> None: assert_error_string( """\ package Test is - type U8 is range 0 .. 255 with Size => 8; + type U8 is unsigned 8; type M is message A : U8 @@ -4182,7 +4162,7 @@ def test_parse_error_duplicate_operator(string: str, regex: str) -> None: ( """\ package Test is - type T is range 0 .. 255 with Size => 8; + type T is unsigned 8; type M is message F1 : T diff --git a/tests/unit/specification/style_test.py b/tests/unit/specification/style_test.py index b6b12e5d0..469a83436 100644 --- a/tests/unit/specification/style_test.py +++ b/tests/unit/specification/style_test.py @@ -133,14 +133,14 @@ def test_no_error(spec: str, tmp_path: Path) -> None: ), ( "package Test is\n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\n" + " type E is unsigned 16;\n" " type S is sequence of Test ::E;\n" "end Test;", r'3:31: error: space before "::" \[token-spacing\]', ), ( "package Test is\n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\n" + " type E is unsigned 16;\n" " type S is sequence of Test:: E;\n" "end Test;", r'3:33: error: space after "::" \[token-spacing\]', @@ -199,28 +199,28 @@ def test_error(tmp_path: Path, spec: str, error: str) -> None: ), ( "package Test is\n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\n" + " type E is unsigned 16;\n" " type S is sequence of Test ::E;\n" "end Test;", "token-spacing", ), ( "package Test is\n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\n" + " type E is unsigned 16;\n" " type S is sequence of Test:: E;\n" "end Test;", "token-spacing", ), ( "package Test is \n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\r\n" + " type E is unsigned 16;\r\n" " type S is sequence of Test:: E;\n" "end Test;\n\n", "all", ), ( "package Test is \n" - " type E is range 0 .. 2 ** 16 - 1 with Size => 16;\r\n" + " type E is unsigned 16;\r\n" " type S is sequence of Test:: E;\n" "end Test;\n\n", "blank-lines, characters, indentation, token-spacing, trailing-spaces", diff --git a/tests/verification/integration_test.py b/tests/verification/integration_test.py index f1c5e0daf..8a1ea0314 100644 --- a/tests/verification/integration_test.py +++ b/tests/verification/integration_test.py @@ -35,8 +35,8 @@ def test_definite_parameterized_message_provability(tmp_path: Path) -> None: def test_message_field_conditions_provability(tmp_path: Path) -> None: spec = """\ package Test is - type Byte is range 0 .. 2 ** 8 - 1 with Size => 8; - type Length_16 is range 0 .. 2 ** 16 - 1 with Size => 16; + type Byte is unsigned 8; + type Length_16 is unsigned 16; type My_Seq is sequence of Byte; @@ -61,7 +61,7 @@ def test_parameterized_message_set_scalar(tmp_path: Path) -> None: spec = """\ package Test is - type Length_16 is range 0 .. 2 ** 16 - 1 with Size => 16; + type Length_16 is unsigned 16; type Signature_Length is range 0 .. 512 with Size => 16; @@ -88,7 +88,7 @@ def test_parameterized_message_set_scalar(tmp_path: Path) -> None: def test_message_large_number_of_fields(tmp_path: Path) -> None: spec = """\ package Test is - type Byte is range 0 .. 2 ** 8 - 1 with Size => 8; + type Byte is unsigned 8; type Repr is message @@ -141,7 +141,7 @@ def test_message_access_to_optional_field_in_condition(tmp_path: Path) -> None: BB => 1) with Size => 8; - type T is range 0 .. 2 ** 16 - 1 with Size => 16; + type T is unsigned 16; type Message is message