提交 aaebd407 编写于 作者: J Jason Malinowski

Add some additional shims to VisualStudioProjectTracker

Live Share was still using VisualStudioProjectTracker to add projects
to their own workspace. This restores enough support for that to work.
上级 1b4c5473
......@@ -397,7 +397,7 @@ private void UninitializeDebugMode()
IVsHierarchy hierarchy, uint itemid)
{
return new ContainedLanguage<TPackage, TLanguageService>(
bufferCoordinator, this.Package.ComponentModel, project, hierarchy, itemid,
bufferCoordinator, this.Package.ComponentModel, project, hierarchy, itemid, projectTrackerOpt: null, project.Id,
(TLanguageService)this);
}
}
......
......@@ -64,6 +64,7 @@ internal abstract partial class AbstractProject : ForegroundThreadAffinitizedObj
Hierarchy = hierarchy;
Guid = projectGuid;
Language = language;
ProjectTracker = projectTracker;
_visualStudioWorkspace = workspace;
this.DisplayName = hierarchy != null && hierarchy.TryGetName(out var name) ? name : projectSystemName;
......@@ -112,9 +113,12 @@ protected virtual string GetOutputFilePath()
internal HostDiagnosticUpdateSource HostDiagnosticUpdateSource { get; }
public virtual ProjectId Id => VisualStudioProject.Id;
public virtual ProjectId Id => VisualStudioProject?.Id ?? ExplicitId;
internal ProjectId ExplicitId { get; set; }
public string Language { get; }
public VisualStudioProjectTracker ProjectTracker { get; }
/// <summary>
/// The <see cref="IVsHierarchy"/> for this project. NOTE: May be null in Deferred Project Load cases.
......
......@@ -9,9 +9,14 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
[Obsolete("This is a compatibility shim for TypeScript and Live Share; please do not use it.")]
internal sealed class DocumentProvider
{
[Obsolete("This is a compatibility shim for Live Share; please do not use it.")]
public DocumentProvider(VisualStudioProjectTracker projectTracker, IServiceProvider serviceProvider, VisualStudioDocumentTrackingService documentTrackingService)
{
}
[Obsolete("This overload is a compatibility shim for TypeScript; please do not use it.")]
public IVisualStudioHostDocument TryGetDocumentForFile(
AbstractProject hostProject,
......
......@@ -3,10 +3,12 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.Extensions;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
......@@ -16,22 +18,53 @@ internal sealed partial class VisualStudioProjectTracker
private readonly VisualStudioProjectFactory _projectFactory;
internal IThreadingContext ThreadingContext { get; }
internal ImmutableArray<AbstractProject> ImmutableProjects => ImmutableArray<AbstractProject>.Empty;
[Obsolete("This is a compatibility shim for Live Share; please do not use it.")]
internal ImmutableArray<AbstractProject> ImmutableProjects => _projects.Values.ToImmutableArray();
internal HostWorkspaceServices WorkspaceServices => _workspace.Services;
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
private readonly Dictionary<ProjectId, AbstractProject> _typeScriptProjects = new Dictionary<ProjectId, AbstractProject>();
[Obsolete("This is a compatibility shim for TypeScript and Live Share; please do not use it.")]
private readonly Dictionary<ProjectId, AbstractProject> _projects = new Dictionary<ProjectId, AbstractProject>();
[Obsolete("This is a compatibility shim; please do not use it.")]
public VisualStudioProjectTracker(Workspace workspace, VisualStudioProjectFactory projectFactory, IThreadingContext threadingContext)
{
_workspace = workspace;
_projectFactory = projectFactory;
ThreadingContext = threadingContext;
DocumentProvider = new DocumentProvider(this, null, null);
}
[Obsolete("This is a compatibility shim for Live Share; please do not use it.")]
public VisualStudioProjectTracker(IServiceProvider serviceProvider, Workspace workspace)
{
_workspace = workspace;
ThreadingContext = serviceProvider.GetMefService<IThreadingContext>();
// This is used by Live Share to target their own workspace which is not the standard VS workspace; as a result this shouldn't have a project factory
// at all, because that's only targeting the VisualStudioWorkspace.
_projectFactory = null;
// We don't set DocumentProvider, because Live Share creates their own and then sets it later.
}
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
public DocumentProvider DocumentProvider => new DocumentProvider();
public DocumentProvider DocumentProvider { get; set; }
public Workspace Workspace => _workspace;
[Obsolete("This is a compatibility shim for Live Share; please do not use it.")]
public void InitializeProviders(DocumentProvider documentProvider, VisualStudioMetadataReferenceManager metadataReferenceProvider, VisualStudioRuleSetManager ruleSetFileProvider)
{
DocumentProvider = documentProvider;
}
[Obsolete("This is a compatibility shim for Live Share; please do not use it.")]
public void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable<AbstractProject> projects)
{
// This shim doesn't expect to get actual things passed to it
Debug.Assert(!projects.Any());
}
/*
......@@ -62,7 +95,7 @@ public ProjectId GetOrCreateProjectIdForPath(string filePath, string projectDisp
public AbstractProject GetProject(ProjectId projectId)
{
// HACK: if we have a TypeScript project, they expect to return the real thing deriving from AbstractProject
if (_typeScriptProjects.TryGetValue(projectId, out var typeScriptProject))
if (_projects.TryGetValue(projectId, out var typeScriptProject))
{
return typeScriptProject;
}
......@@ -110,29 +143,45 @@ public StubProject(VisualStudioProjectTracker projectTracker, Project project)
public override ProjectId Id => _id;
}
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
[Obsolete("This is a compatibility shim for TypeScript and Live Share; please do not use it.")]
public void AddProject(AbstractProject project)
{
project.VisualStudioProject = _projectFactory.CreateAndAddToWorkspace(project.ProjectSystemName, project.Language);
project.UpdateVisualStudioProjectProperties();
_typeScriptProjects[project.Id] = project;
if (_projectFactory != null)
{
project.VisualStudioProject = _projectFactory.CreateAndAddToWorkspace(project.ProjectSystemName, project.Language);
project.UpdateVisualStudioProjectProperties();
}
else
{
// We don't have an ID, so make something up
project.ExplicitId = ProjectId.CreateNewId(project.ProjectSystemName);
Workspace.OnProjectAdded(ProjectInfo.Create(project.ExplicitId, VersionStamp.Create(), project.ProjectSystemName, project.ProjectSystemName, project.Language));
}
_projects[project.Id] = project;
}
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
public bool ContainsProject(AbstractProject project)
{
// This will be set as long as the project has been added and not since removed
return project.VisualStudioProject != null;
return _projects.Values.Contains(project);
}
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
public void RemoveProject(AbstractProject project)
{
_typeScriptProjects.Remove(project.Id);
_projects.Remove(project.Id);
project.VisualStudioProject.RemoveFromWorkspace();
project.VisualStudioProject = null;
if (project.ExplicitId != null)
{
Workspace.OnProjectRemoved(project.ExplicitId);
}
else
{
project.VisualStudioProject.RemoveFromWorkspace();
project.VisualStudioProject = null;
}
}
}
}
......@@ -68,7 +68,7 @@ public static ContainedDocument TryGetContainedDocument(DocumentId id)
}
private readonly IComponentModel _componentModel;
private readonly VisualStudioWorkspace _workspace;
private readonly Workspace _workspace;
private readonly ITextDifferencingSelectorService _differenceSelectorService;
private readonly HostType _hostType;
private readonly ReiteratedVersionSnapshotTracker _snapshotTracker;
......@@ -89,7 +89,7 @@ public static ContainedDocument TryGetContainedDocument(DocumentId id)
ITextBuffer subjectBuffer,
ITextBuffer dataBuffer,
IVsTextBufferCoordinator bufferCoordinator,
VisualStudioWorkspace workspace,
Workspace workspace,
VisualStudioProject project,
IVsHierarchy hierarchy,
uint itemId,
......@@ -179,7 +179,8 @@ public void Dispose()
public DocumentId FindProjectDocumentIdWithItemId(uint itemidInsertionPoint)
{
var hierarchy = _workspace.GetHierarchy(_project.Id);
// We cast to VisualStudioWorkspace because the expectation is this isn't being used in Live Share workspaces
var hierarchy = ((VisualStudioWorkspace)_workspace).GetHierarchy(_project.Id);
foreach (var document in _workspace.CurrentSolution.GetProject(_project.Id).Documents)
{
......@@ -194,7 +195,8 @@ public DocumentId FindProjectDocumentIdWithItemId(uint itemidInsertionPoint)
public uint FindItemIdOfDocument(Document document)
{
var hierarchy = _workspace.GetHierarchy(_project.Id);
// We cast to VisualStudioWorkspace because the expectation is this isn't being used in Live Share workspaces
var hierarchy = ((VisualStudioWorkspace)_workspace).GetHierarchy(_project.Id);
return hierarchy.TryGetItemId(_workspace.CurrentSolution.GetDocument(document.Id).FilePath);
}
......
......@@ -31,7 +31,7 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
private readonly IDiagnosticAnalyzerService _diagnosticAnalyzerService;
private readonly TLanguageService _languageService;
protected readonly VisualStudioWorkspace Workspace;
protected readonly Workspace Workspace;
protected readonly IComponentModel ComponentModel;
public VisualStudioProject Project { get; }
......@@ -69,7 +69,7 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
// flickering.
private ITagAggregator<ITag> _bufferTagAggregator;
[Obsolete("This is a compatibility shim for TypeScript; please do not use it.")]
[Obsolete("This is a compatibility shim for TypeScript and Live Share; please do not use it.")]
public ContainedLanguage(
IVsTextBufferCoordinator bufferCoordinator,
IComponentModel componentModel,
......@@ -85,6 +85,8 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
project.VisualStudioProject,
hierarchy,
itemid,
project.ProjectTracker,
project.Id,
languageService,
vbHelperFormattingRule)
{
......@@ -105,17 +107,21 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
project.VisualStudioProject,
hierarchy,
itemid,
projectTrackerOpt: null,
project.VisualStudioProject.Id,
languageService,
vbHelperFormattingRule)
{
}
public ContainedLanguage(
internal ContainedLanguage(
IVsTextBufferCoordinator bufferCoordinator,
IComponentModel componentModel,
VisualStudioProject project,
IVsHierarchy hierarchy,
uint itemid,
VisualStudioProjectTracker projectTrackerOpt,
ProjectId projectId,
TLanguageService languageService,
IFormattingRule vbHelperFormattingRule = null)
{
......@@ -124,7 +130,7 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
this.Project = project;
_languageService = languageService;
this.Workspace = componentModel.GetService<VisualStudioWorkspace>();
this.Workspace = projectTrackerOpt?.Workspace ?? componentModel.GetService<VisualStudioWorkspace>();
_editorAdaptersFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
_diagnosticAnalyzerService = componentModel.GetService<IDiagnosticAnalyzerService>();
......@@ -137,7 +143,7 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
// Get the ITextBuffer for the primary buffer
Marshal.ThrowExceptionForHR(bufferCoordinator.GetPrimaryBuffer(out var primaryTextLines));
DataBuffer = _editorAdaptersFactoryService.GetDataBuffer((IVsTextBuffer)primaryTextLines);
// Create our tagger
var bufferTagAggregatorFactory = ComponentModel.GetService<IBufferTagAggregatorFactoryService>();
_bufferTagAggregator = bufferTagAggregatorFactory.CreateTagAggregator<ITag>(SubjectBuffer);
......@@ -153,7 +159,20 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
}
}
var documentId = this.Project.AddSourceTextContainer(SubjectBuffer.AsTextContainer(), filePath);
DocumentId documentId;
if (this.Project != null)
{
documentId = this.Project.AddSourceTextContainer(SubjectBuffer.AsTextContainer(), filePath);
}
else
{
documentId = DocumentId.CreateNewId(projectId, $"{nameof(ContainedDocument)}: {filePath}");
// We must jam a document into an existing workspace, which we'll assume is safe to do with OnDocumentAdded
Workspace.OnDocumentAdded(DocumentInfo.Create(documentId, filePath, filePath: filePath));
Workspace.OnDocumentOpened(documentId, SubjectBuffer.AsTextContainer());
}
this.ContainedDocument = new ContainedDocument(
componentModel.GetService<IThreadingContext>(),
......@@ -175,7 +194,19 @@ internal partial class ContainedLanguage<TPackage, TLanguageService>
private void OnDisconnect()
{
this.DataBuffer.Changed -= OnDataBufferChanged;
this.Project.RemoveSourceTextContainer(SubjectBuffer.AsTextContainer());
if (this.Project != null)
{
this.Project.RemoveSourceTextContainer(SubjectBuffer.AsTextContainer());
}
else
{
// It's possible the host of the workspace might have already removed the entire project
if (Workspace.CurrentSolution.ContainsDocument(ContainedDocument.Id))
{
Workspace.OnDocumentRemoved(ContainedDocument.Id);
}
}
this.ContainedDocument.Dispose();
}
......
......@@ -28,7 +28,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Venus
itemid As UInteger,
languageService As VisualBasicLanguageService,
sourceCodeKind As SourceCodeKind)
MyBase.New(bufferCoordinator, componentModel, project, hierarchy, itemid, languageService, VisualBasicHelperFormattingRule.Instance)
MyBase.New(bufferCoordinator, componentModel, project, hierarchy, itemid, projectTrackerOpt:=Nothing, project.Id, languageService, VisualBasicHelperFormattingRule.Instance)
End Sub
Public Function AddStaticEventBinding(pszClassName As String,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册