提交 b9e81c97 编写于 作者: S Sam Harwell

Simplify ConvertToTagTrees and remove incorrect edge case handling

* `buffers` is an unnecessary intermediate variable. Any text buffer present in `buffersToTag`
  but not also present in `buffers` will end up ignored by `ComputeNewTagTree`, and thus not
  influence the result of `ConvertToTagTrees`. Based on this, `buffers` was eliminated to
  simplify the implementation.
* When `spansTagged` has only a single span, it's possible that other tag trees in `oldTagTrees`
  need to propagate forward. The early return failed to account for this, and if hit would drop
  `oldTagTrees` tags for buffers not equal to the buffer from `spansTagged`. In addition, the
  early return failed to account for the case where `spansTagged` only contained a single
  span from a buffer not requested per `buffersToTag`. Following the elimination of `buffers`,
  the value of a special case handling here was notably reduced and the edge case was simply
  eliminated in favor of the remaining code in the method.
* The patter of Select followed by ToLookup was replaced by a single call to ToLookup specifying
  both the keys and the values of the resulting lookup.
上级 f7a68bc5
......@@ -378,37 +378,17 @@ private void CheckSnapshot(ITextSnapshot snapshot)
ILookup<ITextBuffer, ITagSpan<TTag>> newTagsByBuffer,
IEnumerable<DocumentSnapshotSpan> spansTagged)
{
// NOTE: we assume that the following list is already realized and is _not_ lazily
// computed. It's not clear what the contract is of this API.
// common case where we only tagged a single range of a document.
if (spansTagged.IsSingle())
{
return ConvertToTagTree(oldTagTrees, newTagsByBuffer, spansTagged.Single().SnapshotSpan);
}
// heavy linq case
var spansToInvalidateByBuffer = spansTagged.Select(ss => ss.SnapshotSpan).ToLookup(ss => ss.Snapshot.TextBuffer);
var buffers = oldTagTrees.Keys.Concat(newTagsByBuffer.Select(g => g.Key))
.Concat(spansTagged.Select(dss => dss.SnapshotSpan.Snapshot.TextBuffer))
.Distinct();
var spansToInvalidateByBuffer = spansTagged.ToLookup(
keySelector: span => span.SnapshotSpan.Snapshot.TextBuffer,
elementSelector: span => span.SnapshotSpan);
// Walk through each relevant buffer and decide what the interval tree should be
// for that buffer. In general this will work by keeping around old tags that
// weren't in the range that was re-tagged, and merging them with the new tags
// produced for the range that was re-tagged.
var newTagTrees = ImmutableDictionary<ITextBuffer, TagSpanIntervalTree<TTag>>.Empty;
foreach (var buffer in buffers)
foreach (var buffer in buffersToTag)
{
if (!buffersToTag.Contains(buffer))
{
// Avoid computing a new tag tree for a buffer not requested for tagging. This handles cases
// where oldTagTrees contains tags for a buffer that was removed from the buffers of interest,
// and also cases where one or more taggers produced tags outside the requested context.
continue;
}
var newTagTree = ComputeNewTagTree(oldTagTrees, buffer, newTagsByBuffer[buffer], spansToInvalidateByBuffer[buffer]);
if (newTagTree != null)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册