Skip to content

Commit

Permalink
Get error from session down to create_channel_decl
Browse files Browse the repository at this point in the history
Fixes #714
  • Loading branch information
mhadhbir committed Feb 10, 2022
1 parent f86678c commit fdd23bb
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 86 deletions.
22 changes: 11 additions & 11 deletions rflx/specification/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ def create_unproven_session(
session: lang.SessionDecl,
package: ID,
filename: Path,
error: RecordFluxError,
types: Sequence[model.Type] = None,
) -> model.UnprovenSession:
__check_session_identifier(session, filename)
Expand All @@ -208,7 +209,7 @@ def create_unproven_session(
create_id(session.f_aspects.f_final, filename),
[create_state(s, package, filename) for s in session.f_states],
[create_declaration(d, package, filename) for d in session.f_declarations],
[create_formal_declaration(p, package, filename) for p in session.f_parameters],
[create_formal_declaration(p, package, filename, error) for p in session.f_parameters],
types or [],
node_location(session, filename),
)
Expand All @@ -218,9 +219,10 @@ def create_session(
session: lang.SessionDecl,
package: ID,
filename: Path,
error: RecordFluxError,
types: Sequence[model.Type] = None,
) -> model.Session:
return create_unproven_session(session, package, filename, types).proven()
return create_unproven_session(session, package, filename, error, types).proven()


def create_id(identifier: lang.AbstractID, filename: Path) -> ID:
Expand Down Expand Up @@ -516,7 +518,7 @@ def create_variable_decl(


def create_private_type_decl(
declaration: lang.FormalDecl, package: ID, filename: Path
declaration: lang.FormalDecl, package: ID, filename: Path, _error: RecordFluxError
) -> decl.FormalDeclaration:
assert isinstance(declaration, lang.FormalPrivateTypeDecl)
return decl.TypeDeclaration(
Expand All @@ -531,9 +533,9 @@ def create_channel_decl(
declaration: lang.FormalDecl,
_package: ID,
filename: Path,
error: RecordFluxError,
) -> decl.FormalDeclaration:
assert isinstance(declaration, lang.FormalChannelDecl)
error = RecordFluxError()
readable = False
writable = False
for p in declaration.f_parameters:
Expand All @@ -548,7 +550,6 @@ def create_channel_decl(
)
],
)
error.propagate()
elif p.kind_name == "Readable":
readable = True
elif p.kind_name == "Writable":
Expand Down Expand Up @@ -583,6 +584,7 @@ def create_function_decl(
declaration: lang.FormalDecl,
package: ID,
filename: Path,
_error: RecordFluxError,
) -> decl.FormalDeclaration:
assert isinstance(declaration, lang.FormalFunctionDecl)
arguments = []
Expand Down Expand Up @@ -713,14 +715,14 @@ def create_declaration(


def create_formal_declaration(
declaration: lang.FormalDecl, package: ID, filename: Path
declaration: lang.FormalDecl, package: ID, filename: Path, error: RecordFluxError
) -> decl.FormalDeclaration:
handlers = {
"FormalChannelDecl": create_channel_decl,
"FormalFunctionDecl": create_function_decl,
"FormalPrivateTypeDecl": create_private_type_decl,
}
return handlers[declaration.kind_name](declaration, package, filename)
return handlers[declaration.kind_name](declaration, package, filename, error)


def create_math_expression(expression: lang.Expr, filename: Path) -> expr.Expr:
Expand Down Expand Up @@ -1344,9 +1346,7 @@ def create_aspects(aspects: lang.AspectList) -> Tuple[expr.Expr, bool]:
for i, e in enumerate(enumeration.f_elements.f_elements)
]
else:
raise NotImplementedError(
f"Enumeration kind {enumeration.f_elements.kind_name} unsupported"
)
raise NotImplementedError(f"Enmeration kind {enumeration.f_elements.kind_name} unsupported")

size, always_valid = create_aspects(enumeration.f_aspects)

Expand Down Expand Up @@ -1703,7 +1703,7 @@ def __evaluate_specification(
error.extend(e)
elif isinstance(t, lang.SessionDecl):
try:
new_session = create_session(t, package_id, filename, self.__types)
new_session = create_session(t, package_id, filename, error, self.__types)
self.__sessions.append(new_session)
error.extend(new_session.error)
except RecordFluxError as e:
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/specification/grammar_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ def parse_declaration(data: str) -> decl.Declaration:
def parse_formal_declaration(data: str) -> decl.Declaration:
parser_declaration, filename = parse(data, lang.GrammarRule.session_parameter_rule)
assert isinstance(parser_declaration, lang.FormalDecl)
declaration = create_formal_declaration(parser_declaration, ID("Package"), filename)
error = RecordFluxError()
declaration = create_formal_declaration(parser_declaration, ID("Package"), filename, error)
assert isinstance(declaration, decl.Declaration)
return declaration

Expand All @@ -62,7 +63,7 @@ def parse_session(string: str) -> model.Session:
if diagnostics_to_error(unit.diagnostics, error, STDIN):
error.propagate()
assert isinstance(unit.root, lang.SessionDecl)
return create_session(unit.root, ID("Package"), Path("<stdin>"))
return create_session(unit.root, ID("Package"), Path("<stdin>"), error)


def parse_unproven_session(string: str) -> model.UnprovenSession:
Expand All @@ -73,7 +74,7 @@ def parse_unproven_session(string: str) -> model.UnprovenSession:
if diagnostics_to_error(unit.diagnostics, error, STDIN):
error.propagate()
assert isinstance(unit.root, lang.SessionDecl)
return create_unproven_session(unit.root, ID("Package"), Path("<stdin>"))
return create_unproven_session(unit.root, ID("Package"), Path("<stdin>"), error)


def parse_id(data: str, rule: str) -> ID:
Expand Down
144 changes: 72 additions & 72 deletions tests/unit/specification/parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1929,117 +1929,117 @@ def test_parse_error_duplicate_message_aspect_size() -> None:
assert_error_string(
"""
package Test is
type M is
message
B : Opaque
with First => 123, Size => 123, Size => 521;
end message;
type M is
message
B : Opaque
with First => 123, Size => 123, Size => 521;
end message;
end Test;
""",
r'^<stdin>:6:61: parser: error: duplicate aspect "Size"',
r'^<stdin>:6:57: parser: error: duplicate aspect "Size"',
)


def test_parse_error_duplicate_message_aspect_first() -> None:
assert_error_string(
"""
package Test is
type M is
message
B : Opaque
with First => 123, Size => 123, First => 521;
end message;
type M is
message
B : Opaque
with First => 123, Size => 123, First => 521;
end message;
end Test;
""",
r'^<stdin>:6:61: parser: error: duplicate aspect "First"',
r'^<stdin>:6:57: parser: error: duplicate aspect "First"',
)


def test_parse_error_duplicate_channel_aspect_readable() -> None:
assert_error_string(
"""
package Test is
package Test is
type M is
message
B : Opaque
type M is
message
B : Opaque
with Size => 8;
end message;
end message;
generic
Channel : Channel with Readable, Writable, Readable;
session Session with
Initial => Start,
Final => Terminated
is
Message : M;
begin
state Start is
begin
Channel'Read (Message);
transition
goto Reply
generic
Channel : Channel with Readable, Writable, Readable;
session Session with
Initial => Start,
Final => Terminated
is
Message : M;
begin
state Start is
begin
Channel'Read (Message);
transition
goto Reply
if Message'Valid
goto Terminated
end Start;
goto Terminated
end Start;
state Reply is
begin
Channel'Write (Message);
transition
goto Terminated
end Reply;
state Reply is
begin
Channel'Write (Message);
transition
goto Terminated
end Reply;
state Terminated is null state;
end Session;
state Terminated is null state;
end Session;
end Test;
end Test;
""",
r'^<stdin>:11:60: parser: error: duplicate aspect "Readable"',
r'^<stdin>:11:62: parser: error: duplicate aspect "Readable"',
)


def test_parse_error_duplicate_channel_aspect_writable() -> None:
assert_error_string(
"""
package Test is
package Test is
type M is
message
B : Opaque
type M is
message
B : Opaque
with Size => 8;
end message;
end message;
generic
Channel : Channel with Readable, Writable, Writable;
session Session with
Initial => Start,
Final => Terminated
is
Message : M;
begin
state Start is
begin
Channel'Read (Message);
transition
goto Reply
generic
Channel : Channel with Readable, Writable, Writable;
session Session with
Initial => Start,
Final => Terminated
is
Message : M;
begin
state Start is
begin
Channel'Read (Message);
transition
goto Reply
if Message'Valid
goto Terminated
end Start;
goto Terminated
end Start;
state Reply is
begin
Channel'Write (Message);
transition
goto Terminated
end Reply;
state Reply is
begin
Channel'Write (Message);
transition
goto Terminated
end Reply;
state Terminated is null state;
end Session;
state Terminated is null state;
end Session;
end Test;
end Test;
""",
r'^<stdin>:11:60: parser: error: duplicate aspect "Writable"',
r'^<stdin>:11:62: parser: error: duplicate aspect "Writable"',
)


Expand Down

0 comments on commit fdd23bb

Please sign in to comment.