aspnetcore/src/Microsoft.VisualStudio.Mac..../ProjectSystem/DefaultDotNetProjectHost.cs

156 lines
5.4 KiB
C#

// 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.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
using Microsoft.VisualStudio.Editor.Razor;
using MonoDevelop.Projects;
namespace Microsoft.VisualStudio.Mac.LanguageServices.Razor.ProjectSystem
{
internal class DefaultDotNetProjectHost : DotNetProjectHost
{
private const string ExplicitRazorConfigurationCapability = "DotNetCoreRazorConfiguration";
private readonly DotNetProject _project;
private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly VisualStudioMacWorkspaceAccessor _workspaceAccessor;
private readonly TextBufferProjectService _projectService;
private RazorProjectHostBase _razorProjectHost;
public DefaultDotNetProjectHost(
DotNetProject project,
ForegroundDispatcher foregroundDispatcher,
VisualStudioMacWorkspaceAccessor workspaceAccessor,
TextBufferProjectService projectService)
{
if (project == null)
{
throw new ArgumentNullException(nameof(project));
}
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
if (workspaceAccessor == null)
{
throw new ArgumentNullException(nameof(workspaceAccessor));
}
if (projectService == null)
{
throw new ArgumentNullException(nameof(projectService));
}
_project = project;
_foregroundDispatcher = foregroundDispatcher;
_workspaceAccessor = workspaceAccessor;
_projectService = projectService;
}
// Internal for testing
internal DefaultDotNetProjectHost(
ForegroundDispatcher foregroundDispatcher,
VisualStudioMacWorkspaceAccessor workspaceAccessor,
TextBufferProjectService projectService)
{
if (foregroundDispatcher == null)
{
throw new ArgumentNullException(nameof(foregroundDispatcher));
}
if (workspaceAccessor == null)
{
throw new ArgumentNullException(nameof(workspaceAccessor));
}
if (projectService == null)
{
throw new ArgumentNullException(nameof(projectService));
}
_foregroundDispatcher = foregroundDispatcher;
_workspaceAccessor = workspaceAccessor;
_projectService = projectService;
}
public override DotNetProject Project => _project;
public override void Subscribe()
{
_foregroundDispatcher.AssertForegroundThread();
UpdateRazorHostProject();
_project.ProjectCapabilitiesChanged += Project_ProjectCapabilitiesChanged;
_project.Disposing += Project_Disposing;
}
private void Project_Disposing(object sender, EventArgs e)
{
_foregroundDispatcher.AssertForegroundThread();
_project.ProjectCapabilitiesChanged -= Project_ProjectCapabilitiesChanged;
_project.Disposing -= Project_Disposing;
DetatchCurrentRazorProjectHost();
}
private void Project_ProjectCapabilitiesChanged(object sender, EventArgs e) => UpdateRazorHostProject();
// Internal for testing
internal void UpdateRazorHostProject()
{
_foregroundDispatcher.AssertForegroundThread();
DetatchCurrentRazorProjectHost();
if (!_projectService.IsSupportedProject(_project))
{
// Not a Razor compatible project.
return;
}
if (!TryGetProjectSnapshotManager(out var projectSnapshotManager))
{
// Could not get a ProjectSnapshotManager for the current project.
return;
}
if (_project.IsCapabilityMatch(ExplicitRazorConfigurationCapability))
{
// SDK >= 2.1
_razorProjectHost = new DefaultRazorProjectHost(_project, _foregroundDispatcher, projectSnapshotManager);
return;
}
// We're an older version of Razor at this point, SDK < 2.1
_razorProjectHost = new FallbackRazorProjectHost(_project, _foregroundDispatcher, projectSnapshotManager);
}
private bool TryGetProjectSnapshotManager(out ProjectSnapshotManagerBase projectSnapshotManagerBase)
{
if (!_workspaceAccessor.TryGetWorkspace(_project.ParentSolution, out var workspace))
{
// Could not locate workspace for razor project. Project is most likely tearing down.
projectSnapshotManagerBase = null;
return false;
}
var languageService = workspace.Services.GetLanguageServices(RazorLanguage.Name);
projectSnapshotManagerBase = (ProjectSnapshotManagerBase)languageService.GetRequiredService<ProjectSnapshotManager>();
return true;
}
private void DetatchCurrentRazorProjectHost()
{
_razorProjectHost?.Detatch();
_razorProjectHost = null;
}
}
}