Skip to content

[sharpie] Fix --scope path matching#24882

Merged
dalexsoto merged 3 commits intomainfrom
dev/alex/sharpie-enhancements-maybe
Mar 14, 2026
Merged

[sharpie] Fix --scope path matching#24882
dalexsoto merged 3 commits intomainfrom
dev/alex/sharpie-enhancements-maybe

Conversation

@dalexsoto
Copy link
Member

@dalexsoto dalexsoto commented Mar 12, 2026

When using sharpie bind --header <file> --scope <dir>, the --scope argument was stored verbatim without path normalization. Since Clang always reports declaration source locations as absolute paths, a relative --scope value (e.g. MyFramework.framework/Headers) would never match the absolute filename from presumedLoc.FileName, causing IsInScope() to filter out every declaration and produce zero output files — even though parsing succeeded.

Additionally, the StartsWith comparison in IsInScope() could produce false positive matches when one directory name was a prefix of another (e.g. scope /tmp/scope would incorrectly match files in /tmp/scopeextra/).

Finally, when binding a very large number of Objective-C headers (200+), ClangSharp can throw an ArgumentOutOfRangeException with parameter name "handle" during AST traversal, due to cursor/type handle misclassification in its managed wrapper layer. Sharpie caught this exception but reported the raw, opaque message ("Specified argument was out of the range of valid values"), giving users no guidance on how to work around the issue. -> Moved to dotnet/ClangSharp#690

Changes:

  1. Tools.cs: Normalize --scope paths to absolute via Path.GetFullPath() when parsing CLI arguments, matching the behavior already used by --framework mode (which calls Path.GetFullPath on SourceFramework in ResolveFramework()).

  2. ObjectiveCBinder.cs (IsInScope): Append a trailing directory separator to scope directory paths before the StartsWith check, so that /tmp/scope/ does not falsely match /tmp/scopeextra/.

3. BindingResult.cs (ReportUnexpectedError): Detect the specific ArgumentOutOfRangeException("handle") pattern from ClangSharp and report an actionable error message that explains the root cause (translation unit too complex) and suggests workarounds (bind fewer headers, use --scope).

  1. Tests: Added 5 new test cases:
    • Scope_RelativePath: verifies relative --scope paths produce correct output after normalization
    • Scope_FiltersOutOfScopeDeclarations: verifies that only declarations from in-scope headers are bound
    • Scope_PrefixDoesNotFalseMatch: verifies that scope "/foo/bar" does not match "/foo/barbaz/header.h"
    • HandleCrash_ReportsUsefulError: verifies the improved error message for ClangSharp handle exceptions
    • HandleCrash_OtherExceptionsUnchanged: verifies that other exception types still report their original message

…arge translation units

When using `sharpie bind --header <file> --scope <dir>`, the --scope
argument was stored verbatim without path normalization. Since Clang
always reports declaration source locations as absolute paths, a
relative --scope value (e.g. `MyFramework.framework/Headers`) would
never match the absolute filename from `presumedLoc.FileName`,
causing IsInScope() to filter out every declaration and produce zero
output files — even though parsing succeeded.

Additionally, the StartsWith comparison in IsInScope() could produce
false positive matches when one directory name was a prefix of another
(e.g. scope `/tmp/scope` would incorrectly match files in
`/tmp/scopeextra/`).

Finally, when binding a very large number of Objective-C headers
(200+), ClangSharp can throw an ArgumentOutOfRangeException with
parameter name "handle" during AST traversal, due to cursor/type
handle misclassification in its managed wrapper layer. Sharpie caught
this exception but reported the raw, opaque message
("Specified argument was out of the range of valid values"), giving
users no guidance on how to work around the issue.

Changes:

1. Tools.cs: Normalize --scope paths to absolute via Path.GetFullPath()
   when parsing CLI arguments, matching the behavior already used by
   --framework mode (which calls Path.GetFullPath on SourceFramework
   in ResolveFramework()).

2. ObjectiveCBinder.cs (IsInScope): Append a trailing directory
   separator to scope directory paths before the StartsWith check,
   so that `/tmp/scope/` does not falsely match `/tmp/scopeextra/`.

3. BindingResult.cs (ReportUnexpectedError): Detect the specific
   ArgumentOutOfRangeException("handle") pattern from ClangSharp and
   report an actionable error message that explains the root cause
   (translation unit too complex) and suggests workarounds (bind fewer
   headers, use --scope).

4. Tests: Added 5 new test cases:
   - Scope_RelativePath: verifies relative --scope paths produce
     correct output after normalization
   - Scope_FiltersOutOfScopeDeclarations: verifies that only
     declarations from in-scope headers are bound
   - Scope_PrefixDoesNotFalseMatch: verifies that scope "/foo/bar"
     does not match "/foo/barbaz/header.h"
   - HandleCrash_ReportsUsefulError: verifies the improved error
     message for ClangSharp handle exceptions
   - HandleCrash_OtherExceptionsUnchanged: verifies that other
     exception types still report their original message

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@dalexsoto dalexsoto changed the title [sharpie] Fix --scope path matching and improve error reporting for large translation units [sharpie] Fix --scope path matching Mar 12, 2026
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

2 similar comments
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #5b6ffb2] Build passed (Build packages) ✅

Pipeline on Agent
Hash: 5b6ffb2a6b987fcb2ced4d068254c87eb6feb77b [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [PR Build #5b6ffb2] Build passed (Detect API changes) ✅

Pipeline on Agent
Hash: 5b6ffb2a6b987fcb2ced4d068254c87eb6feb77b [PR build]

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 5b6ffb2a6b987fcb2ced4d068254c87eb6feb77b [PR build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

✅ [CI Build #5b6ffb2] Build passed (Build macOS tests) ✅

Pipeline on Agent
Hash: 5b6ffb2a6b987fcb2ced4d068254c87eb6feb77b [PR build]

@dalexsoto
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

1 similar comment
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

🚀 [CI Build #5b6ffb2] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 156 tests passed 🎉

Tests counts

✅ cecil: All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ framework: All 2 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ generator: All 5 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ introspection: All 6 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ linker: All 44 tests passed. [attempt 6] Html Report (VSDrops) Download
✅ monotouch (iOS): All 11 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 15 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ monotouch (macOS): All 12 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ monotouch (tvOS): All 11 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ windows: All 3 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. [attempt 5] Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. [attempt 5] Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. [attempt 2] Html Report (VSDrops) Download
✅ Tests on macOS Tahoe (26): All 5 tests passed. [attempt 2] Html Report (VSDrops) Download

Pipeline on Agent
Hash: 5b6ffb2a6b987fcb2ced4d068254c87eb6feb77b [PR build]

@dalexsoto dalexsoto merged commit 1626f87 into main Mar 14, 2026
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants