Skip to content

Commit ab46826

Browse files
committed
Update ProjectWorkspaceState and HostProject at the same time
1 parent f6384a9 commit ab46826

File tree

25 files changed

+122
-260
lines changed

25 files changed

+122
-260
lines changed

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ await projectManager.UpdateAsync(
7676
updater.ProjectAdded(hostProject);
7777
var tagHelpers = CommonResources.LegacyTagHelpers;
7878
var projectWorkspaceState = ProjectWorkspaceState.Create(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp11);
79-
updater.ProjectWorkspaceStateChanged(hostProject.Key, projectWorkspaceState);
79+
updater.ProjectChanged(hostProject, projectWorkspaceState);
8080
updater.DocumentAdded(hostProject.Key, hostDocument, textLoader);
8181
},
8282
CancellationToken.None);

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/ProjectSystem/RazorProjectService.cs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -369,34 +369,21 @@ private Task AddOrUpdateProjectCoreAsync(
369369
_logger.LogInformation($"Updating project '{project.Key}' TagHelpers ({projectWorkspaceState.TagHelpers.Length}) and C# Language Version ({projectWorkspaceState.CSharpLanguageVersion}).");
370370
}
371371

372-
updater.ProjectWorkspaceStateChanged(project.Key, projectWorkspaceState);
373-
374372
var currentConfiguration = project.Configuration;
375373
var currentRootNamespace = project.RootNamespace;
376-
if (currentConfiguration.ConfigurationName == configuration?.ConfigurationName &&
377-
currentRootNamespace == rootNamespace)
378-
{
379-
_logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'.");
380-
return;
381-
}
382-
383374
if (configuration is null)
384375
{
385376
configuration = FallbackRazorConfiguration.Latest;
386377
_logger.LogInformation($"Updating project '{project.Key}' to use the latest configuration ('{configuration.ConfigurationName}')'.");
387378
}
388-
else if (currentConfiguration.ConfigurationName != configuration.ConfigurationName)
389-
{
390-
_logger.LogInformation($"Updating project '{project.Key}' to Razor configuration '{configuration.ConfigurationName}' with language version '{configuration.LanguageVersion}'.");
391-
}
392-
393-
if (currentRootNamespace != rootNamespace)
379+
else if (currentConfiguration.Equals(configuration) &&
380+
currentRootNamespace == rootNamespace)
394381
{
395-
_logger.LogInformation($"Updating project '{project.Key}''s root namespace to '{rootNamespace}'.");
382+
_logger.LogTrace($"Updating project '{project.Key}'. The project is already using configuration '{configuration.ConfigurationName}' and root namespace '{rootNamespace}'.");
396383
}
397384

398385
var hostProject = new HostProject(project.FilePath, project.IntermediateOutputPath, configuration, rootNamespace, displayName);
399-
updater.ProjectConfigurationChanged(hostProject);
386+
updater.ProjectChanged(hostProject, projectWorkspaceState);
400387
},
401388
cancellationToken);
402389
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DocumentState.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,6 @@ public bool TryGetTextVersion(out VersionStamp result)
150150
return false;
151151
}
152152

153-
public virtual DocumentState WithConfigurationChange()
154-
{
155-
var state = new DocumentState(HostDocument, Version + 1, _textAndVersion, _textLoader);
156-
157-
// Do not cache computed state
158-
159-
return state;
160-
}
161-
162153
public virtual DocumentState WithImportsChange()
163154
{
164155
var state = new DocumentState(HostDocument, Version + 1, _textAndVersion, _textLoader);
@@ -169,7 +160,7 @@ public virtual DocumentState WithImportsChange()
169160
return state;
170161
}
171162

172-
public virtual DocumentState WithProjectWorkspaceStateChange()
163+
public virtual DocumentState WithProjectChange()
173164
{
174165
var state = new DocumentState(HostDocument, Version + 1, _textAndVersion, _textLoader);
175166

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectDifference.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem;
88
[Flags]
99
internal enum ProjectDifference
1010
{
11-
None = 0,
12-
ConfigurationChanged = 1,
13-
ProjectWorkspaceStateChanged = 2,
14-
DocumentAdded = 4,
15-
DocumentRemoved = 8,
16-
DocumentChanged = 16,
11+
None = 1 << 0,
12+
ConfigurationChanged = 1 << 1,
13+
DocumentAdded = 1 << 2,
14+
DocumentRemoved = 1 << 3,
15+
DocumentChanged = 1 << 4,
1716
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshotManager.Updater.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,8 @@ public void ProjectAdded(HostProject project)
5050
public void ProjectRemoved(ProjectKey projectKey)
5151
=> instance.ProjectRemoved(projectKey);
5252

53-
public void ProjectConfigurationChanged(HostProject project)
54-
=> instance.ProjectConfigurationChanged(project);
55-
56-
public void ProjectWorkspaceStateChanged(ProjectKey projectKey, ProjectWorkspaceState projectWorkspaceState)
57-
=> instance.ProjectWorkspaceStateChanged(projectKey, projectWorkspaceState);
53+
public void ProjectChanged(HostProject project, ProjectWorkspaceState projectWorkspaceState)
54+
=> instance.ProjectChanged(project, projectWorkspaceState);
5855

5956
public void SolutionOpened()
6057
=> instance.SolutionOpened();

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectSnapshotManager.cs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ private void ProjectAdded(HostProject hostProject)
306306
}
307307
}
308308

309-
private void ProjectConfigurationChanged(HostProject hostProject)
309+
private void ProjectChanged(HostProject hostProject, ProjectWorkspaceState projectWorkspaceState)
310310
{
311311
if (_initialized)
312312
{
@@ -316,25 +316,7 @@ private void ProjectConfigurationChanged(HostProject hostProject)
316316
if (TryUpdate(
317317
hostProject.Key,
318318
documentFilePath: null,
319-
new HostProjectUpdatedAction(hostProject),
320-
out var oldSnapshot,
321-
out var newSnapshot))
322-
{
323-
NotifyListeners(oldSnapshot, newSnapshot, documentFilePath: null, ProjectChangeKind.ProjectChanged);
324-
}
325-
}
326-
327-
private void ProjectWorkspaceStateChanged(ProjectKey projectKey, ProjectWorkspaceState projectWorkspaceState)
328-
{
329-
if (_initialized)
330-
{
331-
_dispatcher.AssertRunningOnDispatcher();
332-
}
333-
334-
if (TryUpdate(
335-
projectKey,
336-
documentFilePath: null,
337-
new ProjectWorkspaceStateChangedAction(projectWorkspaceState),
319+
new ProjectChangeAction(hostProject, projectWorkspaceState),
338320
out var oldSnapshot,
339321
out var newSnapshot))
340322
{
@@ -591,11 +573,8 @@ private static Entry ComputeNewEntry(Entry originalEntry, IUpdateProjectAction a
591573
}
592574
}
593575

594-
case ProjectWorkspaceStateChangedAction(var workspaceState):
595-
return new Entry(originalEntry.State.WithProjectWorkspaceState(workspaceState));
596-
597-
case HostProjectUpdatedAction(var hostProject):
598-
return new Entry(originalEntry.State.WithHostProject(hostProject));
576+
case ProjectChangeAction(var hostProject, var workspaceState):
577+
return new Entry(originalEntry.State.WithHostProjectAndWorkspaceState(hostProject, workspaceState));
599578

600579
default:
601580
throw new InvalidOperationException($"Unexpected action type {action.GetType()}");

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ProjectState.cs

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ namespace Microsoft.CodeAnalysis.Razor.ProjectSystem;
2020
// Internal tracker for DefaultProjectSnapshot
2121
internal class ProjectState
2222
{
23-
private const ProjectDifference ClearConfigurationVersionMask = ProjectDifference.ConfigurationChanged;
24-
25-
private const ProjectDifference ClearProjectWorkspaceStateVersionMask =
26-
ProjectDifference.ConfigurationChanged |
27-
ProjectDifference.ProjectWorkspaceStateChanged;
28-
2923
private const ProjectDifference ClearDocumentCollectionVersionMask =
3024
ProjectDifference.ConfigurationChanged |
3125
ProjectDifference.DocumentAdded |
@@ -96,7 +90,9 @@ private ProjectState(
9690
DocumentCollectionVersion = Version;
9791
}
9892

99-
if ((difference & ClearConfigurationVersionMask) == 0 && older._projectEngine != null)
93+
if (older._projectEngine != null &&
94+
HostProject.Configuration == older.HostProject.Configuration &&
95+
CSharpLanguageVersion == older.CSharpLanguageVersion)
10096
{
10197
// Optimistically cache the RazorProjectEngine.
10298
_projectEngine = older.ProjectEngine;
@@ -107,24 +103,14 @@ private ProjectState(
107103
ConfigurationVersion = Version;
108104
}
109105

110-
if ((difference & ClearProjectWorkspaceStateVersionMask) == 0 ||
111-
ProjectWorkspaceState == older.ProjectWorkspaceState ||
112-
ProjectWorkspaceState.Equals(older.ProjectWorkspaceState))
106+
if (ProjectWorkspaceState.Equals(older.ProjectWorkspaceState))
113107
{
114108
ProjectWorkspaceStateVersion = older.ProjectWorkspaceStateVersion;
115109
}
116110
else
117111
{
118112
ProjectWorkspaceStateVersion = Version;
119113
}
120-
121-
if ((difference & ClearProjectWorkspaceStateVersionMask) != 0 &&
122-
CSharpLanguageVersion != older.CSharpLanguageVersion)
123-
{
124-
// C# language version changed. This impacts the ProjectEngine, reset it.
125-
_projectEngine = null;
126-
ConfigurationVersion = Version;
127-
}
128114
}
129115

130116
// Internal set for testing.
@@ -314,20 +300,16 @@ public ProjectState WithChangedHostDocument(HostDocument hostDocument, TextLoade
314300
return state;
315301
}
316302

317-
public ProjectState WithHostProject(HostProject hostProject)
303+
public ProjectState WithHostProjectAndWorkspaceState(HostProject hostProject, ProjectWorkspaceState projectWorkspaceState)
318304
{
319-
if (hostProject is null)
320-
{
321-
throw new ArgumentNullException(nameof(hostProject));
322-
}
323-
324305
if (HostProject.Configuration.Equals(hostProject.Configuration) &&
325-
HostProject.RootNamespace == hostProject.RootNamespace)
306+
HostProject.RootNamespace == hostProject.RootNamespace &&
307+
ProjectWorkspaceState.Equals(projectWorkspaceState))
326308
{
327309
return this;
328310
}
329311

330-
var documents = Documents.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.WithConfigurationChange(), FilePathNormalizingComparer.Instance);
312+
var documents = Documents.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.WithProjectChange(), FilePathNormalizingComparer.Instance);
331313

332314
// If the host project has changed then we need to recompute the imports map
333315
var importsToRelatedDocuments = s_emptyImportsToRelatedDocuments;
@@ -338,25 +320,7 @@ public ProjectState WithHostProject(HostProject hostProject)
338320
importsToRelatedDocuments = AddToImportsToRelatedDocuments(importsToRelatedDocuments, document.Value.HostDocument.FilePath, importTargetPaths);
339321
}
340322

341-
var state = new ProjectState(this, ProjectDifference.ConfigurationChanged, hostProject, ProjectWorkspaceState, documents, importsToRelatedDocuments);
342-
return state;
343-
}
344-
345-
public ProjectState WithProjectWorkspaceState(ProjectWorkspaceState projectWorkspaceState)
346-
{
347-
if (ProjectWorkspaceState == projectWorkspaceState)
348-
{
349-
return this;
350-
}
351-
352-
if (ProjectWorkspaceState.Equals(projectWorkspaceState))
353-
{
354-
return this;
355-
}
356-
357-
var difference = ProjectDifference.ProjectWorkspaceStateChanged;
358-
var documents = Documents.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value.WithProjectWorkspaceStateChange(), FilePathNormalizingComparer.Instance);
359-
var state = new ProjectState(this, difference, HostProject, projectWorkspaceState, documents, ImportsToRelatedDocuments);
323+
var state = new ProjectState(this, ProjectDifference.ConfigurationChanged, hostProject, projectWorkspaceState, documents, importsToRelatedDocuments);
360324
return state;
361325
}
362326

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/UpdateProjectAction.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,4 @@ internal record ProjectAddedAction(HostProject HostProject) : IUpdateProjectActi
3030

3131
internal record ProjectRemovedAction(ProjectKey ProjectKey) : IUpdateProjectAction;
3232

