Skip to content

Commit

Permalink
Detecting duplicated components
Browse files Browse the repository at this point in the history
Add check to detect duplicated components of a record
when parsing a TRLC file.
The Language Reference Manual has been updated accordingly,
and its version has been increased to 3.1

Example:
```
Something duplicated
{
	description = "This is fine!"
	description = "This is the duplicate."
}
```

The behavior of the `Record_Object` class is changed such that the `assign` method only
assigns components to the record if it has not been assigned already.
This is implemented by checking if the field type is different from `Implicit_Null`.

The `Parser` class asks the `Record_Object` if the component is `Implicit_Null`.
If no, then an error is sent to the message handler.
  • Loading branch information
phiwuu committed Jan 15, 2025
1 parent 135324d commit fd831e4
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ docs
*.pyc
*.egg-info
.venv/
venv/
build
dist
launch.json
settings.json

# EMACS ignores
*~
Expand Down
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Language support

Up to date with version 3.0 of [TRLC language reference
Up to date with version 3.1 of [TRLC language reference
manual](https://bmw-software-engineering.github.io/trlc/lrm.html).

## Limitations
Expand Down Expand Up @@ -30,6 +30,18 @@ generated in the following situations:
* [TRLC] Fix an UnboundLocalError when missing a term
in an expression.

* [LRM, TRLC] Add check to detect duplicated components of a record when parsing a TRLC file.
Below is an example of a `*.trlc` file demonstrating the new behavior.
```
Something duplicated
{
description = "This is fine!"
description = "This is the duplicate." // will be detected as an error
}
```
The Language Reference Manual has been updated accordingly, and its version
has been increased to 3.1

### 2.0.0

This new major release includes a number of incompatible
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,9 @@ tracing: report.lobster
mkdir -p docs
lobster-html-report report.lobster --out=docs/tracing.html
lobster-ci-report report.lobster

clean-coverage:
@rm -rf htmlcov
@find . -name '.coverage*' -type f -delete
@find . -name '*.pyc' -type f -delete
@echo "All .coverage, .coverage.* and *.pyc files deleted."
3 changes: 2 additions & 1 deletion documentation/LRM.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# TRLC LRM

* [Version 3.0](https://bmw-software-engineering.github.io/trlc/lrm-3.0.html) (Current Stable)
* [Version 3.1](https://bmw-software-engineering.github.io/trlc/lrm.html) (Current Stable)
* [Version 3.0](https://bmw-software-engineering.github.io/trlc/lrm-3.0.html)
* [Version 2.9](https://bmw-software-engineering.github.io/trlc/lrm-2.9.html)
* [Version 2.8](https://bmw-software-engineering.github.io/trlc/lrm-2.8.html)
* [Version 2.7](https://bmw-software-engineering.github.io/trlc/lrm-2.7.html)
Expand Down
7 changes: 6 additions & 1 deletion language-reference-manual/lrm.trlc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package LRM

Versioning Version {
major = 3
minor = 0
minor = 1
}

GFDL_License License {
Expand Down Expand Up @@ -1775,6 +1775,11 @@ section "Record object declarations" {
references to R.)*'''
}

Dynamic_Semantics Single_Value_Assignment {
text = '''A value can be assigned to a component of a record object
only once.'''
}

Note Tuple_Checks {
text = '''The checks for a tuple aggregate are immediately evaluated
after the last value is parsed.'''
Expand Down
6 changes: 6 additions & 0 deletions tests-system/rbt-single-value-assignment/foo.rsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package Example

type Requirement {
description String
critical Boolean
}
13 changes: 13 additions & 0 deletions tests-system/rbt-single-value-assignment/foo.trlc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package Example

Requirement safety {
critical = false
description = "Is it critical, or is it not?"
critical = true
}

Requirement duplicated {
description = "This is fine"
critical = true
description = "This is not fine anymore"
}
5 changes: 5 additions & 0 deletions tests-system/rbt-single-value-assignment/output
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
critical = true
^^^^^^^^ rbt-single-value-assignment/foo.trlc:6: error: component 'critical' already assigned at line 4
description = "This is not fine anymore"
^^^^^^^^^^^ rbt-single-value-assignment/foo.trlc:12: error: component 'description' already assigned at line 10
Processed 1 model and 1 requirement file and found 2 errors
2 changes: 2 additions & 0 deletions tests-system/rbt-single-value-assignment/output.brief
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rbt-single-value-assignment/foo.trlc:6:3: trlc error: component 'critical' already assigned at line 4
rbt-single-value-assignment/foo.trlc:12:3: trlc error: component 'description' already assigned at line 10
5 changes: 5 additions & 0 deletions tests-system/rbt-single-value-assignment/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
critical = true
^^^^^^^^ rbt-single-value-assignment/foo.trlc:6: error: component 'critical' already assigned at line 4
description = "This is not fine anymore"
^^^^^^^^^^^ rbt-single-value-assignment/foo.trlc:12: error: component 'description' already assigned at line 10
Processed 1 model and 1 requirement file and found 2 errors
5 changes: 5 additions & 0 deletions tests-system/rbt-single-value-assignment/output.smtlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
critical = true
^^^^^^^^ rbt-single-value-assignment/foo.trlc:6: error: component 'critical' already assigned at line 4
description = "This is not fine anymore"
^^^^^^^^^^^ rbt-single-value-assignment/foo.trlc:12: error: component 'description' already assigned at line 10
Processed 1 model and 1 requirement file and found 2 errors
6 changes: 6 additions & 0 deletions trlc/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -2999,6 +2999,9 @@ def to_python_dict(self):
return {name: value.to_python_object()
for name, value in self.field.items()}

def is_component_implicit_null(self, component) -> bool:
return not isinstance(self.field[component.name], Implicit_Null)

def assign(self, component, value):
assert isinstance(component, Composite_Component)
assert isinstance(value, (Literal,
Expand All @@ -3008,6 +3011,9 @@ def assign(self, component, value):
Implicit_Null,
Unary_Expression)), \
"value is %s" % value.__class__.__name__
if self.is_component_implicit_null(component):
raise KeyError(f"Component {component.name} already \
assigned to {self.n_typ.name} {self.name}!")
self.field[component.name] = value

def dump(self, indent=0): # pragma: no cover
Expand Down
6 changes: 6 additions & 0 deletions trlc/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,7 @@ def parse_record_object_declaration(self):
# lobster-trace: LRM.Valid_Enumeration_Literals
# lobster-trace: LRM.Mandatory_Components
# lobster-trace: LRM.Evaluation_Of_Checks
# lobster-trace: LRM.Single_Value_Assignment

r_typ = self.parse_qualified_name(self.default_scope,
ast.Record_Type)
Expand All @@ -1810,6 +1811,11 @@ def parse_record_object_declaration(self):
comp = r_typ.components.lookup(self.mh,
self.ct,
ast.Composite_Component)
if obj.is_component_implicit_null(comp):
self.mh.error(self.ct.location,
"component '%s' already assigned at line %i" %
(comp.name,
obj.field[comp.name].location.line_no))
comp.set_ast_link(self.ct)
if r_typ.is_frozen(comp):
self.mh.error(self.ct.location,
Expand Down

0 comments on commit fd831e4

Please sign in to comment.