Prevent Razor Core from running in non-core scenarios.
- Also added tests. #1776
This commit is contained in:
parent
fa2d79296a
commit
4f7aab7720
|
|
@ -16,6 +16,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
[Export(typeof(TextBufferProjectService))]
|
[Export(typeof(TextBufferProjectService))]
|
||||||
internal class DefaultTextBufferProjectService : TextBufferProjectService
|
internal class DefaultTextBufferProjectService : TextBufferProjectService
|
||||||
{
|
{
|
||||||
|
private const string DotNetCoreCapability = "(CSharp|VB)&CPS";
|
||||||
|
|
||||||
private readonly RunningDocumentTable _documentTable;
|
private readonly RunningDocumentTable _documentTable;
|
||||||
private readonly ITextDocumentFactoryService _documentFactory;
|
private readonly ITextDocumentFactoryService _documentFactory;
|
||||||
|
|
||||||
|
|
@ -79,7 +81,20 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
throw new ArgumentNullException(nameof(hierarchy));
|
throw new ArgumentNullException(nameof(hierarchy));
|
||||||
}
|
}
|
||||||
|
|
||||||
return hierarchy.IsCapabilityMatch("DotNetCoreWeb");
|
try
|
||||||
|
{
|
||||||
|
return hierarchy.IsCapabilityMatch(DotNetCoreCapability);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException)
|
||||||
|
{
|
||||||
|
// IsCapabilityMatch throws a NotSupportedException if it can't create a BooleanSymbolExpressionEvaluator COM object
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// IsCapabilityMatch throws an ObjectDisposedException if the underlying hierarchy has been disposed.
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ using System.Diagnostics;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.Razor;
|
using Microsoft.CodeAnalysis.Razor;
|
||||||
using Microsoft.VisualStudio.Editor.Razor;
|
using Microsoft.VisualStudio.Editor.Razor;
|
||||||
|
using Microsoft.VisualStudio.Shell;
|
||||||
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
using Microsoft.VisualStudio.Text;
|
using Microsoft.VisualStudio.Text;
|
||||||
using Microsoft.VisualStudio.Text.Editor;
|
using Microsoft.VisualStudio.Text.Editor;
|
||||||
using Microsoft.VisualStudio.Utilities;
|
using Microsoft.VisualStudio.Utilities;
|
||||||
|
|
@ -20,14 +22,21 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
internal class RazorTextViewConnectionListener : IWpfTextViewConnectionListener
|
internal class RazorTextViewConnectionListener : IWpfTextViewConnectionListener
|
||||||
{
|
{
|
||||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||||
|
private readonly TextBufferProjectService _projectService;
|
||||||
private readonly RazorEditorFactoryService _editorFactoryService;
|
private readonly RazorEditorFactoryService _editorFactoryService;
|
||||||
private readonly Workspace _workspace;
|
private readonly Workspace _workspace;
|
||||||
|
|
||||||
[ImportingConstructor]
|
[ImportingConstructor]
|
||||||
public RazorTextViewConnectionListener(
|
public RazorTextViewConnectionListener(
|
||||||
|
TextBufferProjectService projectService,
|
||||||
RazorEditorFactoryService editorFactoryService,
|
RazorEditorFactoryService editorFactoryService,
|
||||||
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
||||||
{
|
{
|
||||||
|
if (projectService == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(projectService));
|
||||||
|
}
|
||||||
|
|
||||||
if (editorFactoryService == null)
|
if (editorFactoryService == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(editorFactoryService));
|
throw new ArgumentNullException(nameof(editorFactoryService));
|
||||||
|
|
@ -38,6 +47,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
throw new ArgumentNullException(nameof(workspace));
|
throw new ArgumentNullException(nameof(workspace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_projectService = projectService;
|
||||||
_editorFactoryService = editorFactoryService;
|
_editorFactoryService = editorFactoryService;
|
||||||
_workspace = workspace;
|
_workspace = workspace;
|
||||||
|
|
||||||
|
|
@ -47,6 +57,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
// This is only for testing. We want to avoid using the actual Roslyn GetService methods in unit tests.
|
// This is only for testing. We want to avoid using the actual Roslyn GetService methods in unit tests.
|
||||||
internal RazorTextViewConnectionListener(
|
internal RazorTextViewConnectionListener(
|
||||||
ForegroundDispatcher foregroundDispatcher,
|
ForegroundDispatcher foregroundDispatcher,
|
||||||
|
TextBufferProjectService projectService,
|
||||||
RazorEditorFactoryService editorFactoryService,
|
RazorEditorFactoryService editorFactoryService,
|
||||||
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
||||||
{
|
{
|
||||||
|
|
@ -55,6 +66,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (projectService == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(projectService));
|
||||||
|
}
|
||||||
|
|
||||||
if (editorFactoryService == null)
|
if (editorFactoryService == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(editorFactoryService));
|
throw new ArgumentNullException(nameof(editorFactoryService));
|
||||||
|
|
@ -66,6 +82,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
}
|
}
|
||||||
|
|
||||||
_foregroundDispatcher = foregroundDispatcher;
|
_foregroundDispatcher = foregroundDispatcher;
|
||||||
|
_projectService = projectService;
|
||||||
_editorFactoryService = editorFactoryService;
|
_editorFactoryService = editorFactoryService;
|
||||||
_workspace = workspace;
|
_workspace = workspace;
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +111,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hierarchy = _projectService.GetHierarchy(textBuffer);
|
||||||
|
if (!_projectService.IsSupportedProject(hierarchy))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_editorFactoryService.TryGetDocumentTracker(textBuffer, out var documentTracker) ||
|
if (!_editorFactoryService.TryGetDocumentTracker(textBuffer, out var documentTracker) ||
|
||||||
!(documentTracker is DefaultVisualStudioDocumentTracker tracker))
|
!(documentTracker is DefaultVisualStudioDocumentTracker tracker))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,32 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
|
|
||||||
private IContentType NonRazorContentType { get; } = Mock.Of<IContentType>(c => c.IsOfType(It.IsAny<string>()) == false);
|
private IContentType NonRazorContentType { get; } = Mock.Of<IContentType>(c => c.IsOfType(It.IsAny<string>()) == false);
|
||||||
|
|
||||||
|
private TextBufferProjectService SupportedProjectService { get; } = Mock.Of<TextBufferProjectService>(s => s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == true);
|
||||||
|
|
||||||
|
private TextBufferProjectService UnsupportedProjectService { get; } = Mock.Of<TextBufferProjectService>(s => s.IsSupportedProject(It.IsAny<IVsHierarchy>()) == false);
|
||||||
|
|
||||||
|
[ForegroundFact]
|
||||||
|
public void SubjectBuffersConnected_ForNonRazorCoreProject_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var editorFactoryService = new Mock<RazorEditorFactoryService>(MockBehavior.Strict);
|
||||||
|
var factory = new RazorTextViewConnectionListener(Dispatcher, UnsupportedProjectService, editorFactoryService.Object, Workspace);
|
||||||
|
var textView = Mock.Of<IWpfTextView>();
|
||||||
|
var buffers = new Collection<ITextBuffer>()
|
||||||
|
{
|
||||||
|
Mock.Of<ITextBuffer>(b => b.ContentType == RazorContentType && b.Properties == new PropertyCollection()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
factory.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
[ForegroundFact]
|
[ForegroundFact]
|
||||||
public void SubjectBuffersConnected_ForNonRazorTextBuffer_DoesNothing()
|
public void SubjectBuffersConnected_ForNonRazorTextBuffer_DoesNothing()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var editorFactoryService = new Mock<RazorEditorFactoryService>(MockBehavior.Strict);
|
var editorFactoryService = new Mock<RazorEditorFactoryService>(MockBehavior.Strict);
|
||||||
var factory = new RazorTextViewConnectionListener(Dispatcher, editorFactoryService.Object, Workspace);
|
var factory = new RazorTextViewConnectionListener(Dispatcher, SupportedProjectService, editorFactoryService.Object, Workspace);
|
||||||
var textView = Mock.Of<IWpfTextView>();
|
var textView = Mock.Of<IWpfTextView>();
|
||||||
var buffers = new Collection<ITextBuffer>()
|
var buffers = new Collection<ITextBuffer>()
|
||||||
{
|
{
|
||||||
|
|
@ -61,7 +81,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
};
|
};
|
||||||
VisualStudioDocumentTracker documentTracker = new DefaultVisualStudioDocumentTracker("AFile", ProjectManager, ProjectService, EditorSettingsManager, Workspace, buffers[0]);
|
VisualStudioDocumentTracker documentTracker = new DefaultVisualStudioDocumentTracker("AFile", ProjectManager, ProjectService, EditorSettingsManager, Workspace, buffers[0]);
|
||||||
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(factoryService => factoryService.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
|
var editorFactoryService = Mock.Of<RazorEditorFactoryService>(factoryService => factoryService.TryGetDocumentTracker(It.IsAny<ITextBuffer>(), out documentTracker) == true);
|
||||||
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, editorFactoryService, Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, SupportedProjectService, editorFactoryService, Workspace);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
textViewListener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
textViewListener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
@ -93,7 +113,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
tracker.AddTextView(textView1);
|
tracker.AddTextView(textView1);
|
||||||
tracker.AddTextView(textView2);
|
tracker.AddTextView(textView2);
|
||||||
buffers[1].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
buffers[1].Properties.AddProperty(typeof(VisualStudioDocumentTracker), tracker);
|
||||||
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, SupportedProjectService, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
textViewListener.SubjectBuffersDisconnected(textView2, ConnectionReason.BufferGraphChange, buffers);
|
textViewListener.SubjectBuffersDisconnected(textView2, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
@ -106,11 +126,29 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
||||||
Assert.Collection(tracker.TextViews, v => Assert.Same(v, textView1));
|
Assert.Collection(tracker.TextViews, v => Assert.Same(v, textView1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ForegroundFact]
|
||||||
|
public void SubjectBuffersDisconnected_FoNonRazorCoreProject_DoesNothing()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, UnsupportedProjectService, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
||||||
|
var textView = Mock.Of<IWpfTextView>();
|
||||||
|
var buffers = new Collection<ITextBuffer>()
|
||||||
|
{
|
||||||
|
Mock.Of<ITextBuffer>(b => b.ContentType == RazorContentType && b.Properties == new PropertyCollection()),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
textViewListener.SubjectBuffersDisconnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(buffers[0].Properties.ContainsProperty(typeof(VisualStudioDocumentTracker)));
|
||||||
|
}
|
||||||
|
|
||||||
[ForegroundFact]
|
[ForegroundFact]
|
||||||
public void SubjectBuffersDisconnected_ForAnyTextBufferWithoutTracker_DoesNothing()
|
public void SubjectBuffersDisconnected_ForAnyTextBufferWithoutTracker_DoesNothing()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
var textViewListener = new RazorTextViewConnectionListener(Dispatcher, SupportedProjectService, Mock.Of<RazorEditorFactoryService>(), Workspace);
|
||||||
|
|
||||||
var textView = Mock.Of<IWpfTextView>();
|
var textView = Mock.Of<IWpfTextView>();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue