Fix NamespaceExpose handling and improve top-level feature rendering#42
Merged
Conversation
…emantics Per formal-26-03-02.md section 8.3.26.4, a NamespaceExpose (NamespaceRecursive / NamespaceDirectChildren) exposes a namespace's Memberships, never the namespace itself. IsRootRelevantToScope previously treated candidateQualifiedName == subject as always root-relevant regardless of the subject's ExposeRecursionKind, causing excluded subjects to still be drawn as the outer wrapping box in asInterconnectionDiagram renders. Now the self-match direction is only honored for MembershipRecursive/MembershipExact recursion kinds, which do include the subject itself. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tches InterconnectionViewLayoutStrategy.FindRoot previously fell back to a totally empty canvas whenever no single part def could be selected as the diagram root, even when the resolved expose scope directly named one or more concrete top-level part feature usages. This produced an empty diagram for scopes like `expose Subsystem::*;` where Subsystem is a namespace-like part def whose only nested content is a single part usage. BuildLayout now falls back to collecting those top-level scoped part features (CollectTopLevelScopedParts) and laying each out with the same recursive container-vs-leaf logic already used by CollectParts, factored out into BuildPartItem. Connections between the collected top-level features are resolved via ResolveTopLevelConnections and drawn as before. The features render side by side with no enclosing outer frame/title box. LayOutInteriorWithConnections is parameterized with boxDepth and reserveTitleArea so it can be reused for both the normal single-root interior and this new flat top-level case. When the scope matches no top-level feature either, the original empty-canvas fallback (`new LayoutTree(200.0, 100.0, [])`) is preserved exactly. Deviation from plan: BuildPartItem omits the ExposedScope? scope parameter specified in the plan, since the original CollectParts always passed scope: null to its recursive call regardless of its own scope argument, making the parameter provably dead in the extracted method. Adds 6 regression tests covering: the direct repro (single top-level feature, no root def), two sibling top-level features arranged side by side, a top-level feature that is itself a container (recurses into its own interior), no matching feature (empty-canvas fallback preserved), a connection drawn between two top-level features, and a nested feature correctly excluded from top-level collection (not duplicated). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…outStrategy Updates the three companion artifacts for the InterconnectionViewLayoutStrategy feature that renders top-level exposed part features without a frame when no single root definition is found: - design doc: new remarks paragraph, new subsections for CollectTopLevelScopedParts/ResolveTopLevelConnections, BuildPartItem, and the parameterized LayOutInteriorWithConnections, plus an updated Error Handling section describing the new fallback path. - reqstream yaml: three new requirement entries (ScopedTopLevelFeatureFallback, ScopedTopLevelFeatureFallbackConnections, ScopedTopLevelFeatureFallbackEmptyCanvas) linked to the new regression tests. - verification doc: new verification-approach paragraph, acceptance criteria, and test-scenario table rows covering the new fallback. - user guide: notes that an expose scope naming no root definition is no longer always an empty Interconnection View diagram when the scope directly includes top-level part feature usages instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'boxless' to .cspell.yaml words list next to 'frameless' - Shorten 6 over-length (MD013 >120 chars) assertion cells in the interconnection-view-layout-strategy verification doc table, keeping test names and table structure unchanged Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request implements a new fallback behavior for Interconnection View layout in cases where the resolved
exposescope does not name a single root definition, but instead directly includes one or more top-levelpartfeature usages. Instead of rendering an empty canvas, these features are now rendered as "boxless" nodes side by side, with connections between them when appropriate. The changes include updates to documentation, requirements, and the core layout logic to support and explain this behavior, along with comprehensive test coverage.Core Layout Logic and Behavior:
InterconnectionViewLayoutStrategy, so whenFindRootfinds no root but the scope includes top-levelpartfeature usages, those features are rendered as boxless nodes side by side, recursing into their interiors as normal. This prevents valid diagrams from appearing empty when the scope names concrete features but not a root definition. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-fbfb8793b4fa4ef13a24da9593839e3770c507ce240ba736d6c0db8d8b68215bR44-R53))[[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-204c1372a24a23895102610db6cb3b977316ecedf9560a962602fddb53543ab0R254-R306))Documentation and User Guide:
[[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L35-R92),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-a614960ca509ddd055be36ae4fea2a9b7716b47d293b5d32e83dd06a551d6f8eR240-R247),[[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-6348df1926db8d8e121df8483db2afaa47631be7d1f9401967af85b65eeac820L187-R248))[[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-204c1372a24a23895102610db6cb3b977316ecedf9560a962602fddb53543ab0R254-R306),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R30-R42),[[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R101-R114),[[4]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R144-R149))Test Coverage:
[[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R30-R42),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R101-R114),[[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-9ff2f7b125cdf16aa68140707d9d5e8fd38236aa4ede33e4e62c2ed596599023R144-R149))Expose Scope Logic:
ExposeScopeResolver.IsRootRelevantToScopeto correctly handle namespace-form expose scopes, ensuring that only appropriate candidates are considered root-relevant, in line with the SysML v2 specification. ([[1]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079L248-R251),[[2]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079R262-R272),[[3]](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-2da9ff64798edd7056b162755f7abc04652cd79fb446f74f35ad742766d25079L270-R308))Miscellaneous:
[.cspell.yamlR33](https://github.com/demaconsulting/SysML2Tools/pull/42/files#diff-3eb548e27a9fd5527f6ea4dfe6350d3ecde8bcf4783f92658a2f5ae847a985fdR33))These changes together ensure that Interconnection Views are rendered more faithfully to the SysML v2 specification, especially in cases where the exposed scope is more granular or namespace-like.