/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Def/ProjectSystem/ReiteratedVersionSnapshotTracker.cs
83 строки
3 KB
Cyrus Najmabadi
Make sealed
26 мар 2025, 22:21
26 мар 2025, 22:21
d99b771
Код
Авторство
О чём код?
// 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 Microsoft.VisualStudio.Text; namespace Microsoft.VisualStudio.LanguageServices.Implementation; internal sealed class ReiteratedVersionSnapshotTracker { /// <summary> /// tracking text buffer /// </summary> private ITextBuffer _trackingBuffer; /// <summary> /// hold onto latest ReiteratedVersionNumber snapshot of a textbuffer /// there is a bug where many of our features just assume that if they wait, they will end up get the latest snapshot in some ways. /// but, unfortunately that is actually not true. they will, at the end, get latest reiterated version snapshot but /// not the latest version snapshot since we might have skipped/swallowed the latest snapshot since its content didn't change. /// this is especially unfortunate for features that want to move back and forth between source text and ITextSnapshot since holding /// on the latest snapshot won't guarantee that. so, in VS, we hold onto right latest snapshot in VS workspace so that all feature under it /// doesn't need to worry about it. /// this could be moved down to workspace_editor if it actually move up to editor layer. /// but for now, I am putting it here. we can think about moving it down to workspace_editor later. /// </summary> private ITextSnapshot _latestReiteratedVersionSnapshot; public ReiteratedVersionSnapshotTracker(ITextBuffer buffer) { if (buffer != null) { StartTracking(buffer); } } public void StartTracking(ITextBuffer buffer) { // buffer has changed. stop tracking old buffer if (_trackingBuffer != null && buffer != _trackingBuffer) { _trackingBuffer.ChangedHighPriority -= OnTextBufferChanged; _trackingBuffer = null; _latestReiteratedVersionSnapshot = null; } // start tracking new buffer if (buffer != null && _latestReiteratedVersionSnapshot == null) { _latestReiteratedVersionSnapshot = buffer.CurrentSnapshot; _trackingBuffer = buffer; buffer.ChangedHighPriority += OnTextBufferChanged; } } public void StopTracking(ITextBuffer buffer) { if (_trackingBuffer == buffer && buffer != null && _latestReiteratedVersionSnapshot != null) { buffer.ChangedHighPriority -= OnTextBufferChanged; _trackingBuffer = null; _latestReiteratedVersionSnapshot = null; } } private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) { if (sender is ITextBuffer) { var snapshot = _latestReiteratedVersionSnapshot; if (snapshot != null && snapshot.Version != null && e.AfterVersion != null && snapshot.Version.ReiteratedVersionNumber < e.AfterVersion.ReiteratedVersionNumber) { _latestReiteratedVersionSnapshot = e.After; } } } }