Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

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

Not sure why Razor is being commented here -- this is just doing the thing the API is asking us to do....

Copy link
Member Author

Choose a reason for hiding this comment

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

the early set was initially added for Razor here - 863962d

It does get set anyway later on when the cmdline is set.

// 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;
Copy link
Member

@JoeRobich JoeRobich Aug 16, 2024

Choose a reason for hiding this comment

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

Could this have essentially been the only change needed here?

_projectUpdateState = _projectUpdateState.WithProjectOutputPath(creationInfo.CompilationOutputAssemblyFilePath, creationInfo.ProjectId);

Copy link
Member Author

@dibarbet dibarbet Aug 16, 2024

Choose a reason for hiding this comment

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

Possibly - but going through the same property setter as everything else feels safer.


return project;
}

Expand Down