Skip to content

Commit

Permalink
Forced parsing to a background thread
Browse files Browse the repository at this point in the history
[release]
  • Loading branch information
madskristensen committed Jan 2, 2022
1 parent 737d5ab commit 44cdc00
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 83 deletions.
2 changes: 1 addition & 1 deletion src/RestClient/Parser/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class Document
protected Document(string[] lines)
{
_lines = lines;
_ = ParseAsync();
Parse();
}

public List<ParseItem> Items { get; private set; } = new List<ParseItem>();
Expand Down
46 changes: 24 additions & 22 deletions src/RestClient/Parser/DocumentParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace RestClient
{
Expand All @@ -16,42 +15,45 @@ public partial class Document
public bool IsParsing { get; private set; }
public bool IsValid { get; private set; }

public Task ParseAsync()
public void Parse()
{
IsParsing = true;
var isSuccess = false;
var start = 0;

return Task.Run(() =>
try
{
var start = 0;
List<ParseItem> tokens = new();

try
foreach (var line in _lines)
{
List<ParseItem> tokens = new();
IEnumerable<ParseItem>? current = ParseLine(start, line, tokens);

foreach (var line in _lines)
if (current != null)
{
IEnumerable<ParseItem>? current = ParseLine(start, line, tokens);
tokens.AddRange(current);
}

if (current != null)
{
tokens.AddRange(current);
}
start += line.Length;
}

start += line.Length;
}
Items = tokens;

Items = tokens;
OrganizeItems();
ExpandVariables();
ValidateDocument();

OrganizeItems();
ExpandVariables();
ValidateDocument();
}
finally
isSuccess = true;
}
finally
{
IsParsing = false;

if (isSuccess)
{
IsParsing = false;
Parsed?.Invoke(this, EventArgs.Empty);
}
});
}
}

