提交 d8b85eaf 编写于 作者: M Manish Vasani

Merge pull request #10828 from mavasani/TurnOffSolutionAnalysis_Master

Turn off full solution analysis by default for C#
......@@ -1918,7 +1918,6 @@ class MyClass
</Workspace>
Using workspace = TestWorkspace.CreateWorkspace(test)
' set csharp closed diagnostic option on
workspace.Options = workspace.Options.WithChangedOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, LanguageNames.CSharp, True)
Dim project = workspace.CurrentSolution.Projects.Single()
......
......@@ -143,7 +143,7 @@ private Task ClearOnlyDocumentStates(Document document)
private bool CheckOptions(Project project, bool forceAnalysis)
{
var workspace = project.Solution.Workspace;
if (workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, project.Language) &&
if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace, project.Language) &&
workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
{
return true;
......
......@@ -407,7 +407,7 @@ private static async Task<bool> FullAnalysisEnabledAsync(Project project, Cancel
var workspace = project.Solution.Workspace;
var language = project.Language;
if (!workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, language) ||
if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace, language) ||
!workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
{
return false;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Shared.Options
......@@ -9,12 +8,33 @@ internal static class ServiceFeatureOnOffOptions
{
public const string OptionName = "ServiceFeaturesOnOff";
private const bool CSharpClosedFileDiagnosticsEnabledByDefault = false;
private const bool DefaultClosedFileDiagnosticsEnabledByDefault = true;
/// <summary>
/// this option is solely for performance. don't confused by option name.
/// this option doesn't mean we will show all diagnostics that belong to opened files when turned off,
/// rather it means we will only show diagnostics that are cheap to calculate for small scope such as opened files.
/// </summary>
public static readonly PerLanguageOption<bool> ClosedFileDiagnostic = new PerLanguageOption<bool>(
OptionName, "Closed File Diagnostic", defaultValue: true, perLanguageDefaults: ImmutableDictionary<string, bool>.Empty.Add(LanguageNames.CSharp, false));
public static readonly PerLanguageOption<bool?> ClosedFileDiagnostic = new PerLanguageOption<bool?>(OptionName, "Closed File Diagnostic", defaultValue: null);
public static bool IsClosedFileDiagnosticsEnabled(Workspace workspace, string language)
{
var optionsService = workspace.Services.GetService<IOptionService>();
return optionsService != null && IsClosedFileDiagnosticsEnabled(optionsService, language);
}
public static bool IsClosedFileDiagnosticsEnabled(IOptionService optionService, string language)
{
var option = optionService.GetOption(ClosedFileDiagnostic, language);
if (!option.HasValue)
{
return language == LanguageNames.CSharp ?
CSharpClosedFileDiagnosticsEnabledByDefault :
DefaultClosedFileDiagnosticsEnabledByDefault;
}
return option.Value;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion;
......@@ -36,7 +37,22 @@ public int BringUpOnIdentifier
set { SetBooleanOption(CompletionOptions.TriggerOnTypingLetters, value); }
}
[Obsolete("This SettingStore option has now been deprecated in favor of CSharpClosedFileDiagnostics")]
public int ClosedFileDiagnostics
{
get { return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic); }
set
{
// Even though this option has been deprecated, we want to respect the setting if the user has explicitly turned off closed file diagnostics (which is the non-default value for 'ClosedFileDiagnostics').
// So, we invoke the setter only for value = 0.
if (value == 0)
{
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value);
}
}
}
public int CSharpClosedFileDiagnostics
{
get { return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic); }
set { SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value); }
......@@ -520,5 +536,24 @@ private void SetBooleanOption(PerLanguageOption<bool> key, int value)
optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, value != 0);
_optionService.SetOptions(optionSet);
}
private int GetBooleanOption(PerLanguageOption<bool?> key)
{
var option = _optionService.GetOption(key, LanguageNames.CSharp);
if (!option.HasValue)
{
return -1;
}
return option.Value ? 1 : 0;
}
private void SetBooleanOption(PerLanguageOption<bool?> key, int value)
{
bool? boolValue = (value < 0) ? (bool?)null : (value > 0);
var optionSet = _optionService.GetOptions();
optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, boolValue);
_optionService.SetOptions(optionSet);
}
}
}
......@@ -103,6 +103,20 @@ private bool ShouldIncludeOnOffOption(FieldInfo fieldInfo)
protected override string SettingStorageRoot { get { return "TextEditor.CSharp.Specific."; } }
protected override string GetStorageKeyForOption(IOption option)
{
var name = option.Name;
if (option == ServiceFeatureOnOffOptions.ClosedFileDiagnostic)
{
// ClosedFileDiagnostics has been deprecated in favor of CSharpClosedFileDiagnostics.
// ClosedFileDiagnostics had a default value of 'true', while CSharpClosedFileDiagnostics has a default value of 'false'.
// We want to ensure that we don't fetch the setting store value for the old flag, as that can cause the default value for this option to change.
name = nameof(AutomationObject.CSharpClosedFileDiagnostics);
}
return SettingStorageRoot + name;
}
protected override bool SupportsOption(IOption option, string languageName)
{
if (option == OrganizerOptions.PlaceSystemNamespaceFirst ||
......
......@@ -152,7 +152,7 @@ public void RemoveProject(ProjectId projectId)
private bool CheckOptions(Document document)
{
if (_workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, document.Project.Language) &&
if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_workspace, document.Project.Language) &&
_workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
{
return true;
......
......@@ -34,7 +34,7 @@ public virtual bool TryPersist(OptionKey optionKey, object value)
return TryPersist(optionKey, value, (r, k, o, v) => r.SetValue(k, (bool)v ? 1 : 0, RegistryValueKind.DWord));
}
protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, OptionKey, object> valueGetter, out object value)
protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, IOption, object> valueGetter, out object value)
{
if (this.RegistryKey == null)
{
......@@ -58,7 +58,7 @@ protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, OptionKey
return false;
}
value = valueGetter(subKey, collectionPathAndPropertyName.Item2, optionKey);
value = valueGetter(subKey, collectionPathAndPropertyName.Item2, optionKey.Option);
return true;
}
}
......
......@@ -146,7 +146,7 @@ public virtual bool TryFetch(OptionKey optionKey, out object value)
}
var storageKey = GetStorageKeyForOption(optionKey.Option);
value = this.Manager.GetValueOrDefault(storageKey, optionKey.DefaultValue);
value = this.Manager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);
return true;
}
......
......@@ -11,7 +11,7 @@ internal class FullSolutionAnalysisOptionBinding
private readonly string _languageName;
private readonly Option<bool> _fullSolutionAnalysis;
private readonly PerLanguageOption<bool> _closedFileDiagnostics;
private readonly PerLanguageOption<bool?> _closedFileDiagnostics;
public FullSolutionAnalysisOptionBinding(IOptionService optionService, string languageName)
{
......@@ -26,7 +26,7 @@ public bool Value
{
get
{
return _optionService.GetOption(_closedFileDiagnostics, _languageName) &&
return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, _languageName) &&
_optionService.GetOption(_fullSolutionAnalysis);
}
......
......@@ -44,11 +44,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
End Set
End Property
<Obsolete("This SettingStore option has now been deprecated in favor of BasicClosedFileDiagnostics")>
Public Property ClosedFileDiagnostics As Boolean
Get
Return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic)
Return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, LanguageNames.VisualBasic)
End Get
Set(value As Boolean)
' Even though this option has been deprecated, we want to respect the setting if the user has explicitly turned off closed file diagnostics (which is the non-default value for 'ClosedFileDiagnostics').
' So, we invoke the setter only for value = False.
If Not value Then
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value:=0)
End If
End Set
End Property
Public Property BasicClosedFileDiagnostics As Integer
Get
Return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic)
End Get
Set(value As Integer)
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value)
End Set
End Property
......@@ -171,5 +185,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, value)
_optionService.SetOptions(optionSet)
End Sub
Private Function GetBooleanOption(key As PerLanguageOption(Of Boolean?)) As Integer
Dim [option] = _optionService.GetOption(key, LanguageNames.VisualBasic)
If Not [option].HasValue Then
Return -1
End If
Return If([option].Value, 1, 0)
End Function
Private Sub SetBooleanOption(key As PerLanguageOption(Of Boolean?), value As Integer)
Dim boolValue As Boolean? = If(value < 0, Nothing, value > 0)
Dim optionSet = _optionService.GetOptions()
optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, boolValue)
_optionService.SetOptions(optionSet)
End Sub
End Class
End Namespace
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Options
{
internal interface IOption2 : IOption
{
object GetDefaultValue(string language);
}
}
......@@ -10,8 +10,6 @@ public struct OptionKey : IEquatable<OptionKey>
public IOption Option { get; }
public string Language { get; }
internal object DefaultValue => ((IOption2)Option).GetDefaultValue(Language);
public OptionKey(IOption option, string language = null)
{
if (option == null)
......
......@@ -81,7 +81,7 @@ private object LoadOptionFromSerializerOrGetDefault(OptionKey optionKey)
// Just use the default. We will still cache this so we aren't trying to deserialize
// over and over.
return optionKey.DefaultValue;
return optionKey.Option.DefaultValue;
}
}
......
......@@ -51,7 +51,7 @@ public object GetOption(OptionKey optionKey)
if (!_values.TryGetValue(optionKey, out value))
{
value = _service != null ? _service.GetOption(optionKey) : optionKey.DefaultValue;
value = _service != null ? _service.GetOption(optionKey) : optionKey.Option.DefaultValue;
_values = _values.Add(optionKey, value);
}
......
......@@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.Options
/// <summary>
/// An global option. An instance of this class can be used to access an option value from an OptionSet.
/// </summary>
public class Option<T> : IOption2, IOption
public class Option<T> : IOption
{
/// <summary>
/// Feature this option is associated with.
......@@ -22,7 +22,10 @@ public class Option<T> : IOption2, IOption
/// <summary>
/// The type of the option value.
/// </summary>
public Type Type => typeof(T);
public Type Type
{
get { return typeof(T); }
}
/// <summary>
/// The default value of the option.
......@@ -46,13 +49,19 @@ public Option(string feature, string name, T defaultValue = default(T))
this.DefaultValue = defaultValue;
}
Type IOption.Type => typeof(T);
object IOption.DefaultValue => this.DefaultValue;
bool IOption.IsPerLanguage => false;
Type IOption.Type
{
get { return typeof(T); }
}
object IOption.DefaultValue
{
get { return this.DefaultValue; }
}
object IOption2.GetDefaultValue(string language)
bool IOption.IsPerLanguage
{
return this.DefaultValue;
get { return false; }
}
public override string ToString()
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Options
{
......@@ -10,13 +8,8 @@ namespace Microsoft.CodeAnalysis.Options
/// An option that can be specified once per language.
/// </summary>
/// <typeparam name="T"></typeparam>
public class PerLanguageOption<T> : IOption2, IOption
public class PerLanguageOption<T> : IOption
{
/// <summary>
/// Save per language defaults
/// </summary>
private readonly IImmutableDictionary<string, T> _perLanguageDefaults;
/// <summary>
/// Feature this option is associated with.
/// </summary>
......@@ -40,32 +33,7 @@ public Type Type
/// </summary>
public T DefaultValue { get; }
/// <summary>
/// The default option value of specific language
/// </summary>
internal T GetDefaultValue(string language)
{
if (_perLanguageDefaults.Count == 0)
{
return DefaultValue;
}
T languageSpecificDefault;
if (!_perLanguageDefaults.TryGetValue(language, out languageSpecificDefault))
{
return DefaultValue;
}
return languageSpecificDefault;
}
public PerLanguageOption(string feature, string name, T defaultValue) :
this(feature, name, defaultValue, ImmutableDictionary<string, T>.Empty)
{
}
internal PerLanguageOption(
string feature, string name, T defaultValue, IDictionary<string, T> perLanguageDefaults)
public PerLanguageOption(string feature, string name, T defaultValue)
{
if (string.IsNullOrWhiteSpace(feature))
{
......@@ -77,18 +45,9 @@ internal T GetDefaultValue(string language)
throw new ArgumentException(nameof(name));
}
if (perLanguageDefaults == null)
{
throw new ArgumentNullException(nameof(perLanguageDefaults));
}
this.Feature = feature;
this.Name = name;
this.DefaultValue = defaultValue;
this._perLanguageDefaults =
(perLanguageDefaults as IImmutableDictionary<string, T>) ??
ImmutableDictionary.CreateRange<string, T>(perLanguageDefaults);
}
Type IOption.Type
......@@ -106,11 +65,6 @@ bool IOption.IsPerLanguage
get { return true; }
}
object IOption2.GetDefaultValue(string language)
{
return this.GetDefaultValue(language);
}
public override string ToString()
{
return string.Format("{0} - {1}", this.Feature, this.Name);
......
......@@ -394,7 +394,6 @@
<Compile Include="FindSymbols\DeclaredSymbolInfo.cs" />
<Compile Include="FindSymbols\FindReferences\Finders\ILanguageServiceReferenceFinder.cs" />
<Compile Include="LinkedFileDiffMerging\LinkedFileDiffMergingLogger.cs" />
<Compile Include="Options\IOption2.cs" />
<Compile Include="Packaging\IPackageInstallerService.cs" />
<Compile Include="Packaging\IPackageSearchService.cs" />
<Compile Include="FindSymbols\SymbolTree\ISymbolTreeInfoCacheService.cs" />
......@@ -979,4 +978,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册