React to API feedback on VisualStudioRazorParser.
- Changed `ReparseAsync` to be `QueueReparse`. It's now async void to not give the misconception that it blocks until a reparse has been completed. - Removed `IContextChangedListener`. People can get the same effect of the interface by retrieving the document tracker interface via the `RazorEditorFactoryService` and then when its context changes getting the parser. - Exposed `TryGetParser` to aid in replacing `IContextChangedListener`. - Updated tests to not rely on `IContextChangedListener`.
This commit is contained in:
Родитель
d027697389
Коммит
ab62ea9321
|
@ -30,7 +30,6 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
|
||||
private readonly object IdleLock = new object();
|
||||
private readonly ICompletionBroker _completionBroker;
|
||||
private readonly IEnumerable<IContextChangedListener> _contextChangedListeners;
|
||||
private readonly VisualStudioDocumentTracker _documentTracker;
|
||||
private readonly ForegroundDispatcher _dispatcher;
|
||||
private readonly RazorTemplateEngineFactoryService _templateEngineFactory;
|
||||
|
@ -51,8 +50,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
VisualStudioDocumentTracker documentTracker,
|
||||
RazorTemplateEngineFactoryService templateEngineFactory,
|
||||
ErrorReporter errorReporter,
|
||||
ICompletionBroker completionBroker,
|
||||
IEnumerable<IContextChangedListener> contextChangedListeners)
|
||||
ICompletionBroker completionBroker)
|
||||
{
|
||||
if (dispatcher == null)
|
||||
{
|
||||
|
@ -79,16 +77,10 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
throw new ArgumentNullException(nameof(completionBroker));
|
||||
}
|
||||
|
||||
if (contextChangedListeners == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(contextChangedListeners));
|
||||
}
|
||||
|
||||
_dispatcher = dispatcher;
|
||||
_templateEngineFactory = templateEngineFactory;
|
||||
_errorReporter = errorReporter;
|
||||
_completionBroker = completionBroker;
|
||||
_contextChangedListeners = contextChangedListeners;
|
||||
_documentTracker = documentTracker;
|
||||
|
||||
_documentTracker.ContextChanged += DocumentTracker_ContextChanged;
|
||||
|
@ -110,7 +102,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
// Used in unit tests to ensure we can block background idle work.
|
||||
internal ManualResetEventSlim BlockBackgroundIdleWork { get; set; }
|
||||
|
||||
public override async Task ReparseAsync()
|
||||
public override void QueueReparse()
|
||||
{
|
||||
// Can be called from any thread
|
||||
|
||||
|
@ -120,7 +112,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
}
|
||||
else
|
||||
{
|
||||
await Task.Factory.StartNew(ReparseOnForeground, null, CancellationToken.None, TaskCreationOptions.None, _dispatcher.ForegroundScheduler);
|
||||
Task.Factory.StartNew(ReparseOnForeground, null, CancellationToken.None, TaskCreationOptions.None, _dispatcher.ForegroundScheduler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,11 +137,9 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
return;
|
||||
}
|
||||
|
||||
NotifyParserContextChanged();
|
||||
|
||||
// We have a new parser, force a reparse to generate new document information. Note that this
|
||||
// only blocks until the reparse change has been queued.
|
||||
ReparseAsync().GetAwaiter().GetResult();
|
||||
QueueReparse();
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
|
@ -171,21 +161,6 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
return true;
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal void NotifyParserContextChanged()
|
||||
{
|
||||
_dispatcher.AssertForegroundThread();
|
||||
|
||||
// This is temporary until we own the TagHelper resolution system. At that point the parser will push out updates
|
||||
// via DocumentStructureChangedEvents when contexts change. For now, listeners need to know more information about
|
||||
// the parser. In the case that the tracker does not belong to a supported project the editor will tear down its
|
||||
// attachment to the parser when it recognizes the document closing.
|
||||
foreach (var contextChangeListener in _contextChangedListeners)
|
||||
{
|
||||
contextChangeListener.OnContextChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal void StartParser()
|
||||
{
|
||||
|
@ -303,8 +278,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
}
|
||||
}
|
||||
|
||||
// This only blocks until the reparse change has been queued.
|
||||
ReparseAsync().GetAwaiter().GetResult();
|
||||
QueueReparse();
|
||||
}
|
||||
|
||||
private void ReparseOnForeground(object state)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.VisualStudio.Editor.Razor
|
||||
{
|
||||
/// <summary>
|
||||
/// This class will cease to be useful once the Razor tooling owns TagHelper discovery
|
||||
/// </summary>
|
||||
public interface IContextChangedListener
|
||||
{
|
||||
void OnContextChanged(VisualStudioRazorParser parser);
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
{
|
||||
public abstract bool TryGetDocumentTracker(ITextBuffer textBuffer, out VisualStudioDocumentTracker documentTracker);
|
||||
|
||||
internal abstract bool TryGetParser(ITextBuffer textBuffer, out VisualStudioRazorParser parser);
|
||||
public abstract bool TryGetParser(ITextBuffer textBuffer, out VisualStudioRazorParser parser);
|
||||
|
||||
internal abstract bool TryGetSmartIndenter(ITextBuffer textBuffer, out BraceSmartIndenter braceSmartIndenter);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.VisualStudio.Text;
|
||||
|
||||
|
@ -22,6 +21,6 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
|
||||
public abstract ITextBuffer TextBuffer { get; }
|
||||
|
||||
public abstract Task ReparseAsync();
|
||||
public abstract void QueueReparse();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
return true;
|
||||
}
|
||||
|
||||
internal override bool TryGetParser(ITextBuffer textBuffer, out VisualStudioRazorParser parser)
|
||||
public override bool TryGetParser(ITextBuffer textBuffer, out VisualStudioRazorParser parser)
|
||||
{
|
||||
if (textBuffer == null)
|
||||
{
|
||||
|
|
|
@ -19,13 +19,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
private readonly ForegroundDispatcher _dispatcher;
|
||||
private readonly TemplateEngineFactoryService _templateEngineFactoryService;
|
||||
private readonly ICompletionBroker _completionBroker;
|
||||
private readonly IEnumerable<IContextChangedListener> _parserContextChangedListeners;
|
||||
private readonly ErrorReporter _errorReporter;
|
||||
|
||||
[ImportingConstructor]
|
||||
public DefaultVisualStudioRazorParserFactory(
|
||||
ICompletionBroker completionBroker,
|
||||
[ImportMany(typeof(IContextChangedListener))] IEnumerable<IContextChangedListener> parserContextChangedListeners,
|
||||
[Import(typeof(VisualStudioWorkspace))] Workspace workspace)
|
||||
{
|
||||
if (completionBroker == null)
|
||||
|
@ -33,18 +31,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
throw new ArgumentNullException(nameof(completionBroker));
|
||||
}
|
||||
|
||||
if (parserContextChangedListeners == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(parserContextChangedListeners));
|
||||
}
|
||||
|
||||
if (workspace == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(workspace));
|
||||
}
|
||||
|
||||
_completionBroker = completionBroker;
|
||||
_parserContextChangedListeners = parserContextChangedListeners;
|
||||
_dispatcher = workspace.Services.GetRequiredService<ForegroundDispatcher>();
|
||||
_errorReporter = workspace.Services.GetRequiredService<ErrorReporter>();
|
||||
var razorLanguageServices = workspace.Services.GetLanguageServices(RazorLanguage.Name);
|
||||
|
@ -65,8 +57,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
|
|||
documentTracker,
|
||||
_templateEngineFactoryService,
|
||||
_errorReporter,
|
||||
_completionBroker,
|
||||
_parserContextChangedListeners);
|
||||
_completionBroker);
|
||||
return parser;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
documentTracker,
|
||||
CreateTemplateEngineFactory(),
|
||||
new DefaultErrorReporter(),
|
||||
new TestCompletionBroker(),
|
||||
Enumerable.Empty<IContextChangedListener>()))
|
||||
new TestCompletionBroker()))
|
||||
{
|
||||
parser.DocumentTracker_ContextChanged(null, null);
|
||||
var changed = new StringTextSnapshot("Foo @bap Daz");
|
||||
|
@ -528,8 +527,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
documentTracker,
|
||||
templateEngineFactory,
|
||||
new DefaultErrorReporter(),
|
||||
new TestCompletionBroker(),
|
||||
Enumerable.Empty<IContextChangedListener>())
|
||||
new TestCompletionBroker())
|
||||
{
|
||||
// We block idle work with the below reset events. Therefore, make tests fast and have the idle timer fire as soon as possible.
|
||||
IdleDelay = TimeSpan.FromMilliseconds(1),
|
||||
|
|
|
@ -35,8 +35,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
CreateDocumentTracker(),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>())
|
||||
Mock.Of<ICompletionBroker>())
|
||||
{
|
||||
BlockBackgroundIdleWork = new ManualResetEventSlim(),
|
||||
IdleDelay = TimeSpan.FromSeconds(5)
|
||||
|
@ -66,8 +65,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
CreateDocumentTracker(),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>())
|
||||
Mock.Of<ICompletionBroker>())
|
||||
{
|
||||
BlockBackgroundIdleWork = new ManualResetEventSlim(),
|
||||
IdleDelay = TimeSpan.FromSeconds(5)
|
||||
|
@ -96,8 +94,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
CreateDocumentTracker(),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>()))
|
||||
Mock.Of<ICompletionBroker>()))
|
||||
{
|
||||
parser.StartParser();
|
||||
|
||||
|
@ -121,8 +118,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
documentTracker,
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>()))
|
||||
Mock.Of<ICompletionBroker>()))
|
||||
{
|
||||
// Act
|
||||
parser.StartParser();
|
||||
|
@ -133,31 +129,6 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
}
|
||||
}
|
||||
|
||||
[ForegroundFact]
|
||||
public void NotifyParserContextChanged_NotifiesListeners()
|
||||
{
|
||||
// Arrange
|
||||
var listener1 = new Mock<IContextChangedListener>();
|
||||
listener1.Setup(l => l.OnContextChanged(It.IsAny<VisualStudioRazorParser>()));
|
||||
var listener2 = new Mock<IContextChangedListener>();
|
||||
listener2.Setup(l => l.OnContextChanged(It.IsAny<VisualStudioRazorParser>()));
|
||||
using (var parser = new DefaultVisualStudioRazorParser(
|
||||
Dispatcher,
|
||||
CreateDocumentTracker(),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
new[] { listener1.Object, listener2.Object }))
|
||||
{
|
||||
// Act
|
||||
parser.NotifyParserContextChanged();
|
||||
|
||||
// Assert
|
||||
listener1.Verify();
|
||||
listener2.Verify();
|
||||
}
|
||||
}
|
||||
|
||||
[ForegroundFact]
|
||||
public void TryReinitializeParser_ReturnsTrue_IfProjectIsSupported()
|
||||
{
|
||||
|
@ -167,8 +138,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
CreateDocumentTracker(isSupportedProject: true),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>()))
|
||||
Mock.Of<ICompletionBroker>()))
|
||||
{
|
||||
// Act
|
||||
var result = parser.TryReinitializeParser();
|
||||
|
@ -187,8 +157,7 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
CreateDocumentTracker(isSupportedProject: false),
|
||||
Mock.Of<RazorTemplateEngineFactoryService>(),
|
||||
new DefaultErrorReporter(),
|
||||
Mock.Of<ICompletionBroker>(),
|
||||
Enumerable.Empty<IContextChangedListener>()))
|
||||
Mock.Of<ICompletionBroker>()))
|
||||
{
|
||||
// Act
|
||||
var result = parser.TryReinitializeParser();
|
||||
|
|
Загрузка…
Ссылка в новой задаче