Skip to content

Commit

Permalink
Merge pull request #74791 from dibarbet/fix_early_set_output_path
Browse files Browse the repository at this point in the history
Fix issue where output path set in construction never updated the project update state
  • Loading branch information
dibarbet authored Aug 17, 2024
2 parents 5d67a09 + a559dd3 commit 7d94086
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports System.Collections.Immutable
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Workspaces.ProjectSystem
Imports Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework
Imports Roslyn.Test.Utilities

Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim
<[UseExportProvider]>
Public Class ProjectSystemProjectFactoryTests
<WpfFact, WorkItem("https://github.com/dotnet/vscode-csharp/issues/7402")>
Public Async Function ProjectInstantiatedWithCompilationOutputAssemblyFilePathCanBeChanged() As Task
Using environment = New TestEnvironment()
Dim creationInfo = New VisualStudioProjectCreationInfo()
creationInfo.CompilationOutputAssemblyFilePath = "C:\output\project.dll"
Dim project1 = Await environment.ProjectFactory.CreateAndAddToWorkspaceAsync(
"project1", LanguageNames.CSharp, creationInfo, CancellationToken.None)

Dim projectInSolution = environment.Workspace.CurrentSolution.GetProject(project1.Id)

Assert.Equal(creationInfo.CompilationOutputAssemblyFilePath, projectInSolution.CompilationOutputInfo.AssemblyPath)

' Change the path and ensure it's updated
Dim newOutputPath = "C:\output\new\project.dll"
project1.CompilationOutputAssemblyFilePath = newOutputPath

Dim newProjectInSolution As Project = environment.Workspace.CurrentSolution.GetProject(project1.Id)
Assert.Equal(newOutputPath, newProjectInSolution.CompilationOutputInfo.AssemblyPath)
End Using
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ internal ProjectSystemProject(
string assemblyName,
CompilationOptions? compilationOptions,
string? filePath,
ParseOptions? parseOptions,
string? compilationOutputAssemblyFilePath)
ParseOptions? parseOptions)
{
_projectSystemProjectFactory = projectSystemProjectFactory;
_hostInfo = hostInfo;
Expand Down Expand Up @@ -197,7 +196,6 @@ internal ProjectSystemProject(
_compilationOptions = compilationOptions;
_filePath = filePath;
_parseOptions = parseOptions;
_compilationOutputAssemblyFilePath = compilationOutputAssemblyFilePath;

var watchedDirectories = GetWatchedDirectories(language, filePath);
_documentFileChangeContext = _projectSystemProjectFactory.FileChangeWatcher.CreateContext(watchedDirectories);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ public async Task<ProjectSystemProject> CreateAndAddToWorkspaceAsync(string proj
assemblyName,
creationInfo.CompilationOptions,
creationInfo.FilePath,
creationInfo.ParseOptions,
creationInfo.CompilationOutputAssemblyFilePath);
creationInfo.ParseOptions);

var versionStamp = creationInfo.FilePath != null
? VersionStamp.Create(File.GetLastWriteTimeUtc(creationInfo.FilePath))
Expand Down Expand Up @@ -164,6 +163,15 @@ await ApplyChangeToWorkspaceAsync(w =>
onAfterUpdate: null);
}).ConfigureAwait(false);

// Set this value early after solution is created so it is available to Razor. This will get updated
// when the command line is set, but we want a non-null value to be available as soon as possible.
//
// Set the property in a batch; if we set the property directly we'll be taking a synchronous lock here and
// potentially block up thread pool threads. Doing this in a batch means the global lock will be acquired asynchronously.
var disposableBatchScope = await project.CreateBatchScopeAsync(CancellationToken.None).ConfigureAwait(false);
await using var _ = disposableBatchScope.ConfigureAwait(false);
project.CompilationOutputAssemblyFilePath = creationInfo.CompilationOutputAssemblyFilePath;

return project;
}

Expand Down

0 comments on commit 7d94086

Please sign in to comment.