提交 c7bcaed1 编写于 作者: J Jonathon Marolf 提交者: GitHub

editor config naming style (#15065)

* moving naming styles types into the workspace layer.
Teaching abstract options serialization service about naming styles.

* Implementing naming styles support for editorconfig

* responding to david's PR feedback

* responding to Jason's feedback

* responding to Jason's feedback part 2

* addressing the latest set of comments from David

* addressing Jason's comments

* addressing Kevin's comments
上级 dbf2fee3
......@@ -217,6 +217,7 @@
<Compile Include="CodeActions\Preview\PreviewTests.cs" />
<Compile Include="CodeActions\ReplaceMethodWithProperty\ReplaceMethodWithPropertyTests.cs" />
<Compile Include="Diagnostics\InvokeDelegateWithConditionalAccess\InvokeDelegateWithConditionalAccessTests.cs" />
<Compile Include="Diagnostics\NamingStyles\EditorConfigNamingStyleParserTests.cs" />
<Compile Include="Diagnostics\NamingStyles\NamingStylesTests_OptionSets.cs" />
<Compile Include="Diagnostics\PreferFrameworkType\PreferFrameworkTypeTests.cs" />
<Compile Include="Diagnostics\PreferFrameworkType\PreferFrameworkTypeTests_FixAllTests.cs" />
......
// 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.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Roslyn.Test.Utilities;
using Xunit;
using static Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles.EditorConfigNamingStyleParser;
using static Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles.SymbolSpecification;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.NamingStyles
{
public partial class EditorConfigNamingStyleParserTests
{
[Fact]
public static void TestPascalCaseRule()
{
var dictionary = new Dictionary<string, object>()
{
["dotnet_naming_rule.methods_and_properties_must_be_pascal_case.severity"] = "warning",
["dotnet_naming_rule.methods_and_properties_must_be_pascal_case.symbols"] = "method_and_property_symbols",
["dotnet_naming_rule.methods_and_properties_must_be_pascal_case.style"] = "pascal_case_style",
["dotnet_naming_symbols.method_and_property_symbols.applicable_kinds"] = "method,property",
["dotnet_naming_symbols.method_and_property_symbols.applicable_accessibilities"] = "*",
["dotnet_naming_style.pascal_case_style.capitalization"] = "pascal_case"
};
var result = ParseDictionary(dictionary);
Assert.Single(result.NamingRules);
var namingRule = result.NamingRules.Single();
Assert.Single(result.NamingStyles);
var namingStyle = result.NamingStyles.Single();
Assert.Single(result.SymbolSpecifications);
var symbolSpec = result.SymbolSpecifications.Single();
Assert.Equal(namingStyle.ID, namingRule.NamingStyleID);
Assert.Equal(symbolSpec.ID, namingRule.SymbolSpecificationID);
Assert.Equal(DiagnosticSeverity.Warning, namingRule.EnforcementLevel);
Assert.Equal("method_and_property_symbols", symbolSpec.Name);
var expectedApplicableSymbolKindList = new[]
{
new SymbolKindOrTypeKind(SymbolKind.Method),
new SymbolKindOrTypeKind(SymbolKind.Property)
};
AssertEx.SetEqual(expectedApplicableSymbolKindList, symbolSpec.ApplicableSymbolKindList);
Assert.Empty(symbolSpec.RequiredModifierList);
var expectedApplicableAccessibilityList = new[]
{
Accessibility.Public,
Accessibility.Internal,
Accessibility.Private,
Accessibility.Protected,
Accessibility.ProtectedOrInternal
};
AssertEx.SetEqual(expectedApplicableAccessibilityList, symbolSpec.ApplicableAccessibilityList);
Assert.Equal("pascal_case_style", namingStyle.Name);
Assert.Equal("", namingStyle.Prefix);
Assert.Equal("", namingStyle.Suffix);
Assert.Equal("", namingStyle.WordSeparator);
Assert.Equal(Capitalization.PascalCase, namingStyle.CapitalizationScheme);
}
[Fact]
public static void TestAsyncMethodsRule()
{
var dictionary = new Dictionary<string, object>()
{
["dotnet_naming_rule.async_methods_must_end_with_async.severity"] = "error",
["dotnet_naming_rule.async_methods_must_end_with_async.symbols"] = "method_symbols",
["dotnet_naming_rule.async_methods_must_end_with_async.style"] = "end_in_async_style",
["dotnet_naming_symbols.method_symbols.applicable_kinds"] = "method",
["dotnet_naming_symbols.method_symbols.required_modifiers"] = "async",
["dotnet_naming_style.end_in_async_style.capitalization "] = "pascal_case",
["dotnet_naming_style.end_in_async_style.required_suffix"] = "Async",
};
var result = ParseDictionary(dictionary);
Assert.Single(result.NamingRules);
var namingRule = result.NamingRules.Single();
Assert.Single(result.NamingStyles);
var namingStyle = result.NamingStyles.Single();
Assert.Single(result.SymbolSpecifications);
var symbolSpec = result.SymbolSpecifications.Single();
Assert.Equal(namingStyle.ID, namingRule.NamingStyleID);
Assert.Equal(symbolSpec.ID, namingRule.SymbolSpecificationID);
Assert.Equal(DiagnosticSeverity.Error, namingRule.EnforcementLevel);
Assert.Equal("method_symbols", symbolSpec.Name);
Assert.Single(symbolSpec.ApplicableSymbolKindList);
Assert.Contains(new SymbolKindOrTypeKind(SymbolKind.Method), symbolSpec.ApplicableSymbolKindList);
Assert.Single(symbolSpec.RequiredModifierList);
Assert.Contains(new ModifierKind(ModifierKindEnum.IsAsync), symbolSpec.RequiredModifierList);
Assert.Empty(symbolSpec.ApplicableAccessibilityList);
Assert.Equal("end_in_async_style", namingStyle.Name);
Assert.Equal("", namingStyle.Prefix);
Assert.Equal("Async", namingStyle.Suffix);
Assert.Equal("", namingStyle.WordSeparator);
Assert.Equal(Capitalization.PascalCase, namingStyle.CapitalizationScheme);
}
[Fact]
public static void TestPublicMembersCapitalizedRule()
{
var dictionary = new Dictionary<string, object>()
{
["dotnet_naming_rule.public_members_must_be_capitalized.severity"] = "suggestion",
["dotnet_naming_rule.public_members_must_be_capitalized.symbols"] = "public_symbols",
["dotnet_naming_rule.public_members_must_be_capitalized.style"] = "first_word_upper_case_style",
["dotnet_naming_symbols.public_symbols.applicable_kinds"] = "property,method,field,event,delegate",
["dotnet_naming_symbols.public_symbols.applicable_accessibilities"] = "public,internal,protected,protected_internal",
["dotnet_naming_style.first_word_upper_case_style.capitalization"] = "first_word_upper",
};
var result = ParseDictionary(dictionary);
Assert.Single(result.NamingRules);
var namingRule = result.NamingRules.Single();
Assert.Single(result.NamingStyles);
var namingStyle = result.NamingStyles.Single();
Assert.Single(result.SymbolSpecifications);
var symbolSpec = result.SymbolSpecifications.Single();
Assert.Equal(namingStyle.ID, namingRule.NamingStyleID);
Assert.Equal(symbolSpec.ID, namingRule.SymbolSpecificationID);
Assert.Equal(DiagnosticSeverity.Info, namingRule.EnforcementLevel);
Assert.Equal("public_symbols", symbolSpec.Name);
var expectedApplicableSymbolKindList = new[]
{
new SymbolKindOrTypeKind(SymbolKind.Property),
new SymbolKindOrTypeKind(SymbolKind.Method),
new SymbolKindOrTypeKind(SymbolKind.Field),
new SymbolKindOrTypeKind(SymbolKind.Event),
new SymbolKindOrTypeKind(TypeKind.Delegate)
};
AssertEx.SetEqual(expectedApplicableSymbolKindList, symbolSpec.ApplicableSymbolKindList);
var expectedApplicableAccessibilityList = new[]
{
Accessibility.Public,
Accessibility.Internal,
Accessibility.Protected,
Accessibility.ProtectedOrInternal
};
AssertEx.SetEqual(expectedApplicableAccessibilityList, symbolSpec.ApplicableAccessibilityList);
Assert.Empty(symbolSpec.RequiredModifierList);
Assert.Equal("first_word_upper_case_style", namingStyle.Name);
Assert.Equal("", namingStyle.Prefix);
Assert.Equal("", namingStyle.Suffix);
Assert.Equal("", namingStyle.WordSeparator);
Assert.Equal(Capitalization.FirstUpper, namingStyle.CapitalizationScheme);
}
[Fact]
public static void TestNonPublicMembersLowerCaseRule()
{
var dictionary = new Dictionary<string, object>()
{
["dotnet_naming_rule.non_public_members_must_be_lower_case.severity"] = "incorrect",
["dotnet_naming_rule.non_public_members_must_be_lower_case.symbols "] = "non_public_symbols",
["dotnet_naming_rule.non_public_members_must_be_lower_case.style "] = "all_lower_case_style",
["dotnet_naming_symbols.non_public_symbols.applicable_kinds "] = "property,method,field,event,delegate",
["dotnet_naming_symbols.non_public_symbols.applicable_accessibilities"] = "private",
["dotnet_naming_style.all_lower_case_style.capitalization"] = "all_lower",
};
var result = ParseDictionary(dictionary);
Assert.Single(result.NamingRules);
var namingRule = result.NamingRules.Single();
Assert.Single(result.NamingStyles);
var namingStyle = result.NamingStyles.Single();
Assert.Single(result.SymbolSpecifications);
var symbolSpec = result.SymbolSpecifications.Single();
Assert.Equal(namingStyle.ID, namingRule.NamingStyleID);
Assert.Equal(symbolSpec.ID, namingRule.SymbolSpecificationID);
Assert.Equal(DiagnosticSeverity.Hidden, namingRule.EnforcementLevel);
Assert.Equal("non_public_symbols", symbolSpec.Name);
var expectedApplicableSymbolKindList = new[]
{
new SymbolKindOrTypeKind(SymbolKind.Property),
new SymbolKindOrTypeKind(SymbolKind.Method),
new SymbolKindOrTypeKind(SymbolKind.Field),
new SymbolKindOrTypeKind(SymbolKind.Event),
new SymbolKindOrTypeKind(TypeKind.Delegate)
};
AssertEx.SetEqual(expectedApplicableSymbolKindList, symbolSpec.ApplicableSymbolKindList);
Assert.Single(symbolSpec.ApplicableAccessibilityList);
Assert.Contains(Accessibility.Private, symbolSpec.ApplicableAccessibilityList);
Assert.Empty(symbolSpec.RequiredModifierList);
Assert.Equal("all_lower_case_style", namingStyle.Name);
Assert.Equal("", namingStyle.Prefix);
Assert.Equal("", namingStyle.Suffix);
Assert.Equal("", namingStyle.WordSeparator);
Assert.Equal(Capitalization.AllLower, namingStyle.CapitalizationScheme);
}
[Fact]
public static void TestNoRulesAreReturned()
{
var dictionary = new Dictionary<string, object>()
{
["dotnet_naming_symbols.non_public_symbols.applicable_kinds "] = "property,method,field,event,delegate",
["dotnet_naming_symbols.non_public_symbols.applicable_accessibilities"] = "private",
["dotnet_naming_style.all_lower_case_style.capitalization"] = "all_lower",
};
var result = ParseDictionary(dictionary);
Assert.Empty(result.NamingRules);
Assert.Empty(result.NamingStyles);
Assert.Empty(result.SymbolSpecifications);
}
}
}
......@@ -15,76 +15,78 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.NamingStyle
public partial class NamingStylesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
{
private IDictionary<OptionKey, object> ClassNamesArePascalCase =>
Options(new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp), ClassNamesArePascalCaseOptionString());
Options(new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp), ClassNamesArePascalCaseOption());
private IDictionary<OptionKey, object> MethodNamesArePascalCase =>
Options(new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp), MethodNamesArePascalCaseOptionString());
Options(new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp), MethodNamesArePascalCaseOption());
private IDictionary<OptionKey, object> Options(OptionKey option, object value)
{
var options = new Dictionary<OptionKey, object>();
options.Add(option, value);
var options = new Dictionary<OptionKey, object>
{
{ option, value }
};
return options;
}
private string ClassNamesArePascalCaseOptionString()
private NamingStylePreferences ClassNamesArePascalCaseOption()
{
var symbolSpecification = new SymbolSpecification(
Guid.NewGuid(),
"Name",
SpecializedCollections.SingletonEnumerable(new SymbolSpecification.SymbolKindOrTypeKind(TypeKind.Class)).ToList(),
SpecializedCollections.EmptyList<SymbolSpecification.AccessibilityKind>(),
SpecializedCollections.EmptyList<Accessibility>(),
SpecializedCollections.EmptyList<SymbolSpecification.ModifierKind>());
var namingStyle = new NamingStyle();
namingStyle.CapitalizationScheme = Capitalization.PascalCase;
namingStyle.Name = "Name";
namingStyle.Prefix = "";
namingStyle.Suffix = "";
namingStyle.WordSeparator = "";
var namingRule = new SerializableNamingRule();
namingRule.SymbolSpecificationID = symbolSpecification.ID;
namingRule.NamingStyleID = namingStyle.ID;
namingRule.EnforcementLevel = DiagnosticSeverity.Error;
var info = new SerializableNamingStylePreferencesInfo();
var namingStyle = new NamingStyle()
{
CapitalizationScheme = Capitalization.PascalCase,
Name = "Name",
Prefix = "",
Suffix = "",
WordSeparator = ""
};
var namingRule = new SerializableNamingRule()
{
SymbolSpecificationID = symbolSpecification.ID,
NamingStyleID = namingStyle.ID,
EnforcementLevel = DiagnosticSeverity.Error
};
var info = new NamingStylePreferences();
info.SymbolSpecifications.Add(symbolSpecification);
info.NamingStyles.Add(namingStyle);
info.NamingRules.Add(namingRule);
return info.CreateXElement().ToString();
return info;
}
private string MethodNamesArePascalCaseOptionString()
private NamingStylePreferences MethodNamesArePascalCaseOption()
{
var symbolSpecification = new SymbolSpecification(
Guid.NewGuid(),
"Name",
SpecializedCollections.SingletonEnumerable(new SymbolSpecification.SymbolKindOrTypeKind(SymbolKind.Method)).ToList(),
SpecializedCollections.EmptyList<SymbolSpecification.AccessibilityKind>(),
SpecializedCollections.EmptyList<Accessibility>(),
SpecializedCollections.EmptyList<SymbolSpecification.ModifierKind>());
var namingStyle = new NamingStyle();
namingStyle.CapitalizationScheme = Capitalization.PascalCase;
namingStyle.Name = "Name";
namingStyle.Prefix = "";
namingStyle.Suffix = "";
namingStyle.WordSeparator = "";
var namingRule = new SerializableNamingRule();
namingRule.SymbolSpecificationID = symbolSpecification.ID;
namingRule.NamingStyleID = namingStyle.ID;
namingRule.EnforcementLevel = DiagnosticSeverity.Error;
var info = new SerializableNamingStylePreferencesInfo();
var namingStyle = new NamingStyle()
{
CapitalizationScheme = Capitalization.PascalCase,
Name = "Name",
Prefix = "",
Suffix = "",
WordSeparator = ""
};
var namingRule = new SerializableNamingRule()
{
SymbolSpecificationID = symbolSpecification.ID,
NamingStyleID = namingStyle.ID,
EnforcementLevel = DiagnosticSeverity.Error
};
var info = new NamingStylePreferences();
info.SymbolSpecifications.Add(symbolSpecification);
info.NamingStyles.Add(namingStyle);
info.NamingRules.Add(namingRule);
return info.CreateXElement().ToString();
return info;
}
}
}
\ No newline at end of file
......@@ -2,6 +2,8 @@
using System.Linq;
using Microsoft.CodeAnalysis.Options;
using Microsoft.VisualStudio.CodingConventions;
using Microsoft.CodeAnalysis.ErrorLogger;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
namespace Microsoft.CodeAnalysis.Editor.Options
{
......@@ -10,37 +12,32 @@ internal sealed partial class EditorConfigDocumentOptionsProvider : IDocumentOpt
private class DocumentOptions : IDocumentOptions
{
private ICodingConventionsSnapshot _codingConventionSnapshot;
private readonly IErrorLoggerService _errorLogger;
public DocumentOptions(ICodingConventionsSnapshot codingConventionSnapshot)
public DocumentOptions(ICodingConventionsSnapshot codingConventionSnapshot, IErrorLoggerService errorLogger)
{
_codingConventionSnapshot = codingConventionSnapshot;
_errorLogger = errorLogger;
}
public bool TryGetDocumentOption(Document document, OptionKey option, out object value)
{
var editorConfigPersistence = option.Option.StorageLocations.OfType<EditorConfigStorageLocation>().SingleOrDefault();
if (editorConfigPersistence == null)
{
value = null;
return false;
}
if (_codingConventionSnapshot.TryGetConventionValue(editorConfigPersistence.KeyName, out value))
var allRawConventions = _codingConventionSnapshot.AllRawConventions;
try
{
try
{
value = editorConfigPersistence.ParseValue(value.ToString(), option.Option.Type);
return true;
}
catch (Exception)
{
// TODO: report this somewhere?
return false;
}
return editorConfigPersistence.TryParseReadonlyDictionary(allRawConventions, option.Option.Type, out value);
}
else
catch (Exception ex)
{
_errorLogger?.LogException(this, ex);
value = null;
return false;
}
}
......
using System.Collections.Generic;
// 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.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.ErrorLogger;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.VisualStudio.CodingConventions;
......@@ -22,10 +27,12 @@ internal sealed partial class EditorConfigDocumentOptionsProvider : IDocumentOpt
private readonly Dictionary<DocumentId, Task<ICodingConventionContext>> _openDocumentContexts = new Dictionary<DocumentId, Task<ICodingConventionContext>>();
private readonly ICodingConventionsManager _codingConventionsManager;
private readonly IErrorLoggerService _errorLogger;
internal EditorConfigDocumentOptionsProvider(Workspace workspace)
{
_codingConventionsManager = CodingConventionsManagerFactory.CreateCodingConventionsManager();
_errorLogger = workspace.Services.GetService<IErrorLoggerService>();
workspace.DocumentOpened += Workspace_DocumentOpened;
workspace.DocumentClosed += Workspace_DocumentClosed;
......@@ -78,7 +85,7 @@ public async Task<IDocumentOptions> GetOptionsForDocumentAsync(Document document
TaskScheduler.Default);
var context = await cancellableContextTask.ConfigureAwait(false);
return new DocumentOptions(context.CurrentConventions);
return new DocumentOptions(context.CurrentConventions, _errorLogger);
}
else
{
......@@ -105,7 +112,7 @@ public async Task<IDocumentOptions> GetOptionsForDocumentAsync(Document document
using (var context = await conventionsAsync.ConfigureAwait(false))
{
return new DocumentOptions(context.CurrentConventions);
return new DocumentOptions(context.CurrentConventions, _errorLogger);
}
}
}
......
using System;
// 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.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Options;
......
......@@ -2,13 +2,12 @@
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Simplification;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal abstract class NamingStyleDiagnosticAnalyzerBase :
internal abstract class NamingStyleDiagnosticAnalyzerBase :
AbstractCodeStyleDiagnosticAnalyzer, IBuiltInAnalyzer
{
private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(FeaturesResources.Naming_Styles), FeaturesResources.ResourceManager, typeof(FeaturesResources));
......@@ -36,32 +35,17 @@ protected NamingStyleDiagnosticAnalyzerBase()
public bool OpenFileOnly(Workspace workspace) => true;
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterCompilationStartAction(CompilationStartAction);
=> context.RegisterSymbolAction(SymbolAction, _symbolKinds);
private void CompilationStartAction(CompilationStartAnalysisContext context)
private void SymbolAction(SymbolAnalysisContext context)
{
var workspace = (context.Options as WorkspaceAnalyzerOptions)?.Workspace;
var optionSet = (context.Options as WorkspaceAnalyzerOptions)?.Workspace.Options;
var currentValue = optionSet.GetOption(SimplificationOptions.NamingPreferences, context.Compilation.Language);
if (!string.IsNullOrEmpty(currentValue))
var namingStyleRules = context.GetNamingStyleRulesAsync().GetAwaiter().GetResult();
if (namingStyleRules == null)
{
// Deserializing the naming preference info on every CompilationStart is expensive.
// Instead, the diagnostic engine should listen for option changes and have the
// ability to create the new SerializableNamingStylePreferencesInfo when it detects
// any change. The overall system would then only deserialize & allocate when
// actually necessary.
var viewModel = SerializableNamingStylePreferencesInfo.FromXElement(XElement.Parse(currentValue));
var preferencesInfo = viewModel.GetPreferencesInfo();
context.RegisterSymbolAction(
symbolContext => SymbolAction(symbolContext, preferencesInfo),
_symbolKinds);
return;
}
}
private void SymbolAction(SymbolAnalysisContext context, NamingStylePreferencesInfo preferences)
{
if (preferences.TryGetApplicableRule(context.Symbol, out var applicableRule))
if (namingStyleRules.TryGetApplicableRule(context.Symbol, out var applicableRule))
{
if (applicableRule.EnforcementLevel != DiagnosticSeverity.Hidden &&
!applicableRule.IsNameCompliant(context.Symbol.Name, out var failureReason))
......
// 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 Microsoft.CodeAnalysis.Simplification;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
/// <summary>
/// Contains all information related to Naming Style Preferences.
/// 1. Symbol Specifications
/// 2. Name Style
/// 3. Naming Rule (points to Symbol Specification IDs)
/// </summary>
internal class SerializableNamingStylePreferencesInfo
{
public List<SymbolSpecification> SymbolSpecifications;
public List<NamingStyle> NamingStyles;
public List<SerializableNamingRule> NamingRules;
private readonly static int s_serializationVersion = 3;
internal SerializableNamingStylePreferencesInfo()
{
SymbolSpecifications = new List<SymbolSpecification>();
NamingStyles = new List<NamingStyle>();
NamingRules = new List<SerializableNamingRule>();
}
internal NamingStyle GetNamingStyle(Guid namingStyleID)
{
return NamingStyles.Single(s => s.ID == namingStyleID);
}
internal SymbolSpecification GetSymbolSpecification(Guid symbolSpecificationID)
{
return SymbolSpecifications.Single(s => s.ID == symbolSpecificationID);
}
public NamingStylePreferencesInfo GetPreferencesInfo()
{
return new NamingStylePreferencesInfo(NamingRules.Select(r => r.GetRule(this)).ToImmutableArray());
}
internal XElement CreateXElement()
{
return new XElement("NamingPreferencesInfo",
new XAttribute("SerializationVersion", s_serializationVersion),
CreateSymbolSpecificationListXElement(),
CreateNamingStyleListXElement(),
CreateNamingRuleTreeXElement());
}
private XElement CreateNamingRuleTreeXElement()
{
var namingRulesElement = new XElement(nameof(NamingRules));
foreach (var namingRule in NamingRules)
{
namingRulesElement.Add(namingRule.CreateXElement());
}
return namingRulesElement;
}
private XElement CreateNamingStyleListXElement()
{
var namingStylesElement = new XElement(nameof(NamingStyles));
foreach (var namingStyle in NamingStyles)
{
namingStylesElement.Add(namingStyle.CreateXElement());
}
return namingStylesElement;
}
private XElement CreateSymbolSpecificationListXElement()
{
var symbolSpecificationsElement = new XElement(nameof(SymbolSpecifications));
foreach (var symbolSpecification in SymbolSpecifications)
{
symbolSpecificationsElement.Add(symbolSpecification.CreateXElement());
}
return symbolSpecificationsElement;
}
internal static SerializableNamingStylePreferencesInfo FromXElement(XElement namingPreferencesInfoElement)
{
var namingPreferencesInfo = new SerializableNamingStylePreferencesInfo();
var serializationVersion = int.Parse(namingPreferencesInfoElement.Attribute("SerializationVersion").Value);
if (serializationVersion != s_serializationVersion)
{
namingPreferencesInfoElement = XElement.Parse(SimplificationOptions.NamingPreferences.DefaultValue);
}
namingPreferencesInfo.SetSymbolSpecificationListFromXElement(namingPreferencesInfoElement.Element(nameof(SymbolSpecifications)));
namingPreferencesInfo.SetNamingStyleListFromXElement(namingPreferencesInfoElement.Element(nameof(NamingStyles)));
namingPreferencesInfo.SetNamingRuleTreeFromXElement(namingPreferencesInfoElement.Element(nameof(NamingRules)));
return namingPreferencesInfo;
}
private void SetSymbolSpecificationListFromXElement(XElement symbolSpecificationsElement)
{
foreach (var symbolSpecificationElement in symbolSpecificationsElement.Elements(nameof(SymbolSpecification)))
{
SymbolSpecifications.Add(SymbolSpecification.FromXElement(symbolSpecificationElement));
}
}
private void SetNamingStyleListFromXElement(XElement namingStylesElement)
{
foreach (var namingStyleElement in namingStylesElement.Elements(nameof(NamingStyle)))
{
NamingStyles.Add(NamingStyle.FromXElement(namingStyleElement));
}
}
private void SetNamingRuleTreeFromXElement(XElement namingRulesElement)
{
foreach (var namingRuleElement in namingRulesElement.Elements(nameof(SerializableNamingRule)))
{
NamingRules.Add(SerializableNamingRule.FromXElement(namingRuleElement));
}
}
}
}
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Options;
......@@ -77,11 +78,7 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
var syntaxTree = context.Node.SyntaxTree;
var cancellationToken = context.CancellationToken;
var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();
if (optionSet == null)
{
return;
}
var semanticModel = context.SemanticModel;
var language = semanticModel.Language;
......
// 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.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Simplification;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static class SymbolAnalysisContextExtensions
{
public static async Task<NamingStyleRules> GetNamingStyleRulesAsync(this SymbolAnalysisContext context)
{
var location = context.Symbol.Locations.FirstOrDefault();
if (location == null)
{
return null;
}
var optionSet = await context.Options.GetDocumentOptionSetAsync(location.SourceTree, context.CancellationToken).ConfigureAwait(false);
var namimgPreferences = optionSet.GetOption(SimplificationOptions.NamingPreferences, context.Compilation.Language);
return namimgPreferences.GetNamingStyleRules();
}
}
}
......@@ -103,6 +103,7 @@
<Compile Include="AddImport\CodeActions\PackageReference.InstallPackageAndAddImportCodeAction.cs" />
<Compile Include="AddImport\CodeActions\PackageReference.InstallWithPackageManagerCodeAction.cs" />
<Compile Include="ConvertToInterpolatedString\AbstractConvertConcatenationToInterpolatedStringRefactoringProvider.cs" />
<Compile Include="Diagnostics\SymbolAnalysisContextExtensions.cs" />
<Compile Include="EncapsulateField\EncapsulateFieldRefactoringProvider.cs" />
<Compile Include="ExtractInterface\ExtractInterfaceCodeRefactoringProvider.cs" />
<Compile Include="FeaturesResources.Designer.cs">
......@@ -306,7 +307,6 @@
<Compile Include="Diagnostics\AbstractHostDiagnosticUpdateSource.cs" />
<Compile Include="Diagnostics\Analyzers\PreferFrameworkTypeDiagnosticAnalyzerBase.cs" />
<Compile Include="QualifyMemberAccess\AbstractQualifyMemberAccessDiagnosticAnalyzer.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\Capitalization.cs" />
<Compile Include="DocumentationComments\CodeFixes\AbstractAddDocCommentNodesCodeFixProvider.cs" />
<Compile Include="DocumentationComments\CodeFixes\AbstractRemoveDocCommentNodeCodeFixProvider.cs" />
<Compile Include="DocumentSpan.cs" />
......@@ -328,13 +328,7 @@
<Compile Include="Structure\Syntax\AbstractSyntaxStructureProvider.cs" />
<Compile Include="Structure\Syntax\AbstractSyntaxTriviaStructureProvider.cs" />
<Compile Include="Structure\Syntax\BlockSpanCollector.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\NamingRule.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\NamingStylePreferencesInfo.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\Serialization\NamingStyle.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\Serialization\SerializableNamingRule.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\Serialization\SerializableNamingStylePreferencesInfo.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\NamingStyleDiagnosticAnalyzerBase.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyles\Serialization\SymbolSpecification.cs" />
<Compile Include="Diagnostics\Analyzers\NamingStyleDiagnosticAnalyzerBase.cs" />
<Compile Include="Diagnostics\AnalyzerUpdateArgsId.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer.AnalysisData.cs" />
<Compile Include="Diagnostics\EngineV2\DiagnosticIncrementalAnalyzer.AnalysisKind.cs" />
......
......@@ -1755,24 +1755,6 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Missing prefix: &apos;{0}&apos;.
/// </summary>
internal static string Missing_prefix_colon_0 {
get {
return ResourceManager.GetString("Missing_prefix_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Missing suffix: &apos;{0}&apos;.
/// </summary>
internal static string Missing_suffix_colon_0 {
get {
return ResourceManager.GetString("Missing_suffix_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Modifying &apos;{0}&apos; which contains a static variable will prevent the debug session from continuing..
/// </summary>
......@@ -2574,24 +2556,6 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to The first word, &apos;{0}&apos;, must begin with a lower case character.
/// </summary>
internal static string The_first_word_0_must_begin_with_a_lower_case_character {
get {
return ResourceManager.GetString("The_first_word_0_must_begin_with_a_lower_case_character", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The first word, &apos;{0}&apos;, must begin with an upper case character.
/// </summary>
internal static string The_first_word_0_must_begin_with_an_upper_case_character {
get {
return ResourceManager.GetString("The_first_word_0_must_begin_with_an_upper_case_character", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The member is defined in metadata..
/// </summary>
......@@ -2628,51 +2592,6 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to These non-leading words must begin with a lowercase letter: {0}.
/// </summary>
internal static string These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0 {
get {
return ResourceManager.GetString("These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These non-leading words must begin with an upper case letter: {0}.
/// </summary>
internal static string These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0 {
get {
return ResourceManager.GetString("These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words cannot contain lower case characters: {0}.
/// </summary>
internal static string These_words_cannot_contain_lower_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_cannot_contain_lower_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words cannot contain upper case characters: {0}.
/// </summary>
internal static string These_words_cannot_contain_upper_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_cannot_contain_upper_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words must begin with upper case characters: {0}.
/// </summary>
internal static string These_words_must_begin_with_upper_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_must_begin_with_upper_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This signature does not contain parameters that can be changed..
/// </summary>
......
......@@ -898,33 +898,6 @@ Do you want to continue?</value>
<value>Naming rule violation: {0}</value>
<comment>{0} is the rule title, {1} is the way in which the rule was violated</comment>
</data>
<data name="The_first_word_0_must_begin_with_a_lower_case_character" xml:space="preserve">
<value>The first word, '{0}', must begin with a lower case character</value>
</data>
<data name="The_first_word_0_must_begin_with_an_upper_case_character" xml:space="preserve">
<value>The first word, '{0}', must begin with an upper case character</value>
</data>
<data name="Missing_prefix_colon_0" xml:space="preserve">
<value>Missing prefix: '{0}'</value>
</data>
<data name="Missing_suffix_colon_0" xml:space="preserve">
<value>Missing suffix: '{0}'</value>
</data>
<data name="These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0" xml:space="preserve">
<value>These non-leading words must begin with a lowercase letter: {0}</value>
</data>
<data name="These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0" xml:space="preserve">
<value>These non-leading words must begin with an upper case letter: {0}</value>
</data>
<data name="These_words_cannot_contain_lower_case_characters_colon_0" xml:space="preserve">
<value>These words cannot contain lower case characters: {0}</value>
</data>
<data name="These_words_cannot_contain_upper_case_characters_colon_0" xml:space="preserve">
<value>These words cannot contain upper case characters: {0}</value>
</data>
<data name="These_words_must_begin_with_upper_case_characters_colon_0" xml:space="preserve">
<value>These words must begin with upper case characters: {0}</value>
</data>
<data name="Naming_Styles" xml:space="preserve">
<value>Naming Styles</value>
</data>
......
......@@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Completion;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.ExtractMethod;
......@@ -533,12 +534,18 @@ public string Style_NamingPreferences
{
get
{
return _workspace.Options.GetOption(SimplificationOptions.NamingPreferences, LanguageNames.CSharp);
return _workspace.Options.GetOption(SimplificationOptions.NamingPreferences, LanguageNames.CSharp).CreateXElement().ToString();
}
set
{
_workspace.Options = _workspace.Options.WithChangedOption(SimplificationOptions.NamingPreferences, LanguageNames.CSharp, value);
try
{
_workspace.Options = _workspace.Options.WithChangedOption(SimplificationOptions.NamingPreferences, LanguageNames.CSharp, NamingStylePreferences.FromXElement(XElement.Parse(value)));
}
catch (Exception)
{
}
}
}
......
......@@ -16,6 +16,7 @@
using Microsoft.VisualStudio.Settings;
using Microsoft.VisualStudio.Shell;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
{
......@@ -47,15 +48,15 @@ public RoamingVisualStudioProfileOptionPersister(IGlobalOptionService globalOpti
{
Contract.ThrowIfNull(globalOptionService);
this._settingManager = (ISettingsManager)serviceProvider.GetService(typeof(SVsSettingsPersistenceManager));
_settingManager = (ISettingsManager)serviceProvider.GetService(typeof(SVsSettingsPersistenceManager));
_globalOptionService = globalOptionService;
// While the settings persistence service should be available in all SKUs it is possible an ISO shell author has undefined the
// contributing package. In that case persistence of settings won't work (we don't bother with a backup solution for persistence
// as the scenario seems exceedingly unlikely), but we shouldn't crash the IDE.
if (this._settingManager != null)
if (_settingManager != null)
{
ISettingsSubset settingsSubset = this._settingManager.GetSubset("*");
var settingsSubset = _settingManager.GetSubset("*");
settingsSubset.SettingChangedAsync += OnSettingChangedAsync;
}
}
......@@ -81,7 +82,7 @@ private System.Threading.Tasks.Task OnSettingChangedAsync(object sender, Propert
public bool TryFetch(OptionKey optionKey, out object value)
{
if (this._settingManager == null)
if (_settingManager == null)
{
Debug.Fail("Manager field is unexpectedly null.");
value = null;
......@@ -101,7 +102,7 @@ public bool TryFetch(OptionKey optionKey, out object value)
RecordObservedValueToWatchForChanges(optionKey, storageKey);
value = this._settingManager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);
value = _settingManager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);
// VS's ISettingsManager has some quirks around storing enums. Specifically,
// it *can* persist and retrieve enums, but only if you properly call
......@@ -122,11 +123,38 @@ public bool TryFetch(OptionKey optionKey, out object value)
else if (optionKey.Option.Type == typeof(CodeStyleOption<bool>))
{
// We store these as strings, so deserialize
var serializedValue = value as string;
if (serializedValue != null)
if (value is string serializedValue)
{
try
{
value = CodeStyleOption<bool>.FromXElement(XElement.Parse(serializedValue));
}
catch (Exception)
{
value = null;
return false;
}
}
else
{
value = null;
return false;
}
}
else if (optionKey.Option.Type == typeof(NamingStylePreferences))
{
// We store these as strings, so deserialize
if (value is string serializedValue)
{
value = CodeStyleOption<bool>.FromXElement(XElement.Parse(serializedValue));
try
{
value = NamingStylePreferences.FromXElement(XElement.Parse(serializedValue));
}
catch (Exception)
{
value = null;
return false;
}
}
else
{
......@@ -172,7 +200,7 @@ private void RecordObservedValueToWatchForChanges(OptionKey optionKey, string st
public bool TryPersist(OptionKey optionKey, object value)
{
if (this._settingManager == null)
if (_settingManager == null)
{
Debug.Fail("Manager field is unexpectedly null.");
return false;
......@@ -201,8 +229,18 @@ public bool TryPersist(OptionKey optionKey, object value)
value = valueToSerialize.ToXElement().ToString();
}
}
else if (optionKey.Option.Type == typeof(NamingStylePreferences))
{
// We store these as strings, so serialize
var valueToSerialize = value as NamingStylePreferences;
if (value != null)
{
value = valueToSerialize.CreateXElement().ToString();
}
}
this._settingManager.SetValueAsync(storageKey, value, isMachineLocal: false);
_settingManager.SetValueAsync(storageKey, value, isMachineLocal: false);
return true;
}
}
......
......@@ -84,7 +84,7 @@ private void ManageStylesButton_Click(object sender, RoutedEventArgs e)
private void MoveUp_Click(object sender, EventArgs e)
{
int oldSelectedIndex = CodeStyleMembers.SelectedIndex;
var oldSelectedIndex = CodeStyleMembers.SelectedIndex;
if (oldSelectedIndex > 0)
{
_viewModel.MoveItem(oldSelectedIndex, oldSelectedIndex - 1);
......@@ -95,7 +95,7 @@ private void MoveUp_Click(object sender, EventArgs e)
private void MoveDown_Click(object sender, EventArgs e)
{
int oldSelectedIndex = CodeStyleMembers.SelectedIndex;
var oldSelectedIndex = CodeStyleMembers.SelectedIndex;
if (oldSelectedIndex < CodeStyleMembers.Items.Count - 1)
{
_viewModel.MoveItem(oldSelectedIndex, oldSelectedIndex + 1);
......@@ -115,7 +115,7 @@ private void SetFocusToSelectedRow()
{
if (CodeStyleMembers.SelectedIndex >= 0)
{
DataGridRow row = CodeStyleMembers.ItemContainerGenerator.ContainerFromIndex(CodeStyleMembers.SelectedIndex) as DataGridRow;
var row = CodeStyleMembers.ItemContainerGenerator.ContainerFromIndex(CodeStyleMembers.SelectedIndex) as DataGridRow;
if (row == null)
{
CodeStyleMembers.ScrollIntoView(CodeStyleMembers.SelectedItem);
......@@ -124,7 +124,7 @@ private void SetFocusToSelectedRow()
if (row != null)
{
DataGridCell cell = row.FindDescendant<DataGridCell>();
var cell = row.FindDescendant<DataGridCell>();
if (cell != null)
{
cell.Focus();
......@@ -135,7 +135,7 @@ private void SetFocusToSelectedRow()
internal override void SaveSettings()
{
var info = new SerializableNamingStylePreferencesInfo();
var info = new NamingStylePreferences();
foreach (var item in _viewModel.CodeStyleItems)
{
......@@ -165,7 +165,7 @@ internal override void SaveSettings()
}
var oldOptions = OptionService.GetOptions();
var newOptions = oldOptions.WithChangedOption(SimplificationOptions.NamingPreferences, _languageName, info.CreateXElement().ToString());
var newOptions = oldOptions.WithChangedOption(SimplificationOptions.NamingPreferences, _languageName, info);
OptionService.SetOptions(newOptions);
OptionLogger.Log(oldOptions, newOptions);
}
......@@ -174,16 +174,14 @@ internal override void LoadSettings()
{
base.LoadSettings();
var options = OptionService.GetOption(SimplificationOptions.NamingPreferences, _languageName);
if (string.IsNullOrEmpty(options))
var preferences = OptionService.GetOption(SimplificationOptions.NamingPreferences, _languageName);
if (preferences == null)
{
return;
}
var namingPreferencesXml = this.OptionService.GetOption(SimplificationOptions.NamingPreferences, _languageName);
var preferencesInfo = SerializableNamingStylePreferencesInfo.FromXElement(XElement.Parse(namingPreferencesXml));
_viewModel = new NamingStyleOptionPageViewModel(preferencesInfo);
this.DataContext = _viewModel;
_viewModel = new NamingStyleOptionPageViewModel(preferences);
DataContext = _viewModel;
}
internal bool ContainsErrors()
......
......@@ -28,17 +28,17 @@ internal class NamingStyleOptionPageViewModel : AbstractNotifyPropertyChanged
public ObservableCollection<SymbolSpecification> Specifications { get; set; }
public ObservableCollection<NamingStyle> NamingStyles { get; set; }
public NamingStyleOptionPageViewModel(SerializableNamingStylePreferencesInfo info)
public NamingStyleOptionPageViewModel(NamingStylePreferences info)
{
var viewModels = new List<NamingRuleViewModel>();
foreach (var namingRule in info.NamingRules)
{
var viewModel = new NamingRuleViewModel();
viewModel.NamingStyles = new ObservableCollection<NamingStyle>(info.NamingStyles);
viewModel.Specifications = new ObservableCollection<SymbolSpecification>(info.SymbolSpecifications);
viewModel.NotificationPreferences = new List<NotificationOptionViewModel>(_notifications);
var viewModel = new NamingRuleViewModel()
{
NamingStyles = new ObservableCollection<NamingStyle>(info.NamingStyles),
Specifications = new ObservableCollection<SymbolSpecification>(info.SymbolSpecifications),
NotificationPreferences = new List<NotificationOptionViewModel>(_notifications)
};
viewModel.SelectedSpecification = viewModel.Specifications.Single(s => s.ID == namingRule.SymbolSpecificationID);
viewModel.SelectedStyle= viewModel.NamingStyles.Single(s => s.ID == namingRule.NamingStyleID);
viewModel.SelectedNotificationPreference = viewModel.NotificationPreferences.Single(n => n.Notification.Value == namingRule.EnforcementLevel);
......@@ -87,11 +87,11 @@ internal void RemoveItem(NamingRuleViewModel namingRuleViewModel)
internal void UpdateSpecificationList(ManageSymbolSpecificationsDialogViewModel viewModel)
{
var symbolSpecifications = viewModel.Items.Cast<SymbolSpecificationViewModel>().Select(n => new SymbolSpecification(
n.ID,
n.ItemName,
n.SymbolKindList.Where(s => s.IsChecked).Select(k => k.CreateSymbolKindOrTypeKind()).ToList(),
n.AccessibilityList.Where(s => s.IsChecked).Select(a => new SymbolSpecification.AccessibilityKind(a._accessibility)).ToList(),
n.ModifierList.Where(s => s.IsChecked).Select(m => new SymbolSpecification.ModifierKind(m._modifier)).ToList()));
id: n.ID,
symbolSpecName: n.ItemName,
symbolKindList: n.SymbolKindList.Where(s => s.IsChecked).Select(k => k.CreateSymbolKindOrTypeKind()).ToList(),
accessibilityList: n.AccessibilityList.Where(s => s.IsChecked).Select(a => a._accessibility).ToList(),
modifiers: n.ModifierList.Where(s => s.IsChecked).Select(m => new SymbolSpecification.ModifierKind(m._modifier)).ToList()));
Specifications.Clear();
foreach (var specification in symbolSpecifications)
......@@ -132,7 +132,7 @@ internal void MoveItem(int oldSelectedIndex, int newSelectedIndex)
private void SetMoveArrowStatuses()
{
for (int i = 0; i < CodeStyleItems.Count; i++)
for (var i = 0; i < CodeStyleItems.Count; i++)
{
CodeStyleItems[i].CanMoveUp = true;
CodeStyleItems[i].CanMoveDown = true;
......
......@@ -18,12 +18,12 @@ public NamingStyleViewModel(NamingStyle style, bool canBeDeleted, INotificationS
{
_notificationService = notificationService;
_style = style;
this.ID = style.ID;
this.RequiredPrefix = style.Prefix;
this.RequiredSuffix = style.Suffix;
this.WordSeparator = style.WordSeparator;
this.ItemName = style.Name;
this.CanBeDeleted = canBeDeleted;
ID = style.ID;
RequiredPrefix = style.Prefix;
RequiredSuffix = style.Suffix;
WordSeparator = style.WordSeparator;
ItemName = style.Name;
CanBeDeleted = canBeDeleted;
CapitalizationSchemes = new List<CapitalizationDisplay>
{
......@@ -156,8 +156,8 @@ public class CapitalizationDisplay
public CapitalizationDisplay(Capitalization capitalization, string name)
{
this.Capitalization = capitalization;
this.Name = name;
Capitalization = capitalization;
Name = name;
}
}
}
......
......@@ -122,11 +122,11 @@ public string ItemName
internal SymbolSpecification GetSymbolSpecification()
{
return new SymbolSpecification(
ID,
ItemName,
SymbolKindList.Where(s => s.IsChecked).Select(s => s.CreateSymbolKindOrTypeKind()).ToList(),
AccessibilityList.Where(a => a.IsChecked).Select(a => new SymbolSpecification.AccessibilityKind(a._accessibility)).ToList(),
ModifierList.Where(m => m.IsChecked).Select(m => new ModifierKind(m._modifier)).ToList());
id: ID,
symbolSpecName: ItemName,
symbolKindList: SymbolKindList.Where(s => s.IsChecked).Select(s => s.CreateSymbolKindOrTypeKind()).ToList(),
accessibilityList: AccessibilityList.Where(a => a.IsChecked).Select(a => a._accessibility).ToList(),
modifiers: ModifierList.Where(m => m.IsChecked).Select(m => new ModifierKind(m._modifier)).ToList());
}
internal bool TrySubmit()
......@@ -161,14 +161,14 @@ public bool IsChecked
public SymbolKindViewModel(SymbolKind symbolKind, string name, SymbolSpecification specification)
{
this._symbolKind = symbolKind;
_symbolKind = symbolKind;
Name = name;
IsChecked = specification.ApplicableSymbolKindList.Any(k => k.SymbolKind == symbolKind);
}
public SymbolKindViewModel(TypeKind typeKind, string name, SymbolSpecification specification)
{
this._typeKind = typeKind;
_typeKind = typeKind;
Name = name;
IsChecked = specification.ApplicableSymbolKindList.Any(k => k.TypeKind == typeKind);
}
......@@ -204,7 +204,7 @@ public AccessibilityViewModel(Accessibility accessibility, string name, SymbolSp
_accessibility = accessibility;
Name = name;
IsChecked = specification.ApplicableAccessibilityList.Any(a => a.Accessibility == accessibility);
IsChecked = specification.ApplicableAccessibilityList.Any(a => a == accessibility);
}
}
......
......@@ -31,10 +31,10 @@ public static CodeStyleOption<bool> ParseEditorConfigCodeStyleOption(string arg)
switch (args[1].Trim())
{
case "silent": return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.None);
case "suggestion": return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Suggestion);
case "warning": return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Warning);
case "error": return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Error);
case EditorConfigSeverityStrings.Silent: return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.None);
case EditorConfigSeverityStrings.Suggestion: return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Suggestion);
case EditorConfigSeverityStrings.Warning: return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Warning);
case EditorConfigSeverityStrings.Error: return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.Error);
default: return new CodeStyleOption<bool>(value: isEnabled, notification: NotificationOption.None);
}
}
......
// 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;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Execution
......@@ -222,7 +223,6 @@ protected void WriteOptionSetTo(OptionSet options, string language, ObjectWriter
WriteOptionTo(options, language, CodeStyleOptions.QualifyEventAccess, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferCoalesceExpression, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferCollectionInitializer, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferExplicitTupleNames, writer, cancellationToken);
......@@ -230,6 +230,7 @@ protected void WriteOptionSetTo(OptionSet options, string language, ObjectWriter
WriteOptionTo(options, language, CodeStyleOptions.PreferNullPropagation, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferObjectInitializer, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferThrowExpression, writer, cancellationToken);
WriteOptionTo(options, language, SimplificationOptions.NamingPreferences, writer, cancellationToken);
}
protected OptionSet ReadOptionSetFrom(OptionSet options, string language, ObjectReader reader, CancellationToken cancellationToken)
......@@ -242,7 +243,6 @@ protected OptionSet ReadOptionSetFrom(OptionSet options, string language, Object
options = ReadOptionFrom(options, language, CodeStyleOptions.QualifyEventAccess, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferCoalesceExpression, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferCollectionInitializer, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferExplicitTupleNames, reader, cancellationToken);
......@@ -250,7 +250,7 @@ protected OptionSet ReadOptionSetFrom(OptionSet options, string language, Object
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferNullPropagation, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferObjectInitializer, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferThrowExpression, reader, cancellationToken);
options = ReadOptionFrom(options, language, SimplificationOptions.NamingPreferences, reader, cancellationToken);
return options;
}
......@@ -290,6 +290,55 @@ private OptionSet ReadOptionFrom<T>(OptionSet options, string language, PerLangu
return options.WithChangedOption(option, language, value);
}
protected void WriteOptionTo(OptionSet options, Option<NamingStylePreferences> option, ObjectWriter writer, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var value = options.GetOption(option);
writer.WriteString(value.CreateXElement().ToString());
}
protected OptionSet ReadOptionFrom(OptionSet options, Option<NamingStylePreferences> option, ObjectReader reader, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var xmlText = reader.ReadString();
try
{
var value = NamingStylePreferences.FromXElement(XElement.Parse(xmlText));
return options.WithChangedOption(option, value);
}
catch (System.Exception)
{
return options;
}
}
private void WriteOptionTo(OptionSet options, string language, PerLanguageOption<NamingStylePreferences> option, ObjectWriter writer, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var value = options.GetOption(option, language);
writer.WriteString(value.CreateXElement().ToString());
}
private OptionSet ReadOptionFrom(OptionSet options, string language, PerLanguageOption<NamingStylePreferences> option, ObjectReader reader, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var xmlText = reader.ReadString();
try
{
var value = NamingStylePreferences.FromXElement(XElement.Parse(xmlText));
return options.WithChangedOption(option, language, value);
}
catch (System.Exception)
{
return options;
}
}
/// <summary>
/// this is not real option set. it doesn't have all options defined in host. but only those
/// we pre-selected.
......
// 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.Linq;
using System.Runtime.CompilerServices;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static partial class EditorConfigNamingStyleParser
{
/// <remarks>
/// The dictionary we get from the VS editorconfig API uses the same dictionary object if there are no changes, so we can cache based on dictionary
/// </remarks>
private static readonly ConditionalWeakTable<IReadOnlyDictionary<string, object>, NamingStylePreferences> _cache = new ConditionalWeakTable<IReadOnlyDictionary<string, object>, NamingStylePreferences>();
private static readonly object _cacheLock = new object();
public static NamingStylePreferences GetNamingStylesFromDictionary(IReadOnlyDictionary<string, object> allRawConventions)
{
if (_cache.TryGetValue(allRawConventions, out var value))
{
return value;
}
lock (_cacheLock)
{
if (!_cache.TryGetValue(allRawConventions, out value))
{
value = ParseDictionary(allRawConventions);
_cache.Add(allRawConventions, value);
}
return value;
}
}
public static NamingStylePreferences ParseDictionary(IReadOnlyDictionary<string, object> allRawConventions)
{
var symbolSpecifications = new List<SymbolSpecification>();
var namingStyles = new List<NamingStyle>();
var namingRules = new List<SerializableNamingRule>();
var trimmedDictionary = TrimDictionary(allRawConventions);
foreach (var namingRuleTitle in GetRuleTitles(trimmedDictionary))
{
if (TryGetSymbolSpec(namingRuleTitle, trimmedDictionary, out var symbolSpec))
{
symbolSpecifications.Add(symbolSpec);
}
if (TryGetNamingStyleData(namingRuleTitle, trimmedDictionary, out var namingStyle))
{
namingStyles.Add(namingStyle);
}
if (TryGetSerializableNamingRule(namingRuleTitle, symbolSpec, namingStyle, trimmedDictionary, out var serializableNamingRule))
{
namingRules.Add(serializableNamingRule);
}
}
return new NamingStylePreferences(symbolSpecifications, namingStyles, namingRules);
}
private static Dictionary<string, object> TrimDictionary(IReadOnlyDictionary<string, object> allRawConventions)
{
var trimmedDictionary = new Dictionary<string, object>(allRawConventions.Count);
foreach (var item in allRawConventions)
{
var key = item.Key.Trim();
var value = item.Value;
trimmedDictionary[key] = value;
}
return trimmedDictionary;
}
private static IEnumerable<string> GetRuleTitles(IReadOnlyDictionary<string, object> allRawConventions)
=> (from kvp in allRawConventions
where kvp.Key.Trim().StartsWith("dotnet_naming_rule.", StringComparison.Ordinal)
let nameSplit = kvp.Key.Split('.')
where nameSplit.Length == 3
select nameSplit[1])
.Distinct();
}
}
// 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.Generic;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static partial class EditorConfigNamingStyleParser
{
private static bool TryGetSerializableNamingRule(
string namingRuleTitle,
SymbolSpecification symbolSpec,
NamingStyle namingStyle,
IReadOnlyDictionary<string, object> conventionsDictionary,
out SerializableNamingRule serializableNamingRule)
{
if(!TryGetRuleSeverity(namingRuleTitle, conventionsDictionary, out var severity))
{
serializableNamingRule = null;
return false;
}
serializableNamingRule = new SerializableNamingRule()
{
EnforcementLevel = severity,
NamingStyleID = namingStyle.ID,
SymbolSpecificationID = symbolSpec.ID
};
return true;
}
private static bool TryGetRuleSeverity(
string namingRuleName,
IReadOnlyDictionary<string, object> conventionsDictionary,
out DiagnosticSeverity severity)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_rule.{namingRuleName}.severity", out object result))
{
severity = ParseEnforcementLevel(result as string ?? string.Empty);
return true;
}
severity = default(DiagnosticSeverity);
return false;
}
private static DiagnosticSeverity ParseEnforcementLevel(string ruleSeverity)
{
switch (ruleSeverity)
{
case EditorConfigSeverityStrings.Silent: return DiagnosticSeverity.Hidden;
case EditorConfigSeverityStrings.Suggestion: return DiagnosticSeverity.Info;
case EditorConfigSeverityStrings.Warning: return DiagnosticSeverity.Warning;
case EditorConfigSeverityStrings.Error: return DiagnosticSeverity.Error;
default: return DiagnosticSeverity.Hidden;
}
}
}
}
// 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.Generic;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static partial class EditorConfigNamingStyleParser
{
private static bool TryGetNamingStyleData(
string namingRuleName,
IReadOnlyDictionary<string, object> allRawConventions,
out NamingStyle namingStyle)
{
namingStyle = null;
if (!TryGetNamingStyleTitle(namingRuleName, allRawConventions, out string namingStyleTitle))
{
return false;
}
var requiredPrefix = GetNamingRequiredPrefix(namingStyleTitle, allRawConventions);
var requiredSuffix = GetNamingRequiredSuffix(namingStyleTitle, allRawConventions);
var wordSeparator = GetNamingWordSeparator(namingStyleTitle, allRawConventions);
if(!TryGetNamingCapitalization(namingStyleTitle, allRawConventions, out var capitalization))
{
namingStyle = null;
return false;
}
namingStyle = new NamingStyle()
{
Name = namingStyleTitle,
Prefix = requiredPrefix,
Suffix = requiredSuffix,
WordSeparator = wordSeparator,
CapitalizationScheme = capitalization
};
return true;
}
private static bool TryGetNamingStyleTitle(
string namingRuleName,
IReadOnlyDictionary<string, object> conventionsDictionary,
out string namingStyleName)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_rule.{namingRuleName}.style", out object result))
{
namingStyleName = result as string;
return namingStyleName != null;
}
namingStyleName = null;
return false;
}
private static string GetNamingRequiredPrefix(string namingStyleName, IReadOnlyDictionary<string, object> conventionsDictionary)
=> GetStringFromConventionsDictionary(namingStyleName, "required_prefix", conventionsDictionary);
private static string GetNamingRequiredSuffix(string namingStyleName, IReadOnlyDictionary<string, object> conventionsDictionary)
=> GetStringFromConventionsDictionary(namingStyleName, "required_suffix", conventionsDictionary);
private static string GetNamingWordSeparator(string namingStyleName, IReadOnlyDictionary<string, object> conventionsDictionary)
=> GetStringFromConventionsDictionary(namingStyleName, "word_separator", conventionsDictionary);
private static bool TryGetNamingCapitalization(string namingStyleName, IReadOnlyDictionary<string, object> conventionsDictionary, out Capitalization capitalization)
{
var result = GetStringFromConventionsDictionary(namingStyleName, "capitalization", conventionsDictionary);
return TryParseCapitalizationScheme(result, out capitalization);
}
private static string GetStringFromConventionsDictionary(string namingStyleName, string optionName, IReadOnlyDictionary<string, object> conventionsDictionary)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_style.{namingStyleName}.{optionName}", out object result))
{
return result as string ?? string.Empty;
}
return string.Empty;
}
private static bool TryParseCapitalizationScheme(string namingStyleCapitalization, out Capitalization capitalization)
{
switch (namingStyleCapitalization)
{
case "pascal_case":
capitalization = Capitalization.PascalCase;
return true;
case "camel_case":
capitalization = Capitalization.CamelCase;
return true;
case "first_word_upper":
capitalization = Capitalization.FirstUpper;
return true;
case "all_upper":
capitalization = Capitalization.AllUpper;
return true;
case "all_lower":
capitalization = Capitalization.AllLower;
return true;
default:
capitalization = default(Capitalization);
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;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using static Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles.SymbolSpecification;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static partial class EditorConfigNamingStyleParser
{
private static bool TryGetSymbolSpec(
string namingRuleTitle,
IReadOnlyDictionary<string, object> conventionsDictionary,
out SymbolSpecification symbolSpec)
{
symbolSpec = null;
if (!TryGetSymbolSpecNameForNamingRule(namingRuleTitle, conventionsDictionary, out string symbolSpecName))
{
return false;
}
var applicableKinds = GetSymbolsApplicableKinds(symbolSpecName, conventionsDictionary);
var applicableAccessibilities = GetSymbolsApplicableAccessibilities(symbolSpecName, conventionsDictionary);
var requiredModifiers = GetSymbolsRequiredModifiers(symbolSpecName, conventionsDictionary);
symbolSpec = new SymbolSpecification(
symbolSpecName,
symbolKindList: applicableKinds,
accessibilityList: applicableAccessibilities,
modifiers: requiredModifiers);
return true;
}
private static bool TryGetSymbolSpecNameForNamingRule(
string namingRuleName,
IReadOnlyDictionary<string, object> conventionsDictionary,
out string symbolSpecName)
{
symbolSpecName = null;
if (conventionsDictionary.TryGetValue($"dotnet_naming_rule.{namingRuleName}.symbols", out object result))
{
symbolSpecName = result as string;
return symbolSpecName != null;
}
return false;
}
private static ImmutableArray<SymbolKindOrTypeKind> GetSymbolsApplicableKinds(
string symbolSpecName,
IReadOnlyDictionary<string, object> conventionsDictionary)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_symbols.{symbolSpecName}.applicable_kinds", out object result))
{
return ParseSymbolKindList(result as string ?? string.Empty);
}
return ImmutableArray<SymbolKindOrTypeKind>.Empty;
}
private static readonly SymbolKindOrTypeKind _class = new SymbolKindOrTypeKind(TypeKind.Class);
private static readonly SymbolKindOrTypeKind _struct = new SymbolKindOrTypeKind(TypeKind.Struct);
private static readonly SymbolKindOrTypeKind _interface = new SymbolKindOrTypeKind(TypeKind.Interface);
private static readonly SymbolKindOrTypeKind _enum = new SymbolKindOrTypeKind(TypeKind.Enum);
private static readonly SymbolKindOrTypeKind _property = new SymbolKindOrTypeKind(SymbolKind.Property);
private static readonly SymbolKindOrTypeKind _method = new SymbolKindOrTypeKind(SymbolKind.Method);
private static readonly SymbolKindOrTypeKind _field = new SymbolKindOrTypeKind(SymbolKind.Field);
private static readonly SymbolKindOrTypeKind _event = new SymbolKindOrTypeKind(SymbolKind.Event);
private static readonly SymbolKindOrTypeKind _delegate = new SymbolKindOrTypeKind(TypeKind.Delegate);
private static readonly ImmutableArray<SymbolKindOrTypeKind> _all = ImmutableArray.Create(_class, _struct, _interface, _enum, _property, _method, _field, _event, _delegate);
private static ImmutableArray<SymbolKindOrTypeKind> ParseSymbolKindList(string symbolSpecApplicableKinds)
{
if (symbolSpecApplicableKinds == null)
{
return ImmutableArray<SymbolKindOrTypeKind>.Empty;
}
if (symbolSpecApplicableKinds.Trim() == "*")
{
return _all;
}
var builder = ArrayBuilder<SymbolKindOrTypeKind>.GetInstance();
foreach (var symbolSpecApplicableKind in symbolSpecApplicableKinds.Split(',').Select(x => x.Trim()))
{
switch (symbolSpecApplicableKind)
{
case "class":
builder.Add(_class);
break;
case "struct":
builder.Add(_struct);
break;
case "interface":
builder.Add(_interface);
break;
case "enum":
builder.Add(_enum);
break;
case "property":
builder.Add(_property);
break;
case "method":
builder.Add(_method);
break;
case "field":
builder.Add(_field);
break;
case "event":
builder.Add(_event);
break;
case "delegate":
builder.Add(_delegate);
break;
default:
break;
}
}
return builder.ToImmutableAndFree();
}
private static ImmutableArray<Accessibility> GetSymbolsApplicableAccessibilities(
string symbolSpecName,
IReadOnlyDictionary<string, object> conventionsDictionary)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_symbols.{symbolSpecName}.applicable_accessibilities", out object result))
{
return ParseAccessibilityKindList(result as string ?? string.Empty);
}
return ImmutableArray<Accessibility>.Empty;
}
private static readonly ImmutableArray<Accessibility> _allAccessibility = ImmutableArray.Create(Accessibility.Public, Accessibility.Internal, Accessibility.Private, Accessibility.Protected, Accessibility.ProtectedOrInternal);
private static ImmutableArray<Accessibility> ParseAccessibilityKindList(string symbolSpecApplicableAccessibilities)
{
if (symbolSpecApplicableAccessibilities == null)
{
return ImmutableArray<Accessibility>.Empty;
}
if (symbolSpecApplicableAccessibilities.Trim() == "*")
{
return _allAccessibility;
}
var builder = ArrayBuilder<Accessibility>.GetInstance();
foreach (var symbolSpecApplicableAccessibility in symbolSpecApplicableAccessibilities.Split(',').Select(x => x.Trim()))
{
switch (symbolSpecApplicableAccessibility)
{
case "public":
builder.Add(Accessibility.Public);
break;
case "internal":
case "friend":
builder.Add(Accessibility.Internal);
break;
case "private":
builder.Add(Accessibility.Private);
break;
case "protected":
builder.Add(Accessibility.Protected);
break;
case "protected_internal":
case "protected_friend":
builder.Add(Accessibility.ProtectedOrInternal);
break;
default:
break;
}
}
return builder.ToImmutableAndFree();
}
private static ImmutableArray<ModifierKind> GetSymbolsRequiredModifiers(
string symbolSpecName,
IReadOnlyDictionary<string, object> conventionsDictionary)
{
if (conventionsDictionary.TryGetValue($"dotnet_naming_symbols.{symbolSpecName}.required_modifiers", out object result))
{
return ParseModifiers(result as string ?? string.Empty);
}
return ImmutableArray<ModifierKind>.Empty;
}
private static readonly ModifierKind _abstractModifierKind = new ModifierKind(ModifierKindEnum.IsAbstract);
private static readonly ModifierKind _asyncModifierKind = new ModifierKind(ModifierKindEnum.IsAsync);
private static readonly ModifierKind _constModifierKind = new ModifierKind(ModifierKindEnum.IsConst);
private static readonly ModifierKind _readonlyModifierKind = new ModifierKind(ModifierKindEnum.IsReadOnly);
private static readonly ModifierKind _staticModifierKind = new ModifierKind(ModifierKindEnum.IsStatic);
private static readonly ImmutableArray<ModifierKind> _allModifierKind = ImmutableArray.Create(_abstractModifierKind, _asyncModifierKind, _constModifierKind, _readonlyModifierKind, _staticModifierKind);
private static ImmutableArray<ModifierKind> ParseModifiers(string symbolSpecRequiredModifiers)
{
if (symbolSpecRequiredModifiers == null)
{
return ImmutableArray<ModifierKind>.Empty;
}
if (symbolSpecRequiredModifiers.Trim() == "*")
{
return _allModifierKind;
}
var builder = ArrayBuilder<ModifierKind>.GetInstance();
foreach (var symbolSpecRequiredModifier in symbolSpecRequiredModifiers.Split(',').Select(x => x.Trim()))
{
switch (symbolSpecRequiredModifier)
{
case "abstract":
case "must_inherit ":
builder.Add(_abstractModifierKind);
break;
case "async":
builder.Add(_asyncModifierKind);
break;
case "const":
builder.Add(_constModifierKind);
break;
case "readonly":
builder.Add(_readonlyModifierKind);
break;
case "static":
case "shared":
builder.Add(_staticModifierKind);
break;
default:
break;
}
}
return builder.ToImmutableAndFree();
}
}
}
// 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
{
internal static class EditorConfigSeverityStrings
{
public const string Silent = "silent";
public const string Suggestion = "suggestion";
public const string Warning = "warning";
public const string Error = "error";
}
}
......@@ -5,11 +5,11 @@
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal class NamingStylePreferencesInfo
internal class NamingStyleRules
{
public ImmutableArray<NamingRule> NamingRules { get; }
public NamingStylePreferencesInfo(ImmutableArray<NamingRule> namingRules)
public NamingStyleRules(ImmutableArray<NamingRule> namingRules)
{
NamingRules = namingRules;
}
......@@ -45,8 +45,7 @@ private bool IsSymbolNameAnalyzable(ISymbol symbol)
{
if (symbol.Kind == SymbolKind.Method)
{
var methodSymbol = symbol as IMethodSymbol;
if (methodSymbol != null && methodSymbol.MethodKind != MethodKind.Ordinary)
if (symbol is IMethodSymbol methodSymbol && methodSymbol.MethodKind != MethodKind.Ordinary)
{
return false;
}
......@@ -54,8 +53,7 @@ private bool IsSymbolNameAnalyzable(ISymbol symbol)
if (symbol.Kind == SymbolKind.Property)
{
var propertySymbol = symbol as IPropertySymbol;
if (propertySymbol != null && propertySymbol.IsIndexer)
if (symbol is IPropertySymbol propertySymbol && propertySymbol.IsIndexer)
{
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;
using System.Xml.Linq;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
internal static class AccessibilityExtensions
{
internal static bool MatchesSymbol(this Accessibility accessibility, ISymbol symbol)
{
return symbol.DeclaredAccessibility == accessibility;
}
internal static XElement CreateXElement(this Accessibility accessibility)
{
return new XElement("AccessibilityKind", accessibility);
}
internal static Accessibility FromXElement(XElement accessibilityElement)
{
return (Accessibility)Enum.Parse(typeof(Accessibility), accessibilityElement.Value);
}
}
}
\ No newline at end of file
......@@ -68,13 +68,13 @@ public bool IsNameCompliant(string name, out string failureReason)
if (!name.StartsWith(Prefix))
{
failureReason = string.Format(FeaturesResources.Missing_prefix_colon_0, Prefix);
failureReason = string.Format(WorkspacesResources.Missing_prefix_colon_0, Prefix);
return false;
}
if (!name.EndsWith(Suffix))
{
failureReason = string.Format(FeaturesResources.Missing_suffix_colon_0, Suffix);
failureReason = string.Format(WorkspacesResources.Missing_suffix_colon_0, Suffix);
return false;
}
......@@ -104,7 +104,7 @@ public bool IsNameCompliant(string name, out string failureReason)
else
{
var violations = words.Where(w => !char.IsUpper(w[0]));
failureReason = string.Format(FeaturesResources.These_words_must_begin_with_upper_case_characters_colon_0, string.Join(", ", violations));
failureReason = string.Format(WorkspacesResources.These_words_must_begin_with_upper_case_characters_colon_0, string.Join(", ", violations));
return false;
}
case Capitalization.CamelCase:
......@@ -116,7 +116,7 @@ public bool IsNameCompliant(string name, out string failureReason)
{
if (!char.IsLower(words.First()[0]))
{
failureReason = string.Format(FeaturesResources.The_first_word_0_must_begin_with_a_lower_case_character, words.First());
failureReason = string.Format(WorkspacesResources.The_first_word_0_must_begin_with_a_lower_case_character, words.First());
}
var violations = words.Skip(1).Where(w => !char.IsUpper(w[0]));
......@@ -127,7 +127,7 @@ public bool IsNameCompliant(string name, out string failureReason)
failureReason += Environment.NewLine;
}
failureReason += string.Format(FeaturesResources.These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0, string.Join(", ", violations));
failureReason += string.Format(WorkspacesResources.These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0, string.Join(", ", violations));
}
return false;
......@@ -141,7 +141,7 @@ public bool IsNameCompliant(string name, out string failureReason)
{
if (!char.IsUpper(words.First()[0]))
{
failureReason = string.Format(FeaturesResources.The_first_word_0_must_begin_with_an_upper_case_character, words.First());
failureReason = string.Format(WorkspacesResources.The_first_word_0_must_begin_with_an_upper_case_character, words.First());
}
var violations = words.Skip(1).Where(w => !char.IsLower(w[0]));
......@@ -152,7 +152,7 @@ public bool IsNameCompliant(string name, out string failureReason)
failureReason += Environment.NewLine;
}
failureReason += string.Format(FeaturesResources.These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0, string.Join(", ", violations));
failureReason += string.Format(WorkspacesResources.These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0, string.Join(", ", violations));
}
return false;
......@@ -165,7 +165,7 @@ public bool IsNameCompliant(string name, out string failureReason)
else
{
var violations = words.Where(w => !w.ToCharArray().All(c => char.IsUpper(c)));
failureReason = string.Format(FeaturesResources.These_words_cannot_contain_lower_case_characters_colon_0, string.Join(", ", violations));
failureReason = string.Format(WorkspacesResources.These_words_cannot_contain_lower_case_characters_colon_0, string.Join(", ", violations));
return false;
}
case Capitalization.AllLower:
......@@ -176,7 +176,7 @@ public bool IsNameCompliant(string name, out string failureReason)
else
{
var violations = words.Where(w => !w.ToCharArray().All(c => char.IsLower(c)));
failureReason = string.Format(FeaturesResources.These_words_cannot_contain_upper_case_characters_colon_0, string.Join(", ", violations));
failureReason = string.Format(WorkspacesResources.These_words_cannot_contain_upper_case_characters_colon_0, string.Join(", ", violations));
return false;
}
default:
......
// 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 Microsoft.CodeAnalysis.Simplification;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
/// <summary>
/// Contains all information related to Naming Style Preferences.
/// 1. Symbol Specifications
/// 2. Name Style
/// 3. Naming Rule (points to Symbol Specification IDs)
/// </summary>
internal class NamingStylePreferences : IEquatable<NamingStylePreferences>
{
public List<SymbolSpecification> SymbolSpecifications;
public List<NamingStyle> NamingStyles;
public List<SerializableNamingRule> NamingRules;
private readonly static int s_serializationVersion = 3;
internal NamingStylePreferences(List<SymbolSpecification> symbolSpecifications, List<NamingStyle> namingStyles, List<SerializableNamingRule> namingRules)
{
SymbolSpecifications = symbolSpecifications;
NamingStyles = namingStyles;
NamingRules = namingRules;
}
internal NamingStylePreferences()
{
SymbolSpecifications = new List<SymbolSpecification>();
NamingStyles = new List<NamingStyle>();
NamingRules = new List<SerializableNamingRule>();
}
public static NamingStylePreferences Default => FromXElement(XElement.Parse(DefaultNamingPreferencesString));
public static string DefaultNamingPreferencesString => _defaultNamingPreferencesString;
internal NamingStyle GetNamingStyle(Guid namingStyleID)
{
return NamingStyles.Single(s => s.ID == namingStyleID);
}
internal SymbolSpecification GetSymbolSpecification(Guid symbolSpecificationID)
{
return SymbolSpecifications.Single(s => s.ID == symbolSpecificationID);
}
public NamingStyleRules GetNamingStyleRules()
{
return new NamingStyleRules(NamingRules.Select(r => r.GetRule(this)).ToImmutableArray());
}
internal XElement CreateXElement()
{
return new XElement("NamingPreferencesInfo",
new XAttribute("SerializationVersion", s_serializationVersion),
CreateSymbolSpecificationListXElement(),
CreateNamingStyleListXElement(),
CreateNamingRuleTreeXElement());
}
private XElement CreateNamingRuleTreeXElement()
{
var namingRulesElement = new XElement(nameof(NamingRules));
foreach (var namingRule in NamingRules)
{
namingRulesElement.Add(namingRule.CreateXElement());
}
return namingRulesElement;
}
private XElement CreateNamingStyleListXElement()
{
var namingStylesElement = new XElement(nameof(NamingStyles));
foreach (var namingStyle in NamingStyles)
{
namingStylesElement.Add(namingStyle.CreateXElement());
}
return namingStylesElement;
}
private XElement CreateSymbolSpecificationListXElement()
{
var symbolSpecificationsElement = new XElement(nameof(SymbolSpecifications));
foreach (var symbolSpecification in SymbolSpecifications)
{
symbolSpecificationsElement.Add(symbolSpecification.CreateXElement());
}
return symbolSpecificationsElement;
}
internal static NamingStylePreferences FromXElement(XElement namingPreferencesInfoElement)
{
var namingPreferencesInfo = new NamingStylePreferences();
var serializationVersion = int.Parse(namingPreferencesInfoElement.Attribute("SerializationVersion").Value);
if (serializationVersion != s_serializationVersion)
{
namingPreferencesInfoElement = XElement.Parse(DefaultNamingPreferencesString);
}
namingPreferencesInfo.SetSymbolSpecificationListFromXElement(namingPreferencesInfoElement.Element(nameof(SymbolSpecifications)));
namingPreferencesInfo.SetNamingStyleListFromXElement(namingPreferencesInfoElement.Element(nameof(NamingStyles)));
namingPreferencesInfo.SetNamingRuleTreeFromXElement(namingPreferencesInfoElement.Element(nameof(NamingRules)));
return namingPreferencesInfo;
}
private void SetSymbolSpecificationListFromXElement(XElement symbolSpecificationsElement)
{
foreach (var symbolSpecificationElement in symbolSpecificationsElement.Elements(nameof(SymbolSpecification)))
{
SymbolSpecifications.Add(SymbolSpecification.FromXElement(symbolSpecificationElement));
}
}
private void SetNamingStyleListFromXElement(XElement namingStylesElement)
{
foreach (var namingStyleElement in namingStylesElement.Elements(nameof(NamingStyle)))
{
NamingStyles.Add(NamingStyle.FromXElement(namingStyleElement));
}
}
private void SetNamingRuleTreeFromXElement(XElement namingRulesElement)
{
foreach (var namingRuleElement in namingRulesElement.Elements(nameof(SerializableNamingRule)))
{
NamingRules.Add(SerializableNamingRule.FromXElement(namingRuleElement));
}
}
public override bool Equals(object obj)
=> Equals(obj as NamingStylePreferences);
public bool Equals(NamingStylePreferences other)
{
if (object.ReferenceEquals(other, null))
{
return false;
}
return CreateXElement().ToString() == other.CreateXElement().ToString();
}
public static bool operator ==(NamingStylePreferences left, NamingStylePreferences right)
{
var leftIsNull = object.ReferenceEquals(left, null);
var rightIsNull = object.ReferenceEquals(right, null);
if (leftIsNull && rightIsNull)
{
return true;
}
else if(leftIsNull)
{
return false;
}
else if(rightIsNull)
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(NamingStylePreferences left, NamingStylePreferences right)
=> !(left == right);
public override int GetHashCode()
=> CreateXElement().ToString().GetHashCode();
private static readonly string _defaultNamingPreferencesString = $@"
<NamingPreferencesInfo SerializationVersion=""3"">
<SymbolSpecifications>
<SymbolSpecification ID=""5c545a62-b14d-460a-88d8-e936c0a39316"" Name=""{WorkspacesResources.Class}"">
<ApplicableSymbolKindList>
<TypeKind>Class</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""23d856b4-5089-4405-83ce-749aada99153"" Name=""{WorkspacesResources.Interface}"">
<ApplicableSymbolKindList>
<TypeKind>Interface</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""d1796e78-ff66-463f-8576-eb46416060c0"" Name=""{WorkspacesResources.Struct}"">
<ApplicableSymbolKindList>
<TypeKind>Struct</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""d8af8dc6-1ade-441d-9947-8946922e198a"" Name=""{WorkspacesResources.Enum}"">
<ApplicableSymbolKindList>
<TypeKind>Enum</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""408a3347-b908-4b54-a954-1355e64c1de3"" Name=""{WorkspacesResources.Delegate}"">
<ApplicableSymbolKindList>
<TypeKind>Delegate</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""830657f6-e7e5-4830-b328-f109d3b6c165"" Name=""{WorkspacesResources.Event}"">
<ApplicableSymbolKindList>
<SymbolKind>Event</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""390caed4-f0a9-42bb-adbb-b44c4a302a22"" Name=""{WorkspacesResources.Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""af410767-f189-47c6-b140-aeccf1ff242e"" Name=""{WorkspacesResources.Private_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""8076757e-6a4a-47f1-9b4b-ae8a3284e987"" Name=""{WorkspacesResources.Abstract_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsAbstract</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""16133061-a8e7-4392-92c3-1d93cd54c218"" Name=""{WorkspacesResources.Static_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""03a274df-b686-4a76-9138-96aecb9bd33b"" Name=""{WorkspacesResources.Async_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsAsync</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""da6a2919-5aa6-4ad1-a24d-576776ed3974"" Name=""{WorkspacesResources.Property}"">
<ApplicableSymbolKindList>
<SymbolKind>Property</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""b24a91ce-3501-4799-b6df-baf044156c83"" Name=""{WorkspacesResources.Public_or_Protected_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""70af42cb-1741-4027-969c-9edc4877d965"" Name=""{WorkspacesResources.Static_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""10790aa6-0a0b-432d-a52d-d252ca92302b"" Name=""{WorkspacesResources.Private_or_Internal_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""ac995be4-88de-4771-9dcc-a456a7c02d89"" Name=""{WorkspacesResources.Private_or_Internal_Static_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""2c07f5bf-bc81-4c2b-82b4-ae9b3ffd0ba4"" Name=""{WorkspacesResources.Types}"">
<ApplicableSymbolKindList>
<TypeKind>Class</TypeKind>
<TypeKind>Struct</TypeKind>
<TypeKind>Interface</TypeKind>
<TypeKind>Enum</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""5f3ddba1-279f-486c-801e-5c097c36dd85"" Name=""{WorkspacesResources.Non_Field_Members}"">
<ApplicableSymbolKindList>
<SymbolKind>Property</SymbolKind>
<SymbolKind>Method</SymbolKind>
<SymbolKind>Event</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
</SymbolSpecifications>
<NamingStyles>
<NamingStyle ID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" Name=""{WorkspacesResources.Pascal_Case}"" Prefix="""" Suffix="""" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
<NamingStyle ID=""308152f2-a334-48b3-8bec-ddee40785feb"" Name=""{WorkspacesResources.Ends_with_Async}"" Prefix="""" Suffix=""Async"" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
<NamingStyle ID=""1ecc5eb6-b5fc-49a5-a9f1-a980f3e48c92"" Name=""{WorkspacesResources.Begins_with_I}"" Prefix=""I"" Suffix="""" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
</NamingStyles>
<NamingRules>
<SerializableNamingRule SymbolSpecificationID=""23d856b4-5089-4405-83ce-749aada99153"" NamingStyleID=""1ecc5eb6-b5fc-49a5-a9f1-a980f3e48c92"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""2c07f5bf-bc81-4c2b-82b4-ae9b3ffd0ba4"" NamingStyleID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""03a274df-b686-4a76-9138-96aecb9bd33b"" NamingStyleID=""308152f2-a334-48b3-8bec-ddee40785feb"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""5f3ddba1-279f-486c-801e-5c097c36dd85"" NamingStyleID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" EnforcementLevel=""Info"" />
</NamingRules>
</NamingPreferencesInfo>
";
}
}
......@@ -11,7 +11,7 @@ internal class SerializableNamingRule
public Guid NamingStyleID;
public DiagnosticSeverity EnforcementLevel;
public NamingRule GetRule(SerializableNamingStylePreferencesInfo info)
public NamingRule GetRule(NamingStylePreferences info)
{
return new NamingRule(
info.GetSymbolSpecification(SymbolSpecificationID),
......
......@@ -6,6 +6,7 @@
using System.Xml.Linq;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles
{
......@@ -15,7 +16,7 @@ internal class SymbolSpecification
public string Name { get; private set; }
public IList<SymbolKindOrTypeKind> ApplicableSymbolKindList { get; private set; }
public IList<AccessibilityKind> ApplicableAccessibilityList { get; private set; }
public IList<Accessibility> ApplicableAccessibilityList { get; private set; }
public IList<ModifierKind> RequiredModifierList { get; private set; }
internal SymbolSpecification()
......@@ -39,27 +40,28 @@ internal SymbolSpecification()
new SymbolKindOrTypeKind(SymbolKind.Event),
};
ApplicableAccessibilityList = new List<AccessibilityKind>
ApplicableAccessibilityList = new List<Accessibility>
{
new AccessibilityKind(Accessibility.Public),
new AccessibilityKind(Accessibility.Internal),
new AccessibilityKind(Accessibility.Private),
new AccessibilityKind(Accessibility.Protected),
new AccessibilityKind(Accessibility.ProtectedAndInternal),
new AccessibilityKind(Accessibility.ProtectedOrInternal),
Accessibility.Public,
Accessibility.Internal,
Accessibility.Private,
Accessibility.Protected,
Accessibility.ProtectedAndInternal,
Accessibility.ProtectedOrInternal,
};
RequiredModifierList = new List<ModifierKind>();
}
public SymbolSpecification(Guid id, string symbolSpecName,
public SymbolSpecification(string symbolSpecName,
IList<SymbolKindOrTypeKind> symbolKindList,
IList<AccessibilityKind> accessibilityKindList,
IList<ModifierKind> modifiers)
IList<Accessibility> accessibilityList,
IList<ModifierKind> modifiers,
Guid? id = null)
{
ID = id;
ID = id ?? Guid.NewGuid();
Name = symbolSpecName;
ApplicableAccessibilityList = accessibilityKindList;
ApplicableAccessibilityList = accessibilityList;
RequiredModifierList = modifiers;
ApplicableSymbolKindList = symbolKindList;
}
......@@ -162,10 +164,10 @@ private void PopulateSymbolKindListFromXElement(XElement symbolKindListElement)
private void PopulateAccessibilityListFromXElement(XElement accessibilityListElement)
{
var applicableAccessibilityList = new List<AccessibilityKind>();
foreach (var accessibilityElement in accessibilityListElement.Elements(nameof(AccessibilityKind)))
var applicableAccessibilityList = new List<Accessibility>();
foreach (var accessibilityElement in accessibilityListElement.Elements("AccessibilityKind"))
{
applicableAccessibilityList.Add(AccessibilityKind.FromXElement(accessibilityElement));
applicableAccessibilityList.Add(AccessibilityExtensions.FromXElement(accessibilityElement));
}
ApplicableAccessibilityList = applicableAccessibilityList;
}
......@@ -179,7 +181,7 @@ private void PopulateModifierListFromXElement(XElement modifierListElement)
}
}
public class SymbolKindOrTypeKind
public struct SymbolKindOrTypeKind : IEquatable<SymbolKindOrTypeKind>
{
public SymbolKind? SymbolKind { get; set; }
public TypeKind? TypeKind { get; set; }
......@@ -187,10 +189,12 @@ public class SymbolKindOrTypeKind
public SymbolKindOrTypeKind(SymbolKind symbolKind)
{
SymbolKind = symbolKind;
TypeKind = null;
}
public SymbolKindOrTypeKind(TypeKind typeKind)
{
SymbolKind = null;
TypeKind = typeKind;
}
......@@ -228,34 +232,36 @@ internal static SymbolKindOrTypeKind AddTypeKindFromXElement(XElement typeKindEl
{
return new SymbolKindOrTypeKind((TypeKind)Enum.Parse(typeof(TypeKind), typeKindElement.Value));
}
}
public class AccessibilityKind
{
public Accessibility Accessibility { get; set; }
public AccessibilityKind(Accessibility accessibility)
public override bool Equals(object obj)
{
Accessibility = accessibility;
}
if (obj is SymbolKindOrTypeKind symbolKindOrTypeKind)
{
return Equals(symbolKindOrTypeKind);
}
public bool MatchesSymbol(ISymbol symbol)
{
return symbol.DeclaredAccessibility == Accessibility;
return false;
}
internal XElement CreateXElement()
public bool Equals(SymbolKindOrTypeKind other)
{
return new XElement(nameof(AccessibilityKind), Accessibility);
return SymbolKind == other.SymbolKind &&
TypeKind == other.TypeKind;
}
internal static AccessibilityKind FromXElement(XElement accessibilityElement)
public static bool operator ==(SymbolKindOrTypeKind left, SymbolKindOrTypeKind right)
=> left.Equals(right);
public static bool operator !=(SymbolKindOrTypeKind left, SymbolKindOrTypeKind right)
=> !left.Equals(right);
public override int GetHashCode()
{
return new AccessibilityKind((Accessibility)Enum.Parse(typeof(Accessibility), accessibilityElement.Value));
return Hash.Combine(SymbolKind.GetHashCode(), TypeKind.GetHashCode());
}
}
public class ModifierKind
public struct ModifierKind : IEquatable<ModifierKind>
{
public ModifierKindEnum ModifierKindWrapper;
......@@ -309,11 +315,14 @@ internal DeclarationModifiers Modifier
public ModifierKind(DeclarationModifiers modifier)
{
this.Modifier = modifier;
ModifierKindWrapper = default(ModifierKindEnum);
_modifier = default(DeclarationModifiers);
Modifier = modifier;
}
public ModifierKind(ModifierKindEnum modifierKind)
{
_modifier = default(DeclarationModifiers);
ModifierKindWrapper = modifierKind;
}
......@@ -356,6 +365,32 @@ internal static ModifierKind FromXElement(XElement modifierElement)
{
return new ModifierKind((ModifierKindEnum)(ModifierKindEnum)Enum.Parse((Type)typeof(ModifierKindEnum), (string)modifierElement.Value));
}
public override bool Equals(object obj)
{
if (obj is ModifierKind modifierKind)
{
return Equals(modifierKind);
}
return false;
}
public bool Equals(ModifierKind other)
{
return Modifier == other.Modifier;
}
public static bool operator ==(ModifierKind left, ModifierKind right)
=> left.Equals(right);
public static bool operator !=(ModifierKind left, ModifierKind right)
=> !left.Equals(right);
public override int GetHashCode()
{
return Modifier.GetHashCode();
}
}
public enum ModifierKindEnum
{
......
// 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 Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using static Microsoft.CodeAnalysis.CodeStyle.CodeStyleHelpers;
namespace Microsoft.CodeAnalysis.Options
......@@ -15,7 +17,27 @@ internal sealed class EditorConfigStorageLocation : OptionStorageLocation
private Func<string, Type, object> _parseValue;
public object ParseValue(string s, Type type) => _parseValue(s, type);
private Func<IReadOnlyDictionary<string, object>, Type, object> _parseDictionary;
public bool TryParseReadonlyDictionary(IReadOnlyDictionary<string, object> allRawConventions, Type type, out object result)
{
if (_parseValue != null && KeyName != null)
{
if (allRawConventions.TryGetValue(KeyName, out object value))
{
result = _parseValue(value.ToString(), type);
return true;
}
}
else if (_parseDictionary != null)
{
result = _parseDictionary(allRawConventions, type);
return true;
}
result = null;
return false;
}
public EditorConfigStorageLocation(string keyName)
{
......@@ -49,5 +71,27 @@ public EditorConfigStorageLocation(string keyName, Func<string, object> parseVal
// If we're explicitly given a parsing function we can throw away the type when parsing
_parseValue = (s, type) => parseValue(s);
}
public EditorConfigStorageLocation()
{
// If the user didn't pass a keyName assume we need to parse the entire dictionary
_parseDictionary = (dictionary, type) =>
{
if (type == typeof(NamingStylePreferences))
{
return EditorConfigNamingStyleParser.GetNamingStylesFromDictionary(dictionary);
}
else
{
throw new NotSupportedException(WorkspacesResources.Option_0_has_an_unsupported_type_to_use_with_1_You_should_specify_a_parsing_function);
}
};
}
public EditorConfigStorageLocation(Func<IReadOnlyDictionary<string, object>, object> parseDictionary)
{
// If we're explicitly given a parsing function we can throw away the type when parsing
_parseDictionary = (dictionary, type) => parseDictionary(dictionary);
}
}
}
......@@ -84,7 +84,6 @@ override Microsoft.CodeAnalysis.Options.DocumentOptionSet.WithChangedOption(Micr
override Microsoft.CodeAnalysis.XmlDocumentationProvider.GetDocumentationForSymbol(string documentationMemberID, System.Globalization.CultureInfo preferredCulture, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.Default.get -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.FromXElement(System.Xml.Linq.XElement element) -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.NamingPreferences.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<string>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyEventAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyFieldAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyMethodAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
......
// 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 Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Simplification
......@@ -66,21 +67,21 @@ public static class SimplificationOptions
/// This option says if we should simplify away the <see langword="this"/>. or <see langword="Me"/>. in property access expressions.
/// </summary>
[Obsolete]
public static PerLanguageOption<bool> QualifyPropertyAccess{ get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyPropertyAccess), defaultValue: false,
public static PerLanguageOption<bool> QualifyPropertyAccess { get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyPropertyAccess), defaultValue: false,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyPropertyAccess"));
/// <summary>
/// This option says if we should simplify away the <see langword="this"/>. or <see langword="Me"/>. in method access expressions.
/// </summary>
[Obsolete]
public static PerLanguageOption<bool> QualifyMethodAccess{ get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyMethodAccess), defaultValue: false,
public static PerLanguageOption<bool> QualifyMethodAccess { get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyMethodAccess), defaultValue: false,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyMethodAccess"));
/// <summary>
/// This option says if we should simplify away the <see langword="this"/>. or <see langword="Me"/>. in event access expressions.
/// </summary>
[Obsolete]
public static PerLanguageOption<bool> QualifyEventAccess{ get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyEventAccess), defaultValue: false,
public static PerLanguageOption<bool> QualifyEventAccess { get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(QualifyEventAccess), defaultValue: false,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyEventAccess"));
/// <summary>
......@@ -95,261 +96,13 @@ public static class SimplificationOptions
[Obsolete]
public static PerLanguageOption<bool> PreferIntrinsicPredefinedTypeKeywordInMemberAccess { get; } = new PerLanguageOption<bool>(nameof(SimplificationOptions), nameof(PreferIntrinsicPredefinedTypeKeywordInMemberAccess), defaultValue: true);
private static string _defaultNamingPreferences = $@"
<NamingPreferencesInfo SerializationVersion=""3"">
<SymbolSpecifications>
<SymbolSpecification ID=""5c545a62-b14d-460a-88d8-e936c0a39316"" Name=""{WorkspacesResources.Class}"">
<ApplicableSymbolKindList>
<TypeKind>Class</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""23d856b4-5089-4405-83ce-749aada99153"" Name=""{WorkspacesResources.Interface}"">
<ApplicableSymbolKindList>
<TypeKind>Interface</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""d1796e78-ff66-463f-8576-eb46416060c0"" Name=""{WorkspacesResources.Struct}"">
<ApplicableSymbolKindList>
<TypeKind>Struct</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""d8af8dc6-1ade-441d-9947-8946922e198a"" Name=""{WorkspacesResources.Enum}"">
<ApplicableSymbolKindList>
<TypeKind>Enum</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""408a3347-b908-4b54-a954-1355e64c1de3"" Name=""{WorkspacesResources.Delegate}"">
<ApplicableSymbolKindList>
<TypeKind>Delegate</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""830657f6-e7e5-4830-b328-f109d3b6c165"" Name=""{WorkspacesResources.Event}"">
<ApplicableSymbolKindList>
<SymbolKind>Event</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""390caed4-f0a9-42bb-adbb-b44c4a302a22"" Name=""{WorkspacesResources.Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""af410767-f189-47c6-b140-aeccf1ff242e"" Name=""{WorkspacesResources.Private_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""8076757e-6a4a-47f1-9b4b-ae8a3284e987"" Name=""{WorkspacesResources.Abstract_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsAbstract</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""16133061-a8e7-4392-92c3-1d93cd54c218"" Name=""{WorkspacesResources.Static_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""03a274df-b686-4a76-9138-96aecb9bd33b"" Name=""{WorkspacesResources.Async_Method}"">
<ApplicableSymbolKindList>
<SymbolKind>Method</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsAsync</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""da6a2919-5aa6-4ad1-a24d-576776ed3974"" Name=""{WorkspacesResources.Property}"">
<ApplicableSymbolKindList>
<SymbolKind>Property</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""b24a91ce-3501-4799-b6df-baf044156c83"" Name=""{WorkspacesResources.Public_or_Protected_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""70af42cb-1741-4027-969c-9edc4877d965"" Name=""{WorkspacesResources.Static_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""10790aa6-0a0b-432d-a52d-d252ca92302b"" Name=""{WorkspacesResources.Private_or_Internal_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""ac995be4-88de-4771-9dcc-a456a7c02d89"" Name=""{WorkspacesResources.Private_or_Internal_Static_Field}"">
<ApplicableSymbolKindList>
<SymbolKind>Field</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList>
<ModifierKind>IsStatic</ModifierKind>
</RequiredModifierList>
</SymbolSpecification>
<SymbolSpecification ID=""2c07f5bf-bc81-4c2b-82b4-ae9b3ffd0ba4"" Name=""{WorkspacesResources.Types}"">
<ApplicableSymbolKindList>
<TypeKind>Class</TypeKind>
<TypeKind>Struct</TypeKind>
<TypeKind>Interface</TypeKind>
<TypeKind>Enum</TypeKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
<SymbolSpecification ID=""5f3ddba1-279f-486c-801e-5c097c36dd85"" Name=""{WorkspacesResources.Non_Field_Members}"">
<ApplicableSymbolKindList>
<SymbolKind>Property</SymbolKind>
<SymbolKind>Method</SymbolKind>
<SymbolKind>Event</SymbolKind>
</ApplicableSymbolKindList>
<ApplicableAccessibilityList>
<AccessibilityKind>Public</AccessibilityKind>
<AccessibilityKind>Internal</AccessibilityKind>
<AccessibilityKind>Private</AccessibilityKind>
<AccessibilityKind>Protected</AccessibilityKind>
<AccessibilityKind>ProtectedOrInternal</AccessibilityKind>
</ApplicableAccessibilityList>
<RequiredModifierList />
</SymbolSpecification>
</SymbolSpecifications>
<NamingStyles>
<NamingStyle ID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" Name=""{WorkspacesResources.Pascal_Case}"" Prefix="""" Suffix="""" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
<NamingStyle ID=""308152f2-a334-48b3-8bec-ddee40785feb"" Name=""{WorkspacesResources.Ends_with_Async}"" Prefix="""" Suffix=""Async"" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
<NamingStyle ID=""1ecc5eb6-b5fc-49a5-a9f1-a980f3e48c92"" Name=""{WorkspacesResources.Begins_with_I}"" Prefix=""I"" Suffix="""" WordSeparator="""" CapitalizationScheme=""PascalCase"" />
</NamingStyles>
<NamingRules>
<SerializableNamingRule SymbolSpecificationID=""23d856b4-5089-4405-83ce-749aada99153"" NamingStyleID=""1ecc5eb6-b5fc-49a5-a9f1-a980f3e48c92"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""2c07f5bf-bc81-4c2b-82b4-ae9b3ffd0ba4"" NamingStyleID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""03a274df-b686-4a76-9138-96aecb9bd33b"" NamingStyleID=""308152f2-a334-48b3-8bec-ddee40785feb"" EnforcementLevel=""Info"" />
<SerializableNamingRule SymbolSpecificationID=""5f3ddba1-279f-486c-801e-5c097c36dd85"" NamingStyleID=""87e7c501-9948-4b53-b1eb-a6cbe918feee"" EnforcementLevel=""Info"" />
</NamingRules>
</NamingPreferencesInfo>
";
/// <summary>
/// This option describes the naming rules that should be applied to specified categories of symbols,
/// and the level to which those rules should be enforced.
/// </summary>
public static PerLanguageOption<string> NamingPreferences { get; } = new PerLanguageOption<string>(nameof(SimplificationOptions), nameof(NamingPreferences), defaultValue: _defaultNamingPreferences,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.NamingPreferences"));
internal static PerLanguageOption<NamingStylePreferences> NamingPreferences { get; } = new PerLanguageOption<NamingStylePreferences>(nameof(SimplificationOptions), nameof(NamingPreferences), defaultValue: NamingStylePreferences.Default,
storageLocations: new OptionStorageLocation[]{
new EditorConfigStorageLocation(),
new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.NamingPreferences")});
}
}
......@@ -370,6 +370,12 @@
<Compile Include="Execution\SolutionAsset.cs" />
<Compile Include="Execution\WellKnownSynchronizationKinds.cs" />
<Compile Include="Experiments\IExperimentationService.cs" />
<Compile Include="NamingStyles\EditorConfig\EditorConfigSeverityStrings.cs" />
<Compile Include="NamingStyles\EditorConfig\EditorConfigNamingStyleParser.cs" />
<Compile Include="NamingStyles\EditorConfig\EditorConfigNamingStyleParser_NamingRule.cs" />
<Compile Include="NamingStyles\EditorConfig\EditorConfigNamingStyleParser_NamingStyle.cs" />
<Compile Include="NamingStyles\EditorConfig\EditorConfigNamingStyleParser_SymbolSpec.cs" />
<Compile Include="NamingStyles\Serialization\AccessibilityExtensions.cs" />
<Compile Include="LanguageServices\TypeInferenceService\AbstractTypeInferenceService.AbstractTypeInferrer.cs" />
<Compile Include="FindSymbols\SyntaxTree\SyntaxTreeIndex_Persistence.cs" />
<Compile Include="FindSymbols\SyntaxTree\SyntaxTreeIndex_Forwarders.cs" />
......@@ -385,6 +391,13 @@
<Compile Include="PatternMatching\PatternMatches.cs" />
<Compile Include="PatternMatching\PatternMatchKind.cs" />
<Compile Include="Remote\RemoteSupportedLanguages.cs" />
<Compile Include="NamingStyles\Capitalization.cs" />
<Compile Include="NamingStyles\NamingRule.cs" />
<Compile Include="NamingStyles\NamingStyleRules.cs" />
<Compile Include="NamingStyles\Serialization\NamingStyle.cs" />
<Compile Include="NamingStyles\Serialization\SerializableNamingRule.cs" />
<Compile Include="NamingStyles\Serialization\NamingStylePreferences.cs" />
<Compile Include="NamingStyles\Serialization\SymbolSpecification.cs" />
<Compile Include="Shared\Extensions\SolutionExtensions.cs" />
<Compile Include="SymbolKey\SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs" />
<Compile Include="Tags\WellKnownTags.cs" />
......
......@@ -881,6 +881,24 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Missing prefix: &apos;{0}&apos;.
/// </summary>
internal static string Missing_prefix_colon_0 {
get {
return ResourceManager.GetString("Missing_prefix_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Missing suffix: &apos;{0}&apos;.
/// </summary>
internal static string Missing_suffix_colon_0 {
get {
return ResourceManager.GetString("Missing_suffix_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name can be simplified..
/// </summary>
......@@ -1207,6 +1225,24 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to The first word, &apos;{0}&apos;, must begin with a lower case character.
/// </summary>
internal static string The_first_word_0_must_begin_with_a_lower_case_character {
get {
return ResourceManager.GetString("The_first_word_0_must_begin_with_a_lower_case_character", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The first word, &apos;{0}&apos;, must begin with an upper case character.
/// </summary>
internal static string The_first_word_0_must_begin_with_an_upper_case_character {
get {
return ResourceManager.GetString("The_first_word_0_must_begin_with_an_upper_case_character", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The language &apos;{0}&apos; is not supported..
/// </summary>
......@@ -1324,6 +1360,51 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to These non-leading words must begin with a lowercase letter: {0}.
/// </summary>
internal static string These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0 {
get {
return ResourceManager.GetString("These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These non-leading words must begin with an upper case letter: {0}.
/// </summary>
internal static string These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0 {
get {
return ResourceManager.GetString("These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words cannot contain lower case characters: {0}.
/// </summary>
internal static string These_words_cannot_contain_lower_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_cannot_contain_lower_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words cannot contain upper case characters: {0}.
/// </summary>
internal static string These_words_cannot_contain_upper_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_cannot_contain_upper_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to These words must begin with upper case characters: {0}.
/// </summary>
internal static string These_words_must_begin_with_upper_case_characters_colon_0 {
get {
return ResourceManager.GetString("These_words_must_begin_with_upper_case_characters_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This submission already references another submission project..
/// </summary>
......
......@@ -578,14 +578,40 @@
<value>Method</value>
<comment>{locked:method} unless the capitalization should be handled differently</comment>
</data>
<data name="Missing_prefix_colon_0" xml:space="preserve">
<value>Missing prefix: '{0}'</value>
</data>
<data name="Error" xml:space="preserve">
<value>Error</value>
</data>
<data name="None" xml:space="preserve">
<value>None</value>
</data>
<data name="Missing_suffix_colon_0" xml:space="preserve">
<value>Missing suffix: '{0}'</value>
</data>
<data name="These_non_leading_words_must_begin_with_an_upper_case_letter_colon_0" xml:space="preserve">
<value>These non-leading words must begin with an upper case letter: {0}</value>
</data>
<data name="Suggestion" xml:space="preserve">
<value>Suggestion</value>
</data>
<data name="These_non_leading_words_must_begin_with_a_lowercase_letter_colon_0" xml:space="preserve">
<value>These non-leading words must begin with a lowercase letter: {0}</value>
</data>
<data name="These_words_cannot_contain_lower_case_characters_colon_0" xml:space="preserve">
<value>These words cannot contain lower case characters: {0}</value>
</data>
<data name="These_words_cannot_contain_upper_case_characters_colon_0" xml:space="preserve">
<value>These words cannot contain upper case characters: {0}</value>
</data>
<data name="These_words_must_begin_with_upper_case_characters_colon_0" xml:space="preserve">
<value>These words must begin with upper case characters: {0}</value>
</data>
<data name="The_first_word_0_must_begin_with_an_upper_case_character" xml:space="preserve">
<value>The first word, '{0}', must begin with an upper case character</value>
</data>
<data name="The_first_word_0_must_begin_with_a_lower_case_character" xml:space="preserve">
<value>The first word, '{0}', must begin with a lower case character</value>
</data>
</root>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册