private IEnumerable<ParseItem> ParseLine(int start, string line, List<ParseItem> tokens)
Expand Down
2 changes: 1 addition & 1 deletion src/RestClientVS/Commands/GoToDefinitionCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public bool ExecuteCommand(GoToDefinitionCommandArgs args, CommandExecutionConte
{
var position = args.TextView.Caret.Position.BufferPosition.Position;

Document document = RestDocument.FromTextbuffer(args.TextView.TextBuffer);
Document document = args.TextView.TextBuffer.GetRestDocument();
ParseItem token = document.FindItemFromPosition(position);

if (token?.Type == ItemType.Reference)
Expand Down
2 changes: 1 addition & 1 deletion src/RestClientVS/Commands/SendRequestCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
if (docView != null)
{
var position = docView.TextView.Caret.Position.BufferPosition.Position;
Document doc = RestDocument.FromTextbuffer(docView.TextBuffer);
Document doc = docView.TextBuffer.GetRestDocument();
Request request = doc.Requests.FirstOrDefault(r => r.Contains(position));

if (request != null)
Expand Down
3 changes: 3 additions & 0 deletions src/RestClientVS/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ public static class ExtensionMethods
{
public static Span ToSpan(this ParseItem token) =>
new(token.Start, token.Length);

public static RestDocument GetRestDocument(this ITextBuffer buffer) =>
buffer.Properties.GetOrCreateSingletonProperty(() => new RestDocument(buffer));
}
}
4 changes: 2 additions & 2 deletions src/RestClientVS/Language/RestCompletionSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public Task<CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession
{
ITextSnapshotLine line = triggerLocation.GetContainingLine();

Document document = RestDocument.FromTextbuffer(session.TextView.TextBuffer);
Document document = session.TextView.TextBuffer.GetRestDocument();
SnapshotPoint lineStart = line.Start;
ParseItem token = GetPreviousToken(document, lineStart, out var hasEmptyLine);

Expand Down Expand Up @@ -167,7 +167,7 @@ public CompletionStartData InitializeCompletion(CompletionTrigger trigger, Snaps
return CompletionStartData.DoesNotParticipateInCompletion;
}

Document document = RestDocument.FromTextbuffer(triggerLocation.Snapshot.TextBuffer);
Document document = triggerLocation.Snapshot.TextBuffer.GetRestDocument();
ParseItem item = document?.FindItemFromPosition(triggerLocation.Position);

if (item?.Type == ItemType.Reference)
Expand Down
2 changes: 1 addition & 1 deletion src/RestClientVS/Language/RestIntratextAdornmentTagger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class RestIntratextAdornmentTagger : ITagger<IntraTextAdornmentTag>
public RestIntratextAdornmentTagger(ITextBuffer buffer)
{
_buffer = buffer;
_document = RestDocument.FromTextbuffer(buffer);
_document = buffer.GetRestDocument();
}

public IEnumerable<ITagSpan<IntraTextAdornmentTag>> GetTags(NormalizedSnapshotSpanCollection spans)
Expand Down
43 changes: 27 additions & 16 deletions src/RestClientVS/Language/TokenTagger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.Utilities;
using RestClient;

Expand All @@ -34,10 +35,15 @@ internal class TokenTagger : ITagger<TokenTag>, IDisposable
internal TokenTagger(ITextBuffer buffer)
{
_buffer = buffer;
_document = RestDocument.FromTextbuffer(buffer);
_document = buffer.GetRestDocument();
_document.Parsed += ReParse;
_tagsCache = new Dictionary<ParseItem, ITagSpan<TokenTag>>();
ReParse();

ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
await TaskScheduler.Default;
ReParse();
}).FireAndForget();
}

public IEnumerable<ITagSpan<TokenTag>> GetTags(NormalizedSnapshotSpanCollection spans)
Expand All @@ -47,26 +53,31 @@ public IEnumerable<ITagSpan<TokenTag>> GetTags(NormalizedSnapshotSpanCollection

private void ReParse(object sender = null, EventArgs e = null)
{
ThreadHelper.JoinableTaskFactory.StartOnIdle(() =>
{
Dictionary<ParseItem, ITagSpan<TokenTag>> list = new();
// Make sure this is running on a background thread.
ThreadHelper.ThrowIfOnUIThread();

foreach (ParseItem item in _document.Items)
{
AddTagToList(list, item);
Dictionary<ParseItem, ITagSpan<TokenTag>> list = new();

foreach (ParseItem variable in item.References)
{
AddTagToList(list, variable);
}
foreach (ParseItem item in _document.Items)
{
if (_document.IsParsing)
{
// Abort and wait for the next parse event to finish
return;
}

_tagsCache = list;
AddTagToList(list, item);

foreach (ParseItem variable in item.References)
{
AddTagToList(list, variable);
}
}

SnapshotSpan span = new(_buffer.CurrentSnapshot, 0, _buffer.CurrentSnapshot.Length);
TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(span));
_tagsCache = list;

}, VsTaskRunContext.UIThreadIdlePriority).FireAndForget();
SnapshotSpan span = new(_buffer.CurrentSnapshot, 0, _buffer.CurrentSnapshot.Length);
TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(span));
}

private void AddTagToList(Dictionary<ParseItem, ITagSpan<TokenTag>> list, ParseItem item)
Expand Down
3 changes: 3 additions & 0 deletions src/RestClientVS/RestClientVS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.365" ExcludeAssets="Runtime">
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading">
<Version>17.0.64</Version>
</PackageReference>
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.0.5232" />
</ItemGroup>
<ItemGroup>
Expand Down
14 changes: 8 additions & 6 deletions src/RestClientVS/RestDocument.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Threading;
using RestClient;

namespace RestClientVS
Expand All @@ -20,13 +22,12 @@ public RestDocument(ITextBuffer buffer)

FileName = buffer.GetFileName();

#pragma warning disable VSTHRD104 // Offer async methods
ThreadHelper.JoinableTaskFactory.Run(async () =>
ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
{
await Task.Yield();
Project project = await VS.Solutions.GetActiveProjectAsync();
ProjectName = project?.Name;
});
#pragma warning restore VSTHRD104 // Offer async methods
}).FireAndForget();
}

private void BufferChanged(object sender, TextContentChangedEventArgs e)
Expand All @@ -35,9 +36,10 @@ private void BufferChanged(object sender, TextContentChangedEventArgs e)
ParseAsync().FireAndForget();
}

public static RestDocument FromTextbuffer(ITextBuffer buffer)
private async Task ParseAsync()
{
return buffer.Properties.GetOrCreateSingletonProperty(() => new RestDocument(buffer));
await TaskScheduler.Default;
Parse();
}

public void Dispose()
Expand Down
1 change: 0 additions & 1 deletion test/RestClientTest/HttpTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public class HttpTest
public async Task SendAsync(string url)
{
var doc = Document.FromLines(url);
await doc.WaitForParsingCompleteAsync();

RequestResult client = await RequestSender.SendAsync(doc.Requests.First(), TimeSpan.FromSeconds(10));
var raw = await client.Response.ToRawStringAsync();
Expand Down
Loading

0 comments on commit 44cdc00

Please sign in to comment.