Add `ProjectPathProvider` abstract for document tracker creation.
- First iteration of live share replaced the document tracker factory entirely; however, this will be prone to breaking changes in the future when me make changes to document tracker to not rely on a file path. To pre-emptively prevent breaking changes I added a project path provider that can be overridden in the live share case. Note that one big difference here between old and new is that instead of being a MEF service implementation for the project path resolution we're bringing that to the Workspace service level. - Added tests to validate the two flows of the default project path provider.
This commit is contained in:
parent
9a249ffcc1
commit
95d41507fc
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor
|
||||
{
|
||||
internal class DefaultProjectPathProvider : ProjectPathProvider
|
||||
{
|
||||
private readonly TextBufferProjectService _projectService;
|
||||
|
||||
public DefaultProjectPathProvider(TextBufferProjectService projectService)
|
||||
{
|
||||
if (projectService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
}
|
||||
|
||||
_projectService = projectService;
|
||||
}
|
||||
|
||||
public override bool TryGetProjectPath(ITextBuffer textBuffer, out string filePath)
|
||||
{
|
||||
if (textBuffer == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(textBuffer));
|
||||
}
|
||||
|
||||
var project = _projectService.GetHostProject(textBuffer);
|
||||
if (project == null)
|
||||
{
|
||||
filePath = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
filePath = _projectService.GetProjectPath(project);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using Microsoft.CodeAnalysis.Host;
|
||||
using Microsoft.CodeAnalysis.Host.Mef;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor
|
||||
{
|
||||
[System.Composition.Shared]
|
||||
[ExportWorkspaceService(typeof(ProjectPathProvider), ServiceLayer.Default)]
|
||||
internal class DefaultProjectPathProviderFactory : IWorkspaceServiceFactory
|
||||
{
|
||||
private readonly TextBufferProjectService _projectService;
|
||||
|
||||
[ImportingConstructor]
|
||||
public DefaultProjectPathProviderFactory(TextBufferProjectService projectService)
|
||||
{
|
||||
if (projectService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
}
|
||||
|
||||
_projectService = projectService;
|
||||
}
|
||||
|
||||
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
|
||||
{
|
||||
if (workspaceServices == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(workspaceServices));
|
||||
}
|
||||
|
||||
return new DefaultProjectPathProvider(_projectService);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
{
|
||||
internal class DefaultVisualStudioDocumentTrackerFactory : VisualStudioDocumentTrackerFactory
|
||||
{
|
||||
private readonly TextBufferProjectService _projectService;
|
||||
private readonly ITextDocumentFactoryService _textDocumentFactory;
|
||||
private readonly ProjectPathProvider _projectPathProvider;
|
||||
private readonly Workspace _workspace;
|
||||
private readonly ImportDocumentManager _importDocumentManager;
|
||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||
|
|
@ -25,7 +25,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
ForegroundDispatcher foregroundDispatcher,
|
||||
ProjectSnapshotManager projectManager,
|
||||
WorkspaceEditorSettings workspaceEditorSettings,
|
||||
TextBufferProjectService projectService,
|
||||
ProjectPathProvider projectPathProvider,
|
||||
ITextDocumentFactoryService textDocumentFactory,
|
||||
ImportDocumentManager importDocumentManager,
|
||||
Workspace workspace)
|
||||
|
|
@ -45,9 +45,9 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
throw new ArgumentNullException(nameof(workspaceEditorSettings));
|
||||
}
|
||||
|
||||
if (projectService == null)
|
||||
if (projectPathProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
throw new ArgumentNullException(nameof(projectPathProvider));
|
||||
}
|
||||
|
||||
if (textDocumentFactory == null)
|
||||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
_foregroundDispatcher = foregroundDispatcher;
|
||||
_projectManager = projectManager;
|
||||
_workspaceEditorSettings = workspaceEditorSettings;
|
||||
_projectService = projectService;
|
||||
_projectPathProvider = projectPathProvider;
|
||||
_textDocumentFactory = textDocumentFactory;
|
||||
_importDocumentManager = importDocumentManager;
|
||||
_workspace = workspace;
|
||||
|
|
@ -87,16 +87,12 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
return null;
|
||||
}
|
||||
|
||||
var filePath = textDocument.FilePath;
|
||||
var project = _projectService.GetHostProject(textBuffer);
|
||||
if (project == null)
|
||||
if (!_projectPathProvider.TryGetProjectPath(textBuffer, out var projectPath))
|
||||
{
|
||||
Debug.Fail("Text buffer should belong to a project.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var projectPath = _projectService.GetProjectPath(project);
|
||||
|
||||
var filePath = textDocument.FilePath;
|
||||
var tracker = new DefaultVisualStudioDocumentTracker(_foregroundDispatcher, filePath, projectPath, _projectManager, _workspaceEditorSettings, _workspace, textBuffer, _importDocumentManager);
|
||||
|
||||
return tracker;
|
||||
|
|
|
|||
|
|
@ -17,13 +17,11 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
internal class DefaultVisualStudioDocumentTrackerFactoryFactory : ILanguageServiceFactory
|
||||
{
|
||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||
private readonly TextBufferProjectService _projectService;
|
||||
private readonly ITextDocumentFactoryService _textDocumentFactory;
|
||||
|
||||
[ImportingConstructor]
|
||||
public DefaultVisualStudioDocumentTrackerFactoryFactory(
|
||||
ForegroundDispatcher foregroundDispatcher,
|
||||
TextBufferProjectService projectService,
|
||||
ITextDocumentFactoryService textDocumentFactory)
|
||||
{
|
||||
if (foregroundDispatcher == null)
|
||||
|
|
@ -31,18 +29,12 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||
}
|
||||
|
||||
if (projectService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
}
|
||||
|
||||
if (textDocumentFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(textDocumentFactory));
|
||||
}
|
||||
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
_projectService = projectService;
|
||||
_textDocumentFactory = textDocumentFactory;
|
||||
}
|
||||
|
||||
|
|
@ -57,11 +49,13 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
var workspaceEditorSettings = languageServices.GetRequiredService<WorkspaceEditorSettings>();
|
||||
var importDocumentManager = languageServices.GetRequiredService<ImportDocumentManager>();
|
||||
|
||||
var projectPathProvider = languageServices.WorkspaceServices.GetRequiredService<ProjectPathProvider>();
|
||||
|
||||
return new DefaultVisualStudioDocumentTrackerFactory(
|
||||
_foregroundDispatcher,
|
||||
projectManager,
|
||||
workspaceEditorSettings,
|
||||
_projectService,
|
||||
projectPathProvider,
|
||||
_textDocumentFactory,
|
||||
importDocumentManager,
|
||||
languageServices.WorkspaceServices.Workspace);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.CodeAnalysis.Host;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor
|
||||
{
|
||||
internal abstract class ProjectPathProvider : IWorkspaceService
|
||||
{
|
||||
public abstract bool TryGetProjectPath(ITextBuffer textBuffer, out string filePath);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor
|
||||
{
|
||||
public class DefaultProjectPathProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public void TryGetProjectPath_ReturnsFalseIfNoProject()
|
||||
{
|
||||
// Arrange
|
||||
var projectPathProvider = new DefaultProjectPathProvider(Mock.Of<TextBufferProjectService>());
|
||||
var textBuffer = Mock.Of<ITextBuffer>();
|
||||
|
||||
// Act
|
||||
var result = projectPathProvider.TryGetProjectPath(textBuffer, out var filePath);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.Null(filePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetProjectPath_ReturnsTrueIfProject()
|
||||
{
|
||||
// Arrange
|
||||
var expectedProjectPath = "/my/project/path.csproj";
|
||||
var projectService = new Mock<TextBufferProjectService>();
|
||||
projectService.Setup(service => service.GetHostProject(It.IsAny<ITextBuffer>()))
|
||||
.Returns(new object());
|
||||
projectService.Setup(service => service.GetProjectPath(It.IsAny<object>()))
|
||||
.Returns(expectedProjectPath);
|
||||
var projectPathProvider = new DefaultProjectPathProvider(projectService.Object);
|
||||
var textBuffer = Mock.Of<ITextBuffer>();
|
||||
|
||||
// Act
|
||||
var result = projectPathProvider.TryGetProjectPath(textBuffer, out var filePath);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.Equal(expectedProjectPath, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue