File: CodeModel\CodeModelEventQueue.cs
Web Access
Project: src\src\VisualStudio\Core\Impl\Microsoft.VisualStudio.LanguageServices.Implementation.csproj (Microsoft.VisualStudio.LanguageServices.Implementation)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel;
 
internal sealed class CodeModelEventQueue
{
    private readonly Queue<CodeModelEvent> _eventQueue;
 
    public CodeModelEventQueue(Queue<CodeModelEvent> eventQueue)
        => _eventQueue = eventQueue;
 
    private void EnqueueEvent(CodeModelEvent @event)
    {
        // Don't bother with events that are already queued.
        foreach (var queuedEvent in _eventQueue)
        {
            if (queuedEvent.Equals(@event))
            {
                return;
            }
        }
 
        // Events are added to the end of the queue, so we only check the
        // last event to see if we can combine it with the new event. The
        // other events will be for prior edits, and should remain distinct.
        // In order to combine the events, they must both be for the same node, 
        // and they must both be change events.
 
        if (_eventQueue.Count > 0)
        {
            var priorEvent = _eventQueue.Peek();
            if (priorEvent.Node == @event.Node &&
                priorEvent.ParentNode == @event.ParentNode &&
                priorEvent.Type.IsChange() &&
                @event.Type.IsChange())
            {
                priorEvent.Type |= @event.Type;
                return;
            }
        }
 
        _eventQueue.Enqueue(@event);
    }
 
    public void EnqueueAddEvent(SyntaxNode node, SyntaxNode parent)
        => EnqueueEvent(new CodeModelEvent(node, parent, CodeModelEventType.Add));
 
    public void EnqueueRemoveEvent(SyntaxNode node, SyntaxNode parent)
        => EnqueueEvent(new CodeModelEvent(node, parent, CodeModelEventType.Remove));
 
    public void EnqueueChangeEvent(SyntaxNode node, SyntaxNode parent, CodeModelEventType eventType)
        => EnqueueEvent(new CodeModelEvent(node, parent, eventType));
 
    public void Discard()
        => _eventQueue.Dequeue();
 
    public int Count
    {
        get { return _eventQueue.Count; }
    }
}