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))]
|
||||
internal class DefaultTextBufferProjectService : TextBufferProjectService
|
||||
{
|
||||
private const string DotNetCoreCapability = "(CSharp|VB)&CPS";
|
||||
|
||||
private readonly RunningDocumentTable _documentTable;
|
||||
private readonly ITextDocumentFactoryService _documentFactory;
|
||||
|
||||
|
|
@ -79,7 +81,20 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
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.Razor;
|
||||
using Microsoft.VisualStudio.Editor.Razor;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
using Microsoft.VisualStudio.Text.Editor;
|
||||
using Microsoft.VisualStudio.Utilities;
|
||||
|
|
@ -20,14 +22,21 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
internal class RazorTextViewConnectionListener : IWpfTextViewConnectionListener
|
||||
{
|
||||
private readonly ForegroundDispatcher _foregroundDispatcher;
|
||||
private readonly TextBufferProjectService _projectService;
|
||||
private readonly RazorEditorFactoryService _editorFactoryService;
|
||||
private readonly Workspace _workspace;
|
||||
|
||||
[ImportingConstructor]
|
||||
public RazorTextViewConnectionListener(
|
||||
TextBufferProjectService projectService,
|
||||
RazorEditorFactoryService editorFactoryService,
|
||||
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
||||
{
|
||||
if (projectService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
}
|
||||
|
||||
if (editorFactoryService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(editorFactoryService));
|
||||
|
|
@ -38,6 +47,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
throw new ArgumentNullException(nameof(workspace));
|
||||
}
|
||||
|
||||
_projectService = projectService;
|
||||
_editorFactoryService = editorFactoryService;
|
||||
_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.
|
||||
internal RazorTextViewConnectionListener(
|
||||
ForegroundDispatcher foregroundDispatcher,
|
||||
TextBufferProjectService projectService,
|
||||
RazorEditorFactoryService editorFactoryService,
|
||||
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
||||
{
|
||||
|
|
@ -55,6 +66,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
throw new ArgumentNullException(nameof(foregroundDispatcher));
|
||||
}
|
||||
|
||||
if (projectService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(projectService));
|
||||
}
|
||||
|
||||
if (editorFactoryService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(editorFactoryService));
|
||||
|
|
@ -66,6 +82,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
}
|
||||
|
||||
_foregroundDispatcher = foregroundDispatcher;
|
||||
_projectService = projectService;
|
||||
_editorFactoryService = editorFactoryService;
|
||||
_workspace = workspace;
|
||||
}
|
||||
|
|
@ -94,6 +111,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
continue;
|
||||
}
|
||||
|
||||
var hierarchy = _projectService.GetHierarchy(textBuffer);
|
||||
if (!_projectService.IsSupportedProject(hierarchy))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_editorFactoryService.TryGetDocumentTracker(textBuffer, out var documentTracker) ||
|
||||
!(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 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]
|
||||
public void SubjectBuffersConnected_ForNonRazorTextBuffer_DoesNothing()
|
||||
{
|
||||
// Arrange
|
||||
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 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]);
|
||||
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
|
||||
textViewListener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
|
||||
|
|
@ -93,7 +113,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
tracker.AddTextView(textView1);
|
||||
tracker.AddTextView(textView2);
|
||||
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
|
||||
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));
|
||||
}
|
||||
|
||||
[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]
|
||||
public void SubjectBuffersDisconnected_ForAnyTextBufferWithoutTracker_DoesNothing()
|
||||
{
|
||||
// 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>();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue