Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ssort in CI #438

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions aas_core_codegen/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,6 @@ def __new__(cls, lines: Sequence[str]) -> "Lines":
"""
return cast(Lines, lines)

def __add__(self, other: "Lines") -> "Lines":
"""Concatenate two list of lines."""
raise NotImplementedError("Only for type annotations")

# pylint: disable=function-redefined

@overload
Expand All @@ -202,12 +198,16 @@ def __getitem__(self, index: Union[int, slice]) -> Union[str, "Lines"]:
"""Get the line(s) at the given index."""
raise NotImplementedError("Only for type annotations")

def __iter__(self) -> Iterator[str]:
"""Iterate over the lines."""
raise NotImplementedError("Only for type annotations")

def __len__(self) -> int:
"""Return the number of the lines."""
raise NotImplementedError("Only for type annotations")

def __iter__(self) -> Iterator[str]:
"""Iterate over the lines."""
def __add__(self, other: "Lines") -> "Lines":
"""Concatenate two list of lines."""
raise NotImplementedError("Only for type annotations")


Expand Down
74 changes: 37 additions & 37 deletions aas_core_codegen/cpp/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,26 @@ def generate_primitive_type(primitive_type: intermediate.PrimitiveType) -> Strip
return PRIMITIVE_TYPE_MAP[primitive_type]


def primitive_type_is_referencable(primitive_type: intermediate.PrimitiveType) -> bool:
"""Return ``True`` if the primitive type denotes a referencable value in C++."""
if primitive_type is intermediate.PrimitiveType.BOOL:
return False

elif primitive_type is intermediate.PrimitiveType.INT:
return False

elif primitive_type is intermediate.PrimitiveType.FLOAT:
return False

elif primitive_type is intermediate.PrimitiveType.STR:
return True

elif primitive_type is intermediate.PrimitiveType.BYTEARRAY:
return True
else:
assert_never(primitive_type)


def generate_primitive_type_with_const_ref_if_applicable(
primitive_type: intermediate.PrimitiveType,
) -> Stripped:
Expand Down Expand Up @@ -391,6 +411,23 @@ def generate_type(
raise AssertionError("Should not have gotten here")


def is_referencable(type_annotation: intermediate.TypeAnnotationUnion) -> bool:
"""Return ``True`` if the type annotation denotes a referencable value in C++."""
if isinstance(type_annotation, intermediate.OptionalTypeAnnotation):
return True

primitive_type = intermediate.try_primitive_type(type_annotation)
if primitive_type is not None:
return primitive_type_is_referencable(primitive_type)

if isinstance(type_annotation, intermediate.OurTypeAnnotation) and isinstance(
type_annotation.our_type, intermediate.Enumeration
):
return False

return True


def generate_type_with_const_ref_if_applicable(
type_annotation: intermediate.TypeAnnotationUnion,
types_namespace: Optional[Identifier] = None,
Expand Down Expand Up @@ -544,43 +581,6 @@ def generate_namespace_closing(library_namespace: Stripped) -> Stripped:
)


def primitive_type_is_referencable(primitive_type: intermediate.PrimitiveType) -> bool:
"""Return ``True`` if the primitive type denotes a referencable value in C++."""
if primitive_type is intermediate.PrimitiveType.BOOL:
return False

elif primitive_type is intermediate.PrimitiveType.INT:
return False

elif primitive_type is intermediate.PrimitiveType.FLOAT:
return False

elif primitive_type is intermediate.PrimitiveType.STR:
return True

elif primitive_type is intermediate.PrimitiveType.BYTEARRAY:
return True
else:
assert_never(primitive_type)


def is_referencable(type_annotation: intermediate.TypeAnnotationUnion) -> bool:
"""Return ``True`` if the type annotation denotes a referencable value in C++."""
if isinstance(type_annotation, intermediate.OptionalTypeAnnotation):
return True

primitive_type = intermediate.try_primitive_type(type_annotation)
if primitive_type is not None:
return primitive_type_is_referencable(primitive_type)

if isinstance(type_annotation, intermediate.OurTypeAnnotation) and isinstance(
type_annotation.our_type, intermediate.Enumeration
):
return False

return True


def include_guard_var(namespace: Stripped) -> Stripped:
"""
Generate the variable name of the include guard.
Expand Down
24 changes: 12 additions & 12 deletions aas_core_codegen/cpp/description.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,18 @@ def transform_document(
)


def documentation_comment(text: Stripped) -> Stripped:
"""Generate the documentation comment with the given ``text``."""
commented_lines = [] # type: List[str]
for line in text.splitlines():
if len(line.strip()) == 0:
commented_lines.append("///")
else:
commented_lines.append(f"/// {line}")

return Stripped("\n".join(commented_lines))


def generate_comment_for_summary_remarks(
description: intermediate.SummaryRemarksDescription, context: Context
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
Expand Down Expand Up @@ -548,18 +560,6 @@ def generate_comment_for_summary_remarks_constraints(
return documentation_comment(Stripped("\n\n".join(blocks))), None


def documentation_comment(text: Stripped) -> Stripped:
"""Generate the documentation comment with the given ``text``."""
commented_lines = [] # type: List[str]
for line in text.splitlines():
if len(line.strip()) == 0:
commented_lines.append("///")
else:
commented_lines.append(f"/// {line}")

return Stripped("\n".join(commented_lines))


def generate_comment_for_signature(
description: intermediate.DescriptionOfSignature, context: Context
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
Expand Down
126 changes: 63 additions & 63 deletions aas_core_codegen/cpp/structure/_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,69 +75,6 @@ def _human_readable_identifier(
return result


def _verify_structure_name_collisions(
symbol_table: intermediate.SymbolTable,
) -> List[Error]:
"""Verify that the C++ names of the structures do not collide."""
observed_type_names: Dict[
Identifier,
Union[
intermediate.Enumeration,
intermediate.AbstractClass,
intermediate.ConcreteClass,
],
] = dict()

errors = [] # type: List[Error]

# region Inter-structure collisions

for enum_or_cls in itertools.chain(symbol_table.enumerations, symbol_table.classes):
names: List[Identifier]

if isinstance(enum_or_cls, intermediate.Enumeration):
names = [cpp_naming.enum_name(enum_or_cls.name)]
elif isinstance(enum_or_cls, intermediate.AbstractClass):
names = [cpp_naming.interface_name(enum_or_cls.name)]
elif isinstance(enum_or_cls, intermediate.ConcreteClass):
names = [
cpp_naming.interface_name(enum_or_cls.name),
cpp_naming.class_name(enum_or_cls.name),
]
else:
assert_never(enum_or_cls)

for name in names:
other = observed_type_names.get(name, None)

if other is not None:
errors.append(
Error(
enum_or_cls.parsed.node,
f"The C++ name {name!r} "
f"of the {_human_readable_identifier(enum_or_cls)} "
f"collides with the C++ name "
f"of the {_human_readable_identifier(other)}",
)
)
else:
observed_type_names[name] = enum_or_cls

# endregion

# region Intra-structure collisions

for our_type in symbol_table.our_types:
collision_error = _verify_intra_structure_collisions(our_type=our_type)

if collision_error is not None:
errors.append(collision_error)

# endregion

return errors


def _verify_intra_structure_collisions(
our_type: intermediate.OurType,
) -> Optional[Error]:
Expand Down Expand Up @@ -265,6 +202,69 @@ def _verify_intra_structure_collisions(
return None


def _verify_structure_name_collisions(
symbol_table: intermediate.SymbolTable,
) -> List[Error]:
"""Verify that the C++ names of the structures do not collide."""
observed_type_names: Dict[
Identifier,
Union[
intermediate.Enumeration,
intermediate.AbstractClass,
intermediate.ConcreteClass,
],
] = dict()

errors = [] # type: List[Error]

# region Inter-structure collisions

for enum_or_cls in itertools.chain(symbol_table.enumerations, symbol_table.classes):
names: List[Identifier]

if isinstance(enum_or_cls, intermediate.Enumeration):
names = [cpp_naming.enum_name(enum_or_cls.name)]
elif isinstance(enum_or_cls, intermediate.AbstractClass):
names = [cpp_naming.interface_name(enum_or_cls.name)]
elif isinstance(enum_or_cls, intermediate.ConcreteClass):
names = [
cpp_naming.interface_name(enum_or_cls.name),
cpp_naming.class_name(enum_or_cls.name),
]
else:
assert_never(enum_or_cls)

for name in names:
other = observed_type_names.get(name, None)

if other is not None:
errors.append(
Error(
enum_or_cls.parsed.node,
f"The C++ name {name!r} "
f"of the {_human_readable_identifier(enum_or_cls)} "
f"collides with the C++ name "
f"of the {_human_readable_identifier(other)}",
)
)
else:
observed_type_names[name] = enum_or_cls

# endregion

# region Intra-structure collisions

for our_type in symbol_table.our_types:
collision_error = _verify_intra_structure_collisions(our_type=our_type)

if collision_error is not None:
errors.append(collision_error)

# endregion

return errors


class VerifiedIntermediateSymbolTable(intermediate.SymbolTable):
"""Represent a verified symbol table which can be used for code generation."""

Expand Down
18 changes: 9 additions & 9 deletions aas_core_codegen/cpp/transpilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,15 @@ class Transpiler(
):
"""Transpile a node of our AST to C++ code, or return an error."""

_CPP_COMPARISON_MAP = {
parse_tree.Comparator.LT: "<",
parse_tree.Comparator.LE: "<=",
parse_tree.Comparator.GT: ">",
parse_tree.Comparator.GE: ">=",
parse_tree.Comparator.EQ: "==",
parse_tree.Comparator.NE: "!=",
}

def __init__(
self,
type_map: Mapping[
Expand Down Expand Up @@ -495,15 +504,6 @@ def transform_index(

return Stripped(f"{collection}.at({index})"), None

_CPP_COMPARISON_MAP = {
parse_tree.Comparator.LT: "<",
parse_tree.Comparator.LE: "<=",
parse_tree.Comparator.GT: ">",
parse_tree.Comparator.GE: ">=",
parse_tree.Comparator.EQ: "==",
parse_tree.Comparator.NE: "!=",
}

@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
def transform_comparison(
self, node: parse_tree.Comparison
Expand Down
Loading
Loading