diff --git a/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineOptionsMetadata.cs b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineOptionsMetadata.cs new file mode 100644 index 0000000000000..8e0a6e1ad45bb --- /dev/null +++ b/src/VisualStudio/Core/Def/DocumentOutline/DocumentOutlineOptionsMetadata.cs @@ -0,0 +1,16 @@ +// 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. + +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.VisualStudio.LanguageServices.DocumentOutline +{ + internal sealed class DocumentOutlineOptionsMetadata + { + private const string FeatureName = "DocumentOutlineOptions"; + + public static readonly Option2 EnableDocumentOutline = new(FeatureName, nameof(EnableDocumentOutline), defaultValue: false, + storageLocation: new FeatureFlagStorageLocation("Roslyn.DocumentOutline")); + } +} diff --git a/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.VsCodeWindowManager.cs b/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.VsCodeWindowManager.cs index a84b40b2c5f1d..35c763bd43ffb 100644 --- a/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.VsCodeWindowManager.cs +++ b/src/VisualStudio/Core/Def/LanguageService/AbstractLanguageService`2.VsCodeWindowManager.cs @@ -236,6 +236,14 @@ public int RemoveAdornments() // that ReleaseOutline will be called on the old window before GetOutline is called for the new window. int IVsDocOutlineProvider.GetOutline(out IntPtr phwnd, out IOleCommandTarget? ppCmdTarget) { + var enabled = _globalOptions.GetOption(DocumentOutlineOptionsMetadata.EnableDocumentOutline); + if (!enabled) + { + phwnd = default; + ppCmdTarget = null; + return VSConstants.S_OK; + } + var languageServiceBroker = _languageService.Package.ComponentModel.GetService(); var threadingContext = _languageService.Package.ComponentModel.GetService(); var asyncListenerProvider = _languageService.Package.ComponentModel.GetService(); @@ -270,17 +278,17 @@ int IVsDocOutlineProvider.ReleaseOutline(IntPtr hwnd, IOleCommandTarget pCmdTarg var threadingContext = _languageService.Package.ComponentModel.GetService(); threadingContext.ThrowIfNotOnUIThread(); - // Assert that we are not attempting to double free the Document Outline Control and host. - Contract.ThrowIfNull(_documentOutlineViewHost); - Contract.ThrowIfNull(_documentOutlineControl); - - _documentOutlineViewHost.SuspendLayout(); - _documentOutlineControl.Dispose(); - _documentOutlineControl = null; - _documentOutlineViewHost.Child = null; - _documentOutlineViewHost.Parent = null; - _documentOutlineViewHost.Dispose(); - _documentOutlineViewHost = null; + if (_documentOutlineControl is not null && + _documentOutlineViewHost is not null) + { + _documentOutlineViewHost.SuspendLayout(); + _documentOutlineControl.Dispose(); + _documentOutlineControl = null; + _documentOutlineViewHost.Child = null; + _documentOutlineViewHost.Parent = null; + _documentOutlineViewHost.Dispose(); + _documentOutlineViewHost = null; + } return VSConstants.S_OK; }