Replace role enums with attribute-bearing Role struct - #16
Conversation
Critical review findingsSelf-review pulled in via specialist agent. Three real issues worth addressing before merge, two follow-ups. Must fix in this PR[1] High — no enforcement of the name-uniqueness contract. [2] High — [5] Med — Follow-ups (don't block merge)[4] Stateful-output asymmetry comment. The output loop in [6] Test gap. No tests cover (a) custom user-defined Confirmed not issues
|
|
Addressed in fc938dd. All five points handled in the PR; tests went from 28 → 34. [1] High — name-uniqueness contract enforced. Added [2] High — [5] Med — [4] Med — output asymmetry NOTE. Added a multi-line NOTE comment co-located with the input loop in [6] Med — new test file Confirmed-not-issues already had no action items. Build: 34/34 tests pass on local-cas configuration. Note for #26: this push includes header changes (escape helper) that #26 rebase will need to carry into |
|
Second-pass fixes in a787c69. [3] Critical — newline/CR/NUL escape — fixed. `escape_for_cpp_literal` now handles `"`, `\`, `\n`, `\r`, `\0` via a switch. Added `RoleNameWithSpecialCharsIsEscapedInGeneratedSource` test that constructs a role with embedded quote, newline, and backslash; asserts the escaped form appears in the generated source and the raw forms don't. [2]/[6d] Med — dynamic-init order — documented. Added a multi-line NOTE on the `roles::` namespace explaining that calling `add_*` from another TU's static-init phase is unsafe (catalogue globals dynamically initialised). Documenting rather than enforcing — moving to constinit-friendly types would require dropping `std::string`, which is the core of the [2] fix. [6b] Nit — double-copy in add_* — fixed. Pushed into the `*_cache` first (copy), then `std::move` into `m_symbols`. Saves one `SymbolDecl` copy per declaration (one `std::string` for the name plus another for the role name). [5] Test style/coverage — not changed. The `try/catch` pattern is internally consistent across the exception-checking tests; gmock matchers would be cleaner but require linking gmock which the test target currently doesn't. Lifetime test mechanism reviewed and is structurally sound (mutating `local_name` after the call would surface a string_view bug since the test reads `found->role.name` afterward). 37/37 tests pass. |
|
Third-pass nit fixed in 8898972: |
Summary
Replace
InputRole/OutputRoleenums with a single attribute-bearingRolevalue type. Users can construct custom roles inline without library edits; backends switch on attributes (is_stateful,is_symmetric, …) rather than enum identity.Closes the role-semantics item (ARCH-C2) in #14. Surfaces a Phase A asymmetry tracked separately in #15.
Why
The enum design forced a library edit (and a backend switch update) every time a user wanted a new semantic role. The MOOSE Phase A guard could only catch the literal
InputRole::History— a user-defined custom history-like role would slip through unnoticed.What changed
include/numsim_codegen/recipe.h—enum class InputRoleandenum class OutputRolereplaced by onestruct Role { string_view name; bool is_stateful, is_driving, is_symmetric; optional<size_t> expected_rank; }. Name-basedoperator==. Predefined catalogue innamespace numsim::codegen::roles(Strain, StrainIncrement, DeformationGradient, Stress, ConsistentTangent, Temperature, History, Dissipation, Other).SymbolDecl::roleandOutputDecl::roleare nowRole.add_*andfind_*_by_roletakeRole.include/numsim_codegen/targets/moose_material.h— Phase A guard becomesif (i.role.is_stateful), catching any user-defined stateful role rather than only the literalHistoryenumerator. Theinput_role_doc()switch is gone; thevalidParamsdocstring usesi.role.namedirectly.InputRole::Strain→roles::Strain,OutputRole::Stress→roles::Stress. No semantic test changes.User-facing ergonomics
Scope preserved
The Phase A guard inspects only inputs (matches pre-refactor behavior exactly). Stateful outputs are still silently accepted — tracked separately in #15 with the right fix to bundle alongside the negative-test infrastructure in #11.
Test plan
ctest --output-on-failure)linear_elasticity,moose_linear_elastic)