From d1b35c717ae9845329e34b5e79077a071ccf7fc4 Mon Sep 17 00:00:00 2001 From: George Alexandria Date: Sat, 26 Oct 2019 17:18:07 +0300 Subject: [PATCH] Avoid non invalid caching of semantic model and it usages. --- src/vs14/CoCo_vs14/CoCo_vs14.csproj | 26 +++++++++---------- .../Editor/RoslynTextBufferClassifier.cs | 23 ++++++++++------ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/vs14/CoCo_vs14/CoCo_vs14.csproj b/src/vs14/CoCo_vs14/CoCo_vs14.csproj index 81e7117..ce354e3 100644 --- a/src/vs14/CoCo_vs14/CoCo_vs14.csproj +++ b/src/vs14/CoCo_vs14/CoCo_vs14.csproj @@ -60,20 +60,18 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/vs16/CoCo.Analyser_vs16/Editor/RoslynTextBufferClassifier.cs b/src/vs16/CoCo.Analyser_vs16/Editor/RoslynTextBufferClassifier.cs index c94ec32..40dc2e5 100644 --- a/src/vs16/CoCo.Analyser_vs16/Editor/RoslynTextBufferClassifier.cs +++ b/src/vs16/CoCo.Analyser_vs16/Editor/RoslynTextBufferClassifier.cs @@ -19,7 +19,6 @@ internal abstract class RoslynTextBufferClassifier : IClassifier private static readonly List _emptyClassifications = new List(); - private SemanticModel _semanticModel; private bool _isEnable; protected RoslynTextBufferClassifier() @@ -40,7 +39,6 @@ protected RoslynTextBufferClassifier( _editorChangingService = editorChangingService; _editorChangingService.EditorOptionsChanged += OnEditorOptionsChanged; - _textBuffer.Changed += OnTextBufferChanged; _textDocumentFactoryService.TextDocumentDisposed += OnTextDocumentDisposed; } @@ -70,9 +68,22 @@ public IList GetClassificationSpans(SnapshotSpan span) return _emptyClassifications; } - var document = workspace.GetDocument(span.Snapshot.AsText()); - var semanticModel = _semanticModel ?? (_semanticModel = document.GetSemanticModelAsync().Result); + // NOTE: to use the previously classified result as a cached result classifier must correctly determine + // when it can use it or not. To correctly determine it, classifier must handle all bellow events: + // + // * All source code files changing + // * Source file appending/removing/including/excluding to projects + // * All project files changing + // * Project file appending/removing/including/excluding to solution + // * Solution changing + // * Solution/projects current configuration changing + // + // because all of them may affect to a semantic model of code. Subscribing and unsubscribing on all of them is expensive + // and all of them are raised very often that make subscribing non effective. So much better way + // is the get actual data to the everyone requests + var document = workspace.GetDocument(span.Snapshot.AsText()); + var semanticModel = document.GetSemanticModelAsync().Result; return GetClassificationSpans(workspace, semanticModel, span); } @@ -83,8 +94,6 @@ internal abstract List GetClassificationSpans( protected abstract string Language { get; } - private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) => _semanticModel = null; - private void OnEditorOptionsChanged(EditorChangedEventArgs args) { // NOTE: if the state of editor option was changed => raise that classifications were changed for the current buffer @@ -103,8 +112,6 @@ private void OnTextDocumentDisposed(object sender, TextDocumentEventArgs e) { if (e.TextDocument.TextBuffer == _textBuffer) { - _semanticModel = null; - _textBuffer.Changed -= OnTextBufferChanged; _textDocumentFactoryService.TextDocumentDisposed -= OnTextDocumentDisposed; _editorChangingService.EditorOptionsChanged -= OnEditorOptionsChanged; }