diff --git a/src/pystencilssfg/config.py b/src/pystencilssfg/config.py index a94d9ad084cc71e407f57124f86e8863beeb02e0..3b63f4f121d27b53a3973a93996a6d0a99fe09e6 100644 --- a/src/pystencilssfg/config.py +++ b/src/pystencilssfg/config.py @@ -65,7 +65,7 @@ class CodeStyle(ConfigBase): includes_sorting_key: BasicOption[Callable[[HeaderFile], Any]] = BasicOption() """Key function that will be used to sort `#include` statements in generated files. - + Pystencils-sfg will instruct clang-tidy to forego include sorting if this option is set. """ @@ -196,7 +196,8 @@ class SfgConfig(ConfigBase): case OutputMode.STANDALONE: impl_ext = "cpp" - if impl_ext is not None: + if output_mode != OutputMode.HEADER_ONLY: + assert impl_ext is not None output_files.append(output_dir / f"{basename}.{impl_ext}") return tuple(output_files) diff --git a/src/pystencilssfg/emission/clang_format.py b/src/pystencilssfg/emission/clang_format.py index b73d9da973bc107a56f7fef319ee8c0ce3ad5f5f..50c51f176cbbc8abf3872fab319b3069af58141e 100644 --- a/src/pystencilssfg/emission/clang_format.py +++ b/src/pystencilssfg/emission/clang_format.py @@ -14,7 +14,7 @@ def invoke_clang_format( Args: code: Code string to format options: Options controlling the clang-format invocation - sort_includes: Option to be passed on to clang-format's ``--sort-includes`` argument + sort_includes: Option to be passed on to clang-format's ``--sort-includes`` argument Returns: The formatted code, if `clang-format` was run sucessfully. @@ -33,7 +33,7 @@ def invoke_clang_format( force = options.get_option("force") style = options.get_option("code_style") args = [binary, f"--style={style}"] - + if sort_includes is not None: args += ["--sort-includes", sort_includes] diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index dd9a78c61d73bb37dd9ca19d64a07187e87735f1..471e60bc580a00ed21b219e7f91a9a2be383cfd0 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -107,12 +107,13 @@ class SourceFileGenerator: self._header_file.elements.append("#define RESTRICT __restrict__") outer_namespace: str | _GlobalNamespace = config.get_option("outer_namespace") + match (outer_namespace, namespace): case [_GlobalNamespace(), None]: namespace = None case [_GlobalNamespace(), nspace] if nspace is not None: namespace = nspace - case [nspace, None]: + case [nspace, None] if not isinstance(nspace, _GlobalNamespace): namespace = nspace case [outer, inner]: namespace = f"{outer}::{inner}" diff --git a/src/pystencilssfg/ir/analysis.py b/src/pystencilssfg/ir/analysis.py index a2bce074fb707304ed8431d9fa1ddbe66118dbe1..ff8331f3000e6d793ff5e39889ec2f1d3bdeb864 100644 --- a/src/pystencilssfg/ir/analysis.py +++ b/src/pystencilssfg/ir/analysis.py @@ -35,7 +35,9 @@ def collect_includes(file: SfgSourceFile) -> set[HeaderFile]: | SfgMethod(_, _, parameters) | SfgConstructor(_, parameters, _, _) ): - incls = reduce(set.union, (includes(p) for p in parameters), set()) + incls: set[HeaderFile] = reduce( + lambda accu, p: accu | includes(p), parameters, set() + ) if isinstance(entity, (SfgFunction, SfgMethod)): incls |= includes(entity.return_type) return incls @@ -90,7 +92,7 @@ def collect_includes(file: SfgSourceFile) -> set[HeaderFile]: case SfgNamespaceBlock(_, elements) | SfgVisibilityBlock(_, elements): return reduce( lambda accu, elem: accu | walk_syntax(elem), elements, set() - ) + ) # type: ignore case SfgClassBody(_, vblocks): return reduce( diff --git a/src/pystencilssfg/ir/entities.py b/src/pystencilssfg/ir/entities.py index 90205fea5515a4d6b8be58cc97943eebbdfb0e03..a855155177fbcdb174ee8549babd868ae88e78ab 100644 --- a/src/pystencilssfg/ir/entities.py +++ b/src/pystencilssfg/ir/entities.py @@ -235,15 +235,17 @@ class SfgFunction(SfgCodeEntity): self._return_type = return_type self._inline = inline - self._parameters: set[SfgVar] + self._parameters: tuple[SfgVar, ...] from .postprocessing import CallTreePostProcessing param_collector = CallTreePostProcessing() - self._parameters = param_collector(self._tree).function_params + self._parameters = tuple( + sorted(param_collector(self._tree).function_params, key=lambda p: p.name) + ) @property - def parameters(self) -> set[SfgVar]: + def parameters(self) -> tuple[SfgVar, ...]: return self._parameters @property @@ -356,19 +358,21 @@ class SfgMethod(SfgClassMember): self._inline = inline self._const = const - self._parameters: set[SfgVar] + self._parameters: tuple[SfgVar, ...] from .postprocessing import CallTreePostProcessing param_collector = CallTreePostProcessing() - self._parameters = param_collector(self._tree).function_params + self._parameters = tuple( + sorted(param_collector(self._tree).function_params, key=lambda p: p.name) + ) @property def name(self) -> str: return self._name @property - def parameters(self) -> set[SfgVar]: + def parameters(self) -> tuple[SfgVar, ...]: return self._parameters @property diff --git a/tests/generator_scripts/index.yaml b/tests/generator_scripts/index.yaml index c78b335af26d9a175893499345ec29a20d30dd8c..eae4c39ebe4093100a90c700b33cc8984548dd0f 100644 --- a/tests/generator_scripts/index.yaml +++ b/tests/generator_scripts/index.yaml @@ -25,7 +25,7 @@ BasicDefinitions: expect-code: hpp: - regex: >- - #include\s\"config\.h\"\s* + #include\s\"config\.h\"(\s|.)* namespace\s+awesome\s+{\s+.+\s+ #define\sPI\s3\.1415\s+ using\snamespace\sstd\;\s+ diff --git a/tests/integration/cmake_project/GenTest.py b/tests/integration/cmake_project/GenTest.py index 8399e7061ae79b5b3a8c0fe6c3d544f0b5d6f586..093374c997f10d0681bb47c2aa909c8c85d65e73 100644 --- a/tests/integration/cmake_project/GenTest.py +++ b/tests/integration/cmake_project/GenTest.py @@ -1,8 +1,6 @@ from pystencilssfg import SourceFileGenerator -with SourceFileGenerator() as sfg: - sfg.namespace("gen") - +with SourceFileGenerator(namespace="gen") as sfg: retval = 42 if sfg.context.project_info is None else sfg.context.project_info sfg.function("getValue", return_type="int")(