microsoft / microsoft/WinAppVSCE
[Feature]: Explain and allow overriding XAML project ownership when resolution fails
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13
- Forks
- 3
- Avg merge
- 6d 1h
- Merged PRs (30d)
- 11
Description
Is your feature request related to a problem? Please describe.
XamlProjectResolver.FindOwningProject (server/src/WinUiXaml.Workspace/XamlProjectResolver.cs) walks upward from a XAML file looking for a directory containing exactly one .csproj. It returns a bare null in several distinct situations:
- the directory contains two or more
.csprojfiles (ambiguous — the walk aborts immediately, it does not continue to an unambiguous ancestor, lines 68-71) - no
.csprojis found anywhere up to the boundary — e.g. XAML linked in from a shared folder that lives outside any project - the document falls outside every
allowedRoot
All of these collapse into the same null. ResolveAsync and ResolveFrameworkAsync both just return null, so the document is served project-less: the tolerant parser, syntax diagnostics and TextMate coloring still work, but there is no compilation — no type-aware completion, no x:Bind resolution, no hover types, no F12 into code-behind.
The user gets no indication of why, and no way to correct it. FindOwningProjectTests.MultipleProjectsInDirectory_ReturnsNullWhenAmbiguous and NoProject_ReturnsNull assert the identical observable outcome, which confirms the two states are indistinguishable to callers.
There is currently no setting anywhere in the extension or server for pinning a project.
Describe the solution you'd like
Two changes, neither of which requires MSBuild evaluation:
1. Distinguish the failure reason. Return a reason alongside the result (or add TryFindOwningProject(out var reason)) covering at least Found, Ambiguous, NoProjectFound, and OutsideAllowedRoot. Surface it in the server log and in whatever project-status affordance the client presents, so an ambiguous directory reads as "two projects here, pick one" rather than silence.
2. Let the user pin a project. A workspace-folder-scoped setting (e.g. winui-xaml.projectPath) and/or a WinUI: Select XAML Project quick-pick. This one mechanism addresses ambiguity, linked/shared XAML, and unusual layouts together — which matters, because ambiguity is likely the least common cause of a null resolution.
Optional third step — a default instead of giving up. When candidates are ambiguous, prefer the one whose TargetFramework matches net*-windows10.0.* (the WinUI head, almost certainly the one whose IntelliSense is wanted), falling back to alphabetical order. TargetFramework is normally a literal property, so this is an XML read rather than a design-time build.
Additional context
Why content-based disambiguation is not the answer. The instinct is to ask which candidate actually includes the XAML as a Page/ApplicationDefinition item. But in the realistic ambiguous scenario — two heads over one shared source tree — both are SDK-style projects whose default globs pick up **/*.xaml, so both genuinely include the file. There is no owner to discover, only a preference to record. Content-based disambiguation would cost an MSBuild evaluation per candidate and frequently return "both."
Likelihood. Multiple .csproj in one folder is uncommon for WinUI: no WinUI template produces it, and the usual app + Windows Application Packaging Project layout is App.csproj + App.wapproj, which is unaffected because the glob is *.csproj only. It shows up mainly in UWP → WinUI 3 side-by-side migrations. This is a judgment call, not a telemetry-backed measurement.
Related invalidation gap (needs verification before acting). FindOwningProject is also used for cache invalidation at server/src/WinUiXaml.LanguageServer/XamlLanguageServer.cs:558, guarded by if (owning != null). A .cs edit inside a multi-project directory therefore invalidates nothing. That is harmless for a project that was never loaded, but if such a project is a ProjectReference of a loaded app project, edits to its sources may not invalidate the app's cached workspace. There is no test covering this path, and Invalidate does have a ContainsProject check for referenced projects that should be traced before treating it as a bug. Adding an ambiguity tie-break would incidentally close this gap for those directories.
Found while reviewing the XAML language service integration in #50.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with server/src/WinUiXaml.Workspace/XamlProjectResolver.cs and the FindOwningProjectTests cases MultipleProjectsInDirectory_ReturnsNullWhenAmbiguous and NoProject_ReturnsNull. Trace ResolveAsync, ResolveFrameworkAsync, and XamlLanguageServer.cs:558 to understand current handling and invalidation. Done means failure reasons are observable, users can pin a project, and the relevant resolution and invalidation behavior is covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, typescript
- Domain
- backend, developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100