diff --git a/rflx/model/model.py b/rflx/model/model.py index 30e6f7142..21f8df833 100644 --- a/rflx/model/model.py +++ b/rflx/model/model.py @@ -145,7 +145,22 @@ def _check_duplicates( seen: dict[ID, top_level_declaration.TopLevelDeclaration] = {} for d in declarations: - if d.identifier in seen: + if d.package in (const.BUILTINS_PACKAGE, const.INTERNAL_PACKAGE): + continue + + if type_.is_builtin_type(d.identifier.name) or type_.is_internal_type(d.identifier.name): + error.extend( + [ + ( + f'illegal redefinition of built-in type "{d.identifier.name}"', + Subsystem.MODEL, + Severity.ERROR, + d.location, + ), + ], + ) + + elif d.identifier in seen: error.extend( [ ( diff --git a/rflx/specification/parser.py b/rflx/specification/parser.py index 57eca1617..b71639044 100644 --- a/rflx/specification/parser.py +++ b/rflx/specification/parser.py @@ -1563,21 +1563,6 @@ def check_naming(error: RecordFluxError, package: lang.PackageNode, name: Path) ), ], ) - for t in package.f_declarations: - # Eng/RecordFlux/RecordFlux#1208 - if isinstance(t, lang.TypeDecl) and model.is_builtin_type( - create_id(error, t.f_identifier, name).name, - ): - error.extend( - [ - ( - f'illegal redefinition of built-in type "{t.f_identifier.text}"', - Subsystem.MODEL, - Severity.ERROR, - node_location(t, name), - ), - ], - ) @dataclass(frozen=True) @@ -1825,10 +1810,8 @@ def _evaluate_specification( for t in spec.f_package_declaration.f_declarations: if isinstance(t, lang.TypeDecl): - identifier = model.internal_type_identifier( - create_id(error, t.f_identifier, filename), - package_id, - ) + type_id = create_id(error, t.f_identifier, filename) + identifier = ID(package_id * type_id, location=type_id.location) if t.f_definition.kind_name != "MessageTypeDef" and t.f_parameters: error.extend( [ diff --git a/tests/ide/ide_test.py b/tests/ide/ide_test.py index c386663c2..30fd9f833 100644 --- a/tests/ide/ide_test.py +++ b/tests/ide/ide_test.py @@ -43,14 +43,12 @@ def test_multiple_errors() -> None: f'{path}:6:9: parser: info: previous identifier was "RFLX_Invalid"', f'{path}:6:9: parser: error: file name does not match unit name "RFLX_Invalid",' ' should be "rflx_invalid.rflx"', - f'{path}:31:4: model: error: illegal redefinition of built-in type "Boolean"', f'{path}:6:9: parser: error: illegal prefix "RFLX" in package identifier' ' "RFLX_Invalid"', f'{path}:295:5: parser: error: inconsistent package identifier "Inconsistent"', f'{path}:6:9: parser: info: previous identifier was "RFLX_Invalid"', f'{path}:6:9: parser: error: file name does not match unit name "RFLX_Invalid", should' ' be "rflx_invalid.rflx"', - f'{path}:31:4: model: error: illegal redefinition of built-in type "Boolean"', f'{path}:6:9: parser: error: illegal identifier "RFLX_Invalid"', f'{path}:6:9: parser: info: identifiers starting with "RFLX_" are reserved for' " internal use", @@ -144,8 +142,7 @@ def test_multiple_errors() -> None: f'{path}:290:30: model: error: undefined variable "Undef_Var"', f'{path}:28:9: model: error: name conflict for type "RFLX_Invalid::R"', f'{path}:8:9: model: info: previous occurrence of "RFLX_Invalid::R"', - f'{path}:31:9: model: error: name conflict for type "__BUILTINS__::Boolean"', - '__BUILTINS__:0:0: model: info: previous occurrence of "__BUILTINS__::Boolean"', + f'{path}:31:9: model: error: illegal redefinition of built-in type "Boolean"', f"{path}:44:9: model: error: conflicting literals: False, True", '__BUILTINS__:0:0: model: info: previous occurrence of "False"', '__BUILTINS__:0:0: model: info: previous occurrence of "True"', diff --git a/tests/integration/specification_model_test.py b/tests/integration/specification_model_test.py index 25bb7fe96..1665e4ba9 100644 --- a/tests/integration/specification_model_test.py +++ b/tests/integration/specification_model_test.py @@ -126,7 +126,7 @@ def test_illegal_redefinition() -> None: type Boolean is range 0 .. 1 with Size => 2; end Test; """, - r'^:2:4: model: error: illegal redefinition of built-in type "Boolean"$', + r'^:2:9: model: error: illegal redefinition of built-in type "Boolean"$', ) diff --git a/tests/unit/model/model_test.py b/tests/unit/model/model_test.py index 426ff0730..9069398f4 100644 --- a/tests/unit/model/model_test.py +++ b/tests/unit/model/model_test.py @@ -12,6 +12,7 @@ from rflx.expression import Equal, Number from rflx.identifier import ID from rflx.model import ( + BOOLEAN, BUILTIN_TYPES, FINAL, INITIAL, @@ -36,6 +37,38 @@ from tests.data import models +def test_illegal_redefinition_of_builtin_type() -> None: + with pytest.raises( + RecordFluxError, + match=( + r"^" + r':1:2: model: error: illegal redefinition of built-in type "Boolean"\n' + r':3:4: model: error: illegal redefinition of built-in type "Opaque"' + r"$" + ), + ): + Model( + [ + BOOLEAN, + OPAQUE, + Integer( + ID("P::Boolean"), + Number(0), + Number(255), + Number(8), + location=Location((1, 2)), + ), + Integer( + ID("P::Opaque"), + Number(0), + Number(255), + Number(8), + location=Location((3, 4)), + ), + ], + ) + + def test_name_conflict_types() -> None: with pytest.raises( RecordFluxError, diff --git a/tests/unit/specification/parser_test.py b/tests/unit/specification/parser_test.py index 962c201b2..15cdc2335 100644 --- a/tests/unit/specification/parser_test.py +++ b/tests/unit/specification/parser_test.py @@ -1845,21 +1845,6 @@ def test_parse_error_incorrect_name() -> None: ) -def test_parse_error_illegal_redefinition() -> None: - # Eng/RecordFlux/RecordFlux#1208 - error = r'^:2:4: model: error: illegal redefinition of built-in type "Boolean"$' - with pytest.raises(RecordFluxError, match=error): - parser.Parser().parse_string( - textwrap.dedent( - """\ - package Test is - type Boolean is range 0 .. 1 with Size => 2; - end Test; - """, - ), - ) - - def test_parse_error_incorrect_specification() -> None: assert_error_files( [f"{SPEC_DIR}/incorrect_specification.rflx"],