Move away from WPF text view connection listener.

- Had to add a new NuGet feed to access latest VS bits.
- Updated tests to react to new ITextViewConnectionListener.

#1735
This commit is contained in:
N. Taylor Mullen 2017-11-27 14:55:32 -08:00
parent df1d0bbcd4
commit 182714c324
7 changed files with 27 additions and 43 deletions

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.26917.3000 VisualStudioVersion = 15.0.26927.3
MinimumVisualStudioVersion = 15.0.26730.03 MinimumVisualStudioVersion = 15.0.26730.03
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3C0D6505-79B3-49D0-B4C3-176F0F1836ED}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
@ -16,9 +16,10 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F8C12DD6-659D-405A-AA27-FB22AD92A010}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F8C12DD6-659D-405A-AA27-FB22AD92A010}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
build\dependencies.props = build\dependencies.props
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets Directory.Build.targets = Directory.Build.targets
NuGet.config = NuGet.config build\sources.props = build\sources.props
EndProjectSection EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPageGenerator", "src\RazorPageGenerator\RazorPageGenerator.csproj", "{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RazorPageGenerator", "src\RazorPageGenerator\RazorPageGenerator.csproj", "{7BE58880-36AD-4CD5-9E16-2A5AFEA790EF}"

View File

@ -17,8 +17,8 @@
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-25907-02</MicrosoftNETCoreApp21PackageVersion> <MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-25907-02</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
<MicrosoftVisualStudioComponentModelHostPackageVersion>15.0.26606</MicrosoftVisualStudioComponentModelHostPackageVersion> <MicrosoftVisualStudioComponentModelHostPackageVersion>15.0.26606</MicrosoftVisualStudioComponentModelHostPackageVersion>
<MicrosoftVisualStudioEditorPackageVersion>15.0.26606</MicrosoftVisualStudioEditorPackageVersion> <MicrosoftVisualStudioEditorPackageVersion>15.6.161-preview</MicrosoftVisualStudioEditorPackageVersion>
<MicrosoftVisualStudioLanguageIntellisensePackageVersion>15.0.26606</MicrosoftVisualStudioLanguageIntellisensePackageVersion> <MicrosoftVisualStudioLanguageIntellisensePackageVersion>15.6.161-preview</MicrosoftVisualStudioLanguageIntellisensePackageVersion>
<MicrosoftVisualStudioOLEInteropPackageVersion>7.10.6070</MicrosoftVisualStudioOLEInteropPackageVersion> <MicrosoftVisualStudioOLEInteropPackageVersion>7.10.6070</MicrosoftVisualStudioOLEInteropPackageVersion>
<MicrosoftVisualStudioShell150PackageVersion>15.0.26606</MicrosoftVisualStudioShell150PackageVersion> <MicrosoftVisualStudioShell150PackageVersion>15.0.26606</MicrosoftVisualStudioShell150PackageVersion>
<MicrosoftVisualStudioShellInterop100PackageVersion>10.0.30319</MicrosoftVisualStudioShellInterop100PackageVersion> <MicrosoftVisualStudioShellInterop100PackageVersion>10.0.30319</MicrosoftVisualStudioShellInterop100PackageVersion>

View File

@ -8,6 +8,7 @@
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json; https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
https://dotnet.myget.org/F/roslyn/api/v3/index.json; https://dotnet.myget.org/F/roslyn/api/v3/index.json;
https://vside.myget.org/F/vssdk/api/v3/index.json
</RestoreSources> </RestoreSources>
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'"> <RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
$(RestoreSources); $(RestoreSources);

View File

@ -36,7 +36,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
_projectService = projectService; _projectService = projectService;
} }
public override void OnTextViewOpened(ITextView textView, IList<ITextBuffer> subjectBuffers) public override void OnTextViewOpened(ITextView textView, IEnumerable<ITextBuffer> subjectBuffers)
{ {
if (textView == null) if (textView == null)
{ {
@ -48,9 +48,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
throw new ArgumentNullException(nameof(subjectBuffers)); throw new ArgumentNullException(nameof(subjectBuffers));
} }
for (var i = 0; i < subjectBuffers.Count; i++) foreach (var textBuffer in subjectBuffers)
{ {
var textBuffer = subjectBuffers[i];
if (!textBuffer.IsRazorBuffer()) if (!textBuffer.IsRazorBuffer())
{ {
continue; continue;
@ -77,7 +76,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
} }
} }
public override void OnTextViewClosed(ITextView textView, IList<ITextBuffer> subjectBuffers) public override void OnTextViewClosed(ITextView textView, IEnumerable<ITextBuffer> subjectBuffers)
{ {
if (textView == null) if (textView == null)
{ {
@ -94,10 +93,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
// //
// Notice that this method is called *after* changes are applied to the text buffer(s). We need to check every // Notice that this method is called *after* changes are applied to the text buffer(s). We need to check every
// one of them for a tracker because the content type could have changed. // one of them for a tracker because the content type could have changed.
for (var i = 0; i < subjectBuffers.Count; i++) foreach (var textBuffer in subjectBuffers)
{ {
var textBuffer = subjectBuffers[i];
DefaultVisualStudioDocumentTracker documentTracker; DefaultVisualStudioDocumentTracker documentTracker;
if (textBuffer.Properties.TryGetProperty(typeof(VisualStudioDocumentTracker), out documentTracker)) if (textBuffer.Properties.TryGetProperty(typeof(VisualStudioDocumentTracker), out documentTracker))
{ {

View File

@ -9,8 +9,8 @@ namespace Microsoft.VisualStudio.Editor.Razor
{ {
internal abstract class RazorDocumentManager internal abstract class RazorDocumentManager
{ {
public abstract void OnTextViewOpened(ITextView textView, IList<ITextBuffer> subjectBuffers); public abstract void OnTextViewOpened(ITextView textView, IEnumerable<ITextBuffer> subjectBuffers);
public abstract void OnTextViewClosed(ITextView textView, IList<ITextBuffer> subjectBuffers); public abstract void OnTextViewClosed(ITextView textView, IEnumerable<ITextBuffer> subjectBuffers);
} }
} }

View File

@ -2,34 +2,31 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.ObjectModel; using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor; using Microsoft.CodeAnalysis.Razor;
using Microsoft.VisualStudio.Editor.Razor;
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;
namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor namespace Microsoft.VisualStudio.Editor.Razor
{ {
[ContentType(RazorLanguage.ContentType)] [ContentType(RazorLanguage.ContentType)]
[TextViewRole(PredefinedTextViewRoles.Document)] [TextViewRole(PredefinedTextViewRoles.Document)]
[Export(typeof(IWpfTextViewConnectionListener))] [Export(typeof(ITextViewConnectionListener))]
internal class RazorTextViewConnectionListener : IWpfTextViewConnectionListener internal class RazorTextViewConnectionListener : ITextViewConnectionListener
{ {
private readonly ForegroundDispatcher _foregroundDispatcher; private readonly ForegroundDispatcher _foregroundDispatcher;
private readonly Workspace _workspace;
private readonly RazorDocumentManager _documentManager; private readonly RazorDocumentManager _documentManager;
[ImportingConstructor] [ImportingConstructor]
public RazorTextViewConnectionListener( public RazorTextViewConnectionListener(
[Import(typeof(VisualStudioWorkspace))] Workspace workspace, VisualStudioWorkspaceAccessor workspaceAccessor,
RazorDocumentManager documentManager) RazorDocumentManager documentManager)
{ {
if (workspace == null) if (workspaceAccessor == null)
{ {
throw new ArgumentNullException(nameof(workspace)); throw new ArgumentNullException(nameof(workspaceAccessor));
} }
if (documentManager == null) if (documentManager == null)
@ -37,15 +34,13 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
throw new ArgumentNullException(nameof(documentManager)); throw new ArgumentNullException(nameof(documentManager));
} }
_workspace = workspace;
_documentManager = documentManager; _documentManager = documentManager;
_foregroundDispatcher = workspace.Services.GetRequiredService<ForegroundDispatcher>(); _foregroundDispatcher = workspaceAccessor.Workspace.Services.GetRequiredService<ForegroundDispatcher>();
} }
// 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,
Workspace workspace,
RazorDocumentManager documentManager) RazorDocumentManager documentManager)
{ {
if (foregroundDispatcher == null) if (foregroundDispatcher == null)
@ -53,24 +48,16 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
throw new ArgumentNullException(nameof(foregroundDispatcher)); throw new ArgumentNullException(nameof(foregroundDispatcher));
} }
if (workspace == null)
{
throw new ArgumentNullException(nameof(workspace));
}
if (documentManager == null) if (documentManager == null)
{ {
throw new ArgumentNullException(nameof(documentManager)); throw new ArgumentNullException(nameof(documentManager));
} }
_foregroundDispatcher = foregroundDispatcher; _foregroundDispatcher = foregroundDispatcher;
_workspace = workspace;
_documentManager = documentManager; _documentManager = documentManager;
} }
public Workspace Workspace => _workspace; public void SubjectBuffersConnected(ITextView textView, ConnectionReason reason, IReadOnlyCollection<ITextBuffer> subjectBuffers)
public void SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{ {
if (textView == null) if (textView == null)
{ {
@ -87,7 +74,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
_documentManager.OnTextViewOpened(textView, subjectBuffers); _documentManager.OnTextViewOpened(textView, subjectBuffers);
} }
public void SubjectBuffersDisconnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers) public void SubjectBuffersDisconnected(ITextView textView, ConnectionReason reason, IReadOnlyCollection<ITextBuffer> subjectBuffers)
{ {
if (textView == null) if (textView == null)
{ {

View File

@ -3,13 +3,12 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.Editor.Razor;
using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Editor;
using Moq; using Moq;
using Xunit; using Xunit;
namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor namespace Microsoft.VisualStudio.Editor.Razor
{ {
public class RazorTextViewConnectionListenerTest : ForegroundDispatcherTestBase public class RazorTextViewConnectionListenerTest : ForegroundDispatcherTestBase
{ {
@ -17,13 +16,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
public void SubjectBuffersConnected_CallsRazorDocumentManager_OnTextViewOpened() public void SubjectBuffersConnected_CallsRazorDocumentManager_OnTextViewOpened()
{ {
// Arrange // Arrange
var textView = Mock.Of<IWpfTextView>(); var textView = Mock.Of<ITextView>();
var buffers = new Collection<ITextBuffer>(); var buffers = new Collection<ITextBuffer>();
var workspace = new AdhocWorkspace();
var documentManager = new Mock<RazorDocumentManager>(MockBehavior.Strict); var documentManager = new Mock<RazorDocumentManager>(MockBehavior.Strict);
documentManager.Setup(d => d.OnTextViewOpened(textView, buffers)).Verifiable(); documentManager.Setup(d => d.OnTextViewOpened(textView, buffers)).Verifiable();
var listener = new RazorTextViewConnectionListener(Dispatcher, workspace, documentManager.Object); var listener = new RazorTextViewConnectionListener(Dispatcher, documentManager.Object);
// Act // Act
listener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers); listener.SubjectBuffersConnected(textView, ConnectionReason.BufferGraphChange, buffers);
@ -36,13 +34,13 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
public void SubjectBuffersDisonnected_CallsRazorDocumentManager_OnTextViewClosed() public void SubjectBuffersDisonnected_CallsRazorDocumentManager_OnTextViewClosed()
{ {
// Arrange // Arrange
var textView = Mock.Of<IWpfTextView>(); var textView = Mock.Of<ITextView>();
var buffers = new Collection<ITextBuffer>(); var buffers = new Collection<ITextBuffer>();
var workspace = new AdhocWorkspace(); var workspace = new AdhocWorkspace();
var documentManager = new Mock<RazorDocumentManager>(MockBehavior.Strict); var documentManager = new Mock<RazorDocumentManager>(MockBehavior.Strict);
documentManager.Setup(d => d.OnTextViewClosed(textView, buffers)).Verifiable(); documentManager.Setup(d => d.OnTextViewClosed(textView, buffers)).Verifiable();
var listener = new RazorTextViewConnectionListener(Dispatcher, workspace, documentManager.Object); var listener = new RazorTextViewConnectionListener(Dispatcher, documentManager.Object);
// Act // Act
listener.SubjectBuffersDisconnected(textView, ConnectionReason.BufferGraphChange, buffers); listener.SubjectBuffersDisconnected(textView, ConnectionReason.BufferGraphChange, buffers);