33-
internal record HostProjectUpdatedAction(HostProject HostProject) : IUpdateProjectAction;
34-
35-
internal record ProjectWorkspaceStateChangedAction(ProjectWorkspaceState WorkspaceState) : IUpdateProjectAction;
33+
internal record ProjectChangeAction(HostProject HostProject, ProjectWorkspaceState WorkspaceState) : IUpdateProjectAction;

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/LiveShare/Guest/ProjectSnapshotSynchronizationService.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ await _projectManager.UpdateAsync(
8585

8686
if (state.projectWorkspaceState != null)
8787
{
88-
updater.ProjectWorkspaceStateChanged(state.hostProject.Key, state.projectWorkspaceState);
88+
updater.ProjectChanged(state.hostProject, state.projectWorkspaceState);
8989
}
9090
},
9191
state: (hostProject, projectWorkspaceState: args.Newer.ProjectWorkspaceState),
@@ -108,31 +108,16 @@ await _projectManager.UpdateAsync(
108108
}
109109
else if (args.Kind == ProjectProxyChangeKind.ProjectChanged)
110110
{
111-
if (!args.Older!.Configuration.Equals(args.Newer!.Configuration))
111+
if (!args.Older!.Configuration.Equals(args.Newer!.Configuration) ||
112+
!args.Older.ProjectWorkspaceState.Equals(args.Newer.ProjectWorkspaceState))
112113
{
113114
var guestPath = ResolveGuestPath(args.Newer.FilePath);
114115
var guestIntermediateOutputPath = ResolveGuestPath(args.Newer.IntermediateOutputPath);
115116
var hostProject = new HostProject(guestPath, guestIntermediateOutputPath, args.Newer.Configuration, args.Newer.RootNamespace);
117+
var projectWorkspaceState = args.Newer.ProjectWorkspaceState;
116118
await _projectManager.UpdateAsync(
117-
static (updater, hostProject) => updater.ProjectConfigurationChanged(hostProject),
118-
state: hostProject,
119-
CancellationToken.None);
120-
}
121-
else if (args.Older.ProjectWorkspaceState != args.Newer.ProjectWorkspaceState ||
122-
args.Older.ProjectWorkspaceState?.Equals(args.Newer.ProjectWorkspaceState) == false)
123-
{
124-
var guestPath = ResolveGuestPath(args.Newer.FilePath);
125-
await _projectManager.UpdateAsync(
126-
static (updater, state) =>
127-
{
128-
var projectKeys = updater.GetAllProjectKeys(state.guestPath);
129-
130-
foreach (var projectKey in projectKeys)
131-
{
132-
updater.ProjectWorkspaceStateChanged(projectKey, state.projectWorkspaceState);
133-
}
134-
},
135-
state: (guestPath, projectWorkspaceState: args.Newer.ProjectWorkspaceState),
119+
static (updater, state) => updater.ProjectChanged(state.hostProject, state.projectWorkspaceState),
120+
state: (hostProject, projectWorkspaceState),
136121
CancellationToken.None);
137122
}
138123
}
@@ -152,7 +137,7 @@ await _projectManager.UpdateAsync(
152137

153138
if (state.projectWorkspaceState is not null)
154139
{
155-
updater.ProjectWorkspaceStateChanged(state.hostProject.Key, state.projectWorkspaceState);
140+
updater.ProjectChanged(state.hostProject, state.projectWorkspaceState);
156141
}
157142
},
158143
state: (hostProject, projectWorkspaceState: projectHandle.ProjectWorkspaceState),

src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/ProjectSystem/WindowsRazorProjectHostBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protected Task UpdateAsync(Action<ProjectSnapshotManager.Updater> action, Cancel
265265

266266
protected static void UpdateProject(ProjectSnapshotManager.Updater updater, HostProject project)
267267
{
268-
if (!updater.TryGetLoadedProject(project.Key, out _))
268+
if (!updater.TryGetLoadedProject(project.Key, out var current))
269269
{
270270
// Just in case we somehow got in a state where VS didn't tell us that solution close was finished, lets just
271271
// ensure we're going to actually do something with the new project that we've just been told about.
@@ -275,7 +275,7 @@ protected static void UpdateProject(ProjectSnapshotManager.Updater updater, Host
275275
}
276276
else
277277
{
278-
updater.ProjectConfigurationChanged(project);
278+
updater.ProjectChanged(project, current.ProjectWorkspaceState);
279279
}
280280
}
281281

0 commit comments

Comments
 (0)