Skip to content

Allow MSBuildWorkspace to open file-based apps - #84139

Merged
jjonescz merged 65 commits into
dotnet:mainfrom
jjonescz:78887-sprint-MSBuildWorkspace
Jul 30, 2026
Merged

Allow MSBuildWorkspace to open file-based apps#84139
jjonescz merged 65 commits into
dotnet:mainfrom
jjonescz:78887-sprint-MSBuildWorkspace

Conversation

@jjonescz

@jjonescz jjonescz commented Jun 15, 2026

Copy link
Copy Markdown
Member

Resolves #78887.
Resolves #84588 (← public API issue).
Fixes #83304 (we don't use run-api anymore).
Closes #78879 (VirtualProjectXmlProviderTests are removed).
SDK counterpart: dotnet/sdk#54773

Microsoft Reviewers: Open in CodeFlow

@jjonescz jjonescz added Area-IDE Feature - Run File #: and #! directives and file-based C# programs labels Jun 15, 2026
Comment thread src/Workspaces/MSBuild/Contracts/IBuildHost.cs Outdated
Comment thread src/Workspaces/MSBuild/Core/MSBuild/FileBasedPrograms.cs Outdated
Comment thread src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj Outdated
Comment thread src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 61 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/Workspaces/MSBuild/Core/MSBuild/ProjectFileExtensionRegistry.cs:82

  • TryGetLanguageNameFromProjectPath holds _dataGuard while calling IFileBasedProgramService.IsValidEntryPointPath(projectFilePath). That method performs file I/O (File.Exists + potentially opening the file to check for a shebang), so doing it under the lock can block other threads trying to query/associate extensions and can introduce responsiveness issues when the path is on a slow/unavailable filesystem.

Consider doing the dictionary lookup under the lock, then (only if not found) release the lock and perform the file-based-app check outside of it.
src/Workspaces/MSBuild/Test/NetCoreTests.cs:886

  • This timeout is extremely short and is likely to be flaky on slow or contended test machines (100ms can be exceeded just by scheduling delays). Since the purpose here is to guard against the known hang, consider using a more forgiving timeout (seconds) to keep the test stable while still preventing an indefinite hang.
    src/Workspaces/CSharp/Portable/SyncedSource/FileBasedPrograms/Sha256Hasher.cs:15
  • The XML doc comment appears to be a copy/paste artifact: this method hashes an arbitrary string, not specifically a MAC address. This is misleading for future maintainers trying to understand why this helper exists.

Consider updating the comment to describe the actual contract (produce the same SHA-256 hex string format as other tooling for the same input, including normalized casing in HashWithNormalizedCasing).

    /// <summary>
    /// The hashed mac address needs to be the same hashed value as produced by the other distinct sources given the same input. (e.g. VsCode)
    /// </summary>

Copilot AI review requested due to automatic review settings July 27, 2026 13:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 61 changed files in this pull request and generated 2 comments.

Comment thread src/Workspaces/MSBuild/Core/MSBuild/MSBuildWorkspace.cs
Comment thread src/Workspaces/MSBuild/Core/Rpc/RemoteProjectInstance.cs
Copilot AI review requested due to automatic review settings July 27, 2026 14:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 61 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/Workspaces/MSBuild/Test/NetCoreTests.cs:887

  • The 100ms cancellation timeout is extremely tight and risks intermittent failures on slower/loaded test machines (the call may not reliably observe cancellation that quickly). Using a more generous timeout keeps the test validating the hang workaround without introducing flakiness.
    src/Workspaces/CSharp/Portable/SyncedSource/FileBasedPrograms/Sha256Hasher.cs:15
  • The XML doc comment mentions a "hashed mac address", but this helper hashes arbitrary text (paths, etc.). This looks like a copy/paste artifact and is misleading for future maintainers.
    /// <summary>
    /// The hashed mac address needs to be the same hashed value as produced by the other distinct sources given the same input. (e.g. VsCode)
    /// </summary>

