提交 7d27ae38 编写于 作者: J Jason Malinowski

Add a new API which can be used to store metadata for persistence

One current challenge of our option persistence story is the
determination of the name of an option being serialized is mixed in
with the core logic for how to serialize things to a store. This results
in some very hard-to-maintain code since the logic for an option
is spread across many different areas.
上级 8f18ac99
// 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.Immutable;
namespace Microsoft.CodeAnalysis.Options
{
......@@ -11,5 +12,7 @@ public interface IOption
Type Type { get; }
object DefaultValue { get; }
bool IsPerLanguage { get; }
ImmutableArray<OptionPersistence> Persistences { get; }
}
}
namespace Microsoft.CodeAnalysis.Options
{
/// <summary>
/// Specifies that the option should be persisted into the user's local registry hive.
/// </summary>
internal sealed class LocalUserProfilePersistence : OptionPersistence
{
public string KeyName { get; }
public LocalUserProfilePersistence(string keyName)
{
KeyName = keyName;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Options
{
/// <summary>
/// The base type of all persistence information for different options.
/// </summary>
public abstract class OptionPersistence
{
}
}
// 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.Immutable;
namespace Microsoft.CodeAnalysis.Options
{
......@@ -29,7 +30,15 @@ public class Option<T> : IOption
/// </summary>
public Type Type => typeof(T);
public Option(string feature, string name, T defaultValue = default(T))
public ImmutableArray<OptionPersistence> Persistences { get; }
public Option(string feature, string name)
: this(feature, name, default(T))
{
// This constructor forwards to the next one; it exists to maintain source-level compatibility with older callers.
}
public Option(string feature, string name, T defaultValue)
{
if (string.IsNullOrWhiteSpace(feature))
{
......@@ -46,6 +55,12 @@ public Option(string feature, string name, T defaultValue = default(T))
this.DefaultValue = defaultValue;
}
public Option(string feature, string name, T defaultValue, params OptionPersistence[] persistences)
: this(feature, name, defaultValue)
{
Persistences = persistences.ToImmutableArray();
}
object IOption.DefaultValue => this.DefaultValue;
bool IOption.IsPerLanguage => false;
......@@ -60,4 +75,4 @@ public override string ToString()
return new OptionKey(option);
}
}
}
\ No newline at end of file
}
// 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.Immutable;
namespace Microsoft.CodeAnalysis.Options
{
......@@ -30,6 +31,8 @@ public class PerLanguageOption<T> : IOption
/// </summary>
public T DefaultValue { get; }
public ImmutableArray<OptionPersistence> Persistences { get; }
public PerLanguageOption(string feature, string name, T defaultValue)
{
if (string.IsNullOrWhiteSpace(feature))
......@@ -47,6 +50,12 @@ public PerLanguageOption(string feature, string name, T defaultValue)
this.DefaultValue = defaultValue;
}
public PerLanguageOption(string feature, string name, T defaultValue, params OptionPersistence[] persistences)
: this(feature, name, defaultValue)
{
Persistences = persistences.ToImmutableArray();
}
object IOption.DefaultValue => this.DefaultValue;
bool IOption.IsPerLanguage => true;
......@@ -56,4 +65,4 @@ public override string ToString()
return string.Format("{0} - {1}", this.Feature, this.Name);
}
}
}
\ No newline at end of file
}
using System;
namespace Microsoft.CodeAnalysis.Options
{
/// <summary>
/// Specifies that the option should be persisted into a roamed profile across machines.
/// </summary>
internal sealed class RoamingProfilePersistence : OptionPersistence
{
private readonly Func<string, string> _keyNameFromLanguageName;
public string GetKeyNameForLanguage(string languageName)
{
string unsubstitutedKeyName = _keyNameFromLanguageName(languageName);
if (languageName == null)
{
return unsubstitutedKeyName;
}
else
{
string substituteLanguageName = languageName == LanguageNames.CSharp ? "CSharp" :
languageName == LanguageNames.VisualBasic ? "VisualBasic" :
languageName;
return unsubstitutedKeyName.Replace("%LANGUAGE%", substituteLanguageName);
}
}
public RoamingProfilePersistence(string keyName)
{
_keyNameFromLanguageName = _ => keyName;
}
/// <summary>
/// Creates a <see cref="RoamingProfilePersistence"/> that has different key names for different languages.
/// </summary>
/// <param name="keyNameFromLanguageName">A function that maps from a <see cref="LanguageNames"/> value to the key name.</param>
public RoamingProfilePersistence(Func<string, string> keyNameFromLanguageName)
{
_keyNameFromLanguageName = keyNameFromLanguageName;
}
}
}
......@@ -506,7 +506,8 @@ Microsoft.CodeAnalysis.Options.Option<T>
Microsoft.CodeAnalysis.Options.Option<T>.DefaultValue.get -> T
Microsoft.CodeAnalysis.Options.Option<T>.Feature.get -> string
Microsoft.CodeAnalysis.Options.Option<T>.Name.get -> string
Microsoft.CodeAnalysis.Options.Option<T>.Option(string feature, string name, T defaultValue = default(T)) -> void
Microsoft.CodeAnalysis.Options.Option<T>.Option(string feature, string name) -> void
Microsoft.CodeAnalysis.Options.Option<T>.Option(string feature, string name, T defaultValue) -> void
Microsoft.CodeAnalysis.Options.Option<T>.Type.get -> System.Type
Microsoft.CodeAnalysis.Options.OptionKey
Microsoft.CodeAnalysis.Options.OptionKey.Equals(Microsoft.CodeAnalysis.Options.OptionKey other) -> bool
......
......@@ -23,7 +23,14 @@ Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs.SourceTextContainer
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.AddSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> switchSections) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Options.DocumentOptionSet
Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption<T>(Microsoft.CodeAnalysis.Options.PerLanguageOption<T> option) -> T
Microsoft.CodeAnalysis.Options.IOption.Persistences.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Options.OptionPersistence>
Microsoft.CodeAnalysis.Options.Option<T>.Option(string feature, string name, T defaultValue, params Microsoft.CodeAnalysis.Options.OptionPersistence[] persistences) -> void
Microsoft.CodeAnalysis.Options.Option<T>.Persistences.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Options.OptionPersistence>
Microsoft.CodeAnalysis.Options.OptionPersistence
Microsoft.CodeAnalysis.Options.OptionPersistence.OptionPersistence() -> void
Microsoft.CodeAnalysis.Options.OptionSet.OptionSet() -> void
Microsoft.CodeAnalysis.Options.PerLanguageOption<T>.PerLanguageOption(string feature, string name, T defaultValue, params Microsoft.CodeAnalysis.Options.OptionPersistence[] persistences) -> void
Microsoft.CodeAnalysis.Options.PerLanguageOption<T>.Persistences.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Options.OptionPersistence>
Microsoft.CodeAnalysis.Solution.Options.get -> Microsoft.CodeAnalysis.Options.OptionSet
Microsoft.CodeAnalysis.Workspace.DocumentActiveContextChanged -> System.EventHandler<Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs>
Microsoft.CodeAnalysis.Workspace.RaiseDocumentActiveContextChangedEventAsync(Microsoft.CodeAnalysis.Text.SourceTextContainer sourceTextContainer, Microsoft.CodeAnalysis.DocumentId oldActiveContextDocumentId, Microsoft.CodeAnalysis.DocumentId newActiveContextDocumentId) -> System.Threading.Tasks.Task
......
......@@ -395,6 +395,9 @@
<Compile Include="Options\IWorkspaceOptionService.cs" />
<Compile Include="Shared\RuntimeOptions.cs" />
<Compile Include="Shared\RuntimeOptionsProvider.cs" />
<Compile Include="Options\OptionPersistence.cs" />
<Compile Include="Options\LocalUserProfilePersistence.cs" />
<Compile Include="Options\RoamingProfilePersistence.cs" />
<Compile Include="SolutionCrawler\ExportIncrementalAnalyzerProviderAttribute.cs" />
<Compile Include="SolutionCrawler\IIncrementalAnalyzer.cs" />
<Compile Include="SolutionCrawler\IIncrementalAnalyzerProvider.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册