Skip to content

Commit

Permalink
fix: Some simple fixes for printing and parsing the noexcept attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
JhnW committed May 3, 2024
1 parent f5c7f4c commit e37dabf
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ def print(self, source: FunctionInfo, config: Optional[PrinterConfiguration] = N
if source.modification.is_volatile:
result += " volatile"
if source.modification.is_noexcept:
result += " noexcept"
if source.modification.noexcept_value is None:
result += " noexcept"
else:
result += f" noexcept({source.modification.noexcept_value})"

if source.modification.is_default:
result += " = default"
Expand Down
30 changes: 17 additions & 13 deletions src/devana/syntax_abstraction/functioninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def __xor__(self, other):
result.noexcept_value = other.noexcept_value
return result
elif isinstance(other, FunctionModification.ModificationKind):
result = FunctionModification(self.value.__or__(self.value, other)) # noqa
result = FunctionModification(self.value.__or__(self.value, other)) # noqa
if result.is_noexcept:
if self.is_noexcept:
result.noexcept_value = self.noexcept_value
Expand Down Expand Up @@ -173,13 +173,15 @@ def __str__(self):

@property
def noexcept_value(self) -> Optional[str]:
"""Returns noexcept if it appears with parentheses. Due to parsing based on the token list, whitespace
(meaning nothing for c++) is skipped."""
return self._noexcept_value

@noexcept_value.setter
def noexcept_value(self, value):
if not self.value & FunctionModification.ModificationKind.NOEXCEPT:
if value is not None:
self._value |= FunctionModification.ModificationKind.NOEXCEPT # noqa
self._value |= FunctionModification.ModificationKind.NOEXCEPT # noqa
self._noexcept_value = value

@property
Expand Down Expand Up @@ -473,20 +475,23 @@ def modification(self) -> FunctionModification:
elif token.spelling == "volatile":
self._modification |= FunctionModification.VOLATILE
elif token.spelling == "noexcept":
if i+1 != len(tokens) and tokens[i+1].spelling == "(":
if i + 1 != len(tokens) and tokens[i + 1].spelling == "(":
noexcept_value: str = ""
i += 1
if tokens[i+1].spelling == ")":
raise ParserError("error message")
i += 1
while tokens[i].spelling != ")":
noexcept_value += tokens[i].spelling
bracket_counter = 0
while True:
i += 1
self._modification |= FunctionModification.NOEXCEPT(noexcept_value) # noqa
if tokens[i].spelling == "(":
bracket_counter += 1
elif tokens[i].spelling == ")":
bracket_counter -= 1
noexcept_value += tokens[i].spelling
if not bracket_counter > 0:
break

self._modification |= FunctionModification.NOEXCEPT(noexcept_value[1:-1]) # noqa pylint: disable=not-callable
else:
self._modification |= FunctionModification.NOEXCEPT


if self._cursor.is_static_method():
self._modification |= FunctionModification.STATIC
if self._cursor.is_const_method():
Expand All @@ -497,8 +502,7 @@ def modification(self) -> FunctionModification:
self._modification |= FunctionModification.VIRTUAL
if self._cursor.is_default_method():
self._modification |= FunctionModification.DEFAULT
return self._modification

return self._modification # noqa

@modification.setter
def modification(self, value):
Expand Down
4 changes: 4 additions & 0 deletions tests/code_generation/unit/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ def test_basic_function_declaration_mods_basic(self):
source.modification = FunctionModification.NOEXCEPT
result = self.printer.print(source)
self.assertEqual(result, "long foo(float a, int* b = nullptr) noexcept;\n")
with self.subTest("noexcept_value"):
source.modification = FunctionModification.create_noexcept("1==5")
result = self.printer.print(source)
self.assertEqual(result, "long foo(float a, int* b = nullptr) noexcept(1==5);\n")

def test_basic_function_definition(self):
source = FunctionInfo.create_default()
Expand Down
5 changes: 5 additions & 0 deletions tests/parsing/unit/source_files/simple_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ constexpr double attribute_func_3(char a)

static inline double attribute_func_4(char a);

void mod_simple_noexcept_func() noexcept;

static void mod_multiple_noexcept_func() noexcept;

static void mod_arg_noexcept_func() noexcept(1==5 || (2 == 2));
16 changes: 16 additions & 0 deletions tests/parsing/unit/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,22 @@ def test_consteval_body(self):
result = FunctionInfo.from_cursor(node)
self.assertFalse(result.modification.is_consteval)

def test_noexcept_func(self):
node = find_by_name(self.cursor, "mod_simple_noexcept_func")
result = FunctionInfo.from_cursor(node)
self.assertTrue(result.modification.is_noexcept)

node = find_by_name(self.cursor, "mod_multiple_noexcept_func")
result = FunctionInfo.from_cursor(node)
self.assertTrue(result.modification.is_noexcept)
self.assertTrue(result.modification.is_static)

node = find_by_name(self.cursor, "mod_arg_noexcept_func")
result = FunctionInfo.from_cursor(node)
self.assertTrue(result.modification.is_noexcept)
self.assertTrue(result.modification.is_static)
self.assertEqual(result.modification.noexcept_value, "1==5||(2==2)")


class TestFunctionsTemplate(unittest.TestCase):

Expand Down

0 comments on commit e37dabf

Please sign in to comment.