diff --git a/src/Compilers/Core/Portable/InternalUtilities/ConcurrentLruCache.cs b/src/Compilers/Core/Portable/InternalUtilities/ConcurrentLruCache.cs index 579c982671bf0..15fe814d1144b 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ConcurrentLruCache.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ConcurrentLruCache.cs @@ -87,7 +87,7 @@ public void Add(K key, V value) private void MoveNodeToTop(LinkedListNode node) { - if (!object.ReferenceEquals(_nodeList.First, node)) + if (!ReferenceEquals(_nodeList.First, node)) { _nodeList.Remove(node); _nodeList.AddFirst(node); diff --git a/src/Compilers/Test/Core/Traits/Traits.cs b/src/Compilers/Test/Core/Traits/Traits.cs index 2b72c0685c0ab..b21f3558c22ba 100644 --- a/src/Compilers/Test/Core/Traits/Traits.cs +++ b/src/Compilers/Test/Core/Traits/Traits.cs @@ -227,6 +227,7 @@ public static class Features public const string DocCommentFormatting = nameof(DocCommentFormatting); public const string DocumentationComments = nameof(DocumentationComments); public const string EditorConfig = nameof(EditorConfig); + public const string EditorConfigUI = nameof(EditorConfigUI); public const string EncapsulateField = nameof(EncapsulateField); public const string EndConstructGeneration = nameof(EndConstructGeneration); public const string ErrorList = nameof(ErrorList); diff --git a/src/EditorFeatures/CSharp/CSharpEditorResources.resx b/src/EditorFeatures/CSharp/CSharpEditorResources.resx index dc934ab12dff9..0498beacc31e0 100644 --- a/src/EditorFeatures/CSharp/CSharpEditorResources.resx +++ b/src/EditorFeatures/CSharp/CSharpEditorResources.resx @@ -182,4 +182,259 @@ Add Missing Usings on Paste "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + + + Avoid unused value assignments + + + Discard + + + Elsewhere + + + For built-in types + + + Ignore spaces in declaration statements + + + Indent block contents + + + Indent case contents + + + Indent case contents (when block) + + + Indent case labels + + + Indent open and close braces + + + Insert spaces within parentheses of control flow statements + + + Insert spaces within square brackets + + + Insert space after cast + + + Insert space after colon for base or interface in type declaration + + + Insert space after comma + + + Insert space after dot + + + Insert space after keywords in control flow statements + + + Insert space after semicolon in "for" statement + + + Insert space before colon for base or interface in type declaration + + + Insert space before comma + + + Insert space before dot + + + Insert space before open square bracket + + + Insert space before semicolon in "for" statement + + + Insert space between method name and its opening parenthesis + + + Insert space between method name and its opening parenthesis + + + Insert space within argument list parentheses + + + Insert space within empty argument list parentheses + + + Insert space within empty parameter list parentheses + + + Insert space within empty square brackets + + + Insert space within parameter list parentheses + + + Insert space within parentheses of expressions + + + Insert space within parentheses of type casts + + + Inside namespace + + + Label Indentation + + + Leave block on single line + + + Leave statements and member declarations on the same line + + + Never + + + Place "catch" on new line + + + Place "else" on new line + + + Place "finally" on new line + + + Place members in anonymous types on new line + + + Place members in object initializers on new line + + + Place open brace on new line for anonymous methods + + + Place open brace on new line for anonymous types + + + Place open brace on new line for control blocks + + + Place open brace on new line for lambda expression + + + Place open brace on new line for methods and local functions + + + Place open brace on new line for object, collection, array, and with initializers + + + Place open brace on new line for properties, indexers, and events + + + Place open brace on new line for property, indexer, and event accessors + + + Place open brace on new line for types + + + Place query expression clauses on new line + + + Preferred 'using' directive placement + + + Prefer conditional delegate call + + + Prefer deconstructed variable declaration + + + Prefer explicit type + + + Prefer index operator + + + Prefer inlined variable declaration + + + Prefer local function over anonymous function + + + Prefer pattern matching + + + Prefer pattern matching over 'as' with 'null' check + + + Prefer pattern matching over 'is' with 'cast' check + + + Prefer pattern matching over mixed type check + + + Prefer range operator + + + Prefer simple 'default' expression + + + Prefer simple 'using' statement + + + Prefer static local functions + + + Prefer switch expression + + + Prefer throw-expression + + + Prefer 'var' + + + Set spacing for operators + + + Unused local + + + Use expression body for accessors + + + Use expression body for constructors + + + Use expression body for indexers + + + Use expression body for lambdas + + + Use expression body for local functions + + + Use expression body for methods + + + Use expression body for operators + + + Use expression body for properties + + + When on single line + + + When possible + + + When variable type is apparent + + + Outside namespace + \ No newline at end of file diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsLanguageServiceFactory.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsLanguageServiceFactory.cs new file mode 100644 index 0000000000000..b4ffb45e574f0 --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsLanguageServiceFactory.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.CodeStyle +{ + [ExportLanguageServiceFactory(typeof(ILanguageSettingsProviderFactory), LanguageNames.CSharp), Shared] + internal class CSharpCodeStyleSettingsLanguageServiceFactory : ILanguageServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CSharpCodeStyleSettingsLanguageServiceFactory() + { + } + + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) + { + var workspace = languageServices.WorkspaceServices.Workspace; + return new CSharpCodeStyleSettingsProviderFactory(workspace); + } + } +} diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs new file mode 100644 index 0000000000000..bce834f0c12ec --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs @@ -0,0 +1,224 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.AddImports; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.CSharp; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.CodeStyle +{ + internal class CSharpCodeStyleSettingsProvider : SettingsProviderBase + { + public CSharpCodeStyleSettingsProvider(string fileName, OptionUpdater settingsUpdater, Workspace workspace) + : base(fileName, settingsUpdater, workspace) + { + Update(); + } + + protected override void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions) + { + var varSettings = GetVarCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(varSettings); + + var usingSettings = GetUsingsCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(usingSettings); + + var modifierSettings = GetModifierCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(modifierSettings); + + var codeBlockSettings = GetCodeBlockCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(codeBlockSettings); + + var nullCheckingSettings = GetNullCheckingCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(nullCheckingSettings); + + var expressionSettings = GetExpressionCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(expressionSettings); + + var patternMatchingSettings = GetPatternMatchingCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(patternMatchingSettings); + + var variableSettings = GetVariableCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(variableSettings); + + var expressionBodySettings = GetExpressionBodyCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(expressionBodySettings); + + var unusedValueSettings = GetUnusedValueCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(unusedValueSettings); + } + + private static IEnumerable GetVarCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.VarForBuiltInTypes, + description: CSharpEditorResources.For_built_in_types, + trueValueDescription: CSharpEditorResources.Prefer_var, + falseValueDescription: CSharpEditorResources.Prefer_explicit_type, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.VarWhenTypeIsApparent, + description: CSharpEditorResources.When_variable_type_is_apparent, + trueValueDescription: CSharpEditorResources.Prefer_var, + falseValueDescription: CSharpEditorResources.Prefer_explicit_type, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.VarElsewhere, + description: CSharpEditorResources.Elsewhere, + trueValueDescription: CSharpEditorResources.Prefer_var, + falseValueDescription: CSharpEditorResources.Prefer_explicit_type, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetUsingsCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create( + option: CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, + description: CSharpEditorResources.Preferred_using_directive_placement, + enumValues: new[] { AddImportPlacement.InsideNamespace, AddImportPlacement.OutsideNamespace }, + valueDescriptions: new[] { CSharpEditorResources.Inside_namespace, CSharpEditorResources.Outside_namespace }, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetNullCheckingCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferThrowExpression, + description: CSharpEditorResources.Prefer_throw_expression, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferConditionalDelegateCall, + description: CSharpEditorResources.Prefer_conditional_delegate_call, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetModifierCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferStaticLocalFunction, + description: CSharpEditorResources.Prefer_static_local_functions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetCodeBlockCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferSimpleUsingStatement, + description: CSharpEditorResources.Prefer_simple_using_statement, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetExpressionCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferSwitchExpression, description: CSharpEditorResources.Prefer_switch_expression, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferSimpleDefaultExpression, description: CSharpEditorResources.Prefer_simple_default_expression, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferLocalOverAnonymousFunction, description: CSharpEditorResources.Prefer_local_function_over_anonymous_function, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferIndexOperator, description: CSharpEditorResources.Prefer_index_operator, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferRangeOperator, description: CSharpEditorResources.Prefer_range_operator, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetPatternMatchingCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferPatternMatching, description: CSharpEditorResources.Prefer_pattern_matching, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, description: CSharpEditorResources.Prefer_pattern_matching_over_is_with_cast_check, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck, description: CSharpEditorResources.Prefer_pattern_matching_over_as_with_null_check, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferNotPattern, description: CSharpEditorResources.Prefer_pattern_matching_over_mixed_type_check, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetVariableCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferInlinedVariableDeclaration, description: CSharpEditorResources.Prefer_inlined_variable_declaration, editorConfigOptions, visualStudioOptions, updaterService); + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.PreferDeconstructedVariableDeclaration, description: CSharpEditorResources.Prefer_deconstructed_variable_declaration, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetExpressionBodyCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + var enumValues = new[] { ExpressionBodyPreference.Never, ExpressionBodyPreference.WhenPossible, ExpressionBodyPreference.WhenOnSingleLine }; + var valueDescriptions = new[] { CSharpEditorResources.Never, CSharpEditorResources.When_possible, CSharpEditorResources.When_on_single_line }; + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedMethods, + description: CSharpEditorResources.Use_expression_body_for_methods, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, + description: CSharpEditorResources.Use_expression_body_for_constructors, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedOperators, + description: CSharpEditorResources.Use_expression_body_for_operators, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedProperties, + description: CSharpEditorResources.Use_expression_body_for_properties, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, + description: CSharpEditorResources.Use_expression_body_for_indexers, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, + description: CSharpEditorResources.Use_expression_body_for_accessors, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, + description: CSharpEditorResources.Use_expression_body_for_lambdas, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, + description: CSharpEditorResources.Use_expression_body_for_local_functions, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: editorConfigOptions, + visualStudioOptions: visualStudioOptions, updater: updaterService); + } + + private static IEnumerable GetUnusedValueCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + var enumValues = new[] + { + UnusedValuePreference.UnusedLocalVariable, + UnusedValuePreference.DiscardVariable + }; + + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.UnusedValueAssignment, + description: CSharpEditorResources.Avoid_unused_value_assignments, + enumValues, + new[] { CSharpEditorResources.Unused_local, CSharpEditorResources.Discard }, + editorConfigOptions, + visualStudioOptions, + updaterService); + + yield return CodeStyleSetting.Create(CSharpCodeStyleOptions.UnusedValueExpressionStatement, + description: CSharpEditorResources.Avoid_expression_statements_that_implicitly_ignore_value, + enumValues, + new[] { CSharpEditorResources.Unused_local, CSharpEditorResources.Discard }, + editorConfigOptions, + visualStudioOptions, + updaterService); + } + } +} diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProviderFactory.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProviderFactory.cs new file mode 100644 index 0000000000000..1af8c72ade4d0 --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProviderFactory.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.CodeStyle +{ + internal class CSharpCodeStyleSettingsProviderFactory : ILanguageSettingsProviderFactory + { + private readonly Workspace _workspace; + + public CSharpCodeStyleSettingsProviderFactory(Workspace workspace) => _workspace = workspace; + + public ISettingsProvider GetForFile(string filePath) + => new CSharpCodeStyleSettingsProvider(filePath, new OptionUpdater(_workspace, filePath), _workspace); + } +} diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsLanguageServiceFactory.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsLanguageServiceFactory.cs new file mode 100644 index 0000000000000..550c7bf77b32a --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsLanguageServiceFactory.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.Formatting +{ + [ExportLanguageServiceFactory(typeof(ILanguageSettingsProviderFactory), LanguageNames.CSharp), Shared] + internal class CSharpFormattingSettingsLanguageServiceFactory : ILanguageServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CSharpFormattingSettingsLanguageServiceFactory() + { + } + + public ILanguageService CreateLanguageService(HostLanguageServices languageServices) + { + var workspace = languageServices.WorkspaceServices.Workspace; + return new CSharpFormattingSettingsProviderFactory(workspace); + } + } +} diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProvider.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProvider.cs new file mode 100644 index 0000000000000..00341120f9c72 --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProvider.cs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.CSharp; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.Formatting +{ + internal class CSharpFormattingSettingsProvider : SettingsProviderBase + { + public CSharpFormattingSettingsProvider(string filePath, OptionUpdater updaterService, Workspace workspace) + : base(filePath, updaterService, workspace) + { + Update(); + } + + protected override void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions) + { + var spacingOptions = GetSpacingOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(spacingOptions.ToImmutableArray()); + var newLineOptions = GetNewLineOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(newLineOptions.ToImmutableArray()); + var indentationOptions = GetIndentationOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(indentationOptions.ToImmutableArray()); + var wrappingOptions = GetWrappingOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(wrappingOptions.ToImmutableArray()); + } + + private static IEnumerable GetSpacingOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpacingAfterMethodDeclarationName, CSharpEditorResources.Insert_space_between_method_name_and_its_opening_parenthesis2, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinMethodDeclarationParenthesis, CSharpEditorResources.Insert_space_within_parameter_list_parentheses, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBetweenEmptyMethodDeclarationParentheses, CSharpEditorResources.Insert_space_within_empty_parameter_list_parentheses, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterMethodCallName, CSharpEditorResources.Insert_space_between_method_name_and_its_opening_parenthesis1, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, CSharpEditorResources.Insert_space_within_argument_list_parentheses, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, CSharpEditorResources.Insert_space_within_empty_argument_list_parentheses, editorConfigOptions, visualStudioOptions, updaterService); + + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterControlFlowStatementKeyword, CSharpEditorResources.Insert_space_after_keywords_in_control_flow_statements, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinExpressionParentheses, CSharpEditorResources.Insert_space_within_parentheses_of_expressions, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinCastParentheses, CSharpEditorResources.Insert_space_within_parentheses_of_type_casts, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinOtherParentheses, CSharpEditorResources.Insert_spaces_within_parentheses_of_control_flow_statements, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterCast, CSharpEditorResources.Insert_space_after_cast, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, CSharpEditorResources.Ignore_spaces_in_declaration_statements, editorConfigOptions, visualStudioOptions, updaterService); + + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBeforeOpenSquareBracket, CSharpEditorResources.Insert_space_before_open_square_bracket, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBetweenEmptySquareBrackets, CSharpEditorResources.Insert_space_within_empty_square_brackets, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceWithinSquareBrackets, CSharpEditorResources.Insert_spaces_within_square_brackets, editorConfigOptions, visualStudioOptions, updaterService); + + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterColonInBaseTypeDeclaration, CSharpEditorResources.Insert_space_after_colon_for_base_or_interface_in_type_declaration, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterComma, CSharpEditorResources.Insert_space_after_comma, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterDot, CSharpEditorResources.Insert_space_after_dot, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, CSharpEditorResources.Insert_space_after_semicolon_in_for_statement, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBeforeColonInBaseTypeDeclaration, CSharpEditorResources.Insert_space_before_colon_for_base_or_interface_in_type_declaration, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBeforeComma, CSharpEditorResources.Insert_space_before_comma, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBeforeDot, CSharpEditorResources.Insert_space_before_dot, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, CSharpEditorResources.Insert_space_before_semicolon_in_for_statement, editorConfigOptions, visualStudioOptions, updaterService); + + yield return FormattingSetting.Create(CSharpFormattingOptions2.SpacingAroundBinaryOperator, CSharpEditorResources.Set_spacing_for_operators, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetNewLineOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInTypes, CSharpEditorResources.Place_open_brace_on_new_line_for_types, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInMethods, CSharpEditorResources.Place_open_brace_on_new_line_for_methods_local_functions, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInProperties, CSharpEditorResources.Place_open_brace_on_new_line_for_properties_indexers_and_events, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInAccessors, CSharpEditorResources.Place_open_brace_on_new_line_for_property_indexer_and_event_accessors, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInAnonymousMethods, CSharpEditorResources.Place_open_brace_on_new_line_for_anonymous_methods, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInControlBlocks, CSharpEditorResources.Place_open_brace_on_new_line_for_control_blocks, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInAnonymousTypes, CSharpEditorResources.Place_open_brace_on_new_line_for_anonymous_types, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInObjectCollectionArrayInitializers, CSharpEditorResources.Place_open_brace_on_new_line_for_object_collection_array_and_with_initializers, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLinesForBracesInLambdaExpressionBody, CSharpEditorResources.Place_open_brace_on_new_line_for_lambda_expression, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForElse, CSharpEditorResources.Place_else_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForCatch, CSharpEditorResources.Place_catch_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForFinally, CSharpEditorResources.Place_finally_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForMembersInObjectInit, CSharpEditorResources.Place_members_in_object_initializers_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForMembersInAnonymousTypes, CSharpEditorResources.Place_members_in_anonymous_types_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.NewLineForClausesInQuery, CSharpEditorResources.Place_query_expression_clauses_on_new_line, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetIndentationOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return FormattingSetting.Create(CSharpFormattingOptions2.IndentBlock, CSharpEditorResources.Indent_block_contents, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.IndentBraces, CSharpEditorResources.Indent_open_and_close_braces, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.IndentSwitchCaseSection, CSharpEditorResources.Indent_case_contents, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.IndentSwitchCaseSectionWhenBlock, CSharpEditorResources.Indent_case_contents_when_block, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.IndentSwitchSection, CSharpEditorResources.Indent_case_labels, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.LabelPositioning, CSharpEditorResources.Label_Indentation, editorConfigOptions, visualStudioOptions, updaterService); + } + + private static IEnumerable GetWrappingOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService) + { + yield return FormattingSetting.Create(CSharpFormattingOptions2.WrappingPreserveSingleLine, CSharpEditorResources.Leave_block_on_single_line, editorConfigOptions, visualStudioOptions, updaterService); + yield return FormattingSetting.Create(CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, CSharpEditorResources.Leave_statements_and_member_declarations_on_the_same_line, editorConfigOptions, visualStudioOptions, updaterService); + } + } +} diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProviderFactory.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProviderFactory.cs new file mode 100644 index 0000000000000..543617276493a --- /dev/null +++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/Formatting/CSharpFormattingSettingsProviderFactory.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings.DataProvider.Formatting +{ + internal class CSharpFormattingSettingsProviderFactory : ILanguageSettingsProviderFactory + { + private readonly Workspace _workspace; + + public CSharpFormattingSettingsProviderFactory(Workspace workspace) + { + _workspace = workspace; + } + + public ISettingsProvider GetForFile(string filePath) + { + var updaterService = new OptionUpdater(_workspace, filePath); + return new CSharpFormattingSettingsProvider(filePath, updaterService, _workspace); + } + } +} diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf index a53460dd12507..a07969485d458 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf @@ -12,6 +12,16 @@ Přidávají se chybějící direktivy using... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Zvolená verze: {0} @@ -32,11 +42,26 @@ Protokol o dekompilaci + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Opravit interpolovaný doslovný řetězec + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Pro {1} se našlo několik ({0}) sestavení: @@ -62,6 +87,166 @@ Generovat odběr událostí + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Načíst z {0} @@ -72,6 +257,181 @@ Modul se nenašel! + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Pro vložení stiskněte TAB.) @@ -87,6 +447,11 @@ Přeložit modul: {0} z {1} + + Set spacing for operators + Set spacing for operators + + Smart Indenting Chytré odsazování @@ -97,11 +462,71 @@ Rozdělit řetězec + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' UPOZORNĚNÍ: Neshoda verzí. Očekáváno: {0}, získáno: {1} + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache Počet položek v mezipaměti: {0} diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf index 59b46f4f98c59..f83defa306236 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf @@ -12,6 +12,16 @@ Fehlende using-Anweisungen werden hinzugefügt... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Ausgewählte Version: {0} @@ -32,11 +42,26 @@ Dekompilierungsprotokoll + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Interpolierte ausführliche Zeichenfolge korrigieren + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': {0} Assemblys für "{1}" gefunden: @@ -62,6 +87,166 @@ Ereignisabonnement generieren + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Laden von: {0} @@ -72,6 +257,181 @@ Das Modul wurde nicht gefunden. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Zum Einfügen TAB-TASTE drücken) @@ -87,6 +447,11 @@ Modul auflösen: {0} von {1} + + Set spacing for operators + Set spacing for operators + + Smart Indenting Intelligenter Einzug @@ -97,11 +462,71 @@ Zeichenfolge teilen + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' WARNUNG: Versionskonflikt. Erwartet: "{0}", erhalten: "{1}" + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache {0} Elemente im Cache diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf index ac2c95c4042de..ca9a0cd38dd0d 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf @@ -12,6 +12,16 @@ Agregando los valores using que faltan... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Versión elegida: "{0}" @@ -32,11 +42,26 @@ Registro de descompilación + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Corregir cadena textual interpolada + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Se encontraron "{0}" ensamblados para "{1}": @@ -62,6 +87,166 @@ Generar suscripción de eventos + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Cargar desde: "{0}" @@ -72,6 +257,181 @@ No se encontró el módulo. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Presione TAB para insertar) @@ -87,6 +447,11 @@ Resolver el módulo: "{0}" de "{1}" + + Set spacing for operators + Set spacing for operators + + Smart Indenting Sangría inteligente @@ -97,11 +462,71 @@ Dividir cadena + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' AVISO: No coinciden las versiones. Se esperaba "{0}", se obtuvo "{1}" + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache "{0}" elementos en caché diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf index 507debfc81da8..71feeb87ccb24 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf @@ -12,6 +12,16 @@ Ajout des usings manquants... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Version choisie : '{0}' @@ -32,11 +42,26 @@ Journal de décompilation + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Corriger la chaîne verbatim interpolée + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': '{0}' assemblys trouvés pour '{1}' : @@ -62,6 +87,166 @@ Générer un abonnement à des événements + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Charger à partir de : '{0}' @@ -72,6 +257,181 @@ Module introuvable ! + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Appuyez sur TAB pour insérer) @@ -87,6 +447,11 @@ Résoudre le module '{0}' sur '{1}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting Retrait intelligent @@ -97,11 +462,71 @@ Fractionner la chaîne + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' AVERTISSEMENT : Incompatibilité de version. Attendu : '{0}'. Reçu : '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache '{0}' éléments dans le cache diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf index b79f46f23136b..21c83449bca2e 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf @@ -12,6 +12,16 @@ Aggiunta di using mancanti... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Versione selezionata: '{0}' @@ -32,11 +42,26 @@ Log di decompilazione + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Correggi stringa verbatim interpolata + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Sono stati trovati '{0}' assembly per '{1}': @@ -62,6 +87,166 @@ Genera sottoscrizione di eventi + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Carica da: '{0}' @@ -72,6 +257,181 @@ Modulo non trovato. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Premere TAB per inserire) @@ -87,6 +447,11 @@ Risolvi il modulo: '{0}' di '{1}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting Rientro automatico @@ -97,11 +462,71 @@ Dividi stringa + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' AVVISO: versione non corrispondente. Prevista: '{0}'. Ottenuta: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache '{0}' elementi nella cache diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf index 3a15f023b5aa7..a2619effa7f17 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf @@ -12,6 +12,16 @@ 欠落している usings を追加しています... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' 選択されたバージョン: '{0}' @@ -32,11 +42,26 @@ 逆コンパイルのログ + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string 挿入された逐語的文字列を修正します + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': '{1}' の '{0}' 個のアセンブリが見つかりました: @@ -62,6 +87,166 @@ イベント サブスクリプションの生成 + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' 読み込み元: '{0}' @@ -72,6 +257,181 @@ モジュールが見つかりません + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Tab キーを押して挿入) @@ -87,6 +447,11 @@ モジュールの解決: '{1}' の '{0}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting スマート インデント @@ -97,11 +462,71 @@ 文字列を分割します + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' 警告: バージョンが一致しません。必要なバージョン: '{0}'、現在のバージョン: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache キャッシュ内の '{0}' 個の項目 diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf index bd89b0cb2c745..b5f3de05a1c71 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf @@ -12,6 +12,16 @@ 누락된 using 추가 중... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' 선택한 버전: '{0}' @@ -32,11 +42,26 @@ 디컴파일 로그 + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string 보간된 축자 문자열 수정 + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': '{1}'의 어셈블리를 '{0}'개 찾았습니다. @@ -62,6 +87,166 @@ 이벤트 구독 생성 + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' 로드 위치: '{0}' @@ -72,6 +257,181 @@ 모듈을 찾을 수 없습니다. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (삽입하려면 <Tab> 키 누름) @@ -87,6 +447,11 @@ 모듈 확인: '{0}'/'{1}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting 스마트 들여쓰기 @@ -97,11 +462,71 @@ 문자열 분할 + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' WARN: 버전이 일치하지 않습니다. 예상: '{0}', 실제: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache 캐시의 '{0}'개 항목 diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf index f00d3e310b8f7..1dd96fe018a20 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf @@ -12,6 +12,16 @@ Trwa dodawanie brakujących dyrektyw using... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Wybrana wersja: „{0}” @@ -32,11 +42,26 @@ Dziennik dekompilacji + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Napraw interpolowany ciąg dosłowny wyrażenia + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Znaleziono zestawy („{0}”) dla elementu „{1}”: @@ -62,6 +87,166 @@ Generuj subskrypcję zdarzenia + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Załaduj z: „{0}” @@ -72,6 +257,181 @@ Nie znaleziono modułu. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Naciśnij klawisz TAB, aby wstawić) @@ -87,6 +447,11 @@ Rozpoznaj moduł: „{0}” z „{1}” + + Set spacing for operators + Set spacing for operators + + Smart Indenting Inteligentne tworzenie wcięć @@ -97,11 +462,71 @@ Rozdziel ciąg + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' OSTRZEŻENIE: niezgodność wersji. Oczekiwano: „{0}”, uzyskano: „{1}” + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache Elementy w pamięci podręcznej: „{0}” diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf index 231aca00a20ae..248bf1ba90a5c 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf @@ -12,6 +12,16 @@ Adicionando as usings ausentes... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Versão escolhida: '{0}' @@ -32,11 +42,26 @@ Log de descompilação + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Corrigir cadeia de caracteres verbatim interpolada + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Foram encontrados '{0}' assemblies para '{1}': @@ -62,6 +87,166 @@ Gerar Assinatura de Evento + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Carregar de: '{0}' @@ -72,6 +257,181 @@ Módulo não encontrado. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Pressione TAB para inserir) @@ -87,6 +447,11 @@ Resolver o módulo: '{0}' de '{1}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting Recuo Inteligente @@ -97,11 +462,71 @@ Dividir cadeia de caracteres + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' AVISO: incompatibilidade de versão. Esperado: '{0}', Obtido: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache '{0}' itens no cache diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf index b1a1ee7d0a8d7..965ebbbf69613 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf @@ -12,6 +12,16 @@ Добавление недостающих директив using… Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Выбранная версия: "{0}" @@ -32,11 +42,26 @@ Журнал декомпиляции + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Исправить интерполированную буквальную строку + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': Обнаружены сборки ("{0}") для "{1}": @@ -62,6 +87,166 @@ Создать подписку на события + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Загрузить из: "{0}" @@ -72,6 +257,181 @@ Модуль не найден. + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Нажмите клавишу TAB для вставки) @@ -87,6 +447,11 @@ Разрешить модуль: "{0}" из "{1}" + + Set spacing for operators + Set spacing for operators + + Smart Indenting Интеллектуальные отступы @@ -97,11 +462,71 @@ Разделить строку + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' Внимание! Несовпадение версий. Ожидалось: "{0}", получено: "{1}" + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache Элементов в кэше: "{0}" diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf index 0710b15a98b3a..9ff6a72081600 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf @@ -12,6 +12,16 @@ Eksik using yönergeleri ekleniyor... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' Seçilen sürüm: '{0}' @@ -32,11 +42,26 @@ Kaynak koda dönüştürme günlüğü + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string Ara değer olarak eklenmiş tam dizeyi düzelt + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': '{1}' için '{0}' bütünleştirilmiş kod bulundu: @@ -62,6 +87,166 @@ Olay Aboneliği Oluştur + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' Şuradan yükle: '{0}' @@ -72,6 +257,181 @@ Modül bulunamadı! + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (Eklemek için TAB tuşuna basın) @@ -87,6 +447,11 @@ '{1}' modül içinden '{0}' modülü çözümle + + Set spacing for operators + Set spacing for operators + + Smart Indenting Akıllı Girintileme @@ -97,11 +462,71 @@ Dizeyi böl + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' UYARI: Sürüm uyumsuzluğu. Beklenen: '{0}', Alınan: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache Önbellekteki '{0}' öğe diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf index ec33113284dae..ead8ce446a96d 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf @@ -12,6 +12,16 @@ 正在添加缺少的 usings… Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' 所选版本: "{0}" @@ -32,11 +42,26 @@ 反编译日志 + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string 修复插值的逐字字符串 + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': 找到 “{1}”的“{0}”个程序集: @@ -62,6 +87,166 @@ 生成事件订阅 + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' 从以下位置加载: "{0}" @@ -72,6 +257,181 @@ 找不到模块! + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (按 Tab 插入) @@ -87,6 +447,11 @@ 解析模块: "{0}" 个(共 "{1}" 个) + + Set spacing for operators + Set spacing for operators + + Smart Indenting 智能缩进 @@ -97,11 +462,71 @@ 拆分字符串 + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' 警告: 版本不匹配。应为: "{0}",实际为: "{1}" + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache 缓存中的 {0} 项 diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf index 82cf331bbb813..0bb3db86969f4 100644 --- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf +++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf @@ -12,6 +12,16 @@ 正在新增缺少的 using... Shown in a thread await dialog. "usings" is a language specific term and should not be localized + + Avoid expression statements that implicitly ignore value + Avoid expression statements that implicitly ignore value + + + + Avoid unused value assignments + Avoid unused value assignments + + Chosen version: '{0}' 選擇的版本: '{0}' @@ -32,11 +42,26 @@ 反向組譯記錄檔 + + Discard + Discard + + + + Elsewhere + Elsewhere + + Fix interpolated verbatim string 修正插入的逐字字串 + + For built-in types + For built-in types + + Found '{0}' assemblies for '{1}': 找到 '{0}' 個 '{1}' 的組件: @@ -62,6 +87,166 @@ 產生事件訂閱 + + Ignore spaces in declaration statements + Ignore spaces in declaration statements + + + + Indent block contents + Indent block contents + + + + Indent case contents + Indent case contents + + + + Indent case contents (when block) + Indent case contents (when block) + + + + Indent case labels + Indent case labels + + + + Indent open and close braces + Indent open and close braces + + + + Insert space after cast + Insert space after cast + + + + Insert space after colon for base or interface in type declaration + Insert space after colon for base or interface in type declaration + + + + Insert space after comma + Insert space after comma + + + + Insert space after dot + Insert space after dot + + + + Insert space after keywords in control flow statements + Insert space after keywords in control flow statements + + + + Insert space after semicolon in "for" statement + Insert space after semicolon in "for" statement + + + + Insert space before colon for base or interface in type declaration + Insert space before colon for base or interface in type declaration + + + + Insert space before comma + Insert space before comma + + + + Insert space before dot + Insert space before dot + + + + Insert space before open square bracket + Insert space before open square bracket + + + + Insert space before semicolon in "for" statement + Insert space before semicolon in "for" statement + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space between method name and its opening parenthesis + Insert space between method name and its opening parenthesis + + + + Insert space within argument list parentheses + Insert space within argument list parentheses + + + + Insert space within empty argument list parentheses + Insert space within empty argument list parentheses + + + + Insert space within empty parameter list parentheses + Insert space within empty parameter list parentheses + + + + Insert space within empty square brackets + Insert space within empty square brackets + + + + Insert space within parameter list parentheses + Insert space within parameter list parentheses + + + + Insert space within parentheses of expressions + Insert space within parentheses of expressions + + + + Insert space within parentheses of type casts + Insert space within parentheses of type casts + + + + Insert spaces within parentheses of control flow statements + Insert spaces within parentheses of control flow statements + + + + Insert spaces within square brackets + Insert spaces within square brackets + + + + Inside namespace + Inside namespace + + + + Label Indentation + Label Indentation + + + + Leave block on single line + Leave block on single line + + + + Leave statements and member declarations on the same line + Leave statements and member declarations on the same line + + Load from: '{0}' 載入來源: '{0}' @@ -72,6 +257,181 @@ 找不到模組! + + Never + Never + + + + Outside namespace + Outside namespace + + + + Place "catch" on new line + Place "catch" on new line + + + + Place "else" on new line + Place "else" on new line + + + + Place "finally" on new line + Place "finally" on new line + + + + Place members in anonymous types on new line + Place members in anonymous types on new line + + + + Place members in object initializers on new line + Place members in object initializers on new line + + + + Place open brace on new line for anonymous methods + Place open brace on new line for anonymous methods + + + + Place open brace on new line for anonymous types + Place open brace on new line for anonymous types + + + + Place open brace on new line for control blocks + Place open brace on new line for control blocks + + + + Place open brace on new line for lambda expression + Place open brace on new line for lambda expression + + + + Place open brace on new line for methods and local functions + Place open brace on new line for methods and local functions + + + + Place open brace on new line for object, collection, array, and with initializers + Place open brace on new line for object, collection, array, and with initializers + + + + Place open brace on new line for properties, indexers, and events + Place open brace on new line for properties, indexers, and events + + + + Place open brace on new line for property, indexer, and event accessors + Place open brace on new line for property, indexer, and event accessors + + + + Place open brace on new line for types + Place open brace on new line for types + + + + Place query expression clauses on new line + Place query expression clauses on new line + + + + Prefer conditional delegate call + Prefer conditional delegate call + + + + Prefer deconstructed variable declaration + Prefer deconstructed variable declaration + + + + Prefer explicit type + Prefer explicit type + + + + Prefer index operator + Prefer index operator + + + + Prefer inlined variable declaration + Prefer inlined variable declaration + + + + Prefer local function over anonymous function + Prefer local function over anonymous function + + + + Prefer pattern matching + Prefer pattern matching + + + + Prefer pattern matching over 'as' with 'null' check + Prefer pattern matching over 'as' with 'null' check + + + + Prefer pattern matching over 'is' with 'cast' check + Prefer pattern matching over 'is' with 'cast' check + + + + Prefer pattern matching over mixed type check + Prefer pattern matching over mixed type check + + + + Prefer range operator + Prefer range operator + + + + Prefer simple 'default' expression + Prefer simple 'default' expression + + + + Prefer simple 'using' statement + Prefer simple 'using' statement + + + + Prefer static local functions + Prefer static local functions + + + + Prefer switch expression + Prefer switch expression + + + + Prefer throw-expression + Prefer throw-expression + + + + Prefer 'var' + Prefer 'var' + + + + Preferred 'using' directive placement + Preferred 'using' directive placement + + (Press TAB to insert) (按 TAB 鍵插入) @@ -87,6 +447,11 @@ 解析模組: '{0}' 之 '{1}' + + Set spacing for operators + Set spacing for operators + + Smart Indenting 智慧縮排 @@ -97,11 +462,71 @@ 分割字串 + + Unused local + Unused local + + + + Use expression body for accessors + Use expression body for accessors + + + + Use expression body for constructors + Use expression body for constructors + + + + Use expression body for indexers + Use expression body for indexers + + + + Use expression body for lambdas + Use expression body for lambdas + + + + Use expression body for local functions + Use expression body for local functions + + + + Use expression body for methods + Use expression body for methods + + + + Use expression body for operators + Use expression body for operators + + + + Use expression body for properties + Use expression body for properties + + WARN: Version mismatch. Expected: '{0}', Got: '{1}' 警告: 版本不符。應為: '{0}',但取得: '{1}' + + When on single line + When on single line + + + + When possible + When possible + + + + When variable type is apparent + When variable type is apparent + + '{0}' items in cache 快取中有 '{0}' 個項目 diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/Aggregator/SettingsAggregatorTests.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Aggregator/SettingsAggregatorTests.cs new file mode 100644 index 0000000000000..42691dca0a0a9 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Aggregator/SettingsAggregatorTests.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EditorConfigSettings.Aggregator +{ + [UseExportProvider] + public class SettingsAggregatorTests + { + public static Workspace CreateWorkspace(params Type[]? additionalParts) + => new AdhocWorkspace(EditorTestCompositions.EditorFeatures.AddParts(additionalParts).GetHostServices(), WorkspaceKind.Host); + + private static Workspace CreateWorkspaceWithProjectAndDocuments() + { + var projectId = ProjectId.CreateNewId(); + + var workspace = CreateWorkspace(); + + Assert.True(workspace.TryApplyChanges(workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(DocumentId.CreateNewId(projectId), "goo.cs", "public class Goo { }") + .AddAdditionalDocument(DocumentId.CreateNewId(projectId), "add.txt", "text") + .AddAnalyzerConfigDocument(DocumentId.CreateNewId(projectId), "editorcfg", SourceText.From("config"), filePath: "/a/b"))); + + return workspace; + } + + private static void TestGettingProvider() + { + var workspace = CreateWorkspaceWithProjectAndDocuments(); + var settingsAggregator = workspace.Services.GetRequiredService(); + var settingsProvider = settingsAggregator.GetSettingsProvider("/a/b/config"); + Assert.NotNull(settingsProvider); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingCodeStyleProvider() => TestGettingProvider(); + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingAnalyzerProvider() => TestGettingProvider(); + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingFormattingProvider() => TestGettingProvider(); + } +} diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.MockAnalyzerReference.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.MockAnalyzerReference.cs new file mode 100644 index 0000000000000..e022e47342116 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.MockAnalyzerReference.cs @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EditorConfigSettings.DataProvider +{ + public partial class DataProviderTests + { + private class MockAnalyzerReference : AnalyzerReference + { + public readonly CodeFixProvider? Fixer; + public readonly ImmutableArray Analyzers; + + private static readonly CodeFixProvider s_defaultFixer = new MockFixer(); + private static readonly ImmutableArray s_defaultAnalyzers = ImmutableArray.Create(new MockDiagnosticAnalyzer()); + + public MockAnalyzerReference(CodeFixProvider? fixer, ImmutableArray analyzers) + { + Fixer = fixer; + Analyzers = analyzers; + } + + public MockAnalyzerReference() + : this(s_defaultFixer, s_defaultAnalyzers) + { + } + + public MockAnalyzerReference(CodeFixProvider? fixer) + : this(fixer, s_defaultAnalyzers) + { + } + + public override string Display => "MockAnalyzerReference"; + + public override string FullPath => string.Empty; + + public override object Id => "MockAnalyzerReference"; + + public override ImmutableArray GetAnalyzers(string language) + => Analyzers; + + public override ImmutableArray GetAnalyzersForAllLanguages() + => Analyzers; + + public ImmutableArray GetFixers() + => Fixer != null ? ImmutableArray.Create(Fixer) : ImmutableArray.Empty; + + public class MockFixer : CodeFixProvider + { + public const string Id = "MyDiagnostic"; + public bool Called; + public int ContextDiagnosticsCount; + + public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(Id); + + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) + { + Called = true; + ContextDiagnosticsCount = context.Diagnostics.Length; + return Task.CompletedTask; + } + } + + public class MockDiagnosticAnalyzer : DiagnosticAnalyzer + { + public MockDiagnosticAnalyzer(ImmutableArray<(string id, string category)> reportedDiagnosticIdsWithCategories) + => SupportedDiagnostics = CreateSupportedDiagnostics(reportedDiagnosticIdsWithCategories); + + public MockDiagnosticAnalyzer(string diagnosticId, string category) + : this(ImmutableArray.Create((diagnosticId, category))) + { + } + + public MockDiagnosticAnalyzer(ImmutableArray reportedDiagnosticIds) + : this(reportedDiagnosticIds.SelectAsArray(id => (id, "InternalCategory"))) + { + } + + public MockDiagnosticAnalyzer() + : this(ImmutableArray.Create(MockFixer.Id)) + { + } + + private static ImmutableArray CreateSupportedDiagnostics(ImmutableArray<(string id, string category)> reportedDiagnosticIdsWithCategories) + { + var builder = ArrayBuilder.GetInstance(); + foreach (var (diagnosticId, category) in reportedDiagnosticIdsWithCategories) + { + var descriptor = new DiagnosticDescriptor(diagnosticId, "MockDiagnostic", "MockDiagnostic", category, DiagnosticSeverity.Warning, isEnabledByDefault: true); + builder.Add(descriptor); + } + + return builder.ToImmutableAndFree(); + } + + public override ImmutableArray SupportedDiagnostics { get; } + + public override void Initialize(AnalysisContext context) + { + context.RegisterSyntaxTreeAction(c => + { + foreach (var descriptor in SupportedDiagnostics) + { + c.ReportDiagnostic(Diagnostic.Create(descriptor, c.Tree.GetLocation(TextSpan.FromBounds(0, 0)))); + } + }); + } + } + } + } +} diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.TestViewModel.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.TestViewModel.cs new file mode 100644 index 0000000000000..f7b15a93e7ce9 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.TestViewModel.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EditorConfigSettings.DataProvider +{ + public partial class DataProviderTests + { + private class TestViewModel : ISettingsEditorViewModel + { + public void NotifyOfUpdate() { } + + Task ISettingsEditorViewModel.UpdateEditorConfigAsync(SourceText sourceText) + { + throw new NotImplementedException(); + } + } + } +} diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs new file mode 100644 index 0000000000000..66842a26d5565 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs @@ -0,0 +1,136 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Editor.UnitTests; +using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.EditorConfigSettings.DataProvider +{ + [UseExportProvider] + public partial class DataProviderTests + { + private static Workspace GetWorkspace() + { + var projectId = ProjectId.CreateNewId(); + var workspace = new AdhocWorkspace(EditorTestCompositions.EditorFeatures.GetHostServices(), WorkspaceKind.Host); + Assert.True(workspace.TryApplyChanges(workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(DocumentId.CreateNewId(projectId), "goo.cs", "public class Goo { }") + .AddAdditionalDocument(DocumentId.CreateNewId(projectId), "add.txt", "text") + .AddAnalyzerReference(projectId, new MockAnalyzerReference()) + .AddAnalyzerConfigDocument(DocumentId.CreateNewId(projectId), "editorcfg", SourceText.From("config"), filePath: "/a/b"))); + return workspace; + } + + private static IWorkspaceSettingsProviderFactory GettingSettingsProviderFactoryFromWorkspace() + => GetWorkspace().Services.GetRequiredService>(); + + private static ILanguageSettingsProviderFactory GettingSettingsProviderFactoryFromLanguageService(string languageName) + => GetWorkspace().Services.GetLanguageServices(languageName).GetRequiredService>(); + + private static ISettingsProvider TestGettingSettingsProviderFromWorkspace() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromWorkspace(); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + Assert.NotNull(settingsProvider); + return settingsProvider; + } + + private static ISettingsProvider TestGettingSettingsProviderFromLanguageService() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromLanguageService(LanguageNames.CSharp); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + Assert.NotNull(settingsProvider); + return settingsProvider; + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingAnalyzerSettingsProvider() + { + TestGettingSettingsProviderFromWorkspace(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingCodeStyleSettingsProvider() + { + TestGettingSettingsProviderFromWorkspace(); + TestGettingSettingsProviderFromLanguageService(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingFormattingSettingsProvider() + { + TestGettingSettingsProviderFromWorkspace(); + TestGettingSettingsProviderFromLanguageService(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingAnalyzerSettingsProviderWorkspaceServiceAsync() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromWorkspace(); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + var model = new TestViewModel(); + settingsProvider.RegisterViewModel(model); + var dataSnapShot = settingsProvider.GetCurrentDataSnapshot(); + var result = Assert.Single(dataSnapShot); + Assert.Equal("MyDiagnostic", result.Id); + Assert.Equal("MockDiagnostic", result.Title); + Assert.Equal(string.Empty, result.Description); + Assert.Equal("InternalCategory", result.Category); + Assert.True(result.IsEnabled); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingCodeStyleSettingProviderWorkspaceServiceAsync() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromWorkspace(); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + var model = new TestViewModel(); + settingsProvider.RegisterViewModel(model); + var dataSnapShot = settingsProvider.GetCurrentDataSnapshot(); + Assert.Equal(26, dataSnapShot.Length); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingCodeStyleSettingsProviderLanguageServiceAsync() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromLanguageService(LanguageNames.CSharp); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + var model = new TestViewModel(); + settingsProvider.RegisterViewModel(model); + var dataSnapShot = settingsProvider.GetCurrentDataSnapshot(); + Assert.Equal(29, dataSnapShot.Length); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingFormattingSettingProviderWorkspaceServiceAsync() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromWorkspace(); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + var model = new TestViewModel(); + settingsProvider.RegisterViewModel(model); + var dataSnapShot = settingsProvider.GetCurrentDataSnapshot(); + Assert.Equal(5, dataSnapShot.Length); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public void TestGettingFormattingSettingProviderLanguageServiceAsync() + { + var settingsProviderFactory = GettingSettingsProviderFactoryFromLanguageService(LanguageNames.CSharp); + var settingsProvider = settingsProviderFactory.GetForFile("/a/b/config"); + var model = new TestViewModel(); + settingsProvider.RegisterViewModel(model); + var dataSnapShot = settingsProvider.GetCurrentDataSnapshot(); + Assert.Equal(47, dataSnapShot.Length); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.TestAnalyzerConfigOptions.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.TestAnalyzerConfigOptions.cs new file mode 100644 index 0000000000000..d2b3c7460dd33 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.TestAnalyzerConfigOptions.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests +{ + public partial class SettingsUpdaterTests + { + private class TestAnalyzerConfigOptions : AnalyzerConfigOptions + { + public static TestAnalyzerConfigOptions Instance = new TestAnalyzerConfigOptions(); + + public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) + { + value = null; + return false; + } + } + } +} diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.cs new file mode 100644 index 0000000000000..918323c59e58f --- /dev/null +++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/Updater/SettingsUpdaterTests.cs @@ -0,0 +1,368 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.AddImports; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests +{ + [UseExportProvider] + public partial class SettingsUpdaterTests : TestBase + { + private static Workspace CreateWorkspaceWithProjectAndDocuments() + { + var projectId = ProjectId.CreateNewId(); + + var workspace = new AdhocWorkspace(EditorTestCompositions.EditorFeatures.GetHostServices(), WorkspaceKind.Host); + + Assert.True(workspace.TryApplyChanges(workspace.CurrentSolution + .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp) + .AddDocument(DocumentId.CreateNewId(projectId), "goo.cs", "public class Goo { }") + .AddAdditionalDocument(DocumentId.CreateNewId(projectId), "add.txt", "text") + .AddAnalyzerConfigDocument(DocumentId.CreateNewId(projectId), "editorcfg", SourceText.From(""), filePath: "/a/b/config"))); + + return workspace; + } + + private static AnalyzerConfigDocument CreateAnalyzerConfigDocument(Workspace workspace, string contents) + { + var solution = workspace.CurrentSolution; + var documentId = solution.Projects.Single().State.AnalyzerConfigDocumentStates.Ids.First(); + var text = SourceText.From(contents); + var newSolution1 = solution.WithAnalyzerConfigDocumentText(documentId, text, PreservationMode.PreserveIdentity); + var analyzerConfigDocument = newSolution1.GetAnalyzerConfigDocument(documentId); + Assert.True(analyzerConfigDocument!.TryGetText(out var actualText)); + Assert.Same(text, actualText); + return analyzerConfigDocument; + } + + private static async Task TestAsync(string initialEditorConfig, string updatedEditorConfig, params (IOption2, object)[] options) + { + using var workspace = CreateWorkspaceWithProjectAndDocuments(); + var analyzerConfigDocument = CreateAnalyzerConfigDocument(workspace, initialEditorConfig); + var sourcetext = await analyzerConfigDocument.GetTextAsync(default); + var result = SettingsUpdateHelper.TryUpdateAnalyzerConfigDocument(sourcetext, analyzerConfigDocument.FilePath!, workspace.Options, options); + Assert.Equal(updatedEditorConfig, result?.ToString()); + } + + private static async Task TestAsync(string initialEditorConfig, string updatedEditorConfig, params (AnalyzerSetting, DiagnosticSeverity)[] options) + { + using var workspace = CreateWorkspaceWithProjectAndDocuments(); + var analyzerConfigDocument = CreateAnalyzerConfigDocument(workspace, initialEditorConfig); + var sourcetext = await analyzerConfigDocument.GetTextAsync(default); + var result = SettingsUpdateHelper.TryUpdateAnalyzerConfigDocument(sourcetext, analyzerConfigDocument.FilePath!, options); + Assert.Equal(updatedEditorConfig, result?.ToString()); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewWhitespaceOptionAsync() + { + await TestAsync( + string.Empty, + "[*.cs]\r\ncsharp_new_line_before_else=true", + (CSharpFormattingOptions2.NewLineForElse, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewBoolCodeStyleOptionWithSeverityAsync() + { + var option = CSharpCodeStyleOptions.PreferThrowExpression.DefaultValue; + option.Value = true; + option.Notification = CodeStyle.NotificationOption2.Suggestion; + await TestAsync( + string.Empty, + "[*.cs]\r\ncsharp_style_throw_expression=true:suggestion", + (CSharpCodeStyleOptions.PreferThrowExpression, option)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewEnumCodeStyleOptionWithSeverityAsync() + { + var option = CSharpCodeStyleOptions.PreferredUsingDirectivePlacement.DefaultValue; + option.Value = AddImportPlacement.InsideNamespace; + option.Notification = CodeStyle.NotificationOption2.Warning; + await TestAsync( + string.Empty, + "[*.cs]\r\ncsharp_using_directive_placement=inside_namespace:warning", + (CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, option)); + } + + [Theory, CombinatorialData, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + internal async Task TestAddNewAnalyzerOptionOptionAsync( + [CombinatorialValues(Language.CSharp, Language.VisualBasic, (Language.CSharp | Language.VisualBasic))] + Language language, + [CombinatorialValues(DiagnosticSeverity.Warning, DiagnosticSeverity.Error, DiagnosticSeverity.Info, DiagnosticSeverity.Hidden)] + DiagnosticSeverity severity) + { + var expectedHeader = ""; + if (language.HasFlag(Language.CSharp) && language.HasFlag(Language.VisualBasic)) + { + expectedHeader = "[*.{cs,vb}]"; + } + else if (language.HasFlag(Language.CSharp)) + { + expectedHeader = "[*.cs]"; + } + else if (language.HasFlag(Language.VisualBasic)) + { + expectedHeader = "[*.vb]"; + } + + var expectedSeverity = severity.ToEditorConfigString(); + + var id = "Test001"; + var descriptor = new DiagnosticDescriptor(id: id, title: "", messageFormat: "", category: "Naming", defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: false); + var analyzerSetting = new AnalyzerSetting(descriptor, ReportDiagnostic.Suppress, null!, language); + + await TestAsync( + string.Empty, + $"{expectedHeader}\r\ndotnet_diagnostic.{id}.severity={expectedSeverity}", + (analyzerSetting, severity)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestUpdateExistingWhitespaceOptionAsync() + { + await TestAsync( + "[*.cs]\r\ncsharp_new_line_before_else=true", + "[*.cs]\r\ncsharp_new_line_before_else=false", + (CSharpFormattingOptions2.NewLineForElse, false)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewWhitespaceOptionToExistingFileAsync() + { + var initialEditorConfig = @" +[*.{cs,vb}] + +# CA1000: Do not declare static members on generic types +dotnet_diagnostic.CA1000.severity=false + +"; + + var updatedEditorConfig = @" +[*.{cs,vb}] + +# CA1000: Do not declare static members on generic types +dotnet_diagnostic.CA1000.severity=false + + +[*.cs] +csharp_new_line_before_else=true"; + await TestAsync( + initialEditorConfig, + updatedEditorConfig, + (CSharpFormattingOptions2.NewLineForElse, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewWhitespaceOptionToWithNonMathcingGroupsAsync() + { + var initialEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2"; + + var updatedEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 +[*.cs] +csharp_new_line_before_else=true"; + await TestAsync( + initialEditorConfig, + updatedEditorConfig, + (CSharpFormattingOptions2.NewLineForElse, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddNewWhitespaceOptionWithStarGroup() + { + var initialEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] + +# CSharp code style settings: +[*.cs]"; + + var updatedEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] + +# CSharp code style settings: +[*.cs] +csharp_new_line_before_else=true"; + + await TestAsync( + initialEditorConfig, + updatedEditorConfig, + (CSharpFormattingOptions2.NewLineForElse, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddMultimpleNewWhitespaceOptions() + { + await TestAsync( + string.Empty, + "[*.cs]\r\ncsharp_new_line_before_else=true\r\ncsharp_new_line_before_catch=true\r\ncsharp_new_line_before_finally=true", + (CSharpFormattingOptions2.NewLineForElse, true), + (CSharpFormattingOptions2.NewLineForCatch, true), + (CSharpFormattingOptions2.NewLineForFinally, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddOptionThatAppliesToBothLanguages() + { + var initialEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] + +# CSharp code style settings: +[*.cs]"; + + var updatedEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] +dotnet_sort_system_directives_first=true + +# CSharp code style settings: +[*.cs]"; + + await TestAsync( + initialEditorConfig, + updatedEditorConfig, + (GenerationOptions.PlaceSystemNamespaceFirst, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAddOptionWithRelativePathGroupingPresent() + { + var initialEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] + +# Test CSharp code style settings: +[*Test.cs] + +# CSharp code style settings: +[*.cs]"; + + var updatedEditorConfig = @" +root = true + +# Xml files +[*.xml] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] + +# Test CSharp code style settings: +[*Test.cs] + +# CSharp code style settings: +[*.cs] +csharp_new_line_before_else=true"; + + await TestAsync( + initialEditorConfig, + updatedEditorConfig, + (CSharpFormattingOptions2.NewLineForElse, true)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestAnalyzerSettingsUpdaterService() + { + var workspace = CreateWorkspaceWithProjectAndDocuments(); + var updater = new AnalyzerSettingsUpdater(workspace, "/a/b/config"); + var id = "Test001"; + var descriptor = new DiagnosticDescriptor(id: id, title: "", messageFormat: "", category: "Naming", defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: false); + var analyzerSetting = new AnalyzerSetting(descriptor, ReportDiagnostic.Suppress, updater, Language.CSharp); + analyzerSetting.ChangeSeverity(DiagnosticSeverity.Error); + var updates = await updater.GetChangedEditorConfigAsync(default); + var update = Assert.Single(updates); + Assert.Equal($"[*.cs]\r\ndotnet_diagnostic.{id}.severity=error", update.NewText); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestCodeStyleSettingUpdaterService() + { + var workspace = CreateWorkspaceWithProjectAndDocuments(); + var updater = new OptionUpdater(workspace, "/a/b/config"); + var setting = CodeStyleSetting.Create(CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, + "", + TestAnalyzerConfigOptions.Instance, + workspace.Options, + updater); + setting.ChangeSeverity(DiagnosticSeverity.Error); + var updates = await updater.GetChangedEditorConfigAsync(default); + var update = Assert.Single(updates); + Assert.Equal("[*.cs]\r\ncsharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental=true:error", update.NewText); + setting.ChangeValue(1); + updates = await updater.GetChangedEditorConfigAsync(default); + update = Assert.Single(updates); + Assert.Equal("[*.cs]\r\ncsharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental=false:error", update.NewText); + } + + [Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)] + public async Task TestFormattingSettingUpdaterService() + { + var workspace = CreateWorkspaceWithProjectAndDocuments(); + var updater = new OptionUpdater(workspace, "/a/b/config"); + var setting = FormattingSetting.Create(CSharpFormattingOptions2.NewLineForElse, "", TestAnalyzerConfigOptions.Instance, workspace.Options, updater); + setting.SetValue(false); + var updates = await updater.GetChangedEditorConfigAsync(default); + var update = Assert.Single(updates); + Assert.Equal("[*.cs]\r\ncsharp_new_line_before_else=false", update.NewText); + } + } +} diff --git a/src/EditorFeatures/Core.Wpf/Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj b/src/EditorFeatures/Core.Wpf/Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj index 4211ba99baff2..20b9352283106 100644 --- a/src/EditorFeatures/Core.Wpf/Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj +++ b/src/EditorFeatures/Core.Wpf/Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj @@ -68,8 +68,6 @@ - - diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/ISettingsAggregator.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/ISettingsAggregator.cs new file mode 100644 index 0000000000000..74520e4ac98dc --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/ISettingsAggregator.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings +{ + internal interface ISettingsAggregator : IWorkspaceService + { + ISettingsProvider? GetSettingsProvider(string fileName); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs new file mode 100644 index 0000000000000..144b853d9abd9 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregator.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings +{ + internal partial class SettingsAggregator : ISettingsAggregator + { + private readonly Workspace _workspace; + private readonly ISettingsProviderFactory _analyzerProvider; + private ISettingsProviderFactory _formattingProvider; + private ISettingsProviderFactory _codeStyleProvider; + + public SettingsAggregator(Workspace workspace) + { + _workspace = workspace; + _workspace.WorkspaceChanged += UpdateProviders; + _formattingProvider = GetOptionsProviderFactory(_workspace); + _codeStyleProvider = GetOptionsProviderFactory(_workspace); + _analyzerProvider = GetOptionsProviderFactory(_workspace); + } + + private void UpdateProviders(object? sender, WorkspaceChangeEventArgs e) + { + switch (e.Kind) + { + case WorkspaceChangeKind.SolutionChanged: + case WorkspaceChangeKind.SolutionAdded: + case WorkspaceChangeKind.SolutionRemoved: + case WorkspaceChangeKind.SolutionCleared: + case WorkspaceChangeKind.SolutionReloaded: + case WorkspaceChangeKind.ProjectAdded: + case WorkspaceChangeKind.ProjectRemoved: + case WorkspaceChangeKind.ProjectChanged: + _formattingProvider = GetOptionsProviderFactory(_workspace); + _codeStyleProvider = GetOptionsProviderFactory(_workspace); + break; + default: + break; + } + } + + public ISettingsProvider? GetSettingsProvider(string fileName) + { + if (typeof(TData) == typeof(AnalyzerSetting)) + { + return (ISettingsProvider)_analyzerProvider.GetForFile(fileName); + } + + if (typeof(TData) == typeof(FormattingSetting)) + { + return (ISettingsProvider)_formattingProvider.GetForFile(fileName); + } + + if (typeof(TData) == typeof(CodeStyleSetting)) + { + return (ISettingsProvider)_codeStyleProvider.GetForFile(fileName); + } + + return null; + } + + private static ISettingsProviderFactory GetOptionsProviderFactory(Workspace workspace) + { + var providers = new List>(); + var commonProvider = workspace.Services.GetRequiredService>(); + providers.Add(commonProvider); + var solution = workspace.CurrentSolution; + var supportsCSharp = solution.Projects.Any(p => p.Language.Equals(LanguageNames.CSharp, StringComparison.OrdinalIgnoreCase)); + var supportsVisualBasic = solution.Projects.Any(p => p.Language.Equals(LanguageNames.VisualBasic, StringComparison.OrdinalIgnoreCase)); + if (supportsCSharp) + { + TryAddProviderForLanguage(LanguageNames.CSharp, workspace, providers); + } + if (supportsVisualBasic) + { + TryAddProviderForLanguage(LanguageNames.VisualBasic, workspace, providers); + } + + return new CombinedOptionsProviderFactory(providers.ToImmutableArray()); + + static void TryAddProviderForLanguage(string language, Workspace workspace, List> providers) + { + var provider = workspace.Services.GetLanguageServices(language).GetService>(); + if (provider is not null) + { + providers.Add(provider); + } + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs new file mode 100644 index 0000000000000..87a8598b69e32 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Aggregator/SettingsAggregatorFactory.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings +{ + + [ExportWorkspaceServiceFactory(typeof(ISettingsAggregator), ServiceLayer.Default), Shared] + internal class SettingsAggregatorFactory : IWorkspaceServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public SettingsAggregatorFactory() + { + } + + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) + => new SettingsAggregator(workspaceServices.Workspace); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/AnalyzerSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/AnalyzerSetting.cs new file mode 100644 index 0000000000000..98cef0b4f22be --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/AnalyzerSetting.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Globalization; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal class AnalyzerSetting + { + private readonly DiagnosticDescriptor _descriptor; + private readonly AnalyzerSettingsUpdater _settingsUpdater; + + public AnalyzerSetting(DiagnosticDescriptor descriptor, + ReportDiagnostic effectiveSeverity, + AnalyzerSettingsUpdater settingsUpdater, + Language language) + { + _descriptor = descriptor; + _settingsUpdater = settingsUpdater; + DiagnosticSeverity severity = default; + if (effectiveSeverity == ReportDiagnostic.Default) + { + severity = descriptor.DefaultSeverity; + } + else if (effectiveSeverity.ToDiagnosticSeverity() is DiagnosticSeverity severity1) + { + severity = severity1; + } + + var enabled = effectiveSeverity != ReportDiagnostic.Suppress; + IsEnabled = enabled; + Severity = severity; + Language = language; + } + + public string Id => _descriptor.Id; + public string Title => _descriptor.Title.ToString(CultureInfo.CurrentCulture); + public string Description => _descriptor.Description.ToString(CultureInfo.CurrentCulture); + public string Category => _descriptor.Category; + public DiagnosticSeverity Severity { get; private set; } + public bool IsEnabled { get; private set; } + public Language Language { get; } + + internal void ChangeSeverity(DiagnosticSeverity severity) + { + if (severity == Severity) + return; + + Severity = severity; + _ = _settingsUpdater.QueueUpdateAsync(this, severity); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSetting.cs new file mode 100644 index 0000000000000..907245d073918 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSetting.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private class BooleanCodeStyleSetting : BooleanCodeStyleSettingBase + { + private readonly Option2> _option; + private readonly AnalyzerConfigOptions _editorConfigOptions; + private readonly OptionSet _visualStudioOptions; + + public BooleanCodeStyleSetting(Option2> option, + string description, + string? trueValueDescription, + string? falseValueDescription, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, option.Group.Description, trueValueDescription, falseValueDescription, updater) + { + _option = option; + _editorConfigOptions = editorConfigOptions; + _visualStudioOptions = visualStudioOptions; + } + + public override bool IsDefinedInEditorConfig => _editorConfigOptions.TryGetEditorConfigOption>(_option, out _); + + protected override void ChangeSeverity(NotificationOption2 severity) + { + var option = GetOption(); + option.Notification = severity; + _ = Updater.QueueUpdateAsync(_option, option); + } + + public override void ChangeValue(int valueIndex) + { + var value = valueIndex == 0; + var option = GetOption(); + option.Value = value; + _ = Updater.QueueUpdateAsync(_option, option); + } + + protected override CodeStyleOption2 GetOption() + => _editorConfigOptions.TryGetEditorConfigOption(_option, out CodeStyleOption2? value) && value is not null + ? value + : _visualStudioOptions.GetOption(_option); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSettingBase.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSettingBase.cs new file mode 100644 index 0000000000000..bd2e3822b24b7 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.BooleanCodeStyleSettingBase.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private abstract class BooleanCodeStyleSettingBase : CodeStyleSetting + { + private readonly string _trueValueDescription; + private readonly string _falseValueDescription; + + public BooleanCodeStyleSettingBase(string description, + string category, + string? trueValueDescription, + string? falseValueDescription, + OptionUpdater updater) + : base(description, updater) + { + Category = category; + _trueValueDescription = trueValueDescription ?? EditorFeaturesResources.Yes; + _falseValueDescription = falseValueDescription ?? EditorFeaturesResources.No; + } + + public override string Category { get; } + public override Type Type => typeof(bool); + public override DiagnosticSeverity Severity => GetOption().Notification.Severity.ToDiagnosticSeverity() ?? DiagnosticSeverity.Hidden; + public override string GetCurrentValue() => GetOption().Value ? _trueValueDescription : _falseValueDescription; + public override object? Value => GetOption().Value; + public override string[] GetValues() => new[] { _trueValueDescription, _falseValueDescription }; + protected abstract CodeStyleOption2 GetOption(); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSetting.cs new file mode 100644 index 0000000000000..8506d092f0315 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSetting.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private class EnumCodeStyleSetting : EnumCodeStyleSettingBase + where T : Enum + { + private readonly Option2> _option; + private readonly AnalyzerConfigOptions _editorConfigOptions; + private readonly OptionSet _visualStudioOptions; + + public EnumCodeStyleSetting(Option2> option, + string description, + T[] enumValues, + string[] valueDescriptions, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, enumValues, valueDescriptions, option.Group.Description, updater) + { + _option = option; + _editorConfigOptions = editorConfigOptions; + _visualStudioOptions = visualStudioOptions; + } + + public override bool IsDefinedInEditorConfig => _editorConfigOptions.TryGetEditorConfigOption>(_option, out _); + + protected override void ChangeSeverity(NotificationOption2 severity) + { + var option = GetOption(); + option.Notification = severity; + _ = Updater.QueueUpdateAsync(_option, option); + } + + public override void ChangeValue(int valueIndex) + { + var option = GetOption(); + option.Value = _enumValues[valueIndex]; + _ = Updater.QueueUpdateAsync(_option, option); + } + + protected override CodeStyleOption2 GetOption() + => _editorConfigOptions.TryGetEditorConfigOption(_option, out CodeStyleOption2? value) && value is not null + ? value + : _visualStudioOptions.GetOption(_option); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSettingBase.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSettingBase.cs new file mode 100644 index 0000000000000..8856236da98cc --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.EnumCodeStyleSettingBase.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Utilities; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private abstract class EnumCodeStyleSettingBase : CodeStyleSetting + where T : Enum + { + protected readonly T[] _enumValues; + private readonly string[] _valueDescriptions; + + public EnumCodeStyleSettingBase(string description, + T[] enumValues, + string[] valueDescriptions, + string category, + OptionUpdater updater) + : base(description, updater) + { + if (enumValues.Length != valueDescriptions.Length) + { + throw new InvalidOperationException("Values and descriptions must have matching number of elements"); + } + _enumValues = enumValues; + _valueDescriptions = valueDescriptions; + Category = category; + } + + public override string Category { get; } + public override Type Type => typeof(T); + public override string GetCurrentValue() => _valueDescriptions[_enumValues.IndexOf(GetOption().Value)]; + public override object? Value => GetOption().Value; + public override DiagnosticSeverity Severity => GetOption().Notification.Severity.ToDiagnosticSeverity() ?? DiagnosticSeverity.Hidden; + public override string[] GetValues() => _valueDescriptions; + protected abstract CodeStyleOption2 GetOption(); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageBooleanCodeStyleSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageBooleanCodeStyleSetting.cs new file mode 100644 index 0000000000000..b71d06986e1a5 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageBooleanCodeStyleSetting.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private class PerLanguageBooleanCodeStyleSetting : BooleanCodeStyleSettingBase + { + private readonly PerLanguageOption2> _option; + private readonly AnalyzerConfigOptions _editorConfigOptions; + private readonly OptionSet _visualStudioOptions; + + public PerLanguageBooleanCodeStyleSetting(PerLanguageOption2> option, + string description, + string? trueValueDescription, + string? falseValueDescription, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, option.Group.Description, trueValueDescription, falseValueDescription, updater) + { + _option = option; + _editorConfigOptions = editorConfigOptions; + _visualStudioOptions = visualStudioOptions; + } + + public override bool IsDefinedInEditorConfig => _editorConfigOptions.TryGetEditorConfigOption>(_option, out _); + + protected override void ChangeSeverity(NotificationOption2 severity) + { + var option = GetOption(); + option.Notification = severity; + _ = Updater.QueueUpdateAsync(_option, option); + } + + public override void ChangeValue(int valueIndex) + { + var value = valueIndex == 0; + var option = GetOption(); + option.Value = value; + _ = Updater.QueueUpdateAsync(_option, option); + } + + protected override CodeStyleOption2 GetOption() + => _editorConfigOptions.TryGetEditorConfigOption(_option, out CodeStyleOption2? value) && value is not null + ? value + : _visualStudioOptions.GetOption>(new OptionKey2(_option, LanguageNames.CSharp)); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageEnumCodeStyleSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageEnumCodeStyleSetting.cs new file mode 100644 index 0000000000000..df33ae0c833e6 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.PerLanguageEnumCodeStyleSetting.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + private class PerLanguageEnumCodeStyleSetting : EnumCodeStyleSettingBase + where T : Enum + { + private readonly PerLanguageOption2> _option; + private readonly AnalyzerConfigOptions _editorConfigOptions; + private readonly OptionSet _visualStudioOptions; + + public PerLanguageEnumCodeStyleSetting(PerLanguageOption2> option, + string description, + T[] enumValues, + string[] valueDescriptions, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, enumValues, valueDescriptions, option.Group.Description, updater) + { + _option = option; + _editorConfigOptions = editorConfigOptions; + _visualStudioOptions = visualStudioOptions; + } + + public override bool IsDefinedInEditorConfig => _editorConfigOptions.TryGetEditorConfigOption>(_option, out _); + + protected override void ChangeSeverity(NotificationOption2 severity) + { + var option = GetOption(); + option.Notification = severity; + _ = Updater.QueueUpdateAsync(_option, option); + } + + public override void ChangeValue(int valueIndex) + { + var option = GetOption(); + option.Value = _enumValues[valueIndex]; + _ = Updater.QueueUpdateAsync(_option, option); + } + + protected override CodeStyleOption2 GetOption() + => _editorConfigOptions.TryGetEditorConfigOption(_option, out CodeStyleOption2? value) && value is not null + ? value + // TODO(jmarolf): Should we expose duplicate options if the user has a different setting in VB vs. C#? + // Today this code will choose whatever option is set for C# as the default. + : _visualStudioOptions.GetOption>(new OptionKey2(_option, LanguageNames.CSharp)); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.cs new file mode 100644 index 0000000000000..c00bb71b00617 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/CodeStyle/CodeStyleSetting.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract partial class CodeStyleSetting + { + public string Description { get; } + + protected readonly OptionUpdater Updater; + + public abstract string Category { get; } + public abstract object? Value { get; } + public abstract Type Type { get; } + public abstract string[] GetValues(); + public abstract string GetCurrentValue(); + public abstract DiagnosticSeverity Severity { get; } + public abstract bool IsDefinedInEditorConfig { get; } + + public CodeStyleSetting(string description, OptionUpdater updater) + { + Description = description; + Updater = updater; + } + + public void ChangeSeverity(DiagnosticSeverity severity) + { + var notification = severity switch + { + DiagnosticSeverity.Hidden => NotificationOption2.Silent, + DiagnosticSeverity.Info => NotificationOption2.Suggestion, + DiagnosticSeverity.Warning => NotificationOption2.Warning, + DiagnosticSeverity.Error => NotificationOption2.Error, + _ => NotificationOption2.None, + }; + + ChangeSeverity(notification); + } + + protected abstract void ChangeSeverity(NotificationOption2 severity); + public abstract void ChangeValue(int valueIndex); + + internal static CodeStyleSetting Create(Option2> option, + string description, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater, + string? trueValueDescription = null, + string? falseValueDescription = null) + { + return new BooleanCodeStyleSetting(option, description, trueValueDescription, falseValueDescription, editorConfigOptions, visualStudioOptions, updater); + } + + internal static CodeStyleSetting Create(PerLanguageOption2> option, + string description, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater, + string? trueValueDescription = null, + string? falseValueDescription = null) + { + return new PerLanguageBooleanCodeStyleSetting(option, description, trueValueDescription, falseValueDescription, editorConfigOptions, visualStudioOptions, updater); + } + + internal static CodeStyleSetting Create(Option2> option, + string description, + T[] enumValues, + string[] valueDescriptions, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + where T : Enum + { + return new EnumCodeStyleSetting(option, description, enumValues, valueDescriptions, editorConfigOptions, visualStudioOptions, updater); + } + + internal static CodeStyleSetting Create(PerLanguageOption2> option, + string description, + T[] enumValues, + string[] valueDescriptions, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + where T : Enum + { + return new PerLanguageEnumCodeStyleSetting(option, description, enumValues, valueDescriptions, editorConfigOptions, visualStudioOptions, updater); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting.cs new file mode 100644 index 0000000000000..a013f3ad40551 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal abstract class FormattingSetting + { + protected OptionUpdater Updater { get; } + protected string? Language { get; } + + protected FormattingSetting(string description, OptionUpdater updater, string? language = null) + { + Description = description ?? throw new ArgumentNullException(nameof(description)); + Updater = updater; + Language = language; + } + + public string Description { get; } + public abstract string Category { get; } + public abstract Type Type { get; } + public abstract OptionKey2 Key { get; } + public abstract void SetValue(object value); + public abstract object? GetValue(); + public abstract bool IsDefinedInEditorConfig { get; } + + public static PerLanguageFormattingSetting Create(PerLanguageOption2 option, + string description, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + where TOption : notnull + { + return new PerLanguageFormattingSetting(option, description, editorConfigOptions, visualStudioOptions, updater); + } + + public static FormattingSetting Create(Option2 option, + string description, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + where TOption : struct + { + return new FormattingSetting(option, description, editorConfigOptions, visualStudioOptions, updater); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting`1.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting`1.cs new file mode 100644 index 0000000000000..0fcfecad99b36 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/FormattingSetting`1.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal sealed class FormattingSetting : FormattingSetting + where T : notnull + { + public override bool IsDefinedInEditorConfig => _options.TryGetEditorConfigOption(_option, out _); + + private bool _isValueSet; + private T? _value; + public T Value + { + private set + { + if (!_isValueSet) + { + _isValueSet = true; + } + + _value = value; + } + get + { + if (_value is not null && _isValueSet) + { + return _value; + } + + if (_options.TryGetEditorConfigOption(_option, out T? value) && + value is not null) + { + return value; + } + + return _visualStudioOptions.GetOption(_option); + } + } + + public override Type Type => typeof(T); + public override string Category => _option.Group.Description; + + public override OptionKey2 Key => new(_option, _option.OptionDefinition.IsPerLanguage ? Language ?? LanguageNames.CSharp : null); + + private readonly Option2 _option; + private readonly AnalyzerConfigOptions _options; + private readonly OptionSet _visualStudioOptions; + + public FormattingSetting(Option2 option, + string description, + AnalyzerConfigOptions options, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, updater) + { + _option = option; + _options = options; + _visualStudioOptions = visualStudioOptions; + } + + public override void SetValue(object value) + { + Value = (T)value; + _ = Updater.QueueUpdateAsync(_option, value); + } + + public override object? GetValue() => Value; + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/PerLanguageFormattingSetting.cs b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/PerLanguageFormattingSetting.cs new file mode 100644 index 0000000000000..aebf191e07ba2 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Data/Formatting/PerLanguageFormattingSetting.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data +{ + internal sealed class PerLanguageFormattingSetting : FormattingSetting + where T : notnull + { + private bool _isValueSet; + private T? _value; + public T Value + { + private set + { + if (!_isValueSet) + { + _isValueSet = true; + } + + _value = value; + } + get + { + if (_value is not null && _isValueSet) + { + return _value; + } + + if (_editorConfigOptions.TryGetEditorConfigOption(_option, out T? value) && + value is not null) + { + return value; + } + + return (T)_visualStudioOptions.GetOption(Key)!; + } + } + + private readonly PerLanguageOption2 _option; + private readonly AnalyzerConfigOptions _editorConfigOptions; + private readonly OptionSet _visualStudioOptions; + + public PerLanguageFormattingSetting(PerLanguageOption2 option, + string description, + AnalyzerConfigOptions editorConfigOptions, + OptionSet visualStudioOptions, + OptionUpdater updater) + : base(description, updater) + { + _option = option; + _editorConfigOptions = editorConfigOptions; + _visualStudioOptions = visualStudioOptions; + } + + public override string Category => _option.Group.Description; + public override Type Type => typeof(T); + + public override OptionKey2 Key => new(_option, _option.OptionDefinition.IsPerLanguage ? Language ?? LanguageNames.CSharp : null); + + public override bool IsDefinedInEditorConfig => _editorConfigOptions.TryGetEditorConfigOption(_option, out _); + + public override void SetValue(object value) + { + Value = (T)value; + _ = Updater.QueueUpdateAsync(_option, value); + } + + public override object? GetValue() => Value; + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs new file mode 100644 index 0000000000000..61f2157801f12 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProvider.cs @@ -0,0 +1,88 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Extensions; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Analyzer +{ + internal class AnalyzerSettingsProvider : SettingsProviderBase + { + private readonly IDiagnosticAnalyzerService _analyzerService; + + public AnalyzerSettingsProvider(string fileName, AnalyzerSettingsUpdater settingsUpdater, Workspace workspace, IDiagnosticAnalyzerService analyzerService) + : base(fileName, settingsUpdater, workspace) + { + _analyzerService = analyzerService; + Update(); + } + + protected override void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet _) + { + var solution = Workspace.CurrentSolution; + var projects = solution.GetProjectsForPath(FileName); + var analyzerReferences = projects.SelectMany(p => p.AnalyzerReferences).DistinctBy(a => a.Id).ToImmutableArray(); + foreach (var analyzerReference in analyzerReferences) + { + var configSettings = GetSettings(analyzerReference, editorConfigOptions); + AddRange(configSettings); + } + } + + private IEnumerable GetSettings(AnalyzerReference analyzerReference, AnalyzerConfigOptions editorConfigOptions) + { + IEnumerable csharpAnalyzers = analyzerReference.GetAnalyzers(LanguageNames.CSharp); + IEnumerable visualBasicAnalyzers = analyzerReference.GetAnalyzers(LanguageNames.VisualBasic); + var dotnetAnalyzers = csharpAnalyzers.Intersect(visualBasicAnalyzers, DiagnosticAnalyzerComparer.Instance); + csharpAnalyzers = csharpAnalyzers.Except(dotnetAnalyzers, DiagnosticAnalyzerComparer.Instance); + visualBasicAnalyzers = visualBasicAnalyzers.Except(dotnetAnalyzers, DiagnosticAnalyzerComparer.Instance); + + var csharpSettings = ToAnalyzerSetting(csharpAnalyzers, Language.CSharp); + var csharpAndVisualBasicSettings = csharpSettings.Concat(ToAnalyzerSetting(visualBasicAnalyzers, Language.VisualBasic)); + return csharpAndVisualBasicSettings.Concat(ToAnalyzerSetting(dotnetAnalyzers, Language.CSharp | Language.VisualBasic)); + + IEnumerable ToAnalyzerSetting(IEnumerable analyzers, + Language language) + { + return analyzers + .SelectMany(a => _analyzerService.AnalyzerInfoCache.GetDiagnosticDescriptors(a)) + .GroupBy(d => d.Id) + .OrderBy(g => g.Key, StringComparer.CurrentCulture) + .Select(g => + { + var selectedDiagnostic = g.First(); + var severity = selectedDiagnostic.GetEffectiveSeverity(editorConfigOptions); + return new AnalyzerSetting(selectedDiagnostic, severity, SettingsUpdater, language); + }); + } + } + + private class DiagnosticAnalyzerComparer : IEqualityComparer + { + public static readonly DiagnosticAnalyzerComparer Instance = new(); + + public bool Equals(DiagnosticAnalyzer? x, DiagnosticAnalyzer? y) + { + if (x is null && y is null) + return true; + + if (x is null || y is null) + return false; + + return x.GetAnalyzerIdAndVersion().GetHashCode() == y.GetAnalyzerIdAndVersion().GetHashCode(); + } + + public int GetHashCode(DiagnosticAnalyzer obj) => obj.GetAnalyzerIdAndVersion().GetHashCode(); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProviderFactory.cs new file mode 100644 index 0000000000000..9f145c3f021d0 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsProviderFactory.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Analyzer +{ + internal class AnalyzerSettingsProviderFactory : IWorkspaceSettingsProviderFactory + { + private readonly Workspace _workspace; + private readonly IDiagnosticAnalyzerService _analyzerService; + + public AnalyzerSettingsProviderFactory(Workspace workspace, IDiagnosticAnalyzerService analyzerService) + { + _workspace = workspace; + _analyzerService = analyzerService; + } + + public ISettingsProvider GetForFile(string filePath) + { + var updater = new AnalyzerSettingsUpdater(_workspace, filePath); + return new AnalyzerSettingsProvider(filePath, updater, _workspace, _analyzerService); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsWorkspaceServiceFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsWorkspaceServiceFactory.cs new file mode 100644 index 0000000000000..5b7ed248bf9d8 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Analyzer/AnalyzerSettingsWorkspaceServiceFactory.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Analyzer +{ + [ExportWorkspaceServiceFactory(typeof(IWorkspaceSettingsProviderFactory)), Shared] + internal class AnalyzerSettingsWorkspaceServiceFactory : IWorkspaceServiceFactory + { + private readonly IDiagnosticAnalyzerService _analyzerService; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerSettingsWorkspaceServiceFactory(IDiagnosticAnalyzerService analyzerService) + { + _analyzerService = analyzerService; + } + + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) + => new AnalyzerSettingsProviderFactory(workspaceServices.Workspace, _analyzerService); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs new file mode 100644 index 0000000000000..adcba7ae06210 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProvider.cs @@ -0,0 +1,190 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.CodeStyle +{ + internal class CommonCodeStyleSettingsProvider : SettingsProviderBase + { + public CommonCodeStyleSettingsProvider(string filePath, OptionUpdater settingsUpdater, Workspace workspace) + : base(filePath, settingsUpdater, workspace) + { + Update(); + } + + protected override void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions) + { + var qualifySettings = GetQualifyCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(qualifySettings); + + var predefinedTypesSettings = GetPredefinedTypesCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(predefinedTypesSettings); + + var nullCheckingSettings = GetNullCheckingCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(nullCheckingSettings); + + var modifierSettings = GetModifierCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(modifierSettings); + + var codeBlockSettings = GetCodeBlockCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(codeBlockSettings); + + var expressionSettings = GetExpressionCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(expressionSettings); + + var parameterSettings = GetParameterCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(parameterSettings); + + var parenthesesSettings = GetParenthesesCodeStyleOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(parenthesesSettings); + + // TODO(jmarolf): set as stable + } + + private static IEnumerable GetQualifyCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.QualifyFieldAccess, + description: EditorFeaturesResources.Qualify_field_access_with_this_or_Me, + trueValueDescription: EditorFeaturesResources.Prefer_this_or_Me, + falseValueDescription: EditorFeaturesResources.Do_not_prefer_this_or_Me, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.QualifyPropertyAccess, + description: EditorFeaturesResources.Qualify_property_access_with_this_or_Me, + trueValueDescription: EditorFeaturesResources.Prefer_this_or_Me, + falseValueDescription: EditorFeaturesResources.Do_not_prefer_this_or_Me, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.QualifyMethodAccess, + description: EditorFeaturesResources.Qualify_method_access_with_this_or_Me, + trueValueDescription: EditorFeaturesResources.Prefer_this_or_Me, + falseValueDescription: EditorFeaturesResources.Do_not_prefer_this_or_Me, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.QualifyEventAccess, + description: EditorFeaturesResources.Qualify_event_access_with_this_or_Me, + trueValueDescription: EditorFeaturesResources.Prefer_this_or_Me, + falseValueDescription: EditorFeaturesResources.Do_not_prefer_this_or_Me, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + + private static IEnumerable GetPredefinedTypesCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, + description: EditorFeaturesResources.For_locals_parameters_and_members, + trueValueDescription: EditorFeaturesResources.Prefer_predefined_type, + falseValueDescription: EditorFeaturesResources.Prefer_framework_type, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, + description: EditorFeaturesResources.For_member_access_expressions, + trueValueDescription: EditorFeaturesResources.Prefer_predefined_type, + falseValueDescription: EditorFeaturesResources.Prefer_framework_type, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + + private static IEnumerable GetNullCheckingCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferCoalesceExpression, + description: EditorFeaturesResources.Prefer_coalesce_expression, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferNullPropagation, + description: EditorFeaturesResources.Prefer_null_propagation, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferIsNullCheckOverReferenceEqualityMethod, + description: EditorFeaturesResources.Prefer_is_null_for_reference_equality_checks, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + + private static IEnumerable GetModifierCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferReadonly, + description: EditorFeaturesResources.Prefer_readonly_fields, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + + private static IEnumerable GetCodeBlockCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferAutoProperties, + description: EditorFeaturesResources.analyzer_Prefer_auto_properties, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.PreferSystemHashCode, + description: EditorFeaturesResources.Prefer_System_HashCode_in_GetHashCode, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + + private static IEnumerable GetExpressionCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferObjectInitializer, description: EditorFeaturesResources.Prefer_object_initializer, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferCollectionInitializer, description: EditorFeaturesResources.Prefer_collection_initializer, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferSimplifiedBooleanExpressions, description: EditorFeaturesResources.Prefer_simplified_boolean_expressions, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferConditionalExpressionOverAssignment, description: EditorFeaturesResources.Prefer_conditional_expression_over_if_with_assignments, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferConditionalExpressionOverReturn, description: EditorFeaturesResources.Prefer_conditional_expression_over_if_with_returns, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferExplicitTupleNames, description: EditorFeaturesResources.Prefer_explicit_tuple_name, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferInferredTupleNames, description: EditorFeaturesResources.Prefer_inferred_tuple_names, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferInferredAnonymousTypeMemberNames, description: EditorFeaturesResources.Prefer_inferred_anonymous_type_member_names, options, visualStudioOptions, updater); + yield return CodeStyleSetting.Create(CodeStyleOptions2.PreferCompoundAssignment, description: EditorFeaturesResources.Prefer_compound_assignments, options, visualStudioOptions, updater); + } + + private static IEnumerable GetParenthesesCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + var enumValues = new[] { ParenthesesPreference.AlwaysForClarity, ParenthesesPreference.NeverIfUnnecessary }; + var valueDescriptions = new[] { EditorFeaturesResources.Always_for_clarity, EditorFeaturesResources.Never_if_unnecessary }; + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.ArithmeticBinaryParentheses, + description: EditorFeaturesResources.In_arithmetic_binary_operators, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.OtherBinaryParentheses, + description: EditorFeaturesResources.In_other_binary_operators, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.RelationalBinaryParentheses, + description: EditorFeaturesResources.In_relational_binary_operators, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + + yield return CodeStyleSetting.Create(option: CodeStyleOptions2.OtherParentheses, + description: EditorFeaturesResources.In_other_operators, + enumValues: enumValues, + valueDescriptions: valueDescriptions, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + + } + + private static IEnumerable GetParameterCodeStyleOptions(AnalyzerConfigOptions options, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return CodeStyleSetting.Create( + option: CodeStyleOptions2.UnusedParameters, + description: EditorFeaturesResources.Avoid_unused_parameters, + enumValues: new[] { UnusedParametersPreference.NonPublicMethods, UnusedParametersPreference.AllMethods }, + new[] { EditorFeaturesResources.Non_public_methods, EditorFeaturesResources.All_methods }, + editorConfigOptions: options, + visualStudioOptions: visualStudioOptions, updater: updater); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProviderFactory.cs new file mode 100644 index 0000000000000..2477ecf668c1c --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsProviderFactory.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.CodeStyle +{ + internal class CommonCodeStyleSettingsProviderFactory : IWorkspaceSettingsProviderFactory + { + private readonly Workspace _workspace; + + public CommonCodeStyleSettingsProviderFactory(Workspace workspace) => _workspace = workspace; + + public ISettingsProvider GetForFile(string filePath) + => new CommonCodeStyleSettingsProvider(filePath, new OptionUpdater(_workspace, filePath), _workspace); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsWorkspaceServiceFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsWorkspaceServiceFactory.cs new file mode 100644 index 0000000000000..2a34627f74a2d --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CodeStyle/CommonCodeStyleSettingsWorkspaceServiceFactory.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.CodeStyle +{ + [ExportWorkspaceServiceFactory(typeof(IWorkspaceSettingsProviderFactory)), Shared] + internal class CommonCodeStyleSettingsWorkspaceServiceFactory : IWorkspaceServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CommonCodeStyleSettingsWorkspaceServiceFactory() { } + + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) + => new CommonCodeStyleSettingsProviderFactory(workspaceServices.Workspace); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedOptionsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedOptionsProviderFactory.cs new file mode 100644 index 0000000000000..1000896c6a68e --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedOptionsProviderFactory.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Shared.Collections; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal class CombinedOptionsProviderFactory : ISettingsProviderFactory + { + private ImmutableArray> _factories; + + public CombinedOptionsProviderFactory(ImmutableArray> factories) + { + _factories = factories; + } + + public ISettingsProvider GetForFile(string filePath) + { + var providers = TemporaryArray>.Empty; + foreach (var factory in _factories) + { + providers.Add(factory.GetForFile(filePath)); + } + + return new CombinedProvider(providers.ToImmutableAndClear()); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedProvider.cs new file mode 100644 index 0000000000000..f7eef8dddc1e7 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/CombinedProvider.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal class CombinedProvider : ISettingsProvider + { + private readonly ImmutableArray> _providers; + + public CombinedProvider(ImmutableArray> providers) + { + _providers = providers; + } + + public async Task GetChangedEditorConfigAsync(SourceText sourceText) + { + foreach (var provider in _providers) + { + sourceText = await provider.GetChangedEditorConfigAsync(sourceText).ConfigureAwait(false); + } + + return sourceText; + } + + public ImmutableArray GetCurrentDataSnapshot() + { + var snapShot = ImmutableArray.Empty; + foreach (var provider in _providers) + { + snapShot = snapShot.Concat(provider.GetCurrentDataSnapshot()); + } + + return snapShot; + } + + public void RegisterViewModel(ISettingsEditorViewModel model) + { + foreach (var provider in _providers) + { + provider.RegisterViewModel(model); + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProvider.cs new file mode 100644 index 0000000000000..4a9a86ad21ada --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProvider.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Formatting +{ + internal class CommonFormattingSettingsProvider : SettingsProviderBase + { + public CommonFormattingSettingsProvider(string fileName, OptionUpdater settingsUpdater, Workspace workspace) + : base(fileName, settingsUpdater, workspace) + { + Update(); + } + + protected override void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions) + { + var defaultOptions = GetDefaultOptions(editorConfigOptions, visualStudioOptions, SettingsUpdater); + AddRange(defaultOptions); + } + + private static IEnumerable GetDefaultOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updater) + { + yield return FormattingSetting.Create(FormattingOptions2.UseTabs, EditorFeaturesResources.Use_Tabs, editorConfigOptions, visualStudioOptions, updater); + yield return FormattingSetting.Create(FormattingOptions2.TabSize, EditorFeaturesResources.Tab_Size, editorConfigOptions, visualStudioOptions, updater); + yield return FormattingSetting.Create(FormattingOptions2.IndentationSize, EditorFeaturesResources.Indentation_Size, editorConfigOptions, visualStudioOptions, updater); + yield return FormattingSetting.Create(FormattingOptions2.NewLine, EditorFeaturesResources.New_Line, editorConfigOptions, visualStudioOptions, updater); + yield return FormattingSetting.Create(FormattingOptions2.InsertFinalNewLine, EditorFeaturesResources.Insert_Final_Newline, editorConfigOptions, visualStudioOptions, updater); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProviderFactory.cs new file mode 100644 index 0000000000000..21d130c599f42 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsProviderFactory.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Formatting +{ + internal class CommonFormattingSettingsProviderFactory : IWorkspaceSettingsProviderFactory + { + private readonly Workspace _workspace; + + public CommonFormattingSettingsProviderFactory(Workspace workspace) => _workspace = workspace; + + public ISettingsProvider GetForFile(string filePath) + => new CommonFormattingSettingsProvider(filePath, new OptionUpdater(_workspace, filePath), _workspace); + + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsWorkspaceServiceFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsWorkspaceServiceFactory.cs new file mode 100644 index 0000000000000..878bd1198987d --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/Formatting/CommonFormattingSettingsWorkspaceServiceFactory.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider.Formatting +{ + [ExportWorkspaceServiceFactory(typeof(IWorkspaceSettingsProviderFactory)), Shared] + internal class CommonFormattingSettingsWorkspaceServiceFactory : IWorkspaceServiceFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CommonFormattingSettingsWorkspaceServiceFactory() { } + + public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) + => new CommonFormattingSettingsProviderFactory(workspaceServices.Workspace); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ILanguageSettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ILanguageSettingsProviderFactory.cs new file mode 100644 index 0000000000000..800df15d4f056 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ILanguageSettingsProviderFactory.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal interface ILanguageSettingsProviderFactory : ISettingsProviderFactory, ILanguageService + { + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProvider.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProvider.cs new file mode 100644 index 0000000000000..7eaece9b9f9ed --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProvider.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal interface ISettingsProvider + { + void RegisterViewModel(ISettingsEditorViewModel model); + ImmutableArray GetCurrentDataSnapshot(); + Task GetChangedEditorConfigAsync(SourceText sourceText); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProviderFactory.cs new file mode 100644 index 0000000000000..4c87bfb021ae3 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/ISettingsProviderFactory.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal interface ISettingsProviderFactory + { + ISettingsProvider GetForFile(string filePath); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/IWorkspaceSettingsProviderFactory.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/IWorkspaceSettingsProviderFactory.cs new file mode 100644 index 0000000000000..a241256ac0d26 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/IWorkspaceSettingsProviderFactory.cs @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal interface IWorkspaceSettingsProviderFactory : ISettingsProviderFactory, IWorkspaceService + { + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs new file mode 100644 index 0000000000000..c39d19813506b --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/DataProvider/SettingsProviderBase.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Extensions; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.Utilities; +using static Microsoft.CodeAnalysis.ProjectState; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider +{ + internal abstract class SettingsProviderBase : ISettingsProvider + where TOptionsUpdater : ISettingUpdater + { + private readonly List _snapshot = new(); + private static readonly object s_gate = new(); + private ISettingsEditorViewModel? _viewModel; + protected readonly string FileName; + protected readonly TOptionsUpdater SettingsUpdater; + protected readonly Workspace Workspace; + + protected abstract void UpdateOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions); + + protected SettingsProviderBase(string fileName, TOptionsUpdater settingsUpdater, Workspace workspace) + { + FileName = fileName; + SettingsUpdater = settingsUpdater; + Workspace = workspace; + } + + protected void Update() + { + var givenFolder = new DirectoryInfo(FileName).Parent; + var solution = Workspace.CurrentSolution; + var projects = solution.GetProjectsForPath(FileName); + var project = projects.First(); + var configOptionsProvider = new WorkspaceAnalyzerConfigOptionsProvider(project.State); + var workspaceOptions = configOptionsProvider.GetOptionsForSourcePath(givenFolder.FullName); + var result = project.GetAnalyzerConfigOptions(); + var options = new CombinedAnalyzerConfigOptions(workspaceOptions, result); + UpdateOptions(options, Workspace.Options); + } + + public async Task GetChangedEditorConfigAsync(SourceText sourceText) + { + if (!await SettingsUpdater.HasAnyChangesAsync().ConfigureAwait(false)) + { + return sourceText; + } + + var text = await SettingsUpdater.GetChangedEditorConfigAsync(sourceText, default).ConfigureAwait(false); + return text is not null ? text : sourceText; + } + + public ImmutableArray GetCurrentDataSnapshot() + { + lock (s_gate) + { + return _snapshot.ToImmutableArray(); + } + } + + protected void AddRange(IEnumerable items) + { + lock (s_gate) + { + _snapshot.AddRange(items); + } + + _viewModel?.NotifyOfUpdate(); + } + + public void RegisterViewModel(ISettingsEditorViewModel viewModel) + => _viewModel = viewModel ?? throw new ArgumentNullException(nameof(viewModel)); + + private sealed class CombinedAnalyzerConfigOptions : AnalyzerConfigOptions + { + private readonly AnalyzerConfigOptions _workspaceOptions; + private readonly AnalyzerConfigOptionsResult? _result; + + public CombinedAnalyzerConfigOptions(AnalyzerConfigOptions workspaceOptions, AnalyzerConfigOptionsResult? result) + { + _workspaceOptions = workspaceOptions; + _result = result; + } + + public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) + { + if (_workspaceOptions.TryGetValue(key, out value)) + { + return true; + } + + if (!_result.HasValue) + { + value = null; + return false; + } + + if (_result.Value.AnalyzerOptions.TryGetValue(key, out value)) + { + return true; + } + + var diagnosticKey = "dotnet_diagnostic.(?.*).severity"; + var match = Regex.Match(key, diagnosticKey); + if (match.Success && match.Groups["key"].Value is string isolatedKey && + _result.Value.TreeOptions.TryGetValue(isolatedKey, out var severity)) + { + value = severity.ToEditorConfigString(); + return true; + } + + value = null; + return false; + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Extensions/EnumerableExtensions.cs b/src/EditorFeatures/Core/EditorConfigSettings/Extensions/EnumerableExtensions.cs new file mode 100644 index 0000000000000..6ef0a5228cda0 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Extensions/EnumerableExtensions.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Extensions +{ + internal static class EnumerableExtensions + { + public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) + { + var seenKeys = new HashSet(); + foreach (var element in source) + { + if (seenKeys.Add(keySelector(element))) + { + yield return element; + } + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Extensions/SolutionExtensions.cs b/src/EditorFeatures/Core/EditorConfigSettings/Extensions/SolutionExtensions.cs new file mode 100644 index 0000000000000..fe06a29a6b5c8 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Extensions/SolutionExtensions.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.IO; +using System.Linq; +using Microsoft.CodeAnalysis.PooledObjects; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Extensions +{ + internal static class SolutionExtensions + { + public static ImmutableArray GetProjectsForPath(this Solution solution, string givenPath) + { + if (Path.GetDirectoryName(givenPath) is not string givenFolderPath || + solution.FilePath is null) + { + return solution.Projects.ToImmutableArray(); + } + + var givenFolder = new DirectoryInfo(givenFolderPath); + if (givenFolder.FullName == (new DirectoryInfo(solution.FilePath).Parent).FullName) + { + return solution.Projects.ToImmutableArray(); + } + + var builder = ArrayBuilder.GetInstance(); + foreach (var (projectDirectoryPath, project) in solution.Projects.Select(p => (new DirectoryInfo(p.FilePath).Parent, p))) + { + if (ContainsPath(givenFolder, projectDirectoryPath)) + { + builder.Add(project); + } + } + + return builder.ToImmutableAndFree(); + + static bool ContainsPath(DirectoryInfo givenPath, DirectoryInfo projectPath) + { + if (projectPath.FullName == givenPath.FullName) + { + return true; + } + + while (projectPath.Parent is not null) + { + if (projectPath.Parent.FullName == givenPath.FullName) + { + return true; + } + projectPath = projectPath.Parent; + } + + return false; + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/ISettingsEditorViewModel.cs b/src/EditorFeatures/Core/EditorConfigSettings/ISettingsEditorViewModel.cs new file mode 100644 index 0000000000000..5cabb84670fd5 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/ISettingsEditorViewModel.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor +{ + internal interface ISettingsEditorViewModel + { + void NotifyOfUpdate(); + Task UpdateEditorConfigAsync(SourceText sourceText); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Language.cs b/src/EditorFeatures/Core/EditorConfigSettings/Language.cs new file mode 100644 index 0000000000000..54002e7c301c0 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Language.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings +{ + [Flags] + internal enum Language + { + CSharp = 1, + VisualBasic = 2, + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Updater/AnalyzerSettingsUpdater.cs b/src/EditorFeatures/Core/EditorConfigSettings/Updater/AnalyzerSettingsUpdater.cs new file mode 100644 index 0000000000000..f96b83172e91a --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Updater/AnalyzerSettingsUpdater.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater +{ + internal class AnalyzerSettingsUpdater : SettingsUpdaterBase + { + public AnalyzerSettingsUpdater(Workspace workspace, string editorconfigPath) : base(workspace, editorconfigPath) + { + } + + protected override SourceText? GetNewText(SourceText sourceText, + IReadOnlyList<(AnalyzerSetting option, DiagnosticSeverity value)> settingsToUpdate, + CancellationToken token) + => SettingsUpdateHelper.TryUpdateAnalyzerConfigDocument(sourceText, EditorconfigPath, settingsToUpdate); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Updater/ISettingUpdater.cs b/src/EditorFeatures/Core/EditorConfigSettings/Updater/ISettingUpdater.cs new file mode 100644 index 0000000000000..fac1c922c97b6 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Updater/ISettingUpdater.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater +{ + internal interface ISettingUpdater + { + Task QueueUpdateAsync(TSetting setting, TValue value); + Task GetChangedEditorConfigAsync(SourceText sourceText, CancellationToken token); + Task HasAnyChangesAsync(); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Updater/OptionUpdater.cs b/src/EditorFeatures/Core/EditorConfigSettings/Updater/OptionUpdater.cs new file mode 100644 index 0000000000000..f57e0d103d397 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Updater/OptionUpdater.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater +{ + + internal class OptionUpdater : SettingsUpdaterBase + { + public OptionUpdater(Workspace workspace, string editorconfigPath) + : base(workspace, editorconfigPath) + { + } + + protected override SourceText? GetNewText(SourceText SourceText, + IReadOnlyList<(IOption2 option, object value)> settingsToUpdate, + CancellationToken token) + => SettingsUpdateHelper.TryUpdateAnalyzerConfigDocument(SourceText, EditorconfigPath, Workspace.Options, settingsToUpdate); + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdateHelper.cs b/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdateHelper.cs new file mode 100644 index 0000000000000..dd5ca9a124dc7 --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdateHelper.cs @@ -0,0 +1,352 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater +{ + internal static partial class SettingsUpdateHelper + { + private const string DiagnosticOptionPrefix = "dotnet_diagnostic."; + private const string SeveritySuffix = ".severity"; + + public static SourceText? TryUpdateAnalyzerConfigDocument(SourceText originalText, + string filePath, + IReadOnlyList<(AnalyzerSetting option, DiagnosticSeverity value)> settingsToUpdate) + { + if (originalText is null) + return null; + if (settingsToUpdate is null) + return null; + if (filePath is null) + return null; + + var settings = settingsToUpdate.Select(x => TryGetOptionValueAndLanguage(x.option, x.value)).ToList(); + + return TryUpdateAnalyzerConfigDocument(originalText, filePath, settings); + + static (string option, string value, Language language) TryGetOptionValueAndLanguage(AnalyzerSetting diagnostic, DiagnosticSeverity severity) + { + var optionName = $"{DiagnosticOptionPrefix}{diagnostic.Id}{SeveritySuffix}"; + var optionValue = severity.ToEditorConfigString(); + var language = diagnostic.Language; + return (optionName, optionValue, language); + } + } + + public static SourceText? TryUpdateAnalyzerConfigDocument(SourceText originalText, + string filePath, + OptionSet optionSet, + IReadOnlyList<(IOption2 option, object value)> settingsToUpdate) + { + if (originalText is null) + return null; + if (settingsToUpdate is null) + return null; + if (filePath is null) + return null; + + var updatedText = originalText; + var settings = settingsToUpdate.Select(x => TryGetOptionValueAndLanguage(x.option, x.value, optionSet)) + .Where(x => x.success) + .Select(x => (x.option, x.value, x.language)) + .ToList(); + + return TryUpdateAnalyzerConfigDocument(originalText, filePath, settings); + + static (bool success, string option, string value, Language language) TryGetOptionValueAndLanguage(IOption2 option, object value, OptionSet optionSet) + { + if (option.StorageLocations.FirstOrDefault(x => x is IEditorConfigStorageLocation2) is not IEditorConfigStorageLocation2 storageLocation) + { + return (false, null!, null!, default); + } + + var optionName = storageLocation.KeyName; + var optionValue = storageLocation.GetEditorConfigStringValue(value, optionSet); + if (value is ICodeStyleOption codeStyleOption && !optionValue.Contains(':')) + { + var severity = codeStyleOption.Notification switch + { + { Severity: ReportDiagnostic.Hidden } => "silent", + { Severity: ReportDiagnostic.Info } => "suggestion", + { Severity: ReportDiagnostic.Warn } => "warning", + { Severity: ReportDiagnostic.Error } => "error", + _ => string.Empty + }; + optionValue = $"{optionValue}:{severity}"; + } + + var language = option.IsPerLanguage ? Language.CSharp | Language.VisualBasic : Language.CSharp; + return (true, optionName, optionValue, language); + } + } + + public static SourceText? TryUpdateAnalyzerConfigDocument(SourceText originalText, + string filePath, + IReadOnlyList<(string option, string value, Language language)> settingsToUpdate) + { + if (originalText is null) + throw new ArgumentNullException(nameof(originalText)); + if (filePath is null) + throw new ArgumentNullException(nameof(filePath)); + if (settingsToUpdate is null) + throw new ArgumentNullException(nameof(settingsToUpdate)); + + var updatedText = originalText; + TextLine? lastValidHeaderSpanEnd; + TextLine? lastValidSpecificHeaderSpanEnd; + foreach (var (option, value, language) in settingsToUpdate) + { + SourceText? newText; + (newText, lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd) = UpdateIfExistsInFile(updatedText, filePath, option, value, language); + if (newText != null) + { + updatedText = newText; + continue; + } + + (newText, lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd) = AddMissingRule(updatedText, lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd, option, value, language); + if (newText != null) + { + updatedText = newText; + } + } + + return updatedText.Equals(originalText) ? null : updatedText; + } + + /// + /// Regular expression for .editorconfig header. + /// For example: "[*.cs] # Optional comment" + /// "[*.{vb,cs}]" + /// "[*] ; Optional comment" + /// "[ConsoleApp/Program.cs]" + /// + private static readonly Regex s_headerPattern = new(@"\[(\*|[^ #;\[\]]+\.({[^ #;{}\.\[\]]+}|[^ #;{}\.\[\]]+))\]\s*([#;].*)?"); + + /// + /// Regular expression for .editorconfig code style option entry. + /// For example: + /// 1. "dotnet_style_object_initializer = true # Optional comment" + /// 2. "dotnet_style_object_initializer = true:suggestion ; Optional comment" + /// 3. "dotnet_diagnostic.CA2000.severity = suggestion # Optional comment" + /// 4. "dotnet_analyzer_diagnostic.category-Security.severity = suggestion # Optional comment" + /// 5. "dotnet_analyzer_diagnostic.severity = suggestion # Optional comment" + /// Regex groups: + /// 1. Option key + /// 2. Option value + /// 3. Optional severity suffix in option value, i.e. ':severity' suffix + /// 4. Optional comment suffix + /// + private static readonly Regex s_optionEntryPattern = new($@"(.*)=([\w, ]*)(:[\w]+)?([ ]*[;#].*)?"); + + private static (SourceText? newText, TextLine? lastValidHeaderSpanEnd, TextLine? lastValidSpecificHeaderSpanEnd) UpdateIfExistsInFile(SourceText editorConfigText, + string filePath, + string optionName, + string optionValue, + Language language) + { + var editorConfigDirectory = PathUtilities.GetDirectoryName(filePath); + Assumes.NotNull(editorConfigDirectory); + var relativePath = PathUtilities.GetRelativePath(editorConfigDirectory.ToLowerInvariant(), filePath); + + TextLine? mostRecentHeader = null; + TextLine? lastValidHeader = null; + TextLine? lastValidHeaderSpanEnd = null; + + TextLine? lastValidSpecificHeader = null; + TextLine? lastValidSpecificHeaderSpanEnd = null; + + var textChange = new TextChange(); + foreach (var curLine in editorConfigText.Lines) + { + var curLineText = curLine.ToString(); + if (s_optionEntryPattern.IsMatch(curLineText)) + { + var groups = s_optionEntryPattern.Match(curLineText).Groups; + var (untrimmedKey, key, value, severity, comment) = GetGroups(groups); + + // Verify the most recent header is a valid header + if (IsValidHeader(mostRecentHeader, lastValidHeader) && + string.Equals(key, optionName, StringComparison.OrdinalIgnoreCase)) + { + // We found the rule in the file -- replace it with updated option value. + textChange = new TextChange(curLine.Span, $"{untrimmedKey}={optionValue}{comment}"); + } + } + else if (s_headerPattern.IsMatch(curLineText.Trim())) + { + mostRecentHeader = curLine; + if (ShouldSetAsLastValidHeader(curLineText, out var mostRecentHeaderText)) + { + lastValidHeader = mostRecentHeader; + } + else + { + var (fileName, splicedFileExtensions) = ParseHeaderParts(mostRecentHeaderText); + if ((relativePath.IsEmpty() || new Regex(fileName).IsMatch(relativePath)) && + HeaderMatchesLanguageRequirements(language, splicedFileExtensions)) + { + lastValidHeader = mostRecentHeader; + } + } + } + + // We want to keep track of how far this (valid) section spans. + if (IsValidHeader(mostRecentHeader, lastValidHeader) && IsNotEmptyOrComment(curLineText)) + { + lastValidHeaderSpanEnd = curLine; + if (lastValidSpecificHeader != null && mostRecentHeader.Equals(lastValidSpecificHeader)) + { + lastValidSpecificHeaderSpanEnd = curLine; + } + } + } + + // We return only the last text change in case of duplicate entries for the same rule. + if (textChange != default) + { + return (editorConfigText.WithChanges(textChange), lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd); + } + + // Rule not found. + return (null, lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd); + + static (string untrimmedKey, string key, string value, string severitySuffixInValue, string commentValue) GetGroups(GroupCollection groups) + { + var untrimmedKey = groups[1].Value.ToString(); + var key = untrimmedKey.Trim(); + var value = groups[2].Value.ToString(); + var severitySuffixInValue = groups[3].Value.ToString(); + var commentValue = groups[4].Value.ToString(); + return (untrimmedKey, key, value, severitySuffixInValue, commentValue); + } + + static bool IsValidHeader(TextLine? mostRecentHeader, TextLine? lastValidHeader) + { + return mostRecentHeader is not null && + lastValidHeader is not null && + mostRecentHeader.Equals(lastValidHeader); + } + + static bool ShouldSetAsLastValidHeader(string curLineText, out string mostRecentHeaderText) + { + var groups = s_headerPattern.Match(curLineText.Trim()).Groups; + mostRecentHeaderText = groups[1].Value.ToString().ToLowerInvariant(); + return mostRecentHeaderText.Equals("*", StringComparison.Ordinal); + } + + static (string fileName, string[] splicedFileExtensions) ParseHeaderParts(string mostRecentHeaderText) + { + // We splice on the last occurrence of '.' to account for filenames containing periods. + var nameExtensionSplitIndex = mostRecentHeaderText.LastIndexOf('.'); + var fileName = mostRecentHeaderText.Substring(0, nameExtensionSplitIndex); + var splicedFileExtensions = mostRecentHeaderText[(nameExtensionSplitIndex + 1)..].Split(',', ' ', '{', '}'); + + // Replacing characters in the header with the regex equivalent. + fileName = fileName.Replace(".", @"\."); + fileName = fileName.Replace("*", ".*"); + fileName = fileName.Replace("/", @"\/"); + + return (fileName, splicedFileExtensions); + } + + static bool IsNotEmptyOrComment(string currentLineText) + { + return !string.IsNullOrWhiteSpace(currentLineText) && !currentLineText.Trim().StartsWith("#", StringComparison.OrdinalIgnoreCase); + } + + static bool HeaderMatchesLanguageRequirements(Language language, string[] splicedFileExtensions) + { + return IsCSharpOnly(language, splicedFileExtensions) || IsVisualBasicOnly(language, splicedFileExtensions) || IsBothVisualBasicAndCSharp(language, splicedFileExtensions); + } + + static bool IsCSharpOnly(Language language, string[] splicedFileExtensions) + { + return language.HasFlag(Language.CSharp) && !language.HasFlag(Language.VisualBasic) && splicedFileExtensions.Contains("cs") && splicedFileExtensions.Length == 1; + } + + static bool IsVisualBasicOnly(Language language, string[] splicedFileExtensions) + { + return language.HasFlag(Language.VisualBasic) && !language.HasFlag(Language.CSharp) && splicedFileExtensions.Contains("vb") && splicedFileExtensions.Length == 1; + } + + static bool IsBothVisualBasicAndCSharp(Language language, string[] splicedFileExtensions) + { + return language.HasFlag(Language.VisualBasic) && language.HasFlag(Language.CSharp) && splicedFileExtensions.Contains("vb") && splicedFileExtensions.Contains("cs"); + } + } + + private static (SourceText? newText, TextLine? lastValidHeaderSpanEnd, TextLine? lastValidSpecificHeaderSpanEnd) AddMissingRule(SourceText editorConfigText, + TextLine? lastValidHeaderSpanEnd, + TextLine? lastValidSpecificHeaderSpanEnd, + string optionName, + string optionValue, + Language language) + { + var newEntry = $"{optionName}={optionValue}"; + if (lastValidSpecificHeaderSpanEnd.HasValue) + { + if (lastValidSpecificHeaderSpanEnd.Value.ToString().Trim().Length != 0) + { + newEntry = "\r\n" + newEntry; // TODO(jmarolf): do we need to read in the users newline settings? + } + + return (editorConfigText.WithChanges((TextChange)new TextChange(new TextSpan(lastValidSpecificHeaderSpanEnd.Value.Span.End, 0), newEntry)), lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd); + } + else if (lastValidHeaderSpanEnd.HasValue) + { + if (lastValidHeaderSpanEnd.Value.ToString().Trim().Length != 0) + { + newEntry = "\r\n" + newEntry; // TODO(jmarolf): do we need to read in the users newline settings? + } + + return (editorConfigText.WithChanges((TextChange)new TextChange(new TextSpan(lastValidHeaderSpanEnd.Value.Span.End, 0), newEntry)), lastValidHeaderSpanEnd, lastValidSpecificHeaderSpanEnd); + } + + // We need to generate a new header such as '[*.cs]' or '[*.vb]': + // - For compiler diagnostic entries and code style entries which have per-language option = false, generate only [*.cs] or [*.vb]. + // - For the remainder, generate [*.{cs,vb}] + // Insert a newline if not already present + var lines = editorConfigText.Lines; + var lastLine = lines.Count > 0 ? lines[^1] : default; + var prefix = string.Empty; + if (lastLine.ToString().Trim().Length != 0) + { + prefix = "\r\n"; + } + + // Insert newline if file is not empty + if (lines.Count > 1 && lastLine.ToString().Trim().Length == 0) + { + prefix += "\r\n"; + } + + if (language.HasFlag(Language.CSharp) && language.HasFlag(Language.VisualBasic)) + { + prefix += "[*.{cs,vb}]\r\n"; + } + else if (language.HasFlag(Language.CSharp)) + { + prefix += "[*.cs]\r\n"; + } + else if (language.HasFlag(Language.VisualBasic)) + { + prefix += "[*.vb]\r\n"; + } + + var result = editorConfigText.WithChanges((TextChange)new TextChange(new TextSpan(editorConfigText.Length, 0), prefix + newEntry)); + return (result, lastValidHeaderSpanEnd, result.Lines[^2]); + } + } +} diff --git a/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdaterBase.cs b/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdaterBase.cs new file mode 100644 index 0000000000000..e9eea754fdfcc --- /dev/null +++ b/src/EditorFeatures/Core/EditorConfigSettings/Updater/SettingsUpdaterBase.cs @@ -0,0 +1,103 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Updater +{ + internal abstract class SettingsUpdaterBase : ISettingUpdater + { + private readonly List<(TOption option, TValue value)> _queue = new(); + private readonly SemaphoreSlim _guard = new(1); + protected readonly Workspace Workspace; + protected readonly string EditorconfigPath; + + protected abstract SourceText? GetNewText(SourceText analyzerConfigDocument, IReadOnlyList<(TOption option, TValue value)> settingsToUpdate, CancellationToken token); + + protected SettingsUpdaterBase(Workspace workspace, string editorconfigPath) + { + Workspace = workspace; + EditorconfigPath = editorconfigPath; + } + + public async Task QueueUpdateAsync(TOption setting, TValue value) + { + using (await _guard.DisposableWaitAsync().ConfigureAwait(false)) + { + _queue.Add((setting, value)); + } + + return true; + } + + public async Task GetChangedEditorConfigAsync(AnalyzerConfigDocument analyzerConfigDocument, CancellationToken token) + { + if (analyzerConfigDocument is null) + return null; + + var originalText = await analyzerConfigDocument.GetTextAsync(token).ConfigureAwait(false); + using (await _guard.DisposableWaitAsync(token).ConfigureAwait(false)) + { + var newText = GetNewText(originalText, _queue, token); + if (newText is null || newText.Equals(originalText)) + { + _queue.Clear(); + return null; + } + else + { + _queue.Clear(); + return newText; + } + } + } + + public async Task?> GetChangedEditorConfigAsync(CancellationToken token) + { + var solution = Workspace.CurrentSolution; + var analyzerConfigDocument = solution.Projects + .SelectMany(p => p.AnalyzerConfigDocuments) + .FirstOrDefault(d => d.FilePath == EditorconfigPath); + var newText = await GetChangedEditorConfigAsync(analyzerConfigDocument, token).ConfigureAwait(false); + if (newText is null) + { + return null; + } + + var originalText = await analyzerConfigDocument.GetTextAsync(token).ConfigureAwait(false); + return newText.GetTextChanges(originalText); + } + + public async Task GetChangedEditorConfigAsync(SourceText originalText, CancellationToken token) + { + using (await _guard.DisposableWaitAsync(token).ConfigureAwait(false)) + { + var newText = GetNewText(originalText, _queue, token); + if (newText is null || newText.Equals(originalText)) + { + _queue.Clear(); + return null; + } + else + { + _queue.Clear(); + return newText; + } + } + } + + public async Task HasAnyChangesAsync() + { + using (await _guard.DisposableWaitAsync().ConfigureAwait(false)) + { + return _queue.Any(); + } + } + } +} diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.resx b/src/EditorFeatures/Core/EditorFeaturesResources.resx index 78f79c7e0045c..2f6899e590dce 100644 --- a/src/EditorFeatures/Core/EditorFeaturesResources.resx +++ b/src/EditorFeatures/Core/EditorFeaturesResources.resx @@ -951,4 +951,127 @@ Do you want to proceed? Gathering Suggestions - Waiting for the solution to fully load + + No + + + Yes + + + Always for clarity + + + Prefer auto properties + + + Avoid unused parameters + + + Do not prefer 'this.' or 'Me.' + + + For locals, parameters and members + + + For member access expressions + + + In arithmetic operators + + + In other binary operators + + + In other operators + + + In relational operators + + + Never if unnecessary + + + Non-public methods + + + Prefer coalesce expression + + + Prefer collection initializer + + + Prefer compound assignments + + + Prefer conditional expression over 'if' with assignments + + + Prefer conditional expression over 'if' with returns + + + Prefer explicit tuple name + + + Prefer framework type + + + Prefer inferred anonymous type member names + + + Prefer inferred tuple element names + + + Prefer 'is null' for reference equality checks + + + Prefer null propagation + + + Prefer object initializer + + + Prefer predefined type + + + Prefer readonly fields + + + Prefer simplified boolean expressions + + + Prefer 'System.HashCode' in 'GetHashCode' + + + Prefer 'this.' or 'Me.' + + + Qualify event access with 'this' or 'Me' + + + Qualify field access with 'this' or 'Me' + + + Qualify method access with 'this' or 'Me' + + + Qualify property access with 'this' or 'Me' + + + Indentation Size + + + Insert Final Newline + + + New Line + + + Tab Size + + + Use Tabs + + + All methods + \ No newline at end of file diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf index f021a47cec7e1..6539fa8dcfff7 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Relace přejmenování na řádku je pro identifikátor {0} aktivní. Pokud chcete získat přístup k dalším možnostem, znovu volejte přejmenování na řádku. Můžete kdykoli pokračovat v úpravách identifikátoru, který se přejmenovává. @@ -12,6 +22,11 @@ Aplikují se změny. + + Avoid unused parameters + Avoid unused parameters + + Change configuration Změnit konfiguraci @@ -27,6 +42,11 @@ Nakonfigurovat teď + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Tuto zprávu už příště nezobrazovat @@ -57,6 +77,16 @@ Filtr Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup Příkaz Formátovat dokument provedl další čištění. @@ -87,11 +117,41 @@ Přejít na základní typ + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Vložené nápovědy + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Neplatný název sestavení @@ -112,6 +172,26 @@ Hledají se báze... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operátor – přetížení @@ -122,6 +202,91 @@ Sledování vkládání + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Text preprocesoru @@ -132,6 +297,26 @@ Interpunkce + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Přejmenovat _soubor (typ neodpovídá názvu souboru) @@ -162,6 +347,11 @@ Symbol – statický + + Tab Size + Tab Size + + The symbol has no base. Tento symbol nemá žádný základ. @@ -187,6 +377,11 @@ Přepíná se komentář k řádku... + + Use Tabs + Use Tabs + + User Members - Constants Uživatelské členy – konstanty @@ -412,6 +607,11 @@ Při přejmenování dojde k aktualizaci {0} odkazů v {1} souborech. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Tento element nejde přejmenovat, protože je obsažen v souboru jen pro čtení. @@ -632,6 +832,11 @@ Už se sleduje dokument se shodným klíčem. + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked Dokument se aktuálně nesleduje. diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf index d95dac708cd4a..7dab8aa18dd1f 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Für den Bezeichner "{0}" ist eine Inline-Umbenennungssitzung aktiv. Rufen Sie die Inline-Umbenennung erneut auf, um auf zusätzliche Optionen zuzugreifen. Sie können den Bezeichner, der gerade umbenannt wird, jederzeit weiterbearbeiten. @@ -12,6 +22,11 @@ Änderungen werden übernommen + + Avoid unused parameters + Avoid unused parameters + + Change configuration Konfiguration ändern @@ -27,6 +42,11 @@ Jetzt konfigurieren + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Diese Meldung nicht mehr anzeigen @@ -57,6 +77,16 @@ Filter Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup Bei der Dokumentformatierung wurde eine zusätzliche Bereinigung durchgeführt. @@ -87,11 +117,41 @@ Zu Basis wechseln + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Inlinehinweise + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Ungültiger Assemblyname. @@ -112,6 +172,26 @@ Basen werden gesucht... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operator - überladen @@ -122,6 +202,91 @@ Nachverfolgung von Einfügevorgängen + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Präprozessortext @@ -132,6 +297,26 @@ Interpunktion + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) _Datei umbenennen (Typ entspricht nicht dem Dateinamen) @@ -162,6 +347,11 @@ Symbol – statisch + + Tab Size + Tab Size + + The symbol has no base. Das Symbol verfügt über keine Basis. @@ -187,6 +377,11 @@ Kommentarzeile wird ein-/ausgeschaltet... + + Use Tabs + Use Tabs + + User Members - Constants Benutzermember – Konstanten @@ -412,6 +607,11 @@ Durch das Umbenennen werden {0} Verweise in {1} Dateien aktualisiert. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Dieses Element kann nicht umbenannt werden, weil es in einer schreibgeschützten Datei enthalten ist. @@ -632,6 +832,11 @@ Dokument mit identischem Schlüssel wird bereits verfolgt + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked Dokument wird aktuell nicht verfolgt diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf index 1851eb7accc6d..91f0299c0d109 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Hay una sesión de cambio de nombre insertado que está activa para el identificador "{0}". Vuelva a invocar el cambio de nombre insertado para acceder a más opciones. Puede continuar editando el identificador cuyo nombre se va a cambiar en cualquier momento. @@ -12,6 +22,11 @@ Aplicando cambios + + Avoid unused parameters + Avoid unused parameters + + Change configuration Configuración de cambio @@ -27,6 +42,11 @@ Configúrela ahora + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again No volver a mostrar este mensaje @@ -57,6 +77,16 @@ Filtrar Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup El formateo del documento realizó una limpieza adicional @@ -87,11 +117,41 @@ Ir a base + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Sugerencias insertadas + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Nombre de ensamblado no válido @@ -112,6 +172,26 @@ Buscando las bases... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operador: sobrecargado @@ -122,6 +202,91 @@ Seguimiento de pegado + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Texto del preprocesador @@ -132,6 +297,26 @@ Puntuación + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Ca_mbiar nombre de archivo (el tipo no coincide con el nombre de archivo) @@ -162,6 +347,11 @@ Símbolo: estático + + Tab Size + Tab Size + + The symbol has no base. El símbolo no tiene base. @@ -187,6 +377,11 @@ Alternando comentario de línea... + + Use Tabs + Use Tabs + + User Members - Constants Usuarios miembros: constantes @@ -412,6 +607,11 @@ Al cambiar el nombre se actualizarán {0} referencias en {1} archivos. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. No se puede cambiar el nombre de este elemento porque está incluido en un archivo de solo lectura. @@ -632,6 +832,11 @@ Ya se está siguiendo un documento con una clave idéntica + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked el documento no es objeto de seguimiento actualmente diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf index 9f7a1b08820e4..734ca3ccf60db 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Une session de renommage inline est active pour l'identificateur '{0}'. Appelez à nouveau le renommage inline pour accéder à des options supplémentaires. Vous pouvez continuer à modifier l'identificateur renommé à tout moment. @@ -12,6 +22,11 @@ Application des changements + + Avoid unused parameters + Avoid unused parameters + + Change configuration Changer la configuration @@ -27,6 +42,11 @@ Configurer maintenant + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Ne plus afficher ce message @@ -57,6 +77,16 @@ Filtrer Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup L'opération Mettre en forme le document a effectué un nettoyage supplémentaire @@ -87,11 +117,41 @@ Accéder à la base + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Indicateurs inline + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Nom d'assembly non valide @@ -112,6 +172,26 @@ Localisation des bases... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Opérateur - surchargé @@ -122,6 +202,91 @@ Suivi du collage + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Texte du préprocesseur @@ -132,6 +297,26 @@ Ponctuation + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Renommer le _fichier (le type ne correspond pas au nom du fichier) @@ -162,6 +347,11 @@ Symbole - statique + + Tab Size + Tab Size + + The symbol has no base. Le symbole n'a pas de base. @@ -187,6 +377,11 @@ Activation/désactivation du commentaire de ligne... + + Use Tabs + Use Tabs + + User Members - Constants Membres utilisateurs - constantes @@ -412,6 +607,11 @@ Le renommage va entraîner la mise à jour de {0} références dans {1} fichiers. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Vous ne pouvez pas renommer cet élément, car il est contenu dans un fichier en lecture seule. @@ -632,6 +832,11 @@ Suivi du document déjà initié avec une clé identique + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked Le document ne fait pas actuellement l'objet d'un suivi diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf index 9f33e8372d21d..ca26b60ca9ecd 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Per l'identificatore '{0}' è attiva una sessione di ridenominazione inline. Richiamare nuovamente la ridenominazione inline per accedere alle opzioni aggiuntive. È possibile continuare a modificare l'identificatore da rinominare in qualsiasi momento. @@ -12,6 +22,11 @@ Applicazione delle modifiche in corso + + Avoid unused parameters + Avoid unused parameters + + Change configuration Cambia la configurazione @@ -27,6 +42,11 @@ Configura ora + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Non visualizzare più questo messaggio @@ -57,6 +77,16 @@ Filtro Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup Formatta documento ha eseguito una pulizia aggiuntiva @@ -87,11 +117,41 @@ Vai a base + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Suggerimenti inline + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Nome di assembly non valido @@ -112,6 +172,26 @@ Individuazione delle basi... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operatore - Overload @@ -122,6 +202,91 @@ Verifica Incolla + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Testo preprocessore @@ -132,6 +297,26 @@ Punteggiatura + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Rinomina _file (il tipo non corrisponde al nome file) @@ -162,6 +347,11 @@ Simbolo - Statico + + Tab Size + Tab Size + + The symbol has no base. Non è presente alcuna base per il simbolo. @@ -187,6 +377,11 @@ Attivazione/disattivazione del commento per la riga... + + Use Tabs + Use Tabs + + User Members - Constants Membri utente - Costanti @@ -412,6 +607,11 @@ Con la ridenominazione verranno aggiornati {0} riferimenti in {1} file. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Non è possibile rinominare questo elemento perché è contenuto in un file di sola lettura. @@ -632,6 +832,11 @@ La verifica del documento con chiave identica è già in corso + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked al momento il documento non è sottoposto a verifica diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf index c8db7e1a59d4a..5508feabfa76b 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. 識別子 '{0}' のインラインの名前変更セッションがアクティブです。追加オプションにアクセスするには、インラインの名前変更をもう一度呼び出します。名前を変更する識別子はいつでも引き続き編集できます。 @@ -12,6 +22,11 @@ 変更の適用 + + Avoid unused parameters + Avoid unused parameters + + Change configuration 構成の変更 @@ -27,6 +42,11 @@ 今すぐ構成する + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again 今後、このメッセージを表示しない @@ -57,6 +77,16 @@ フィルター Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup ドキュメントのフォーマットで追加のクリーンアップが実行されました @@ -87,11 +117,41 @@ 基本へ移動 + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints インラインのヒント + + Insert Final Newline + Insert Final Newline + + Invalid assembly name 無効なアセンブリ名 @@ -112,6 +172,26 @@ ベースを検索しています... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded 演算子 - オーバーロード @@ -122,6 +202,91 @@ 追跡の貼り付け + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text プリプロセッサ テキスト @@ -132,6 +297,26 @@ 句読点 + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) ファイル名の変更 (種類がファイル名と一致しません)(_F) @@ -162,6 +347,11 @@ シンボル - 静的 + + Tab Size + Tab Size + + The symbol has no base. シンボルにベースがありません。 @@ -187,6 +377,11 @@ 行コメントを切り替えています... + + Use Tabs + Use Tabs + + User Members - Constants ユーザー メンバー - 定数 @@ -412,6 +607,11 @@ 名前を変更すると、{1} 個のファイル内の {0} 個の参照が更新されます。 + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. この要素は、読み取り専用ファイルに含まれているため、名前を変更できません。 @@ -632,6 +832,11 @@ 同じキーを持つドキュメントを既に追跡しています + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked ドキュメントが現在追跡されていません diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf index 2c53542b5f05f..295e6f802a05b 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. 식별자 '{0}'의 인라인 이름 바꾸기 세션이 활성 상태입니다. 추가 옵션에 액세스하려면 인라인 이름 바꾸기를 다시 호출하세요. 언제든지 이름을 바꾸려는 식별자를 계속 편집할 수 있습니다. @@ -12,6 +22,11 @@ 변경 내용 적용 + + Avoid unused parameters + Avoid unused parameters + + Change configuration 구성 변경 @@ -27,6 +42,11 @@ 지금 구성 + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again 이 메시지를 다시 표시하지 않음 @@ -57,6 +77,16 @@ 필터 Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup 추가 정리를 수행 하는 문서 @@ -87,11 +117,41 @@ 기본으로 이동 + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints 인라인 힌트 + + Insert Final Newline + Insert Final Newline + + Invalid assembly name 잘못된 어셈블리 이름 @@ -112,6 +172,26 @@ 베이스를 찾는 중... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded 연산자 - 오버로드됨 @@ -122,6 +202,91 @@ 붙여넣기 추적 + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text 전처리기 텍스트 @@ -132,6 +297,26 @@ 문장 부호 + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) 파일 이름 바꾸기(형식이 파일 이름과 일치하지 않음)(_F) @@ -162,6 +347,11 @@ 기호 - 정적 + + Tab Size + Tab Size + + The symbol has no base. 기호에 베이스가 없습니다. @@ -187,6 +377,11 @@ 줄 주석을 토글하는 중... + + Use Tabs + Use Tabs + + User Members - Constants 사용자 멤버 - 상수 @@ -412,6 +607,11 @@ 이름 바꾸기로 {1}개의 파일에서 {0}개의 참조가 업데이트됩니다. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. 이 요소는 읽기 전용 파일에 포함되어 있으므로 이름을 바꿀 수 없습니다. @@ -632,6 +832,11 @@ 동일한 키로 이미 문서를 추적하는 중 + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked 문서를 현재 추적하고 있지 않습니다. diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf index d4635cf956c79..823fd239c3d54 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Wbudowana sesja zmieniania nazwy jest aktywna dla identyfikatora „{0}”. Wywołaj ponownie wbudowane zmienianie nazwy, aby uzyskać dostęp do dodatkowych opcji. W dowolnym momencie możesz kontynuować edytowanie identyfikatora, którego nazwa jest zmieniana. @@ -12,6 +22,11 @@ Stosowanie zmian + + Avoid unused parameters + Avoid unused parameters + + Change configuration Zmień konfigurację @@ -27,6 +42,11 @@ Skonfiguruj je teraz + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Nie pokazuj tego komunikatu ponownie @@ -57,6 +77,16 @@ Filtr Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup Funkcja formatowania dokumentu wykonała dodatkowe czyszczenie @@ -87,11 +117,41 @@ Przejdź do podstawy + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Wskazówki w tekście + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Nieprawidłowa nazwa zestawu @@ -112,6 +172,26 @@ Trwa lokalizowanie baz... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operator — przeciążony @@ -122,6 +202,91 @@ Śledzenie wklejania + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Tekst preprocesora @@ -132,6 +297,26 @@ Interpunkcja + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Zmień nazwę _pliku (typ nie zgadza się z nazwą pliku) @@ -162,6 +347,11 @@ Symbol — statyczny + + Tab Size + Tab Size + + The symbol has no base. Symbol nie ma wartości podstawowej. @@ -187,6 +377,11 @@ Trwa przełączanie komentarza wiersza... + + Use Tabs + Use Tabs + + User Members - Constants Składowe użytkowników — stałe @@ -412,6 +607,11 @@ Zmiana nazwy spowoduje zaktualizowanie odwołań ({0}) w plikach ({1}). + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Nie możesz zmienić nazwy tego elementu, ponieważ jest on zawarty w pliku tylko do odczytu. @@ -632,6 +832,11 @@ Dokument z identycznym kluczem jest już śledzony + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked dokument obecnie nie jest śledzony diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf index 7e76a95441135..00eb77d4bcf95 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Uma sessão de renomeação embutida está ativa para o identificador '{0}'. Invoque a renomeação embutida novamente para acessar opções adicionais. Você pode continuar a editar o identificador que está sendo renomeado a qualquer momento. @@ -12,6 +22,11 @@ Aplicando mudanças + + Avoid unused parameters + Avoid unused parameters + + Change configuration Alterar configuração @@ -27,6 +42,11 @@ Configurar agora + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Não mostrar esta mensagem novamente @@ -57,6 +77,16 @@ Filtrar Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup A Formatação do Documento executou uma limpeza adicional @@ -87,11 +117,41 @@ Ir Para a Base + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Dicas Embutidas + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Nome do assembly inválido @@ -112,6 +172,26 @@ Localizando as bases... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Operador – Sobrecarregado @@ -122,6 +202,91 @@ Colar Acompanhamento + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Texto de Pré-Processador @@ -132,6 +297,26 @@ Pontuação + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Renomear _arquivo (o tipo não corresponde ao nome do arquivo) @@ -162,6 +347,11 @@ Símbolo – Estático + + Tab Size + Tab Size + + The symbol has no base. O símbolo não tem nenhuma base. @@ -187,6 +377,11 @@ Ativando/desativando o comentário de linha... + + Use Tabs + Use Tabs + + User Members - Constants Membros de Usuário – Constantes @@ -412,6 +607,11 @@ Renomear atualizará {0} referências em {1} arquivos. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Você não pode renomear este elemento porque ele está contido em um arquivo somente leitura. @@ -632,6 +832,11 @@ Já está a rastrear o documento com chave idêntica + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked documento não está sendo rastreado no momento diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf index 9ca80001bed53..e797ae4690a91 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. Встроенный сеанс переименования активен для идентификатора "{0}". Снова вызовите встроенное переименование, чтобы получить доступ к дополнительным параметрам. Вы можете в любое время продолжить изменение переименованного идентификатора. @@ -12,6 +22,11 @@ Применение изменений + + Avoid unused parameters + Avoid unused parameters + + Change configuration Изменить конфигурацию @@ -27,6 +42,11 @@ Настройте ее сейчас + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Больше не показывать это сообщение @@ -57,6 +77,16 @@ Фильтр Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup При форматировании документа была выполнена дополнительная очистка @@ -87,11 +117,41 @@ Перейти к базовому + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Встроенные подсказки + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Недопустимое имя сборки @@ -112,6 +172,26 @@ Обнаружение баз… + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded Оператор — перегружен @@ -122,6 +202,91 @@ Вставить отслеживание + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Текст препроцессора @@ -132,6 +297,26 @@ Пунктуация + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) Переименовать фай_л (тип не соответствует имени файла) @@ -162,6 +347,11 @@ Символ — статический + + Tab Size + Tab Size + + The symbol has no base. У этого символа нет основания. @@ -187,6 +377,11 @@ Переключение комментария строки... + + Use Tabs + Use Tabs + + User Members - Constants Участники-пользователи — константы @@ -412,6 +607,11 @@ При переименовании будут обновлены ссылки в количестве {0} шт. в следующем числе файлов: {1}. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Невозможно переименовать этот элемент, так как он содержится в файле, доступном только для чтения. @@ -632,6 +832,11 @@ Документ с идентичным ключом уже отслеживается. + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked Документ в настоящее время не отслеживается. diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf index 0d35b1572e24f..42dd9347671f5 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. '{0}' tanımlayıcısı için bir satır içi yeniden adlandırma oturumu etkin. Ek seçeneklere erişmek için satır içi yeniden adlandırmayı tekrar çağırın. İstediğiniz zaman yeniden adlandırılan tanımlayıcıyı düzenlemeye devam edebilirsiniz. @@ -12,6 +22,11 @@ Değişiklikler uygulanıyor + + Avoid unused parameters + Avoid unused parameters + + Change configuration Değiştir yapılandırma @@ -27,6 +42,11 @@ Hemen yapılandırın + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again Bu iletiyi bir daha gösterme @@ -57,6 +77,16 @@ Filtre Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup Biçimi belge ek temizleme işlemi @@ -87,11 +117,41 @@ Tabana Git + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints Satır İçi İpuçları + + Insert Final Newline + Insert Final Newline + + Invalid assembly name Geçersiz derleme adı @@ -112,6 +172,26 @@ Tabanlar bulunuyor... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded İşleç - Aşırı Yüklenmiş @@ -122,6 +202,91 @@ İzleme Yapıştır + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text Ön İşlemci Metni @@ -132,6 +297,26 @@ Noktalama İşareti + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) _Dosyayı yeniden adlandır (tür, dosya adıyla eşleşmiyor) @@ -162,6 +347,11 @@ Sembol - statik + + Tab Size + Tab Size + + The symbol has no base. Sembolde taban yok. @@ -187,6 +377,11 @@ Satır açıklaması değiştiriliyor... + + Use Tabs + Use Tabs + + User Members - Constants Kullanıcı Üyeler - Sabitler @@ -412,6 +607,11 @@ Yeniden adlandırma işlemi {1} dosyadaki {0} başvuruyu güncelleştirecek. + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. Salt okunur bir dosyada bulunduğundan bu öğeyi yeniden adlandıramazsınız. @@ -632,6 +832,11 @@ Belge zaten özdeş anahtar ile izleniyor + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked Belge şu anda izlenmiyor diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf index 30322875c1dff..01cd292694cf0 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. 标识符“{0}”的内联重命名会话处于活动状态。再次调用内联重命名以访问其他选项。可随时继续编辑正在重命名的标识符。 @@ -12,6 +22,11 @@ 应用更改 + + Avoid unused parameters + Avoid unused parameters + + Change configuration 更改配置 @@ -27,6 +42,11 @@ 立即配置 + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again 不再显示此消息 @@ -57,6 +77,16 @@ 筛选 Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup 格式文档执行了额外的清理 @@ -87,11 +117,41 @@ 转到基础映像 + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints 内联提示 + + Insert Final Newline + Insert Final Newline + + Invalid assembly name 程序集名称无效 @@ -112,6 +172,26 @@ 正在查找基... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded 运算符-重载 @@ -122,6 +202,91 @@ 粘贴跟踪信息 + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text 预处理器文本 @@ -132,6 +297,26 @@ 标点 + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) 重命名文件(类型与文件名不匹配)(_F) @@ -162,6 +347,11 @@ 符号-静态 + + Tab Size + Tab Size + + The symbol has no base. 符号没有基数。 @@ -187,6 +377,11 @@ 正在切换为行注释... + + Use Tabs + Use Tabs + + User Members - Constants 用户成员-常量 @@ -412,6 +607,11 @@ 重命名将更新 {1} 个文件中的 {0} 个引用。 + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. 无法重命名此元素,因为它包含在只读文件中。 @@ -632,6 +832,11 @@ 已使用等价键跟踪文档 + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked 当前未跟踪文档 diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf index 75f00e8d42a2b..285e7d9493df4 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf @@ -2,6 +2,16 @@ + + All methods + All methods + + + + Always for clarity + Always for clarity + + An inline rename session is active for identifier '{0}'. Invoke inline rename again to access additional options. You may continue to edit the identifier being renamed at any time. 識別碼 '{0}' 有正在使用的內嵌重新命名工作階段。再次叫用內嵌重新命名可存取其他選項。您隨時可以繼續編輯正在重新命名的識別碼。 @@ -12,6 +22,11 @@ 正在套用變更 + + Avoid unused parameters + Avoid unused parameters + + Change configuration 變更組態 @@ -27,6 +42,11 @@ 立即設定 + + Do not prefer 'this.' or 'Me.' + Do not prefer 'this.' or 'Me.' + + Do not show this message again 不再顯示此訊息 @@ -57,6 +77,16 @@ 篩選 Caption/tooltip for "Filter" image element displayed in completion popup. + + For locals, parameters and members + For locals, parameters and members + + + + For member access expressions + For member access expressions + + Format Document performed additional cleanup 執行額外清除的格式化文件 @@ -87,11 +117,41 @@ 移至基底 + + In arithmetic operators + In arithmetic operators + + + + In other binary operators + In other binary operators + + + + In other operators + In other operators + + + + In relational operators + In relational operators + + + + Indentation Size + Indentation Size + + Inline Hints 內嵌提示 + + Insert Final Newline + Insert Final Newline + + Invalid assembly name 組件名稱無效 @@ -112,6 +172,26 @@ 正在尋找基底... + + Never if unnecessary + Never if unnecessary + + + + New Line + New Line + + + + No + No + + + + Non-public methods + Non-public methods + + Operator - Overloaded 運算子 - 多載 @@ -122,6 +202,91 @@ 貼上追蹤 + + Prefer 'System.HashCode' in 'GetHashCode' + Prefer 'System.HashCode' in 'GetHashCode' + + + + Prefer coalesce expression + Prefer coalesce expression + + + + Prefer collection initializer + Prefer collection initializer + + + + Prefer compound assignments + Prefer compound assignments + + + + Prefer conditional expression over 'if' with assignments + Prefer conditional expression over 'if' with assignments + + + + Prefer conditional expression over 'if' with returns + Prefer conditional expression over 'if' with returns + + + + Prefer explicit tuple name + Prefer explicit tuple name + + + + Prefer framework type + Prefer framework type + + + + Prefer inferred anonymous type member names + Prefer inferred anonymous type member names + + + + Prefer inferred tuple element names + Prefer inferred tuple element names + + + + Prefer 'is null' for reference equality checks + Prefer 'is null' for reference equality checks + + + + Prefer null propagation + Prefer null propagation + + + + Prefer object initializer + Prefer object initializer + + + + Prefer predefined type + Prefer predefined type + + + + Prefer readonly fields + Prefer readonly fields + + + + Prefer simplified boolean expressions + Prefer simplified boolean expressions + + + + Prefer 'this.' or 'Me.' + Prefer 'this.' or 'Me.' + + Preprocessor Text 前置處理器文字 @@ -132,6 +297,26 @@ 標點符號 + + Qualify event access with 'this' or 'Me' + Qualify event access with 'this' or 'Me' + + + + Qualify field access with 'this' or 'Me' + Qualify field access with 'this' or 'Me' + + + + Qualify method access with 'this' or 'Me' + Qualify method access with 'this' or 'Me' + + + + Qualify property access with 'this' or 'Me' + Qualify property access with 'this' or 'Me' + + Rename _file (type does not match file name) 重新命名檔案 (類型不符合檔案名稱)(_F) @@ -162,6 +347,11 @@ 符號 - 靜態 + + Tab Size + Tab Size + + The symbol has no base. 該符號沒有任何基底。 @@ -187,6 +377,11 @@ 正在切換行註解... + + Use Tabs + Use Tabs + + User Members - Constants 使用者成員 - 常數 @@ -412,6 +607,11 @@ 重新命名會更新 {1} 個檔案中的 {0} 個參考。 + + Yes + Yes + + You cannot rename this element because it is contained in a read-only file. 因為此項目包含在唯讀檔案中,所以無法重新命名。 @@ -632,6 +832,11 @@ 已追蹤具有相同索引鍵的文件 + + Prefer auto properties + Prefer auto properties + + document is not currently being tracked 文件目前未加以追蹤 diff --git a/src/EditorFeatures/Test/EditorConfigSettings/Data/CodeStyleSettingsTest.cs b/src/EditorFeatures/Test/EditorConfigSettings/Data/CodeStyleSettingsTest.cs new file mode 100644 index 0000000000000..295ab30e205a6 --- /dev/null +++ b/src/EditorFeatures/Test/EditorConfigSettings/Data/CodeStyleSettingsTest.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +extern alias WORKSPACES; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using WORKSPACES::Microsoft.CodeAnalysis.Options; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.UnitTests.EditorConfigSettings.Data +{ + public class CodeStyleSettingsTest + { + [Theory] + [InlineData(true)] + [InlineData(false)] + public static void CodeStyleSettingBoolFactory(bool defaultValue) + { + var option = CreateBoolOption(defaultValue); + var editorConfigOptions = new TestAnalyzerConfigOptions(); + var visualStudioOptions = new TestOptionSet(option.DefaultValue); + var setting = CodeStyleSetting.Create(option, description: "TestDesciption", editorConfigOptions, visualStudioOptions, updater: null!); + Assert.Equal(string.Empty, setting.Category); + Assert.Equal("TestDesciption", setting.Description); + Assert.False(setting.IsDefinedInEditorConfig); + Assert.Equal(typeof(bool), setting.Type); + Assert.Equal(defaultValue, setting.Value); + } + + [Theory] + [InlineData(DayOfWeek.Monday)] + [InlineData(DayOfWeek.Friday)] + public static void CodeStyleSettingEnumFactory(DayOfWeek defaultValue) + { + var option = CreateEnumOption(defaultValue); + var editorConfigOptions = new TestAnalyzerConfigOptions(); + var visualStudioOptions = new TestOptionSet(option.DefaultValue); + var setting = CodeStyleSetting.Create(option, + description: "TestDesciption", + enumValues: (DayOfWeek[])Enum.GetValues(typeof(DayOfWeek)), + valueDescriptions: Enum.GetNames(typeof(DayOfWeek)), + editorConfigOptions, + visualStudioOptions, + updater: null!); + Assert.Equal(string.Empty, setting.Category); + Assert.Equal("TestDesciption", setting.Description); + Assert.False(setting.IsDefinedInEditorConfig); + Assert.Equal(typeof(DayOfWeek), setting.Type); + Assert.Equal(defaultValue, setting.Value); + } + + private static Option2> CreateBoolOption(bool @default = false) + { + var option = CodeStyleOption2.Default; + option.Value = @default; + return new Option2>(feature: "TestFeature", + name: "TestOption", + defaultValue: option); + } + + private static Option2> CreateEnumOption(T @default) + where T : notnull, Enum + { + var option = CodeStyleOption2.Default; + option.Value = @default; + return new Option2>(feature: "TestFeature", + name: "TestOption", + defaultValue: option); + } + + private class TestAnalyzerConfigOptions : AnalyzerConfigOptions + { + private readonly IDictionary _dictionary; + public TestAnalyzerConfigOptions((string, string)[]? options = null) + => _dictionary = options?.ToDictionary(x => x.Item1, x => x.Item2) ?? new Dictionary(); + public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) + => _dictionary.TryGetValue(key, out value); + } + + private class TestOptionSet : OptionSet + { + private readonly object? _value; + public TestOptionSet(CodeStyleOption2 value) => _value = value; + public override OptionSet WithChangedOption(OptionKey optionAndLanguage, object? value) => this; + internal override IEnumerable GetChangedOptions(OptionSet optionSet) => Array.Empty(); + private protected override object? GetOptionCore(OptionKey optionKey) => _value; + } + } +} diff --git a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModel.cs b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModel.cs new file mode 100644 index 0000000000000..18186ed974e12 --- /dev/null +++ b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModel.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings +{ + internal class BinaryOperatorSpacingOptionsViewModel : EnumSettingViewModel + { + private readonly FormattingSetting _setting; + + public BinaryOperatorSpacingOptionsViewModel(FormattingSetting setting) + { + _setting = setting; + } + + protected override void ChangePropertyTo(BinaryOperatorSpacingOptions newValue) + { + _setting.SetValue(newValue); + } + + protected override BinaryOperatorSpacingOptions GetCurrentValue() + { + return (BinaryOperatorSpacingOptions)_setting.GetValue()!; + } + + protected override IReadOnlyDictionary GetValuesAndDescriptions() + { + return EnumerateOptions().ToDictionary(x => x.description, x => x.value); + + static IEnumerable<(string description, BinaryOperatorSpacingOptions value)> EnumerateOptions() + { + yield return (CSharpVSResources.Ignore_spaces_around_binary_operators, BinaryOperatorSpacingOptions.Ignore); + yield return (CSharpVSResources.Remove_spaces_before_and_after_binary_operators, BinaryOperatorSpacingOptions.Remove); + yield return (CSharpVSResources.Insert_space_before_and_after_binary_operators, BinaryOperatorSpacingOptions.Single); + } + } + } +} diff --git a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModelFactory.cs b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModelFactory.cs new file mode 100644 index 0000000000000..6a5085101a91b --- /dev/null +++ b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/BinaryOperatorSpacingOptionsViewModelFactory.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings +{ + [Export(typeof(IEnumSettingViewModelFactory)), Shared] + internal class BinaryOperatorSpacingOptionsViewModelFactory : IEnumSettingViewModelFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public BinaryOperatorSpacingOptionsViewModelFactory() + { + } + + public IEnumSettingViewModel CreateViewModel(FormattingSetting setting) + { + return new BinaryOperatorSpacingOptionsViewModel(setting); + } + + public bool IsSupported(OptionKey2 key) + => key.Option.Type == typeof(BinaryOperatorSpacingOptions); + } +} diff --git a/src/VisualStudio/CSharp/Impl/EditorConfigSettings/LabelPositionOptionsViewModel.cs b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/LabelPositionOptionsViewModel.cs new file mode 100644 index 0000000000000..bbbfcda4f07d9 --- /dev/null +++ b/src/VisualStudio/CSharp/Impl/EditorConfigSettings/LabelPositionOptionsViewModel.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.EditorConfigSettings +{ + + [Export(typeof(IEnumSettingViewModelFactory)), Shared] + internal class LabelPositionOptionsViewModelFactory : IEnumSettingViewModelFactory + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public LabelPositionOptionsViewModelFactory() + { + } + + public IEnumSettingViewModel CreateViewModel(FormattingSetting setting) + { + return new LabelPositionOptionsViewModel(setting); + } + + public bool IsSupported(OptionKey2 key) + => key.Option.Type == typeof(LabelPositionOptions); + } + + internal class LabelPositionOptionsViewModel : EnumSettingViewModel + { + private readonly FormattingSetting _setting; + + public LabelPositionOptionsViewModel(FormattingSetting setting) + { + _setting = setting; + } + + protected override void ChangePropertyTo(LabelPositionOptions newValue) + { + _setting.SetValue(newValue); + } + + protected override LabelPositionOptions GetCurrentValue() + { + return (LabelPositionOptions)_setting.GetValue()!; + } + + protected override IReadOnlyDictionary GetValuesAndDescriptions() + { + return EnumerateOptions().ToDictionary(x => x.description, x => x.value); + + static IEnumerable<(string description, LabelPositionOptions value)> EnumerateOptions() + { + yield return ("place goto labels in leftmost column", LabelPositionOptions.LeftMost); + yield return ("indent labels normally", LabelPositionOptions.NoIndent); + yield return ("place goto labels one indent less than current", LabelPositionOptions.OneLess); + } + } + } +} diff --git a/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj b/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj index 8eb596e8f12be..3a8ea68c1b12b 100644 --- a/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj +++ b/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj @@ -15,18 +15,9 @@ false - - - + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml new file mode 100644 index 0000000000000..4111d4fb1be9b --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml @@ -0,0 +1,17 @@ + + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml.cs new file mode 100644 index 0000000000000..676850c75f5b0 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/AnalyzerSettingsView.xaml.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.TextManager.Interop; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View +{ + /// + /// Interaction logic for AnalyzerSettingsView.xaml + /// + internal partial class AnalyzerSettingsView : UserControl, ISettingsEditorView + { + private readonly IWpfSettingsEditorViewModel _viewModel; + + public AnalyzerSettingsView(IWpfSettingsEditorViewModel viewModel) + { + InitializeComponent(); + _viewModel = viewModel; + TableControl = _viewModel.GetTableControl(); + AnalyzerTable.Child = TableControl.Control; + } + + public UserControl SettingControl => this; + public IWpfTableControl TableControl { get; } + public Task UpdateEditorConfigAsync(SourceText sourceText) => _viewModel.UpdateEditorConfigAsync(sourceText); + public void OnClose() => _viewModel.ShutDown(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerCategoryColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerCategoryColumnDefinition.cs new file mode 100644 index 0000000000000..e4b5b811a825f --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerCategoryColumnDefinition.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + [Export(typeof(IDefaultColumnGroup))] + [Name(nameof(AnalyzerCategoryGroupingSet))] // Required, name of the default group + [GroupColumns(Category)] // Required, the names of the columns in the grouping + internal class AnalyzerCategoryGroupingSet : IDefaultColumnGroup + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerCategoryGroupingSet() + { + } + } + + [Export(typeof(ITableColumnDefinition))] + [Name(Category)] // TODO(jmarolf): make sure all columns have ToString implementation + internal class AnalyzerCategoryColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerCategoryColumnDefinition() + { + } + + public override string Name => Category; + public override string DisplayName => ServicesVSResources.Category; + public override double MinWidth => 80; + public override bool DefaultVisible => false; + public override bool IsFilterable => true; + public override bool IsSortable => true; + public override TextWrapping TextWrapping => TextWrapping.NoWrap; + + private static string? GetCategoryName(ITableEntryHandle entry) + => entry.TryGetValue(Category, out string? categoryName) + ? categoryName + : null; + + public override IEntryBucket? CreateBucketForEntry(ITableEntryHandle entry) + { + var categoryName = GetCategoryName(entry); + return categoryName is not null ? new StringEntryBucket(categoryName) : null; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerDescriptionColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerDescriptionColumnDefinition.cs new file mode 100644 index 0000000000000..24cd35c1ca60b --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerDescriptionColumnDefinition.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Description)] + internal class AnalyzerDescriptionColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerDescriptionColumnDefinition() + { + } + + public override string Name => Description; + public override string DisplayName => ServicesVSResources.Description; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override double MinWidth => 350; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerEnabledColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerEnabledColumnDefinition.cs new file mode 100644 index 0000000000000..d0f2080ae369a --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerEnabledColumnDefinition.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Enabled)] + internal class AnalyzerEnabledColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerEnabledColumnDefinition() + { + } + + public override string Name => Enabled; + public override string DisplayName => ServicesVSResources.Enabled; + public override bool IsFilterable => true; + public override bool IsSortable => true; + public override double MinWidth => 50; + + public override bool TryCreateColumnContent(ITableEntryHandle entry, bool singleColumnView, out FrameworkElement content) + { + var checkBox = new CheckBox(); + if (entry.TryGetValue(Name, out bool enabled)) + { + checkBox.IsChecked = enabled; + } + + content = checkBox; + return true; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerIdColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerIdColumnDefinition.cs new file mode 100644 index 0000000000000..8880f4e256fa3 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerIdColumnDefinition.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Id)] + internal class AnalyzerIdColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerIdColumnDefinition() + { + } + + public override string Name => Id; + public override string DisplayName => ServicesVSResources.Id; + public override bool IsFilterable => true; + public override bool IsSortable => true; + public override double MinWidth => 50; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerSeverityColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerSeverityColumnDefinition.cs new file mode 100644 index 0000000000000..758fb3353fbb2 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerSeverityColumnDefinition.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Severity)] + internal class AnalyzerSeverityColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerSeverityColumnDefinition() + { + } + + public override string Name => Severity; + public override string DisplayName => ServicesVSResources.Severity; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override double MinWidth => 120; + + public override bool TryCreateStringContent(ITableEntryHandle entry, bool truncatedText, bool singleColumnView, out string? content) + { + if (!entry.TryGetValue(Severity, out AnalyzerSetting setting)) + { + content = null; + return false; + } + + content = setting.Severity switch + { + CodeAnalysis.DiagnosticSeverity.Hidden => ServicesVSResources.Disabled, + CodeAnalysis.DiagnosticSeverity.Info => ServicesVSResources.Suggestion, + CodeAnalysis.DiagnosticSeverity.Warning => ServicesVSResources.Warning, + CodeAnalysis.DiagnosticSeverity.Error => ServicesVSResources.Error, + _ => string.Empty, + }; + return true; + } + + public override bool TryCreateColumnContent(ITableEntryHandle entry, bool singleColumnView, out FrameworkElement? content) + { + if (!entry.TryGetValue(Severity, out AnalyzerSetting severity)) + { + content = null; + return false; + } + + var control = new SeverityControl(severity); + content = control; + return true; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerTitleColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerTitleColumnDefinition.cs new file mode 100644 index 0000000000000..d582f72188bab --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/ColumnDefinitions/AnalyzerTitleColumnDefinition.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Analyzer; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View.ColumnDefinitions +{ + + [Export(typeof(ITableColumnDefinition))] + [Name(Title)] + internal class AnalyzerTitleColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public AnalyzerTitleColumnDefinition() + { + } + + public override string Name => Title; + public override string DisplayName => ServicesVSResources.Title; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override double MinWidth => 350; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml new file mode 100644 index 0000000000000..77e8bb80fd63f --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml @@ -0,0 +1,10 @@ + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml.cs new file mode 100644 index 0000000000000..0cedb7386f8a7 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/View/SeverityControl.xaml.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows; +using System.Windows.Automation; +using System.Windows.Controls; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.Imaging; +using Microsoft.VisualStudio.Imaging.Interop; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View +{ + /// + /// Interaction logic for SeverityControl.xaml + /// + internal partial class SeverityControl : UserControl + { + private readonly ComboBox _comboBox; + private readonly AnalyzerSetting _setting; + + public SeverityControl(AnalyzerSetting setting) + { + InitializeComponent(); + _comboBox = new ComboBox() + { + ItemsSource = new[] + { + ServicesVSResources.Disabled, + ServicesVSResources.Suggestion, + ServicesVSResources.Warning, + ServicesVSResources.Error + } + }; + + switch (setting.Severity) + { + case DiagnosticSeverity.Hidden: + _comboBox.SelectedIndex = 0; + break; + case DiagnosticSeverity.Info: + _comboBox.SelectedIndex = 1; + break; + case DiagnosticSeverity.Warning: + _comboBox.SelectedIndex = 2; + break; + case DiagnosticSeverity.Error: + _comboBox.SelectedIndex = 3; + break; + default: + break; + } + + _comboBox.SelectionChanged += ComboBox_SelectionChanged; + _comboBox.SetValue(AutomationProperties.NameProperty, ServicesVSResources.Severity); + _ = RootGrid.Children.Add(_comboBox); + _setting = setting; + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + var severity = _comboBox.SelectedIndex switch + { + 0 => DiagnosticSeverity.Hidden, + 1 => DiagnosticSeverity.Info, + 2 => DiagnosticSeverity.Warning, + 3 => DiagnosticSeverity.Error, + _ => throw new InvalidOperationException(), + }; + + if (_setting.Severity != severity) + { + _setting.ChangeSeverity(severity); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsEntriesSnapshot.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsEntriesSnapshot.cs new file mode 100644 index 0000000000000..9ff153d53e7ba --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsEntriesSnapshot.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.ViewModel +{ + internal partial class AnalyzerSettingsViewModel : SettingsViewModelBase< + AnalyzerSetting, + AnalyzerSettingsViewModel.SettingsSnapshotFactory, + AnalyzerSettingsViewModel.SettingsEntriesSnapshot> + { + internal sealed class SettingsEntriesSnapshot : SettingsEntriesSnapshotBase + { + public SettingsEntriesSnapshot(ImmutableArray data, int currentVersionNumber) : base(data, currentVersionNumber) { } + + protected override bool TryGetValue(AnalyzerSetting result, string keyName, out object? content) + { + content = keyName switch + { + ColumnDefinitions.Analyzer.Enabled => result.IsEnabled, + ColumnDefinitions.Analyzer.Id => result.Id, + ColumnDefinitions.Analyzer.Title => result.Title, + ColumnDefinitions.Analyzer.Description => result.Description, + ColumnDefinitions.Analyzer.Category => result.Category, + ColumnDefinitions.Analyzer.Severity => result, + _ => null, + }; + + return content is not null; + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsSnapshotFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsSnapshotFactory.cs new file mode 100644 index 0000000000000..e7d1880bcd3b3 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.SettingsSnapshotFactory.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.ViewModel +{ + internal partial class AnalyzerSettingsViewModel : SettingsViewModelBase< + AnalyzerSetting, + AnalyzerSettingsViewModel.SettingsSnapshotFactory, + AnalyzerSettingsViewModel.SettingsEntriesSnapshot> + { + internal sealed class SettingsSnapshotFactory : SettingsSnapshotFactoryBase + { + public SettingsSnapshotFactory(ISettingsProvider data) : base(data) { } + + protected override SettingsEntriesSnapshot CreateSnapshot(ImmutableArray data, int currentVersionNumber) + => new(data, currentVersionNumber); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.cs new file mode 100644 index 0000000000000..b7bd04325b264 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Analyzers/ViewModel/AnalyzerSettingsViewModel.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.ViewModel +{ + + internal partial class AnalyzerSettingsViewModel : SettingsViewModelBase< + AnalyzerSetting, + AnalyzerSettingsViewModel.SettingsSnapshotFactory, + AnalyzerSettingsViewModel.SettingsEntriesSnapshot> + { + + public AnalyzerSettingsViewModel(ISettingsProvider data, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider) + : base(data, controlProvider, tableMangerProvider) + { } + + public override string Identifier => "AnalyzerSettings"; + + protected override SettingsSnapshotFactory CreateSnapshotFactory(ISettingsProvider data) + => new(data); + + protected override IEnumerable GetInitialColumnStates() + => new[] + { + new ColumnState2(ColumnDefinitions.Analyzer.Id, isVisible: true, width: 0), + new ColumnState2(ColumnDefinitions.Analyzer.Title, isVisible: true, width: 0), + new ColumnState2(ColumnDefinitions.Analyzer.Description, isVisible: false, width: 0), + new ColumnState2(ColumnDefinitions.Analyzer.Category, isVisible: true, width: 0, groupingPriority: 1), + new ColumnState2(ColumnDefinitions.Analyzer.Severity, isVisible: true, width: 0) + }; + + protected override string[] GetFixedColumns() + => new[] + { + ColumnDefinitions.Analyzer.Category, + ColumnDefinitions.Analyzer.Id, + ColumnDefinitions.Analyzer.Title, + ColumnDefinitions.Analyzer.Description, + ColumnDefinitions.Analyzer.Severity + }; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml new file mode 100644 index 0000000000000..2f44eacd3d449 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml @@ -0,0 +1,16 @@ + + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml.cs new file mode 100644 index 0000000000000..f1940dad1defc --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSettingsView.xaml.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.TextManager.Interop; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View +{ + /// + /// Interaction logic for CodeStyleView.xaml + /// + internal partial class CodeStyleSettingsView : UserControl, ISettingsEditorView + { + private readonly IWpfSettingsEditorViewModel _viewModel; + + public CodeStyleSettingsView(IWpfSettingsEditorViewModel viewModel) + { + InitializeComponent(); + _viewModel = viewModel; + TableControl = _viewModel.GetTableControl(); + CodeStyleTable.Child = TableControl.Control; + DataContext = viewModel; + } + + public UserControl SettingControl => this; + public IWpfTableControl TableControl { get; } + public Task UpdateEditorConfigAsync(SourceText sourceText) => _viewModel.UpdateEditorConfigAsync(sourceText); + public void OnClose() => _viewModel.ShutDown(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml new file mode 100644 index 0000000000000..021c05a555c5f --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml @@ -0,0 +1,13 @@ + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml.cs new file mode 100644 index 0000000000000..e04c00f8dc1ad --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleSeverityControl.xaml.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows.Automation; +using System.Windows.Controls; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View +{ + /// + /// Interaction logic for CodeStyleSeverityControl.xaml + /// + internal partial class CodeStyleSeverityControl : UserControl + { + private readonly ComboBox _comboBox; + private readonly CodeStyleSetting _setting; + + public CodeStyleSeverityControl(CodeStyleSetting setting) + { + InitializeComponent(); + _setting = setting; + _comboBox = new ComboBox() + { + ItemsSource = new[] + { + ServicesVSResources.Refactoring_Only, + ServicesVSResources.Suggestion, + ServicesVSResources.Warning, + ServicesVSResources.Error + } + }; + + _comboBox.SelectedIndex = setting.Severity switch + { + DiagnosticSeverity.Hidden => 0, + DiagnosticSeverity.Info => 1, + DiagnosticSeverity.Warning => 2, + DiagnosticSeverity.Error => 3, + _ => throw new InvalidOperationException(), + }; + + _comboBox.SelectionChanged += ComboBox_SelectionChanged; + _comboBox.SetValue(AutomationProperties.NameProperty, ServicesVSResources.Severity); + _ = RootGrid.Children.Add(_comboBox); + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + var severity = _comboBox.SelectedIndex switch + { + 0 => DiagnosticSeverity.Hidden, + 1 => DiagnosticSeverity.Info, + 2 => DiagnosticSeverity.Warning, + 3 => DiagnosticSeverity.Error, + _ => throw new InvalidOperationException(), + }; + + if (_setting.Severity != severity) + { + _setting.ChangeSeverity(severity); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml new file mode 100644 index 0000000000000..8aa05eb16a41d --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml @@ -0,0 +1,10 @@ + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml.cs new file mode 100644 index 0000000000000..546a1927e11de --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/CodeStyleValueControl.xaml.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using System.Windows.Automation; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View +{ + /// + /// Interaction logic for CodeStyleValueControl.xaml + /// + internal partial class CodeStyleValueControl : UserControl + { + private readonly ComboBox _comboBox; + private readonly CodeStyleSetting _setting; + + public CodeStyleValueControl(CodeStyleSetting setting) + { + InitializeComponent(); + var values = setting.GetValues().ToList(); + var index = values.IndexOf(setting.GetCurrentValue()); + _comboBox = new ComboBox() + { + ItemsSource = values + }; + _comboBox.SelectedIndex = index; + _comboBox.SetValue(AutomationProperties.NameProperty, ServicesVSResources.Value); + _comboBox.SelectionChanged += ComboBox_SelectionChanged; + _ = RootGrid.Children.Add(_comboBox); + _setting = setting; + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + _setting.ChangeValue(_comboBox.SelectedIndex); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleCategoryColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleCategoryColumnDefinition.cs new file mode 100644 index 0000000000000..85229dc2b4138 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleCategoryColumnDefinition.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.CodeStyle; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View.ColumnDefinitions +{ + [Export(typeof(IDefaultColumnGroup))] + [Name(nameof(CodeStyleCategoryGroupingSet))] // Required, name of the default group + [GroupColumns(Category)] // Required, the names of the columns in the grouping + internal class CodeStyleCategoryGroupingSet : IDefaultColumnGroup + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CodeStyleCategoryGroupingSet() + { + } + } + + [Export(typeof(ITableColumnDefinition))] + [Name(Category)] + internal class CodeStyleCategoryColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CodeStyleCategoryColumnDefinition() + { + } + + public override string Name => Category; + public override string DisplayName => ServicesVSResources.Category; + public override double MinWidth => 80; + public override bool DefaultVisible => false; + public override bool IsFilterable => true; + public override bool IsSortable => true; + public override TextWrapping TextWrapping => TextWrapping.NoWrap; + + private static string? GetCategoryName(ITableEntryHandle entry) + => entry.TryGetValue(Category, out var categoryName) + ? categoryName as string + : null; + + public override IEntryBucket? CreateBucketForEntry(ITableEntryHandle entry) + { + var categoryName = GetCategoryName(entry); + return categoryName is not null ? new StringEntryBucket(categoryName) : null; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleDescriptionColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleDescriptionColumnDefinition.cs new file mode 100644 index 0000000000000..78f0e9c77da6e --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleDescriptionColumnDefinition.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.CodeStyle; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Description)] + internal class CodeStyleDescriptionColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CodeStyleDescriptionColumnDefinition() + { + } + + public override string Name => Description; + public override string DisplayName => ServicesVSResources.Description; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override double MinWidth => 350; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleSeverityColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleSeverityColumnDefinition.cs new file mode 100644 index 0000000000000..5ca42dbadfdee --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleSeverityColumnDefinition.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.CodeStyle; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Severity)] + internal class CodeStyleSeverityColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CodeStyleSeverityColumnDefinition() + { + } + + public override string Name => Severity; + public override string DisplayName => ServicesVSResources.Severity; + public override double MinWidth => 120; + public override bool DefaultVisible => false; + public override bool IsFilterable => false; + public override bool IsSortable => false; + + public override bool TryCreateColumnContent(ITableEntryHandle entry, bool singleColumnView, out FrameworkElement? content) + { + if (!entry.TryGetValue(Severity, out CodeStyleSetting setting)) + { + content = null; + return false; + } + + var control = new CodeStyleSeverityControl(setting); + content = control; + return true; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleValueColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleValueColumnDefinition.cs new file mode 100644 index 0000000000000..6e415fdb1dfaa --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/View/ColumnDefinitions/CodeStyleValueColumnDefinition.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.CodeStyle; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View.ColumnDefinitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Value)] + internal class CodeStyleValueColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CodeStyleValueColumnDefinition() + { + } + + public override string Name => Value; + public override string DisplayName => ServicesVSResources.Value; + public override double MinWidth => 120; + public override bool DefaultVisible => false; + public override bool IsFilterable => false; + public override bool IsSortable => false; + + public override bool TryCreateColumnContent(ITableEntryHandle entry, bool singleColumnView, out FrameworkElement? content) + { + if (!entry.TryGetValue(Value, out CodeStyleSetting severity)) + { + content = null; + return false; + } + + var control = new CodeStyleValueControl(severity); + content = control; + return true; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsEntriesSnapshot.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsEntriesSnapshot.cs new file mode 100644 index 0000000000000..3df9aa19ef67d --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsEntriesSnapshot.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.ViewModel +{ + internal partial class CodeStyleSettingsViewModel + { + internal class SettingsEntriesSnapshot : SettingsEntriesSnapshotBase + { + public SettingsEntriesSnapshot(ImmutableArray data, int currentVersionNumber) : base(data, currentVersionNumber) { } + + protected override bool TryGetValue(CodeStyleSetting result, string keyName, out object? content) + { + content = keyName switch + { + ColumnDefinitions.CodeStyle.Description => result.Description, + ColumnDefinitions.CodeStyle.Category => result.Category, + ColumnDefinitions.CodeStyle.Severity => result, + ColumnDefinitions.CodeStyle.Value => result, + _ => null, + }; + + return content is not null; + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsSnapshotFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsSnapshotFactory.cs new file mode 100644 index 0000000000000..4521d19999ff2 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.SettingsSnapshotFactory.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.ViewModel +{ + internal partial class CodeStyleSettingsViewModel + { + internal sealed class SettingsSnapshotFactory : SettingsSnapshotFactoryBase + { + public SettingsSnapshotFactory(ISettingsProvider data) : base(data) { } + + protected override SettingsEntriesSnapshot CreateSnapshot(ImmutableArray data, int currentVersionNumber) + => new(data, currentVersionNumber); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.cs new file mode 100644 index 0000000000000..d64574e94cba7 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/CodeStyle/ViewModel/CodeStyleSettingsViewModel.cs @@ -0,0 +1,49 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.ViewModel +{ + internal partial class CodeStyleSettingsViewModel : SettingsViewModelBase< + CodeStyleSetting, + CodeStyleSettingsViewModel.SettingsSnapshotFactory, + CodeStyleSettingsViewModel.SettingsEntriesSnapshot> + { + public CodeStyleSettingsViewModel(ISettingsProvider data, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider) + : base(data, controlProvider, tableMangerProvider) + { } + + public override string Identifier => "CodeStyleSettings"; + + protected override SettingsSnapshotFactory CreateSnapshotFactory(ISettingsProvider data) + => new(data); + + protected override IEnumerable GetInitialColumnStates() + => new[] + { + new ColumnState2(ColumnDefinitions.CodeStyle.Category, isVisible: false, width: 0, groupingPriority: 1), + new ColumnState2(ColumnDefinitions.CodeStyle.Description, isVisible: true, width: 0), + new ColumnState2(ColumnDefinitions.CodeStyle.Value, isVisible: true, width: 0), + new ColumnState2(ColumnDefinitions.CodeStyle.Severity, isVisible: true, width: 0) + }; + + protected override string[] GetFixedColumns() + => new[] + { + ColumnDefinitions.CodeStyle.Category, + ColumnDefinitions.CodeStyle.Description, + ColumnDefinitions.CodeStyle.Value, + ColumnDefinitions.CodeStyle.Severity + }; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/ColumnDefinitions.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/ColumnDefinitions.cs new file mode 100644 index 0000000000000..669d7b7c5f07c --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/ColumnDefinitions.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal static class ColumnDefinitions + { + private const string Prefix = "editorconfig."; + + internal static class Analyzer + { + private const string AnalyzerPrefix = "analyzer."; + public const string Category = Prefix + AnalyzerPrefix + "categoryname"; + public const string Enabled = Prefix + AnalyzerPrefix + "enabledname"; + public const string Description = Prefix + AnalyzerPrefix + "descriptionname"; + public const string Id = Prefix + AnalyzerPrefix + "idname"; + public const string Severity = Prefix + AnalyzerPrefix + "severityname"; + public const string Title = Prefix + AnalyzerPrefix + "titlename"; + } + + internal static class CodeStyle + { + private const string CodeStylePrefix = "codestyle."; + public const string Category = Prefix + CodeStylePrefix + "categoryname"; + public const string Description = Prefix + CodeStylePrefix + "descriptionname"; + public const string Value = Prefix + CodeStylePrefix + "valuename"; + public const string Severity = Prefix + CodeStylePrefix + "severityname"; + } + + internal static class Formatting + { + private const string FormattingPrefix = "Formatting."; + public const string Category = Prefix + FormattingPrefix + "categoryname"; + public const string Description = Prefix + FormattingPrefix + "descriptionname"; + public const string Value = Prefix + FormattingPrefix + "valuename"; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EditorTextUpdater.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EditorTextUpdater.cs new file mode 100644 index 0000000000000..ed941cfef95a7 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EditorTextUpdater.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; +using Microsoft.VisualStudio.Text; +using Microsoft.VisualStudio.TextManager.Interop; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal class EditorTextUpdater + { + private readonly IVsEditorAdaptersFactoryService _editorAdaptersFactoryService; + private readonly IVsTextLines _textLines; + + public EditorTextUpdater(IVsEditorAdaptersFactoryService editorAdaptersFactoryService, + IVsTextLines textLines) + { + _editorAdaptersFactoryService = editorAdaptersFactoryService; + _textLines = textLines; + } + + public void UpdateText(IReadOnlyList changes) + { + var buffer = _editorAdaptersFactoryService.GetDocumentBuffer(_textLines); + if (buffer is null) + { + return; + } + TextEditApplication.UpdateText(changes.ToImmutableArray(), buffer, EditOptions.DefaultMinimalChange); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml new file mode 100644 index 0000000000000..eeee83644d8ac --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml @@ -0,0 +1,11 @@ + + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml.cs new file mode 100644 index 0000000000000..096c20f270098 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumPropertyView.xaml.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Windows.Automation; +using System.Windows.Controls; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + + /// + /// Interaction logic for EnumPropertyView.xaml + /// + internal partial class EnumSettingView : UserControl + { + private readonly IEnumSettingViewModel _model; + private readonly string[] _descriptions; + private readonly ComboBox _comboBox; + + public EnumSettingView(IEnumSettingViewModel model) + { + InitializeComponent(); + _model = model; + + _descriptions = _model.GetValueDescriptions(); + _comboBox = new ComboBox() + { + ItemsSource = _descriptions + }; + + _comboBox.SelectedIndex = model.GetValueIndex(); + _comboBox.SetValue(AutomationProperties.NameProperty, ServicesVSResources.Value); + _comboBox.SelectionChanged += ComboBox_SelectionChanged; + + _ = RootGrid.Children.Add(_comboBox); + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + var index = _comboBox.SelectedIndex; + if (index < _descriptions.Length && index >= 0) + { + _model.ChangeProperty(_descriptions[index]); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumSettingViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumSettingViewModel.cs new file mode 100644 index 0000000000000..53b21e40562aa --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/EnumSettingViewModel.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal abstract class EnumSettingViewModel : IEnumSettingViewModel + where T : Enum + { + private readonly IReadOnlyDictionary _mapping; + + protected EnumSettingViewModel() + { + _mapping = GetValuesAndDescriptions(); + } + + public void ChangeProperty(string propertyDescription) + { + if (_mapping.TryGetValue(propertyDescription, out var value)) + { + ChangePropertyTo(value); + } + } + + public string[] GetValueDescriptions() + => _mapping.Keys.ToArray(); + + public int GetValueIndex() + { + var value = GetCurrentValue(); + return _mapping.Values.ToList().IndexOf(value); + } + + protected abstract IReadOnlyDictionary GetValuesAndDescriptions(); + protected abstract void ChangePropertyTo(T newValue); + protected abstract T GetCurrentValue(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModel.cs new file mode 100644 index 0000000000000..3f80a67b2b500 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModel.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + + internal interface IEnumSettingViewModel + { + string[] GetValueDescriptions(); + int GetValueIndex(); + void ChangeProperty(string v); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModelFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModelFactory.cs new file mode 100644 index 0000000000000..5e1ba1fe2c235 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/IEnumSettingViewModelFactory.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal interface IEnumSettingViewModelFactory + { + bool IsSupported(OptionKey2 key); + IEnumSettingViewModel CreateViewModel(FormattingSetting setting); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/RemoveSinkWhenDisposed.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/RemoveSinkWhenDisposed.cs new file mode 100644 index 0000000000000..83d27a9c2959a --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/RemoveSinkWhenDisposed.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal class RemoveSinkWhenDisposed : IDisposable + { + private readonly List _tableSinks; + private readonly ITableDataSink _sink; + + public RemoveSinkWhenDisposed(List tableSinks, ITableDataSink sink) + { + _tableSinks = tableSinks; + _sink = sink; + } + + public void Dispose() + { + // whoever subscribed is no longer interested in my data. + // Remove them from the list of sinks + _ = _tableSinks.Remove(_sink); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsEntriesSnapshotBase.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsEntriesSnapshotBase.cs new file mode 100644 index 0000000000000..822218aedebf3 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsEntriesSnapshotBase.cs @@ -0,0 +1,55 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using Microsoft.VisualStudio.Shell.TableControl; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal abstract class SettingsEntriesSnapshotBase : WpfTableEntriesSnapshotBase + { + private readonly ImmutableArray _data; + private readonly int _currentVersionNumber; + + public SettingsEntriesSnapshotBase(ImmutableArray data, int currentVersionNumber) + { + _data = data; + _currentVersionNumber = currentVersionNumber; + } + + public override int VersionNumber => _currentVersionNumber; + public override int Count => _data.Length; + + public override bool TryGetValue(int index, string keyName, out object? content) + { + T? result; + try + { + if (index < 0 || index > _data.Length) + { + content = null; + return false; + } + + result = _data[index]; + + if (result == null) + { + content = null; + return false; + } + } + catch (Exception) + { + content = null; + return false; + } + + return TryGetValue(result, keyName, out content); + } + + protected abstract bool TryGetValue(T result, string keyName, out object? content); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsSnapshotFactoryBase.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsSnapshotFactoryBase.cs new file mode 100644 index 0000000000000..e18edd875cfb0 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsSnapshotFactoryBase.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.Threading; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal abstract class SettingsSnapshotFactoryBase : TableEntriesSnapshotFactoryBase + where TEntriesSnapshot : SettingsEntriesSnapshotBase + { + private readonly ISettingsProvider _data; + + // State + private int _currentVersionNumber; + private int _lastSnapshotVersionNumber = -1; + private TEntriesSnapshot? _lastSnapshot; + + // Disallow concurrent modification of state + private readonly object _gate = new(); + + public SettingsSnapshotFactoryBase(ISettingsProvider data) + { + _data = data; + } + + public override int CurrentVersionNumber => _currentVersionNumber; + + public override ITableEntriesSnapshot? GetCurrentSnapshot() => GetSnapshot(CurrentVersionNumber); + + internal void NotifyOfUpdate() => Interlocked.Increment(ref _currentVersionNumber); + + public override ITableEntriesSnapshot? GetSnapshot(int versionNumber) + { + lock (_gate) + { + if (versionNumber == _currentVersionNumber) + { + if (_lastSnapshotVersionNumber == _currentVersionNumber) + { + return _lastSnapshot; + } + else + { + var data = _data.GetCurrentDataSnapshot(); + var snapshot = CreateSnapshot(data, _currentVersionNumber); + + _lastSnapshot = snapshot; + _lastSnapshotVersionNumber = _currentVersionNumber; + + return snapshot; + } + } + else if (versionNumber < _currentVersionNumber) + { + // We can return null from this method. + // This will signal to Table Control to request current snapshot. + return null; + } + else // versionNumber > this.currentVersionNumber + { + throw new InvalidOperationException($"Invalid GetSnapshot request. Requested version: {versionNumber}. Current version: {_currentVersionNumber}"); + } + } + } + + protected abstract TEntriesSnapshot CreateSnapshot(ImmutableArray data, int currentVersionNumber); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsViewModelBase.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsViewModelBase.cs new file mode 100644 index 0000000000000..dcbcbd29f4219 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/SettingsViewModelBase.cs @@ -0,0 +1,87 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.CodeAnalysis.Text; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common +{ + internal abstract partial class SettingsViewModelBase : IWpfSettingsEditorViewModel, ITableDataSource + where TSnapshotFactory : SettingsSnapshotFactoryBase + where TEntriesSnapshot : SettingsEntriesSnapshotBase + { + private readonly ISettingsProvider _data; + private readonly IWpfTableControlProvider _controlProvider; + private readonly TSnapshotFactory _snapshotFactory; + private readonly ITableManager _tableManager; + private ITableEntriesSnapshot? _lastPublishedSnapshot; + + private List TableSinks { get; } = new List(); + + protected SettingsViewModelBase(ISettingsProvider data, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider) + { + _data = data; + _controlProvider = controlProvider; + _data.RegisterViewModel(this); + _tableManager = tableMangerProvider.GetTableManager(Identifier); + _snapshotFactory = CreateSnapshotFactory(_data); + _ = _tableManager.AddSource(this); + } + + public abstract string Identifier { get; } + protected abstract TSnapshotFactory CreateSnapshotFactory(ISettingsProvider data); + protected abstract string[] GetFixedColumns(); + protected abstract IEnumerable GetInitialColumnStates(); + + public string SourceTypeIdentifier => "EditorConfigSettings"; + public string? DisplayName => null; + + public void NotifyOfUpdate() + { + _snapshotFactory.NotifyOfUpdate(); + var snapshot = _snapshotFactory.GetCurrentSnapshot(); + + // Notify the sinks. Generally, VS Table Control will request data 500ms after the last notification. + foreach (var tableSink in TableSinks) + { + // Notify that an update is available + tableSink.ReplaceSnapshot(snapshot, _lastPublishedSnapshot); + } + + _lastPublishedSnapshot = snapshot; + } + + public IDisposable Subscribe(ITableDataSink sink) + { + TableSinks.Add(sink); + _snapshotFactory.NotifyOfUpdate(); + _lastPublishedSnapshot = _snapshotFactory.GetCurrentSnapshot(); + sink.AddSnapshot(_lastPublishedSnapshot); + return new RemoveSinkWhenDisposed(TableSinks, sink); + } + + public IWpfTableControl4 GetTableControl() + { + var initialColumnStates = GetInitialColumnStates(); + var fixedColumns = GetFixedColumns(); + return (IWpfTableControl4)_controlProvider.CreateControl( + _tableManager, + true, + initialColumnStates, + fixedColumns); + } + + public void ShutDown() => _ = _tableManager.RemoveSource(this); + + public Task UpdateEditorConfigAsync(SourceText sourceText) => _data.GetChangedEditorConfigAsync(sourceText); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingCategoryColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingCategoryColumnDefinition.cs new file mode 100644 index 0000000000000..9b1b7ae7f4156 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingCategoryColumnDefinition.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Formatting; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View.ColumnDefnitions +{ + [Export(typeof(IDefaultColumnGroup))] + [Name(nameof(FormattingCategoryGroupingSet))] // Required, name of the default group + [GroupColumns(Category)] // Required, the names of the columns in the grouping + internal class FormattingCategoryGroupingSet : IDefaultColumnGroup + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public FormattingCategoryGroupingSet() + { + } + } + + [Export(typeof(ITableColumnDefinition))] + [Name(Category)] + internal class FormattingCategoryColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public FormattingCategoryColumnDefinition() + { + } + + public override string Name => Category; + public override string DisplayName => ServicesVSResources.Category; + public override double MinWidth => 80; + public override bool DefaultVisible => false; + public override bool IsFilterable => true; + public override bool IsSortable => true; + public override TextWrapping TextWrapping => TextWrapping.NoWrap; + + private static string? GetCategoryName(ITableEntryHandle entry) + => entry.TryGetValue(Category, out string? categoryName) + ? categoryName + : null; + + public override IEntryBucket? CreateBucketForEntry(ITableEntryHandle entry) + { + var categoryName = GetCategoryName(entry); + return categoryName is not null ? new StringEntryBucket(GetCategoryName(entry)) : null; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingDescriptionColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingDescriptionColumnDefinition.cs new file mode 100644 index 0000000000000..eb11d8badf6df --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingDescriptionColumnDefinition.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Formatting; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View.ColumnDefnitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Description)] + internal class FormattingDescriptionColumnDefinition : TableColumnDefinitionBase + { + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public FormattingDescriptionColumnDefinition() + { + } + + public override string Name => Description; + public override string DisplayName => ServicesVSResources.Description; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override double DefaultWidth => 350; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingValueColumnDefinition.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingValueColumnDefinition.cs new file mode 100644 index 0000000000000..48128122cc5b2 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/ColumnDefnitions/FormattingValueColumnDefinition.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Windows; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.Utilities; +using static Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common.ColumnDefinitions.Formatting; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View.ColumnDefnitions +{ + [Export(typeof(ITableColumnDefinition))] + [Name(Value)] + internal class FormattingValueColumnDefinition : TableColumnDefinitionBase + { + private readonly IEnumerable _factories; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public FormattingValueColumnDefinition([ImportMany] IEnumerable factories) + { + _factories = factories; + } + + public override string Name => Value; + public override string DisplayName => ServicesVSResources.Value; + public override double MinWidth => 80; + public override bool DefaultVisible => false; + public override bool IsFilterable => false; + public override bool IsSortable => false; + public override TextWrapping TextWrapping => TextWrapping.NoWrap; + + public override bool TryCreateColumnContent(ITableEntryHandle entry, bool singleColumnView, out FrameworkElement? content) + { + if (!entry.TryGetValue(Value, out FormattingSetting setting)) + { + content = null; + return false; + } + if (setting.Type == typeof(bool)) + { + content = new FormattingBoolSettingView(setting); + return true; + } + + foreach (var factory in _factories) + { + if (factory.IsSupported(setting.Key)) + { + var viewModel = factory.CreateViewModel(setting); + content = new EnumSettingView(viewModel); + return true; + } + } + + content = null; + return false; + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml new file mode 100644 index 0000000000000..abc9308db376a --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml @@ -0,0 +1,9 @@ + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml.cs new file mode 100644 index 0000000000000..3562a1359ded7 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingBoolSettingView.xaml.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Windows; +using System.Windows.Automation; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View +{ + /// + /// Interaction logic for WhitespaceValueSettingControl.xaml + /// + internal partial class FormattingBoolSettingView : UserControl + { + private readonly FormattingSetting _setting; + + public FormattingBoolSettingView(FormattingSetting setting) + { + InitializeComponent(); + RootCheckBox.SetValue(AutomationProperties.NameProperty, ServicesVSResources.Value); + _setting = setting; + + if (setting.GetValue() is bool value) + { + RootCheckBox.IsChecked = value; + } + + RootCheckBox.Checked += CheckBoxChanged; + RootCheckBox.Unchecked += CheckBoxChanged; + } + + private void CheckBoxChanged(object sender, RoutedEventArgs e) + { + var value = RootCheckBox.IsChecked == true; + if (_setting.GetValue() is bool currentValue && + value != currentValue) + { + _setting.SetValue(value); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml new file mode 100644 index 0000000000000..6e914a4f5de62 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml @@ -0,0 +1,18 @@ + + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml.cs new file mode 100644 index 0000000000000..6a7c8179581ac --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/View/FormattingSettingsView.xaml.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.TextManager.Interop; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View +{ + /// + /// Interaction logic for FormattingSettingsView.xaml + /// + internal partial class FormattingSettingsView : UserControl, ISettingsEditorView + { + private readonly IWpfSettingsEditorViewModel _viewModel; + + public FormattingSettingsView(IWpfSettingsEditorViewModel viewModel) + { + InitializeComponent(); + _viewModel = viewModel; + TableControl = _viewModel.GetTableControl(); + FormattingTable.Child = TableControl.Control; + } + + public UserControl SettingControl => this; + public IWpfTableControl TableControl { get; } + public Task UpdateEditorConfigAsync(SourceText sourceText) => _viewModel.UpdateEditorConfigAsync(sourceText); + public void OnClose() => _viewModel.ShutDown(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsEntriesSnapshot.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsEntriesSnapshot.cs new file mode 100644 index 0000000000000..efb58f722bd51 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsEntriesSnapshot.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + internal partial class FormattingViewModel + { + internal sealed class SettingsEntriesSnapshot : SettingsEntriesSnapshotBase + { + public SettingsEntriesSnapshot(ImmutableArray data, int currentVersionNumber) : base(data, currentVersionNumber) { } + + protected override bool TryGetValue(FormattingSetting result, string keyName, out object? content) + { + content = keyName switch + { + ColumnDefinitions.Formatting.Description => result.Description, + ColumnDefinitions.Formatting.Category => result.Category, + ColumnDefinitions.Formatting.Value => result, + _ => null, + }; + + return content is not null; + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsSnapshotFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsSnapshotFactory.cs new file mode 100644 index 0000000000000..c29473e1aa092 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.SettingsSnapshotFactory.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + internal partial class FormattingViewModel + { + internal sealed class SettingsSnapshotFactory : SettingsSnapshotFactoryBase + { + public SettingsSnapshotFactory(ISettingsProvider data) : base(data) { } + + protected override SettingsEntriesSnapshot CreateSnapshot(ImmutableArray data, int currentVersionNumber) + => new(data, currentVersionNumber); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.cs new file mode 100644 index 0000000000000..67c5de89a5bb6 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/FormattingViewModel.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.DataProvider; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Shell.TableManager; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + internal partial class FormattingViewModel : SettingsViewModelBase< + FormattingSetting, + FormattingViewModel.SettingsSnapshotFactory, + FormattingViewModel.SettingsEntriesSnapshot> + { + public FormattingViewModel(ISettingsProvider data, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider) + : base(data, controlProvider, tableMangerProvider) + { } + + public override string Identifier => "Whitespace"; + + protected override SettingsSnapshotFactory CreateSnapshotFactory(ISettingsProvider data) + => new(data); + + protected override IEnumerable GetInitialColumnStates() + => new[] + { + new ColumnState2(ColumnDefinitions.Formatting.Category, isVisible: false, width: 0, groupingPriority: 1), + new ColumnState2(ColumnDefinitions.Formatting.Description, isVisible: true, width: 0), + new ColumnState2(ColumnDefinitions.Formatting.Value, isVisible: true, width: 0) + }; + + protected override string[] GetFixedColumns() + => new[] + { + ColumnDefinitions.Formatting.Category, + ColumnDefinitions.Formatting.Description, + ColumnDefinitions.Formatting.Value + }; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/IndentationSizeViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/IndentationSizeViewModel.cs new file mode 100644 index 0000000000000..c8f750aff18cc --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/IndentationSizeViewModel.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + [Export(typeof(IEnumSettingViewModelFactory)), Shared] + internal class IndentationSizeVViewModelFactory : IEnumSettingViewModelFactory + { + private readonly OptionKey2 _key; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public IndentationSizeVViewModelFactory() + { + _key = new OptionKey2(FormattingOptions2.IndentationSize, LanguageNames.CSharp); + } + + public IEnumSettingViewModel CreateViewModel(FormattingSetting setting) + { + return new IndentationSizeViewModel(setting); + } + + public bool IsSupported(OptionKey2 key) => _key == key; + } + + internal enum IndentationSizeSetting + { + _1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, + } + + internal class IndentationSizeViewModel : EnumSettingViewModel + { + private readonly FormattingSetting _setting; + + public IndentationSizeViewModel(FormattingSetting setting) + { + _setting = setting; + } + + protected override void ChangePropertyTo(IndentationSizeSetting newValue) + { + switch (newValue) + { + case IndentationSizeSetting._1: + _setting.SetValue(1); + break; + case IndentationSizeSetting._2: + _setting.SetValue(2); + break; + case IndentationSizeSetting._3: + _setting.SetValue(3); + break; + case IndentationSizeSetting._4: + _setting.SetValue(4); + break; + case IndentationSizeSetting._5: + _setting.SetValue(5); + break; + case IndentationSizeSetting._6: + _setting.SetValue(6); + break; + case IndentationSizeSetting._7: + _setting.SetValue(7); + break; + case IndentationSizeSetting._8: + _setting.SetValue(8); + break; + default: + break; + } + } + + protected override IndentationSizeSetting GetCurrentValue() + { + return _setting.GetValue() switch + { + 1 => IndentationSizeSetting._1, + 2 => IndentationSizeSetting._2, + 3 => IndentationSizeSetting._3, + 4 => IndentationSizeSetting._4, + 5 => IndentationSizeSetting._5, + 6 => IndentationSizeSetting._6, + 7 => IndentationSizeSetting._7, + _ => IndentationSizeSetting._8, + }; + } + + protected override IReadOnlyDictionary GetValuesAndDescriptions() + { + return EnumerateOptions().ToDictionary(x => x.description, x => x.value); + + static IEnumerable<(string description, IndentationSizeSetting value)> EnumerateOptions() + { + yield return ("1", IndentationSizeSetting._1); + yield return ("2", IndentationSizeSetting._2); + yield return ("3", IndentationSizeSetting._3); + yield return ("4", IndentationSizeSetting._4); + yield return ("5", IndentationSizeSetting._5); + yield return ("6", IndentationSizeSetting._6); + yield return ("7", IndentationSizeSetting._7); + yield return ("8", IndentationSizeSetting._8); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/NewLineViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/NewLineViewModel.cs new file mode 100644 index 0000000000000..0258467dc7ff6 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/NewLineViewModel.cs @@ -0,0 +1,97 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + [Export(typeof(IEnumSettingViewModelFactory)), Shared] + internal class NewLineViewModelFactory : IEnumSettingViewModelFactory + { + private readonly OptionKey2 _key; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public NewLineViewModelFactory() + { + _key = new OptionKey2(FormattingOptions2.NewLine, LanguageNames.CSharp); + } + + public IEnumSettingViewModel CreateViewModel(FormattingSetting setting) + { + return new NewLineViewModel(setting); + } + + public bool IsSupported(OptionKey2 key) => _key == key; + } + + internal enum NewLineSetting + { + Newline, + CarrageReturn, + CarrageReturnNewline, + NotSet + } + + internal class NewLineViewModel : EnumSettingViewModel + { + private readonly FormattingSetting _setting; + + public NewLineViewModel(FormattingSetting setting) + { + _setting = setting; + } + + protected override void ChangePropertyTo(NewLineSetting newValue) + { + switch (newValue) + { + case NewLineSetting.Newline: + _setting.SetValue("\n"); + break; + case NewLineSetting.CarrageReturn: + _setting.SetValue("\r"); + break; + case NewLineSetting.CarrageReturnNewline: + _setting.SetValue("\r\n"); + break; + case NewLineSetting.NotSet: + default: + break; + } + } + + protected override NewLineSetting GetCurrentValue() + { + return _setting.GetValue() switch + { + "\n" => NewLineSetting.Newline, + "\r" => NewLineSetting.CarrageReturn, + "\r\n" => NewLineSetting.CarrageReturnNewline, + _ => NewLineSetting.NotSet, + }; + } + + protected override IReadOnlyDictionary GetValuesAndDescriptions() + { + return EnumerateOptions().ToDictionary(x => x.description, x => x.value); + + static IEnumerable<(string description, NewLineSetting value)> EnumerateOptions() + { + yield return (ServicesVSResources.Newline_n, NewLineSetting.Newline); + yield return (ServicesVSResources.Carrage_Return_r, NewLineSetting.CarrageReturn); + yield return (ServicesVSResources.Carrage_Return_Newline_rn, NewLineSetting.CarrageReturnNewline); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeSettings.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeSettings.cs new file mode 100644 index 0000000000000..ddd0594e2b312 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeSettings.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + internal enum TabSizeSettings + { + _1 = 1, + _2, + _3, + _4, + _5, + _6, + _7, + _8, + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModel.cs new file mode 100644 index 0000000000000..ea51e1505a6bb --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModel.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + internal class TabSizeViewModel : EnumSettingViewModel + { + private readonly FormattingSetting _setting; + + public TabSizeViewModel(FormattingSetting setting) + { + _setting = setting; + } + + protected override void ChangePropertyTo(TabSizeSettings newValue) + => _setting.SetValue((int)newValue); + + protected override TabSizeSettings GetCurrentValue() + { + return _setting.GetValue() switch + { + 1 => TabSizeSettings._1, + 2 => TabSizeSettings._2, + 3 => TabSizeSettings._3, + 4 => TabSizeSettings._4, + 5 => TabSizeSettings._5, + 6 => TabSizeSettings._6, + 7 => TabSizeSettings._7, + _ => TabSizeSettings._8, + }; + } + + protected override IReadOnlyDictionary GetValuesAndDescriptions() + { + return EnumerateOptions().ToDictionary(x => x.description, x => x.value); + + static IEnumerable<(string description, TabSizeSettings value)> EnumerateOptions() + { + yield return ("1", TabSizeSettings._1); + yield return ("2", TabSizeSettings._2); + yield return ("3", TabSizeSettings._3); + yield return ("4", TabSizeSettings._4); + yield return ("5", TabSizeSettings._5); + yield return ("6", TabSizeSettings._6); + yield return ("7", TabSizeSettings._7); + yield return ("8", TabSizeSettings._8); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModelFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModelFactory.cs new file mode 100644 index 0000000000000..e33d79adb8132 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Formatting/ViewModel/TabSizeViewModelFactory.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel +{ + [Export(typeof(IEnumSettingViewModelFactory)), Shared] + internal class TabSizeViewModelFactory : IEnumSettingViewModelFactory + { + private readonly OptionKey2 _key; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public TabSizeViewModelFactory() + { + _key = new OptionKey2(FormattingOptions2.TabSize, LanguageNames.CSharp); + } + + public IEnumSettingViewModel CreateViewModel(FormattingSetting setting) + { + return new TabSizeViewModel(setting); + } + + public bool IsSupported(OptionKey2 key) => _key == key; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/ISettingsEditorView.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/ISettingsEditorView.cs new file mode 100644 index 0000000000000..e23b0524f3eac --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/ISettingsEditorView.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using System.Windows.Controls; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Shell.TableControl; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal interface ISettingsEditorView + { + UserControl SettingControl { get; } + IWpfTableControl TableControl { get; } + Task UpdateEditorConfigAsync(SourceText sourceText); + void OnClose(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/IWpfSettingsEditorViewModel.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/IWpfSettingsEditorViewModel.cs new file mode 100644 index 0000000000000..5a3f8d4327a0f --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/IWpfSettingsEditorViewModel.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Editor; +using Microsoft.VisualStudio.Shell.TableControl; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal interface IWpfSettingsEditorViewModel : ISettingsEditorViewModel + { + IWpfTableControl4 GetTableControl(); + void ShutDown(); + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/ServiceProviderExtensions.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/ServiceProviderExtensions.cs new file mode 100644 index 0000000000000..8c9be12a391ea --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/ServiceProviderExtensions.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics.CodeAnalysis; +using Microsoft.VisualStudio.Shell; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal static class ServiceProviderExtensions + { + public static bool TryGetService(this IServiceProvider sp, [NotNullWhen(true)] out TInterface? @interface) + where TInterface : class + { + @interface = sp.GetService(throwOnFailure: false); + return @interface is not null; + } + + public static bool TryGetService(this IServiceProvider sp, [NotNullWhen(true)] out TInterface? @interface) + where TInterface : class + { + @interface = sp.GetService(); + return @interface is not null; + } + + public static TInterface? GetService(this IServiceProvider sp) + where TInterface : class + { + return sp.GetService(throwOnFailure: false); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml new file mode 100644 index 0000000000000..4e0c57c19e250 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml.cs new file mode 100644 index 0000000000000..2e1bbac25a334 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorControl.xaml.cs @@ -0,0 +1,98 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Linq; +using System.Windows.Controls; +using Microsoft.CodeAnalysis; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Common; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.TextManager.Interop; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + /// + /// Interaction logic for SettingsEditorControl.xaml + /// + internal partial class SettingsEditorControl : UserControl + { + private readonly ISettingsEditorView _formattingView; + private readonly ISettingsEditorView _codeStyleView; + private readonly ISettingsEditorView _analyzerSettingsView; + private readonly Workspace _workspace; + private readonly string _filepath; + private readonly IThreadingContext _threadingContext; + private readonly EditorTextUpdater _textUpdater; + + public static string Formatting => ServicesVSResources.Formatting; + public static string CodeStyle => ServicesVSResources.Code_Style; + public static string Analyzers => ServicesVSResources.Analyzers; + + public SettingsEditorControl(ISettingsEditorView formattingView, + ISettingsEditorView codeStyleView, + ISettingsEditorView analyzerSettingsView, + Workspace workspace, + string filepath, + IThreadingContext threadingContext, + IVsEditorAdaptersFactoryService editorAdaptersFactoryService, + IVsTextLines textLines) + { + InitializeComponent(); + DataContext = this; + _workspace = workspace; + _filepath = filepath; + _threadingContext = threadingContext; + _textUpdater = new EditorTextUpdater(editorAdaptersFactoryService, textLines); + _formattingView = formattingView; + FormattingTab.Content = _formattingView.SettingControl; + _codeStyleView = codeStyleView; + CodeStyleTab.Content = _codeStyleView.SettingControl; + _analyzerSettingsView = analyzerSettingsView; + AnalyzersTab.Content = _analyzerSettingsView.SettingControl; + } + + internal void SynchronizeSettings() + { + if (!IsKeyboardFocusWithin) + { + return; + } + + var solution = _workspace.CurrentSolution; + var analyzerConfigDocument = solution.Projects + .Select(p => p.TryGetExistingAnalyzerConfigDocumentAtPath(_filepath)).FirstOrDefault(); + if (analyzerConfigDocument is null) + { + return; + } + + _threadingContext.JoinableTaskFactory.Run(async () => + { + var originalText = await analyzerConfigDocument.GetTextAsync(default).ConfigureAwait(false); + var updatedText = await _formattingView.UpdateEditorConfigAsync(originalText).ConfigureAwait(false); + updatedText = await _codeStyleView.UpdateEditorConfigAsync(updatedText).ConfigureAwait(false); + updatedText = await _analyzerSettingsView.UpdateEditorConfigAsync(updatedText).ConfigureAwait(false); + _textUpdater.UpdateText(updatedText.GetTextChanges(originalText)); + }); + } + + internal IWpfTableControl[] GetTableControls() + => new[] + { + _formattingView.TableControl, + _codeStyleView.TableControl, + _analyzerSettingsView.TableControl, + }; + + internal void OnClose() + { + _formattingView.OnClose(); + _codeStyleView.OnClose(); + _analyzerSettingsView.OnClose(); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs new file mode 100644 index 0000000000000..9d5c0f56592f0 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorFactory.cs @@ -0,0 +1,164 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Composition; +using System.Runtime.InteropServices; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.OLE.Interop; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.TextManager.Interop; +using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + [Export(typeof(SettingsEditorFactory))] + [Guid(SettingsEditorFactoryGuidString)] + internal sealed class SettingsEditorFactory : IVsEditorFactory, IDisposable + { + public static readonly Guid SettingsEditorFactoryGuid = new(SettingsEditorFactoryGuidString); + public const string SettingsEditorFactoryGuidString = "68b46364-d378-42f2-9e72-37d86c5f4468"; + public const string Extension = ".editorconfig"; + + private readonly ISettingsAggregator _settingsDataProviderFactory; + private readonly VisualStudioWorkspace _workspace; + private readonly IWpfTableControlProvider _controlProvider; + private readonly ITableManagerProvider _tableMangerProvider; + private readonly IVsEditorAdaptersFactoryService _vsEditorAdaptersFactoryService; + private readonly IThreadingContext _threadingContext; + private ServiceProvider? _vsServiceProvider; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public SettingsEditorFactory(VisualStudioWorkspace workspace, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider, + IVsEditorAdaptersFactoryService vsEditorAdaptersFactoryService, + IThreadingContext threadingContext) + { + _settingsDataProviderFactory = workspace.Services.GetRequiredService(); + _workspace = workspace; + _controlProvider = controlProvider; + _tableMangerProvider = tableMangerProvider; + _vsEditorAdaptersFactoryService = vsEditorAdaptersFactoryService; + _threadingContext = threadingContext; + } + + public void Dispose() + { + if (_vsServiceProvider is not null) + { + _vsServiceProvider.Dispose(); + _vsServiceProvider = null; + } + } + + public int CreateEditorInstance(uint grfCreateDoc, + string pszMkDocument, + string pszPhysicalView, + IVsHierarchy pvHier, + uint itemid, + IntPtr punkDocDataExisting, + out IntPtr ppunkDocView, + out IntPtr ppunkDocData, + out string? pbstrEditorCaption, + out Guid pguidCmdUI, + out int pgrfCDW) + { + // Initialize to null + ppunkDocView = IntPtr.Zero; + ppunkDocData = IntPtr.Zero; + pguidCmdUI = SettingsEditorFactoryGuid; + pgrfCDW = 0; + pbstrEditorCaption = null; + + // Validate inputs + if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0) + { + return VSConstants.E_INVALIDARG; + } + + IVsTextLines? textBuffer = null; + if (punkDocDataExisting == IntPtr.Zero) + { + Assumes.NotNull(_vsServiceProvider); + if (_vsServiceProvider.TryGetService(out var localRegistry)) + { + var textLinesGuid = typeof(IVsTextLines).GUID; + _ = localRegistry.CreateInstance(typeof(VsTextBufferClass).GUID, null, ref textLinesGuid, 1 /*CLSCTX_INPROC_SERVER*/, out var ptr); + try + { + textBuffer = Marshal.GetObjectForIUnknown(ptr) as IVsTextLines; + } + finally + { + _ = Marshal.Release(ptr); // Release RefCount from CreateInstance call + } + + if (textBuffer is IObjectWithSite objectWithSite) + { + var oleServiceProvider = _vsServiceProvider.GetService(); + objectWithSite.SetSite(oleServiceProvider); + } + } + } + else + { + textBuffer = Marshal.GetObjectForIUnknown(punkDocDataExisting) as IVsTextLines; + if (textBuffer == null) + { + return VSConstants.VS_E_INCOMPATIBLEDOCDATA; + } + } + + if (textBuffer is null) + { + throw new InvalidOperationException("unable to acquire text buffer"); + } + + // Create the editor + var newEditor = new SettingsEditorPane(_vsEditorAdaptersFactoryService, + _threadingContext, + _settingsDataProviderFactory, + _controlProvider, + _tableMangerProvider, + pszMkDocument, + textBuffer, + _workspace); + ppunkDocView = Marshal.GetIUnknownForObject(newEditor); + ppunkDocData = Marshal.GetIUnknownForObject(textBuffer); + pbstrEditorCaption = ""; + return VSConstants.S_OK; + } + + public int SetSite(IOleServiceProvider psp) + { + _vsServiceProvider = new ServiceProvider(psp); + return VSConstants.S_OK; + } + + public int Close() => VSConstants.S_OK; + + public int MapLogicalView(ref Guid rguidLogicalView, out string? pbstrPhysicalView) + { + pbstrPhysicalView = null; // initialize out parameter + + // we support only a single physical view + if (VSConstants.LOGVIEWID_Primary == rguidLogicalView) + { + return VSConstants.S_OK; // primary view uses NULL as pbstrPhysicalView + } + else + { + return VSConstants.E_NOTIMPL; // you must return E_NOTIMPL for any unrecognized rguidLogicalView values + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchFilter.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchFilter.cs new file mode 100644 index 0000000000000..8148321792dea --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchFilter.cs @@ -0,0 +1,137 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell.TableControl; +using System.Collections.Generic; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal sealed partial class SettingsEditorPane + { + internal class SearchFilter : IEntryFilter + { + private readonly IEnumerable _searchTokens; + private readonly IReadOnlyList? _visibleColumns; + + public SearchFilter(IVsSearchQuery searchQuery, IWpfTableControl control) + { + _searchTokens = SearchUtilities.ExtractSearchTokens(searchQuery); + if (_searchTokens == null) + { + _searchTokens = Array.Empty(); + } + + var newVisibleColumns = new List(); + foreach (var c in control.ColumnStates) + { + if (c.IsVisible || ((c as ColumnState2)?.GroupingPriority > 0)) + { + var definition = control.ColumnDefinitionManager.GetColumnDefinition(c.Name); + if (definition != null) + { + newVisibleColumns.Add(definition); + } + } + } + + _visibleColumns = newVisibleColumns; + } + + public bool Match(ITableEntryHandle entry) + { + if (_visibleColumns is null) + { + return false; + } + + // An entry is considered matching a search query if all tokens in the search query are matching at least one of entry's columns. + // Reserve one more column for details content + var cachedColumnValues = new string[_visibleColumns.Count + 1]; + + foreach (var searchToken in _searchTokens) + { + // No support for filters yet + if (searchToken is IVsSearchFilterToken) + { + continue; + } + + if (!AtLeastOneColumnOrDetailsContentMatches(entry, searchToken, cachedColumnValues)) + { + return false; + } + } + + return true; + } + + private bool AtLeastOneColumnOrDetailsContentMatches(ITableEntryHandle entry, IVsSearchToken searchToken, string[] cachedColumnValues) + { + // Check details content for any matches + if (cachedColumnValues[0] == null) + { + cachedColumnValues[0] = GetDetailsContentAsString(entry); + } + + var detailsContent = cachedColumnValues[0]; + if (detailsContent != null && Match(detailsContent, searchToken)) + { + // Found match in details content + return true; + } + + if (_visibleColumns is null) + { + return false; + } + + // Check each column for any matches + for (var i = 0; i < _visibleColumns.Count; i++) + { + if (cachedColumnValues[i + 1] == null) + { + cachedColumnValues[i + 1] = GetColumnValueAsString(entry, _visibleColumns[i]); + } + + var columnValue = cachedColumnValues[i + 1]; + + if (columnValue != null && Match(columnValue, searchToken)) + { + // Found match in this column + return true; + } + } + + // No match found in this entry + return false; + } + + private static string GetColumnValueAsString(ITableEntryHandle entry, ITableColumnDefinition column) + => (entry.TryCreateStringContent(column, truncatedText: false, singleColumnView: false, content: out var columnValue) && columnValue is not null) + ? columnValue + : string.Empty; + + private static string GetDetailsContentAsString(ITableEntryHandle entry) + { + string? detailsString = null; + + if (entry.CanShowDetails) + { + if (entry is IWpfTableEntry wpfEntry) + { + _ = wpfEntry.TryCreateDetailsStringContent(out detailsString); + } + } + + return detailsString ?? string.Empty; + } + + private static bool Match(string columnValue, IVsSearchToken searchToken) + => (columnValue is not null) && (columnValue.IndexOf(searchToken.ParsedTokenText, StringComparison.OrdinalIgnoreCase) >= 0); + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchTask.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchTask.cs new file mode 100644 index 0000000000000..210d6ac71574b --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.SearchTask.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Threading; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal sealed partial class SettingsEditorPane + { + internal class SearchTask : VsSearchTask + { + private readonly IThreadingContext _threadingContext; + private readonly IWpfTableControl[] _controls; + + public SearchTask(uint dwCookie, + IVsSearchQuery pSearchQuery, + IVsSearchCallback pSearchCallback, + IWpfTableControl[] controls, + IThreadingContext threadingContext) + : base(dwCookie, pSearchQuery, pSearchCallback) + { + _threadingContext = threadingContext; + _controls = controls; + } + + protected override void OnStartSearch() + { + _ = _threadingContext.JoinableTaskFactory.RunAsync( + async () => + { + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); + foreach (var control in _controls) + { + _ = control.SetFilter(string.Empty, new SearchFilter(SearchQuery, control)); + } + + await TaskScheduler.Default; + uint resultCount = 0; + foreach (var control in _controls) + { + var results = await control.ForceUpdateAsync().ConfigureAwait(false); + resultCount += (uint)results.FilteredAndSortedEntries.Count; + } + + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); + SearchCallback.ReportComplete(this, dwResultsFound: resultCount); + }); + } + + protected override void OnStopSearch() + { + _ = _threadingContext.JoinableTaskFactory.RunAsync( + async () => + { + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); + foreach (var control in _controls) + { + _ = control.SetFilter(string.Empty, null); + } + }); + } + } + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs new file mode 100644 index 0000000000000..ebb94d37e7329 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/SettingsEditorPane.cs @@ -0,0 +1,381 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.ComponentModel.Design; +using System.Runtime.InteropServices; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings; +using Microsoft.CodeAnalysis.Editor.EditorConfigSettings.Data; +using Microsoft.CodeAnalysis.Editor.Shared.Extensions; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.Internal.VisualStudio.Shell.TableControl; +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.View; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Analyzers.ViewModel; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.View; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.CodeStyle.ViewModel; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.View; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Formatting.ViewModel; +using Microsoft.VisualStudio.OLE.Interop; +using Microsoft.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell.TableManager; +using Microsoft.VisualStudio.TextManager.Interop; +using static Microsoft.VisualStudio.VSConstants; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings +{ + internal sealed partial class SettingsEditorPane : WindowPane, IOleComponent, IVsDeferredDocView, IVsLinkedUndoClient, IVsWindowSearch + { + private readonly IVsEditorAdaptersFactoryService _vsEditorAdaptersFactoryService; + private readonly IThreadingContext _threadingContext; + private readonly ISettingsAggregator _settingsDataProviderService; + private readonly IWpfTableControlProvider _controlProvider; + private readonly ITableManagerProvider _tableMangerProvider; + private readonly string _fileName; + private readonly IVsTextLines _textBuffer; + private readonly Workspace _workspace; + private uint _componentId; + private IOleUndoManager? _undoManager; + private SettingsEditorControl? _control; + + public SettingsEditorPane(IVsEditorAdaptersFactoryService vsEditorAdaptersFactoryService, + IThreadingContext threadingContext, + ISettingsAggregator settingsDataProviderService, + IWpfTableControlProvider controlProvider, + ITableManagerProvider tableMangerProvider, + string fileName, + IVsTextLines textBuffer, + Workspace workspace) + : base(null) + { + _vsEditorAdaptersFactoryService = vsEditorAdaptersFactoryService; + _threadingContext = threadingContext; + _settingsDataProviderService = settingsDataProviderService; + _controlProvider = controlProvider; + _tableMangerProvider = tableMangerProvider; + _fileName = fileName; + _textBuffer = textBuffer; + _workspace = workspace; + } + + protected override void Initialize() + { + base.Initialize(); + + // Create and initialize the editor + if (_componentId == default && this.TryGetService(out var componentManager)) + { + var componentRegistrationInfo = new[] + { + new OLECRINFO + { + cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO)), + grfcrf = (uint)_OLECRF.olecrfNeedIdleTime | (uint)_OLECRF.olecrfNeedPeriodicIdleTime, + grfcadvf = (uint)_OLECADVF.olecadvfModal | (uint)_OLECADVF.olecadvfRedrawOff | (uint)_OLECADVF.olecadvfWarningsOff, + uIdleTimeInterval = 100 + } + }; + + var hr = componentManager.FRegisterComponent(this, componentRegistrationInfo, out _componentId); + _ = ErrorHandler.Succeeded(hr); + } + + if (this.TryGetService(out _undoManager)) + { + var linkCapableUndoMgr = (IVsLinkCapableUndoManager)_undoManager; + if (linkCapableUndoMgr is not null) + { + _ = linkCapableUndoMgr.AdviseLinkedUndoClient(this); + } + } + + // hook up our panel + _control = new SettingsEditorControl( + GetFormattingView(), + GetCodeStyleView(), + GetAnalyzerView(), + _workspace, + _fileName, + _threadingContext, + _vsEditorAdaptersFactoryService, + _textBuffer); + Content = _control; + + RegisterIndependentView(true); + if (this.TryGetService(out var menuCommandService)) + { + AddCommand(menuCommandService, GUID_VSStandardCommandSet97, (int)VSStd97CmdID.NewWindow, + new EventHandler(OnNewWindow), new EventHandler(OnQueryNewWindow)); + AddCommand(menuCommandService, GUID_VSStandardCommandSet97, (int)VSStd97CmdID.ViewCode, + new EventHandler(OnViewCode), new EventHandler(OnQueryViewCode)); + } + + ISettingsEditorView GetFormattingView() + { + var dataProvider = _settingsDataProviderService.GetSettingsProvider(_fileName); + if (dataProvider is null) + { + throw new InvalidOperationException("Unable to get formatter settings"); + } + var viewModel = new FormattingViewModel(dataProvider, _controlProvider, _tableMangerProvider); + return new FormattingSettingsView(viewModel); + } + + ISettingsEditorView GetCodeStyleView() + { + var dataProvider = _settingsDataProviderService.GetSettingsProvider(_fileName); + if (dataProvider is null) + { + throw new InvalidOperationException("Unable to get code style settings"); + } + var viewModel = new CodeStyleSettingsViewModel(dataProvider, _controlProvider, _tableMangerProvider); + return new CodeStyleSettingsView(viewModel); + } + + ISettingsEditorView GetAnalyzerView() + { + var dataProvider = _settingsDataProviderService.GetSettingsProvider(_fileName); + if (dataProvider is null) + { + throw new InvalidOperationException("Unable to get analyzer settings"); + } + + var viewModel = new AnalyzerSettingsViewModel(dataProvider, _controlProvider, _tableMangerProvider); + return new AnalyzerSettingsView(viewModel); + } + } + + private void OnQueryNewWindow(object sender, EventArgs e) + { + var command = (OleMenuCommand)sender; + command.Enabled = true; + } + + private void OnNewWindow(object sender, EventArgs e) + { + NewWindow(); + } + + private void OnQueryViewCode(object sender, EventArgs e) + { + var command = (OleMenuCommand)sender; + command.Enabled = true; + } + + private void OnViewCode(object sender, EventArgs e) + { + ViewCode(); + } + + private void NewWindow() + { + if (this.TryGetService(out var uishellOpenDocument) && + this.TryGetService(out var windowFrameOrig)) + { + var logicalView = Guid.Empty; + var hr = uishellOpenDocument.OpenCopyOfStandardEditor(windowFrameOrig, ref logicalView, out var windowFrameNew); + if (windowFrameNew != null) + { + hr = windowFrameNew.Show(); + } + + _ = ErrorHandler.ThrowOnFailure(hr); + } + } + + private void ViewCode() + { + var sourceCodeTextEditorGuid = VsEditorFactoryGuid.TextEditor_guid; + + // Open the referenced document using our editor. + VsShellUtilities.OpenDocumentWithSpecificEditor(this, _fileName, + sourceCodeTextEditorGuid, LOGVIEWID_Primary, out _, out _, out var frame); + _ = ErrorHandler.ThrowOnFailure(frame.Show()); + } + + protected override void OnClose() + { + // unhook from Undo related services + if (_undoManager != null) + { + var linkCapableUndoMgr = (IVsLinkCapableUndoManager)_undoManager; + if (linkCapableUndoMgr != null) + { + _ = linkCapableUndoMgr.UnadviseLinkedUndoClient(); + } + + // Throw away the undo stack etc. + // It is important to "zombify" the undo manager when the owning object is shutting down. + // This is done by calling IVsLifetimeControlledObject.SeverReferencesToOwner on the undoManager. + // This call will clear the undo and redo stacks. This is particularly important to do if + // your undo units hold references back to your object. It is also important if you use + // "mdtStrict" linked undo transactions as this sample does (see IVsLinkedUndoTransactionManager). + // When one object involved in linked undo transactions clears its undo/redo stacks, then + // the stacks of the other documents involved in the linked transaction will also be cleared. + var lco = (IVsLifetimeControlledObject)_undoManager; + _ = lco.SeverReferencesToOwner(); + _undoManager = null; + } + + if (this.TryGetService(out var componentManager)) + { + _ = componentManager.FRevokeComponent(_componentId); + } + + _control?.OnClose(); + + Dispose(true); + + base.OnClose(); + } + + public int FDoIdle(uint grfidlef) + { + if (_control is not null) + { + _control.SynchronizeSettings(); + } + return S_OK; + } + + /// + /// Registers an independent view with the IVsTextManager so that it knows + /// the user is working with a view over the text buffer. This will trigger + /// the text buffer to prompt the user whether to reload the file if it is + /// edited outside of the environment. + /// + /// True to subscribe, false to unsubscribe + private void RegisterIndependentView(bool subscribe) + { + if (this.TryGetService(out var textManager)) + { + _ = subscribe + ? textManager.RegisterIndependentView(this, _textBuffer) + : textManager.UnregisterIndependentView(this, _textBuffer); + } + } + + /// + /// Helper function used to add commands using IMenuCommandService + /// + /// The IMenuCommandService interface. + /// This guid represents the menu group of the command. + /// The command ID of the command. + /// An EventHandler which will be called whenever the command is invoked. + /// An EventHandler which will be called whenever we want to query the status of + /// the command. If null is passed in here then no EventHandler will be added. + private static void AddCommand(IMenuCommandService menuCommandService, + Guid menuGroup, + int cmdID, + EventHandler commandEvent, + EventHandler queryEvent) + { + // Create the OleMenuCommand from the menu group, command ID, and command event + var menuCommandID = new CommandID(menuGroup, cmdID); + var command = new OleMenuCommand(commandEvent, menuCommandID); + + // Add an event handler to BeforeQueryStatus if one was passed in + if (null != queryEvent) + { + command.BeforeQueryStatus += queryEvent; + } + + // Add the command using our IMenuCommandService instance + menuCommandService.AddCommand(command); + } + + public int get_DocView(out IntPtr ppUnkDocView) + { + ppUnkDocView = Marshal.GetIUnknownForObject(this); + return S_OK; + } + + public int get_CmdUIGuid(out Guid pGuidCmdId) + { + pGuidCmdId = SettingsEditorFactory.SettingsEditorFactoryGuid; + return S_OK; + } + + public int FReserved1(uint dwReserved, uint message, IntPtr wParam, IntPtr lParam) => S_OK; + public int FPreTranslateMessage(MSG[] pMsg) => S_OK; + public void OnEnterState(uint uStateID, int fEnter) { } + public void OnAppActivate(int fActive, uint dwOtherThreadID) { } + public void OnLoseActivation() { } + public void OnActivationChange(IOleComponent pic, int fSameComponent, OLECRINFO[] pcrinfo, int fHostIsActivating, OLECHOSTINFO[] pchostinfo, uint dwReserved) { } + public int FContinueMessageLoop(uint uReason, IntPtr pvLoopData, MSG[] pMsgPeeked) => S_OK; + public int FQueryTerminate(int fPromptUser) => 1; //true + public void Terminate() { } + public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved) => IntPtr.Zero; + public int OnInterveningUnitBlockingLinkedUndo() => E_FAIL; + + public IVsSearchTask? CreateSearch(uint dwCookie, IVsSearchQuery pSearchQuery, IVsSearchCallback pSearchCallback) + { + if (_control is not null) + { + var tables = _control.GetTableControls(); + return new SearchTask(dwCookie, pSearchQuery, pSearchCallback, tables, _threadingContext); + } + + return null; + } + + public void ClearSearch() + { + _threadingContext.ThrowIfNotOnUIThread(); + if (_control is not null) + { + var tables = _control.GetTableControls(); + // remove filter on tablar data controls + foreach (var tableControl in tables) + { + _ = tableControl.SetFilter(string.Empty, null); + } + } + } + + public void ProvideSearchSettings(IVsUIDataSource pSearchSettings) + { + SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.ControlMaxWidth, 200); + SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchStartType, (int)VSSEARCHSTARTTYPE.SST_DELAYED); + SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchStartDelay, 100); + SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchUseMRU, true); + SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.PrefixFilterMRUItems, false); + SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.MaximumMRUItems, 25); + SetStringValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchWatermark, ServicesVSResources.Search_Settings); + SetBoolValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchPopupAutoDropdown, false); + SetStringValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.ControlBorderThickness, "1"); + SetIntValue(pSearchSettings, SearchSettingsDataSource.PropertyNames.SearchProgressType, (int)VSSEARCHPROGRESSTYPE.SPT_INDETERMINATE); + + void SetBoolValue(IVsUIDataSource source, string property, bool value) + { + var valueProp = BuiltInPropertyValue.FromBool(value); + _ = source.SetValue(property, valueProp); + } + + void SetIntValue(IVsUIDataSource source, string property, int value) + { + var valueProp = BuiltInPropertyValue.Create(value); + _ = source.SetValue(property, valueProp); + } + + void SetStringValue(IVsUIDataSource source, string property, string value) + { + var valueProp = BuiltInPropertyValue.Create(value); + _ = source.SetValue(property, valueProp); + } + } + + public bool OnNavigationKeyDown(uint dwNavigationKey, uint dwModifiers) => false; + + public bool SearchEnabled { get; } = true; + + public Guid Category { get; } = new Guid("1BE8950F-AF27-4B71-8D54-1F7FFEFDC237"); + public IVsEnumWindowSearchFilters? SearchFiltersEnum => null; + public IVsEnumWindowSearchOptions? SearchOptionsEnum => null; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/FontSizeConverter.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/FontSizeConverter.cs new file mode 100644 index 0000000000000..c766f4f049a20 --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/FontSizeConverter.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Microsoft.VisualStudio.LanguageServices.EditorConfigSettings.Styles +{ + internal class FontSizeConverter : IValueConverter + { + // Scaling percentage. E.g. 122 means 122%. + public int Scale { get; set; } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => (double)value * Scale / 100.0; + + public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => null; + } +} diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/ThemedDialogResources.xaml b/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/ThemedDialogResources.xaml new file mode 100644 index 0000000000000..7959ca6ae556e --- /dev/null +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Styles/ThemedDialogResources.xaml @@ -0,0 +1,85 @@ + + + + + \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index 5fab552e80282..1eb93e319b038 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -33,7 +33,7 @@ 6cf2e545-6109-4730-8883-cf43d7aec3e1 - + @@ -199,8 +199,7 @@ - + diff --git a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef index 27e41b380e9ba..cf0c02e3f8465 100644 --- a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef +++ b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef @@ -24,3 +24,14 @@ "Value"=dword:00000000 "Title"="Enable experimental C#/VB LSP completion experience" "PreviewPaneChannels"="IntPreview,int.main" + +// 68b46364-d378-42f2-9e72-37d86c5f4468 is the guid for SettingsEditorFactory +// 6cf2e545-6109-4730-8883-cf43d7aec3e1 is the guid for RoslynPackage +[$RootKey$\Editors\{68b46364-d378-42f2-9e72-37d86c5f4468}] +"Package"="{6cf2e545-6109-4730-8883-cf43d7aec3e1}" +[$RootKey$\Editors\{68b46364-d378-42f2-9e72-37d86c5f4468}\Extensions] +// dword must be larger that 26 (the priority of the textmate editor) +// we set it to 100 (64 in hex) here +"editorconfig"=dword:00000064 +[$RootKey$\Editors\{68b46364-d378-42f2-9e72-37d86c5f4468}\LogicalViews] +"{7651a703-06e5-11d1-8ebd-00a0c90f26ea}"="" diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 7261ce5c45d59..2b80da67155e7 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -24,6 +24,7 @@ using Microsoft.CodeAnalysis.Versions; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices.ColorSchemes; +using Microsoft.VisualStudio.LanguageServices.EditorConfigSettings; using Microsoft.VisualStudio.LanguageServices.Experimentation; using Microsoft.VisualStudio.LanguageServices.Implementation; using Microsoft.VisualStudio.LanguageServices.Implementation.DesignerAttribute; @@ -136,6 +137,9 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke _solutionEventMonitor = new SolutionEventMonitor(_workspace); TrackBulkFileOperations(); + + var settingsEditorFactory = _componentModel.GetService(); + RegisterEditorFactory(settingsEditorFactory); } private void InitializeColors() diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index 46b3381616243..4b383c59a84d9 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1653,4 +1653,55 @@ I agree to all of the foregoing: This action cannot be undone. Do you wish to continue? + + Analyzers + + + Carrage Return + Newline (\\r\\n) + + + Carrage Return (\\r) + + + Category + + + Code Style + + + Disabled + + + Enabled + + + Error + + + Formatting + + + Id + + + Newline (\\n) + + + Refactoring Only + + + Suggestion + + + Title + + + Value + + + Warning + + + Search Settings + \ No newline at end of file diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index b5189e1a7fc45..78d2b64d74833 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -77,6 +77,11 @@ Vždy kvůli srozumitelnosti + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Lokalita volání + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Dokončila se analýza kódu pro {0}. @@ -217,6 +242,11 @@ Aktuální parametr + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Při podržení kláves Alt+F1 zobrazit všechny nápovědy @@ -267,6 +297,11 @@ Povolit diagnostiku pull (experimentální, vyžaduje restart) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Zadejte hodnotu místa volání, nebo zvolte jiný druh vložení hodnoty. @@ -282,6 +317,11 @@ Celé řešení + + Error + Error + + Evaluating ({0} tasks in queue) Vyhodnocování (počet úloh ve frontě: {0}) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Generovat soubor .editorconfig z nastavení @@ -312,6 +357,11 @@ Zvýrazňovat související komponenty pod kurzorem + + Id + Id + + In other operators V jiných operátorech @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Stáhnout členy + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Uložit soubor .editorconfig + + Search Settings + Search Settings + + Select destination Vybrat cíl @@ -917,6 +982,11 @@ Některé barvy barevného schématu se přepsaly změnami na stránce možností Prostředí > Písma a barvy. Pokud chcete zrušit všechna přizpůsobení, vyberte na stránce Písma a barvy možnost Použít výchozí. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Potlačit nápovědy, když název parametru odpovídá záměru metody @@ -967,6 +1037,11 @@ Toto je neplatný obor názvů. + + Title + Title + + Type name: Název typu: @@ -1027,6 +1102,11 @@ Použít pojmenovaný argument "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Zde přiřazená hodnota se nikdy nepoužije. @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Upozornění: duplicitní název parametru diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index 6bf8f12101348..e60716fd3d02b 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -77,6 +77,11 @@ Immer zur besseren Unterscheidung + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Aufrufsite + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Die Codeanalyse für "{0}" wurde abgeschlossen. @@ -217,6 +242,11 @@ Aktueller Parameter + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Alle Hinweise beim Drücken von ALT+F1 anzeigen @@ -267,6 +297,11 @@ Pull-Diagnose aktivieren (experimentell, Neustart erforderlich) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Geben Sie einen Aufrufsitewert ein, oder wählen Sie eine andere Art der Werteingabe aus. @@ -282,6 +317,11 @@ Gesamte Projektmappe + + Error + Error + + Evaluating ({0} tasks in queue) Auswertung ({0} Tasks in der Warteschlange) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings EDITORCONFIG-Datei aus Einstellungen generieren @@ -312,6 +357,11 @@ Zugehörige Komponenten unter dem Cursor markieren + + Id + Id + + In other operators In anderen Operatoren @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Member nach oben ziehen + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ EDITORCONFIG-Datei speichern + + Search Settings + Search Settings + + Select destination Ziel auswählen @@ -917,6 +982,11 @@ Einige Farbschemafarben werden durch Änderungen überschrieben, die auf der Optionsseite "Umgebung" > "Schriftarten und Farben" vorgenommen wurden. Wählen Sie auf der Seite "Schriftarten und Farben" die Option "Standardwerte verwenden" aus, um alle Anpassungen rückgängig zu machen. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Hinweise unterdrücken, wenn der Parametername mit der Methodenabsicht übereinstimmt @@ -967,6 +1037,11 @@ Dies ist ein ungültiger Namespace. + + Title + Title + + Type name: Typenname: @@ -1027,6 +1102,11 @@ Benanntes Argument verwenden "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Der hier zugewiesene Wert wird nie verwendet. @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Warnung: doppelter Parametername diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index 0773ae1ab3d10..42add4119c7dd 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -77,6 +77,11 @@ Siempre por claridad + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Sitio de llamada + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. El análisis de código se ha completado para "{0}". @@ -217,6 +242,11 @@ Parámetro actual + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Mostrar todas las sugerencias al presionar Alt+F1 @@ -267,6 +297,11 @@ Habilitar diagnósticos "pull" (experimental, requiere reiniciar) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Escriba un valor de sitio de llamada o elija otro tipo de inserción de valor. @@ -282,6 +317,11 @@ Toda la solución + + Error + Error + + Evaluating ({0} tasks in queue) Evaluando ({0} tareas en cola) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Generar archivo .editorconfig a partir de la configuración @@ -312,6 +357,11 @@ Resaltar componentes relacionados bajo el cursor + + Id + Id + + In other operators En otros operadores @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Extraer miembros + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Guardar archivo .editorconfig + + Search Settings + Search Settings + + Select destination Seleccionar destino @@ -917,6 +982,11 @@ Algunos de los colores de la combinación se reemplazan por los cambios realizados en la página de opciones de Entorno > Fuentes y colores. Elija "Usar valores predeterminados" en la página Fuentes y colores para revertir todas las personalizaciones. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Suprimir las sugerencias cuando el nombre del parámetro coincida con la intención del método @@ -967,6 +1037,11 @@ Este espacio de nombres no es válido + + Title + Title + + Type name: Nombre de tipo: @@ -1027,6 +1102,11 @@ Usar argumento con nombre "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used El valor asignado aquí no se usa nunca @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Advertencia: Nombre de parámetro duplicado diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index 66ca64f575e7b..ce66c20ea3ed9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -77,6 +77,11 @@ Toujours pour plus de clarté + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Site d'appel + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Analyse du code effectuée pour '{0}'. @@ -217,6 +242,11 @@ Paramètre actuel + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Afficher tous les indicateurs en appuyant sur Alt+F1 @@ -267,6 +297,11 @@ Activer les diagnostics de 'tirage (pull)' (expérimental, nécessite un redémarrage) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Entrer une valeur de site d'appel ou choisir un autre type d'injection de valeur @@ -282,6 +317,11 @@ Solution complète + + Error + Error + + Evaluating ({0} tasks in queue) Évaluation ({0} tâches en file d'attente) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Générer le fichier .editorconfig à partir des paramètres @@ -312,6 +357,11 @@ Surligner les composants liés sous le curseur + + Id + Id + + In other operators Dans les autres opérateurs @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Élever les membres + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Enregistrer le fichier .editorconfig + + Search Settings + Search Settings + + Select destination Sélectionner la destination @@ -917,6 +982,11 @@ Certaines couleurs du modèle de couleurs sont substituées à la suite des changements apportés dans la page d'options Environnement > Polices et couleurs. Choisissez Utiliser les valeurs par défaut dans la page Polices et couleurs pour restaurer toutes les personnalisations. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Supprimer les indicateurs quand le nom de paramètre correspond à l'intention de la méthode @@ -967,6 +1037,11 @@ Ceci est un espace de noms non valide + + Title + Title + + Type name: Nom du type : @@ -1027,6 +1102,11 @@ Utiliser un argument nommé "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used La valeur affectée ici n'est jamais utilisée @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Avertissement : Nom de paramètre dupliqué diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index 84d6b5b8418ce..72a65ec3d00c1 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -77,6 +77,11 @@ Sempre per chiarezza + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Sito di chiamata + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Esecuzione di Code Analysis completata per '{0}'. @@ -217,6 +242,11 @@ Parametro corrente + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Visualizza tutti i suggerimenti quando si preme ALT+F1 @@ -267,6 +297,11 @@ Abilita diagnostica 'pull' (sperimentale, richiede il riavvio) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Immettere un valore per il sito di chiamata o scegliere un tipo di inserimento valori diverso @@ -282,6 +317,11 @@ Intera soluzione + + Error + Error + + Evaluating ({0} tasks in queue) In fase di valutazione ({0} attività in coda) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Genera file con estensione editorconfig dalle impostazioni @@ -312,6 +357,11 @@ Evidenzia i componenti correlati sotto il cursore + + Id + Id + + In other operators In altri operatori @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Recupera membri + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Salva file con estensione editorconfig + + Search Settings + Search Settings + + Select destination Seleziona destinazione @@ -917,6 +982,11 @@ Alcuni colori della combinazione colori sono sostituiti dalle modifiche apportate nella pagina di opzioni Ambiente > Tipi di carattere e colori. Scegliere `Usa impostazioni predefinite` nella pagina Tipi di carattere e colori per ripristinare tutte le personalizzazioni. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Non visualizzare suggerimenti quando il nome del parametro corrisponde alla finalità del metodo @@ -967,6 +1037,11 @@ Questo è uno spazio dei nomi non valido + + Title + Title + + Type name: Nome del tipo: @@ -1027,6 +1102,11 @@ Usa l'argomento denominato "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Il valore assegnato qui non viene mai usato @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Avviso: nome di parametro duplicato diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index 0c2d35a055059..7f21ef693eaec 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -77,6 +77,11 @@ わかりやすくするために常に + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ 呼び出しサイト + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. '{0}' のコード分析が完了しました。 @@ -217,6 +242,11 @@ 現在のパラメーター + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Alt+F1 を押しながらすべてのヒントを表示する @@ -267,6 +297,11 @@ 'pull' 診断を有効にする (試験段階、再起動が必要) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind 呼び出しサイトの値を入力するか、別の値の挿入の種類を選択してください @@ -282,6 +317,11 @@ ソリューション全体 + + Error + Error + + Evaluating ({0} tasks in queue) 評価中 ({0} 個のタスクがキューにあります) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings 設定から .editorconfig ファイルを生成 @@ -312,6 +357,11 @@ カーソルの下にある関連コンポーネントをハイライトする + + Id + Id + + In other operators その他の演算子内で @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ メンバーをプルアップ + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ .editorconfig ファイルの保存 + + Search Settings + Search Settings + + Select destination 宛先の選択 @@ -917,6 +982,11 @@ 一部の配色パターンの色は、[環境] > [フォントおよび色] オプション ページで行われた変更によって上書きされます。[フォントおよび色] オプション ページで [既定値を使用] を選択すると、すべてのカスタマイズが元に戻ります。 + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent パラメーター名がメソッドの意図と一致する場合にヒントを非表示にする @@ -967,6 +1037,11 @@ これは無効な名前空間です + + Title + Title + + Type name: 種類の名前: @@ -1027,6 +1102,11 @@ 名前付き引数を使用する "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used ここで割り当てた値は一度も使用されません @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name 警告: パラメーター名が重複しています diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index c9dffedffb7a8..2e500eba7fddc 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -77,6 +77,11 @@ 명확하게 하기 위해 항상 + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ 호출 사이트 + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. '{0}'에 대한 코드 분석이 완료되었습니다. @@ -217,6 +242,11 @@ 현재 매개 변수 + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Alt+F1을 누른 채 모든 힌트 표시 @@ -267,6 +297,11 @@ '풀' 진단 사용(실험적, 다시 시작 필요) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind 호출 사이트 값을 입력하거나 다른 값 삽입 종류를 선택하세요. @@ -282,6 +317,11 @@ 전체 솔루션 + + Error + Error + + Evaluating ({0} tasks in queue) 평가 중(큐의 {0}개 작업) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings 설정에서 .editorconfig 파일 생성 @@ -312,6 +357,11 @@ 커서 아래의 관련 구성 요소 강조 + + Id + Id + + In other operators 기타 연산자 @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ 멤버 풀하기 + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ editorconfig 파일 저장 + + Search Settings + Search Settings + + Select destination 대상 선택 @@ -917,6 +982,11 @@ 색 구성표의 일부 색이 [환경] > [글꼴 및 색] 옵션 페이지에서 변경한 내용에 따라 재정의됩니다. 모든 사용자 지정을 되돌리려면 [글꼴 및 색] 페이지에서 '기본값 사용'을 선택하세요. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent 매개 변수 이름이 메서드의 의도와 일치하는 경우 힌트 표시 안 함 @@ -967,6 +1037,11 @@ 잘못된 네임스페이스입니다. + + Title + Title + + Type name: 형식 이름: @@ -1027,6 +1102,11 @@ 명명된 인수 사용 "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used 여기에 할당된 값은 사용되지 않습니다. @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name 경고: 매개 변수 이름이 중복되었습니다. diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index 7ec15693ddf5f..b5b68596d83b9 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -77,6 +77,11 @@ Zawsze w celu zachowania jednoznaczności + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Miejsce wywołania + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Ukończono analizę kodu dla elementu „{0}”. @@ -217,6 +242,11 @@ Bieżący parametr + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Wyświetl wszystkie wskazówki po naciśnięciu klawiszy Alt+F1 @@ -267,6 +297,11 @@ Włącz diagnostykę operacji „pull” (eksperymentalne, wymaga ponownego uruchomienia) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Wprowadź wartość lokalizacji wywołania lub wybierz inny rodzaj iniekcji wartości @@ -282,6 +317,11 @@ Całe rozwiązanie + + Error + Error + + Evaluating ({0} tasks in queue) Szacowanie (zadania w kolejce: {0}) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Wygeneruj plik .editorconfig na podstawie ustawień @@ -312,6 +357,11 @@ Wyróżnij powiązane składniki pod kursorem + + Id + Id + + In other operators W innych operatorach @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Podciągnij składowe w górę + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Zapisz plik .editorconfig + + Search Settings + Search Settings + + Select destination Wybierz miejsce docelowe @@ -917,6 +982,11 @@ Niektóre kolory w schemacie kolorów są przesłaniane przez zmiany wprowadzone na stronie opcji Środowisko > Czcionki i kolory. Wybierz pozycję „Użyj ustawień domyślnych” na stronie Czcionki i kolory, aby wycofać wszystkie dostosowania. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Pomiń wskazówki, gdy nazwa parametru pasuje do intencji metody @@ -967,6 +1037,11 @@ To jest nieprawidłowa przestrzeń nazw + + Title + Title + + Type name: Nazwa typu: @@ -1027,6 +1102,11 @@ Użyj nazwanego argumentu "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Przypisana tu wartość nigdy nie jest używana @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Ostrzeżenie: zduplikowana nazwa parametru diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index e81125728c3a4..ca39ce2664ea6 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -77,6 +77,11 @@ Sempre para esclarecimento + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Chamar site + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Análise de código concluída para '{0}'. @@ -217,6 +242,11 @@ Parâmetro atual + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Exibir todas as dicas ao pressionar Alt+F1 @@ -267,6 +297,11 @@ Habilitar o diagnóstico de 'pull' (experimental, exige uma reinicialização) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Insira um valor de site de chamada ou escolha um tipo de injeção de valor diferente @@ -282,6 +317,11 @@ Solução Inteira + + Error + Error + + Evaluating ({0} tasks in queue) Avaliando ({0} tarefas na fila) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Gerar o arquivo .editorconfig das configurações @@ -312,6 +357,11 @@ Realçar componentes relacionados usando o cursor + + Id + Id + + In other operators Em outros operadores @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Levantar os membros + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Salvar arquivo .editorconfig + + Search Settings + Search Settings + + Select destination Selecionar destino @@ -917,6 +982,11 @@ Algumas cores do esquema de cores estão sendo substituídas pelas alterações feitas na página de Ambiente > Opções de Fontes e Cores. Escolha 'Usar Padrões' na página Fontes e Cores para reverter todas as personalizações. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Suprimir as dicas quando o nome do parâmetro corresponder à intenção do método @@ -967,6 +1037,11 @@ Este é um namespace inválido + + Title + Title + + Type name: Nome do tipo: @@ -1027,6 +1102,11 @@ Usar argumento nomeado "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used O valor atribuído aqui nunca é usado @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Aviso: nome de parâmetro duplicado diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index e69cabe68805d..185ab2ad080a5 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -77,6 +77,11 @@ Всегда использовать для ясности + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Место вызова + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. Анализ кода для "{0}" выполнен. @@ -217,6 +242,11 @@ Текущий параметр + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Отображать все подсказки при нажатии клавиш ALT+F1 @@ -267,6 +297,11 @@ Включить диагностику "pull" (экспериментальная функция, требуется перезапуск) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Введите значение места вызова или выберите другой тип введения значения @@ -282,6 +317,11 @@ Все решение + + Error + Error + + Evaluating ({0} tasks in queue) Оценка (задач в очереди: {0}) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Создать файл EDITORCONFIG на основе параметров @@ -312,6 +357,11 @@ Выделить связанные компоненты под курсором + + Id + Id + + In other operators В других операторах @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Повышение элементов + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ Сохранить файл EDITORCONFIG + + Search Settings + Search Settings + + Select destination Выбрать место назначения @@ -917,6 +982,11 @@ Некоторые цвета цветовой схемы переопределяются изменениями, сделанными на странице "Среда" > "Шрифты и цвета". Выберите "Использовать значения по умолчанию" на странице "Шрифты и цвета", чтобы отменить все настройки. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Скрывать подсказки, если имя параметра соответствует намерению метода. @@ -967,6 +1037,11 @@ Это недопустимое пространство имен. + + Title + Title + + Type name: Имя типа: @@ -1027,6 +1102,11 @@ Использовать именованный аргумент "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Заданное здесь значение не используется. @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Предупреждение: повторяющееся имя параметра. diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index 0fb7479558408..72f968d5f2ff6 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -77,6 +77,11 @@ Açıklık sağlamak için her zaman + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ Çağrı konumu + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. '{0}' için kod analizi tamamlandı. @@ -217,6 +242,11 @@ Geçerli parametre + + Disabled + Disabled + + Display all hints while pressing Alt+F1 Alt+F1 tuşlarına basılırken tüm ipuçlarını görüntüle @@ -267,6 +297,11 @@ 'Pull' tanılamasını etkinleştir (deneysel, yeniden başlatma gerekir) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind Bir çağrı sitesi değeri girin veya farklı bir değer yerleştirme tipi seçin @@ -282,6 +317,11 @@ Tüm çözüm + + Error + Error + + Evaluating ({0} tasks in queue) Değerlendiriliyor (kuyrukta {0} görev var) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings Ayarlardan .editorconfig dosyası oluştur @@ -312,6 +357,11 @@ İmlecin altında ilgili bileşenleri vurgula + + Id + Id + + In other operators Diğer işleçlerde @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ Üyeleri Yukarı Çek + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ .editorconfig dosyasını kaydet + + Search Settings + Search Settings + + Select destination Hedef seçin @@ -917,6 +982,11 @@ Bazı renk düzeni renkleri, Ortam > Yazı Tipleri ve Renkler seçenek sayfasında yapılan değişiklikler tarafından geçersiz kılınıyor. Tüm özelleştirmeleri geri döndürmek için Yazı Tipleri ve Renkler sayfasında `Varsayılanları Kullan` seçeneğini belirleyin. + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent Parametre adı metodun hedefi ile eşleştiğinde ipuçlarını gizle @@ -967,6 +1037,11 @@ Bu geçersiz bir ad alanı + + Title + Title + + Type name: Tür adı: @@ -1027,6 +1102,11 @@ Adlandırılmış bağımsız değişken kullan "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used Burada atanan değer hiçbir zaman kullanılmadı @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name Uyarı: Yinelenen parametre adı diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index 444999fa40114..81c3fdd8502ae 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -77,6 +77,11 @@ 为始终保持清楚起见 + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ 调用站点 + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. “{0}”的代码分析已完成。 @@ -217,6 +242,11 @@ 当前参数 + + Disabled + Disabled + + Display all hints while pressing Alt+F1 按 Alt+F1 时显示所有提示 @@ -267,6 +297,11 @@ 启用“拉取”诊断(实验性,需要重启) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind 输入调用站点值或选择其他值注入类型 @@ -282,6 +317,11 @@ 整个解决方案 + + Error + Error + + Evaluating ({0} tasks in queue) 正在评估(队列中有 {0} 个任务) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings 基于设置生成 .editorconfig 文件 @@ -312,6 +357,11 @@ 突出显示光标下的相关组件 + + Id + Id + + In other operators 在其他运算符中 @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ 拉取成员 + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ 保存 .editorconfig 文件 + + Search Settings + Search Settings + + Select destination 选择目标 @@ -917,6 +982,11 @@ 在“环境”>“字体和颜色”选项页中所做的更改将替代某些配色方案颜色。在“字体和颜色”页中选择“使用默认值”,还原所有自定义项。 + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent 当参数名称与方法的意图匹配时禁止显示提示 @@ -967,6 +1037,11 @@ 这是一个无效的命名空间 + + Title + Title + + Type name: 类型名称: @@ -1027,6 +1102,11 @@ 使用命名参数 "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used 此处分配的值从未使用过 @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name 警告: 参数名重复 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index b4e5db7539867..eafb48be3a897 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -77,6 +77,11 @@ 一律使用以明確表示 + + Analyzers + Analyzers + + Analyzing project references... Analyzing project references... @@ -157,11 +162,31 @@ 呼叫網站 + + Carrage Return + Newline (\\r\\n) + Carrage Return + Newline (\\r\\n) + + + + Carrage Return (\\r) + Carrage Return (\\r) + + + + Category + Category + + Choose which action you would like to perform on the unused references. Choose which action you would like to perform on the unused references. + + Code Style + Code Style + + Code analysis completed for '{0}'. '{0}' 的程式碼分析已完成。 @@ -217,6 +242,11 @@ 目前的參數 + + Disabled + Disabled + + Display all hints while pressing Alt+F1 按 Alt+F1 時顯示所有提示 @@ -267,6 +297,11 @@ 啟用 'pull' 診斷 (實驗性,需要重新啟動) + + Enabled + Enabled + + Enter a call site value or choose a different value injection kind 請輸入呼叫位置值,或選擇其他值插入種類 @@ -282,6 +317,11 @@ 整個解決方案 + + Error + Error + + Evaluating ({0} tasks in queue) 正在評估 (佇列中的 {0} 工作) @@ -302,6 +342,11 @@ Format document + + Formatting + Formatting + + Generate .editorconfig file from settings 從設定產生 .editorconfig 檔案 @@ -312,6 +357,11 @@ 反白資料指標下的相關元件 + + Id + Id + + In other operators 其他運算子中 @@ -612,6 +662,11 @@ New line preferences (experimental): + + Newline (\\n) + Newline (\\n) + + No unused references were found. No unused references were found. @@ -757,6 +812,11 @@ 提升成員 + + Refactoring Only + Refactoring Only + + Reference Reference @@ -842,6 +902,11 @@ 儲存 .editorconfig 檔案 + + Search Settings + Search Settings + + Select destination 選取目的地 @@ -917,6 +982,11 @@ [環境] > [字型和色彩選項] 頁面中所做的變更覆寫了某些色彩配置的色彩。請選擇 [字型和色彩] 頁面中的 [使用預設] 來還原所有自訂。 + + Suggestion + Suggestion + + Suppress hints when parameter name matches the method's intent 當參數名稱符合方法的意圖時,不出現提示 @@ -967,6 +1037,11 @@ 這是無效的命名空間 + + Title + Title + + Type name: 類型名稱: @@ -1027,6 +1102,11 @@ 使用具名引數 "argument" is a programming term for a value passed to a function + + Value + Value + + Value assigned here is never used 這裡指派的值從未使用過 @@ -1057,6 +1137,11 @@ Visual Studio 2019 + + Warning + Warning + + Warning: duplicate parameter name 警告: 參數名稱重複 diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs index d5533c1114d22..300b3bb806e4b 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs @@ -284,7 +284,7 @@ public async Task> GetAnalyzerOptionsForPath return _lazyAnalyzerConfigSet.GetValue(CancellationToken.None).GetOptionsForSourcePath(sourceFilePath); } - private sealed class WorkspaceAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider + internal sealed class WorkspaceAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider { private readonly ProjectState _projectState; @@ -303,6 +303,9 @@ public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) return new WorkspaceAnalyzerConfigOptions(_projectState._lazyAnalyzerConfigSet.GetValue(CancellationToken.None).GetOptionsForSourcePath(textFile.Path)); } + public AnalyzerConfigOptions GetOptionsForSourcePath(string path) + => new WorkspaceAnalyzerConfigOptions(_projectState._lazyAnalyzerConfigSet.GetValue(CancellationToken.None).GetOptionsForSourcePath(path)); + private sealed class WorkspaceAnalyzerConfigOptions : AnalyzerConfigOptions { private readonly ImmutableDictionary _backing; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/DiagnosticDescriptorExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/DiagnosticDescriptorExtensions.cs index 3afb0f2b755e8..63c3322d77652 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/DiagnosticDescriptorExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/DiagnosticDescriptorExtensions.cs @@ -6,12 +6,14 @@ using System.Diagnostics; using System.Linq; +using Microsoft.CodeAnalysis.Diagnostics; namespace Microsoft.CodeAnalysis.Shared.Extensions { internal static class DiagnosticDescriptorExtensions { private const string DotnetAnalyzerDiagnosticPrefix = "dotnet_analyzer_diagnostic"; + private const string DotnetDiagnosticPrefix = "dotnet_diagnostic"; private const string CategoryPrefix = "category"; private const string SeveritySuffix = "severity"; @@ -43,6 +45,48 @@ public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor de return effectiveSeverity; } + public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor descriptor, AnalyzerConfigOptions analyzerConfigOptions) + { + // Check if the option is defined explicitly in the editorconfig + var diagnosticKey = $"{DotnetDiagnosticPrefix}.{descriptor.Id}.{SeveritySuffix}"; + if (analyzerConfigOptions.TryGetValue(diagnosticKey, out var value) && + EditorConfigSeverityStrings.TryParse(value, out var severity)) + { + return severity; + } + + // Check if the option is defined as part of a bulk configuration + // Analyzer bulk configuration does not apply to: + // 1. Disabled by default diagnostics + // 2. Compiler diagnostics + // 3. Non-configurable diagnostics + if (!descriptor.IsEnabledByDefault || + descriptor.CustomTags.Any(tag => tag == WellKnownDiagnosticTags.Compiler || tag == WellKnownDiagnosticTags.NotConfigurable)) + { + return ReportDiagnostic.Default; + } + + // If user has explicitly configured default severity for the diagnostic category, that should be respected. + // For example, 'dotnet_analyzer_diagnostic.category-security.severity = error' + var categoryBasedKey = $"{DotnetAnalyzerDiagnosticPrefix}.{CategoryPrefix}-{descriptor.Category}.{SeveritySuffix}"; + if (analyzerConfigOptions.TryGetValue(categoryBasedKey, out value) && + EditorConfigSeverityStrings.TryParse(value, out severity)) + { + return severity; + } + + // Otherwise, if user has explicitly configured default severity for all analyzer diagnostics, that should be respected. + // For example, 'dotnet_analyzer_diagnostic.severity = error' + if (analyzerConfigOptions.TryGetValue(DotnetAnalyzerDiagnosticSeverityKey, out value) && + EditorConfigSeverityStrings.TryParse(value, out severity)) + { + return severity; + } + + // option not defined in editorconfig, assumed to be the default + return ReportDiagnostic.Default; + } + /// /// Tries to get configured severity for the given /// from bulk configuration analyzer config options, i.e.