Comment thread src/Workspaces/MSBuild/Test/NetCoreTests.cs

@RikkiGibson RikkiGibson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't look closely at the msbuildhost changes. But what I saw in LS layer looked great. Great work, I'm glad we are moving to this!

// App2.cs

var tempDir = _tempRoot.CreateDirectory();
DeferDeleteCacheDirectory(tempDir.Path);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this was just a no-op in the tests that don't DTB?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the DeferDeleteCacheDirectory call inside CreateDiscoveryTestServerAsync (to simplify the same pattern everywhere but also because it now needs access to the lsp server instance).

""";
var sourceFile = tempDir.CreateFile("SomeFile.cs").WriteAllText(sourceText);

// Until we can discover the `#:ref`erenced project, build it so it works as metadata reference.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm. Do you think discovery should parse directives when we have a positive entry point match and walk the #:refs? (not for this PR obviously.) That feels viable since we would only pay the cost after identifying the #!.

Copilot AI review requested due to automatic review settings July 29, 2026 14:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 56 out of 61 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/Workspaces/CSharp/Portable/SyncedSource/FileBasedPrograms/FileLevelDirectiveHelpers.cs:165

  • DirectiveDeduplicator.CheckDirective returns shouldKeep=false for duplicate sdk/property/package directives with the same value (to avoid emitting duplicate imports/properties). However, FindLeadingDirectives currently ignores shouldKeep and always adds the directive to the builder, so identical duplicates still flow into project generation and can cause duplicate <Sdk>, property, or package items.
    src/Workspaces/MSBuild/Test/NetCoreTests.cs:913
  • Using a 100ms cancellation timeout here is very likely to be flaky on slower/loaded CI machines. Since this is guarding against a known hang, a longer timeout (seconds) keeps the test stable while still preventing indefinite hangs.

@jasonmalinowski jasonmalinowski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@jjonescz
jjonescz merged commit 7e7ebef into dotnet:main Jul 30, 2026
28 checks passed
@jjonescz
jjonescz deleted the 78887-sprint-MSBuildWorkspace branch July 30, 2026 08:03
GoldMikeDev pushed a commit to GoldMikeDev/FollyOfTheUnbound that referenced this pull request Jul 30, 2026
… merge

CI (CodeQL "Analyze (csharp)") has been failing since the upstream-main
merge with CS0433 errors in FormatterBenchmarks.cs: CSharpSyntaxFormattingOptions
and NewLinePlacement exist in both the fork's own local build of
Workspaces\CSharp\Portable (FollyOfTheUnbound.CodeAnalysis.CSharpUnbound.Workspaces,
via ProjectReference) and the real released Microsoft.CodeAnalysis.CSharp.Workspaces
4.12.0 NuGet package.

Root cause: Microsoft.CodeAnalysis.LanguageServer.UnitTests.csproj (which
IdeCoreBenchmarks references for net10.0) has a PackageReference to
Microsoft.CodeAnalysis.CSharp.Analyzer.Testing, added upstream in
dotnet#84139 ("Allow MSBuildWorkspace to open file-based apps"). That
package transitively depends on Microsoft.CodeAnalysis.CSharp.Workspaces,
centrally pinned to 4.12.0 in eng/Packages.props (deliberately, for
stable analyzer-testing infrastructure) -- which only started
colliding with this fork's own local-build wiring once the upstream
commit and this fork's IdeCoreBenchmarks project graph were merged
together in this branch's recent upstream-main merge.

Fixed by excluding that transitive package's compile assets in
IdeCoreBenchmarks.csproj for the net10.0 TFM -- it doesn't need the
NuGet build, since it already references the local one directly.
jaredpar pushed a commit to jaredpar/roslyn that referenced this pull request Jul 30, 2026
@jjonescz jjonescz added this to the 18.11 milestone Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-IDE Feature - Run File #: and #! directives and file-based C# programs VSCode

Projects

None yet

6 participants