Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit bc73132

Browse files
KirillOsenkovmonojenkins
authored andcommitted
Refactor how virtual and dynamic documents are added to the workspace.
Virtual documents come from Razor when a .cshtml file is opened and they have .cshtml.g.cs file extension. These are C# projection buffers generated by Razor and only exist while the corresponding .cshtml file is open in an editor. Dynamic documents also come from Razor but these come from all .razor and .cshtml files in the project that have the MSBuild item type "Content". These don't have to be open in the editor. The problem is that we weren't adding virtual and dynamic documents in all scenarios. Specifically when the solution was initially loaded our code was not running and so if a Razor document was open before the solution was loading it wouldn't get added to the workspace properly. To mitigate this we've found a single codepath (LoadProject) that all the logic in the project system goes through. This includes the initial load as well as reload. This is the single place where a Roslyn ProjectInfo is created, and it's also a better location to add virtual and dynamic documents to the project being loaded. There is now no need to call AddVirtualDocuments from three separate locations. Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1012526
1 parent 8fc52fa commit bc73132

File tree

3 files changed

+27
-25
lines changed

3 files changed

+27
-25
lines changed

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ internal async Task<ProjectInfo> LoadProject (
167167
return null;
168168
}
169169

170+
IEnumerable<DocumentInfo> documents = projectDocuments.Documents;
171+
var virtualDocuments = workspace.GetVirtualDocuments (projectId);
172+
if (virtualDocuments.Any ()) {
173+
documents = documents.Concat (virtualDocuments);
174+
}
175+
170176
// TODO: Pass in the WorkspaceMetadataFileReferenceResolver
171177
var info = ProjectInfo.Create (
172178
projectId,
@@ -180,7 +186,7 @@ internal async Task<ProjectInfo> LoadProject (
180186
null, // defaultNamespace
181187
cp?.CreateCompilationOptions (),
182188
cp?.CreateParseOptions (config),
183-
projectDocuments.Documents,
189+
documents,
184190
cacheInfo.ProjectReferences,
185191
cacheInfo.References.Select (x => x.CurrentSnapshot),
186192
analyzerReferences: cacheInfo.AnalyzerFiles.SelectAsArray (x => {
@@ -194,6 +200,9 @@ internal async Task<ProjectInfo> LoadProject (
194200
hostObjectType: null,
195201
hasAllInformation: true
196202
);
203+
204+
info = workspace.WithDynamicDocuments (p, info);
205+
197206
return info;
198207
}
199208

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.cs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -320,23 +320,18 @@ internal void RemoveDocument(DocumentId documentId)
320320
OnDocumentRemoved (documentId);
321321
}
322322

323-
/// <summary>
324-
/// Razor (.cshtml) needs to be able to add C# documents to a project that are not backed by a file on disk.
325-
/// As these don't come from the project system, we need to keep track of these documents to readd them
326-
/// manually every time the project is reloaded from disk.
327-
/// </summary>
328-
internal ProjectInfo AddVirtualDocuments(ProjectInfo projectInfo)
329-
{
330-
lock (virtualDocuments) {
331-
var virtualDocumentsToAdd = virtualDocuments.Where (d => d.Id.ProjectId == projectInfo.Id);
332-
if (virtualDocumentsToAdd.Any ()) {
333-
projectInfo = projectInfo.WithDocuments (projectInfo.Documents.Concat (virtualDocumentsToAdd));
334-
}
335-
}
336-
337-
return projectInfo;
338-
}
339-
323+
/// <summary>
324+
/// Razor (.cshtml) needs to be able to add C# documents to a project that are not backed by a file on disk.
325+
/// As these don't come from the project system, we need to keep track of these documents to readd them
326+
/// manually every time the project is loaded from disk.
327+
/// </summary>
328+
internal IEnumerable<DocumentInfo> GetVirtualDocuments (ProjectId projectId)
329+
{
330+
lock (virtualDocuments) {
331+
return virtualDocuments.Where (d => d.Id.ProjectId == projectId).ToList ();
332+
}
333+
}
334+
340335
// This is called by OnProjectRemoved.
341336
protected override void ClearProjectData (ProjectId projectId)
342337
{
@@ -513,7 +508,6 @@ async Task ReloadProjects (CancellationToken cancellationToken)
513508
OnProjectAdded (projectInfo);
514509
} else {
515510
lock (projectModifyLock) {
516-
projectInfo = AddVirtualDocuments (projectInfo);
517511
OnProjectReloaded (projectInfo);
518512
}
519513
}
@@ -1514,8 +1508,6 @@ void OnProjectModified (object sender, MonoDevelop.Projects.SolutionItemModified
15141508
try {
15151509
lock (projectModifyLock) {
15161510
ProjectInfo newProjectContents = t.Result;
1517-
newProjectContents = WithDynamicDocuments (project, newProjectContents);
1518-
newProjectContents = AddVirtualDocuments (newProjectContents);
15191511
OnProjectReloaded (newProjectContents);
15201512
foreach (var docId in GetOpenDocumentIds (newProjectContents.Id).ToArray ()) {
15211513
if (CurrentSolution.GetDocument (docId) == null) {
@@ -1538,11 +1530,13 @@ void OnProjectModified (object sender, MonoDevelop.Projects.SolutionItemModified
15381530
}
15391531
}
15401532

1541-
internal ProjectInfo WithDynamicDocuments (MonoDevelop.Projects.DotNetProject project, ProjectInfo projectInfo)
1533+
internal ProjectInfo WithDynamicDocuments (MonoDevelop.Projects.Project project, ProjectInfo projectInfo)
15421534
{
1543-
var contentItems = project.MSBuildProject.EvaluatedItems.Where(item => item.Name == "Content" && item.Include.EndsWith(".razor", StringComparison.OrdinalIgnoreCase)).Select(item => item.Include);
1535+
var contentItems = project.MSBuildProject.EvaluatedItems
1536+
.Where (item => item.Name == "Content" && item.Include.EndsWith (".razor", StringComparison.OrdinalIgnoreCase))
1537+
.Select (item => item.Include);
15441538

1545-
return dynamicFileManager?.UpdateDynamicFiles(projectInfo, contentItems, this);
1539+
return dynamicFileManager?.UpdateDynamicFiles (projectInfo, contentItems, this);
15461540
}
15471541

15481542
internal override void SetDocumentContext (DocumentId documentId)

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/TypeSystemService_WorkspaceHandling.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ async void OnSolutionItemAdded (object sender, MonoDevelop.Projects.SolutionItem
564564
var projectInfo = await ws.LoadProject (project, CancellationToken.None, oldProject, framework);
565565
if (oldProject != null) {
566566
if (oldProjectIds.Remove (projectInfo.Id)) {
567-
projectInfo = ws.AddVirtualDocuments (projectInfo);
568567
ws.OnProjectReloaded (projectInfo);
569568
} else {
570569
ws.OnProjectAdded (projectInfo);

0 commit comments

Comments
 (0)