/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.IVsImmediateStatementCompletion2.cs
168 строк
7 KB
Jason Malinowski
Remove the eager fetch of IVsEditorAdaptersFactoryService
29 авг 2025, 00:35
29 авг 2025, 00:35
4294749
Код
Авторство
О чём код?
// 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; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.LanguageServices.Implementation.DebuggerIntelliSense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService; internal abstract partial class AbstractLanguageService<TPackage, TLanguageService> : IVsImmediateStatementCompletion2 { protected Dictionary<IVsTextView, DebuggerIntelliSenseFilter> filters = []; int IVsImmediateStatementCompletion2.EnableStatementCompletion(int enable, int startIndex, int endIndex, IVsTextView textView) { if (filters.TryGetValue(textView, out var filter)) { if (enable != 0) { filter.EnableCompletion(); } else { filter.DisableCompletion(); } } // Debugger wants Roslyn to return OK in all cases, // for example, even if Rolsyn tried to enable the one already enabled. return VSConstants.S_OK; } int IVsImmediateStatementCompletion2.InstallStatementCompletion(int install, IVsTextView textView, int initialEnable) { // We'll install a filter whenever the debugger asks, but it won't do anything but call // the next filter until the context is set. To ensure that we correctly install and // uninstall from the many possible textviews we can work on, we maintain a dictionary // of textview->filters. if (install != 0) { if (!this.filters.TryGetValue(textView, out var filter)) { var editorAdaptersFactoryService = this.Package.ComponentModel.GetService<IVsEditorAdaptersFactoryService>(); filter = new DebuggerIntelliSenseFilter( editorAdaptersFactoryService.GetWpfTextView(textView), this.Package.ComponentModel, this.Package.ComponentModel.GetService<IFeatureServiceFactory>()); this.filters[textView] = filter; Marshal.ThrowExceptionForHR(textView.AddCommandFilter(filter, out var nextFilter)); filter.SetNextFilter(nextFilter); } filter.SetContentType(install: true); } else { Marshal.ThrowExceptionForHR(textView.RemoveCommandFilter(this.filters[textView])); this.filters[textView].SetContentType(install: false); this.filters[textView].Dispose(); this.filters.Remove(textView); } return VSConstants.S_OK; } int IVsImmediateStatementCompletion2.SetCompletionContext(string filePath, IVsTextLines buffer, TextSpan[] currentStatementSpan, object punkContext, IVsTextView textView) { // The immediate window is always marked read-only and the language service is // responsible for asking the buffer to make itself writable. We'll have to do that for // commit, so we need to drag the IVsTextLines around, too. Marshal.ThrowExceptionForHR(textView.GetBuffer(out var debuggerBuffer)); var editorAdaptersFactoryService = this.Package.ComponentModel.GetService<IVsEditorAdaptersFactoryService>(); var view = editorAdaptersFactoryService.GetWpfTextView(textView); // Sometimes, they give us a null context buffer. In that case, there's probably not any // work to do. if (buffer != null) { var contextBuffer = editorAdaptersFactoryService.GetDataBuffer(buffer); if (!contextBuffer.ContentType.IsOfType(this.ContentTypeName)) { FatalError.ReportAndCatch( new ArgumentException($"Expected content type {this.ContentTypeName} " + $"but got buffer of content type {contextBuffer.ContentType}")); return VSConstants.E_FAIL; } // Clean the old context in any case upfront: // even if we fail to initialize, the old context must be cleaned. this.filters[textView].RemoveContext(); var context = CreateContext(view, textView, debuggerBuffer, contextBuffer, currentStatementSpan); if (context.TryInitialize()) { this.filters[textView].SetContext(context); } } return VSConstants.S_OK; } // Let our deriving language services build up an appropriate context. protected abstract AbstractDebuggerIntelliSenseContext CreateContext(IWpfTextView view, IVsTextView vsTextView, IVsTextLines debuggerBuffer, ITextBuffer contextBuffer, Microsoft.VisualStudio.TextManager.Interop.TextSpan[] currentStatementSpan); #region Methods that are never called int IVsImmediateStatementCompletion2.EnableStatementCompletion_Deprecated(int enable, int startIndex, int endIndex) { Debug.Assert(false); return VSConstants.S_OK; } int IVsImmediateStatementCompletion2.GetFilter(IVsTextView textView, out IVsTextViewFilter filter) { // They never even call this, so just make it compile Debug.Assert(false); filter = null; return VSConstants.S_OK; } int IVsImmediateStatementCompletion.EnableStatementCompletion_Deprecated(int enable, int startIndex, int endIndex) { Debug.Assert(false); return VSConstants.S_OK; } int IVsImmediateStatementCompletion.InstallStatementCompletion(int install, IVsTextView textView, int initialEnable) { Debug.Assert(false); return VSConstants.S_OK; } int IVsImmediateStatementCompletion.SetCompletionContext_Deprecated(string filePath, IVsTextLines buffer, TextSpan[] currentStatementSpan, object punkContext) { Debug.Assert(false); return VSConstants.S_OK; } int IVsImmediateStatementCompletion2.SetCompletionContext_Deprecated(string filepath, IVsTextLines buffer, TextSpan[] currentStatementSpan, object punkContext) { Debug.Assert(false); return VSConstants.S_OK; } #endregion }