Skip to content

[minor] Return the root itself from AbsoluteDirectoryPath.Parent - #144

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/absolute-directory-path-root-parent
Aug 4, 2026
Merged

[minor] Return the root itself from AbsoluteDirectoryPath.Parent#144
matt-edmondson merged 1 commit into
mainfrom
fix/absolute-directory-path-root-parent

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Problem

AbsoluteDirectoryPath.Parent returned an empty path at a root. Empty passes AbsoluteDirectoryPath validation (it is allowed for initialisation), but it is not a location — passed to the filesystem it reads as "no contents" rather than failing, so callers walking upwards silently landed nowhere instead of stopping at the root.

Surfaced by ktsu-dev/ImGuiApp#281, where the .. row of the ImGui filesystem browser crashed on Linux. That code trimmed separators off the path string, which also strips the leading separator — the root itself on Unix — leaving a relative path that failed validation:

System.ArgumentException: Cannot convert "home" to AbsoluteDirectoryPath

The consumer-side trimming is fixed separately; this PR removes the reason to hand-roll it at all.

Change

A root is now its own parent, matching how the filesystem resolves /.. to / and C:\.. to C:\. Every value Parent returns is therefore a usable absolute directory. Use IsRoot, or compare the parent against the path, to detect that walking upwards has finished.

Scoped to AbsoluteDirectoryPath. RelativeDirectoryPath.Parent and the DirectoryPath primitive are untouched — "the parent of a" is a genuinely different question for relative paths, and existing tests pin that behaviour.

Compatibility

This changes documented behaviour of a public property, hence [minor]. Anyone using the empty path as a "no parent" sentinel changes silently — IsRoot has always been the supported check. No new infinite-loop risk: empty was already a fixed point (Parent of "" is ""), so while (true) d = d.Parent; never terminated before either. GetAncestors already carried if (next == current) break; // Prevent infinite loop at root, so its results are unchanged.

Verification

  • New Semantics.Test/Paths/AbsoluteDirectoryPathParentTests.cs (7 tests): parent chains, root-is-its-own-parent, UNC share roots, Parent never returning an empty or relative path while walking up, termination at the fixed point, and GetAncestors ending at the root without repeating it. Uses the repo's per-OS ternary convention so the Unix cases execute on Linux rather than skipping.
  • Full suite: 1079 passed, 0 failed — nothing depended on the old empty-parent behaviour.
  • Solution builds clean across all target frameworks (0 warnings).
  • Ran the patched ktsu.Semantics.Paths.dll on real Linux (WSL): /home/matt/Documents → /home/matt → /home → / → /, IsRoot("/") true, GetAncestors correct.

🤖 Generated with Claude Code

Walking up from a root reported an empty path. Empty passes AbsoluteDirectoryPath
validation but is not a location: passed to the filesystem it reads as "no contents"
rather than failing, so callers walking upwards silently landed nowhere instead of
stopping at the root.

A root is now its own parent, matching how the filesystem resolves /.. to / and
C:\.. to C:\. Every value Parent returns is therefore a usable absolute directory.
Use IsRoot, or compare the parent against the path, to detect that walking upwards
has finished. GetAncestors already guarded against the self-referential root, so its
results are unchanged.

Surfaced by ktsu-dev/ImGuiApp#281, where the ".." row of the filesystem browser
crashed on Linux: it trimmed separators off the path string, which also strips the
leading separator that is the root on Unix, leaving a relative path that failed
AbsoluteDirectoryPath validation.

Claude-Session: https://claude.ai/code/session_01UwSLytSdW2pHmSmsSBAj8r
@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@matt-edmondson
matt-edmondson merged commit 7d3e7f7 into main Aug 4, 2026
5 of 6 checks passed
@matt-edmondson
matt-edmondson deleted the fix/absolute-directory-path-root-parent branch August 4, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant