From b88787058cf485e871961c817d095a113e85a34a Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Sat, 5 Nov 2016 14:37:03 -0700 Subject: [PATCH] editorconfig codestyle options --- ...harpSimplifyTypeNamesDiagnosticAnalyzer.cs | 10 ++-- .../CSharpTypeStyleDiagnosticAnalyzerBase.cs | 11 +++- ...harpInlineDeclarationDiagnosticAnalyzer.cs | 12 +++-- ...keDelegateWithConditionalAccessAnalyzer.cs | 12 ++++- ...ractUseExpressionBodyDiagnosticAnalyzer.cs | 11 +++- .../CSharpAsAndNullCheckDiagnosticAnalyzer.cs | 12 ++++- .../CSharpIsAndCastCheckDiagnosticAnalyzer.cs | 12 ++++- .../Portable/Diagnostics/AnalyzerHelper.cs | 25 ++++++++- ...eferFrameworkTypeDiagnosticAnalyzerBase.cs | 7 +-- ...SimplifyTypeNamesDiagnosticAnalyzerBase.cs | 14 ++--- ...ctQualifyMemberAccessDiagnosticAnalyzer.cs | 5 +- ...UseCoalesceExpressionDiagnosticAnalyzer.cs | 9 +++- ...ExpressionForNullableDiagnosticAnalyzer.cs | 10 +++- ...CollectionInitializerDiagnosticAnalyzer.cs | 9 +++- ...actUseNullPropagationDiagnosticAnalyzer.cs | 9 +++- ...tUseObjectInitializerDiagnosticAnalyzer.cs | 10 +++- ...actUseThrowExpressionDiagnosticAnalyzer.cs | 9 +++- .../CodeStyle/CSharpCodeStyleOptions.cs | 54 ++++++++++++++----- .../Portable/CodeStyle/CodeStyleHelpers.cs | 29 ++++++++++ .../Portable/CodeStyle/CodeStyleOptions.cs | 49 ++++++++++++----- .../Core/Portable/Workspaces.csproj | 3 +- 21 files changed, 256 insertions(+), 66 deletions(-) create mode 100644 src/Workspaces/Core/Portable/CodeStyle/CodeStyleHelpers.cs diff --git a/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpSimplifyTypeNamesDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpSimplifyTypeNamesDiagnosticAnalyzer.cs index 4ef79d87fa6e8..166342ace513f 100644 --- a/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpSimplifyTypeNamesDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpSimplifyTypeNamesDiagnosticAnalyzer.cs @@ -47,10 +47,12 @@ protected override void AnalyzeNode(SyntaxNodeAnalysisContext context) } Diagnostic diagnostic; + var options = context.Options; + var cancellationToken = context.CancellationToken; Func descendIntoChildren = n => { if (!IsRegularCandidate(n) || - !TrySimplifyTypeNameExpression(context.SemanticModel, n, context.Options, out diagnostic, context.CancellationToken)) + !TrySimplifyTypeNameExpression(context.SemanticModel, n, options, out diagnostic, cancellationToken)) { return true; } @@ -62,16 +64,16 @@ protected override void AnalyzeNode(SyntaxNodeAnalysisContext context) // find regular node first - search from top to down. once found one, don't get into its children foreach (var candidate in context.Node.DescendantNodesAndSelf(descendIntoChildren)) { - context.CancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); } // now search structure trivia foreach (var candidate in context.Node.DescendantNodesAndSelf(descendIntoChildren: n => !IsCrefCandidate(n), descendIntoTrivia: true)) { - context.CancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); if (IsCrefCandidate(candidate) && - TrySimplifyTypeNameExpression(context.SemanticModel, candidate, context.Options, out diagnostic, context.CancellationToken)) + TrySimplifyTypeNameExpression(context.SemanticModel, candidate, options, out diagnostic, cancellationToken)) { context.ReportDiagnostic(diagnostic); } diff --git a/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpTypeStyleDiagnosticAnalyzerBase.cs b/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpTypeStyleDiagnosticAnalyzerBase.cs index 1be40d874fad6..5938ada928e13 100644 --- a/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpTypeStyleDiagnosticAnalyzerBase.cs +++ b/src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpTypeStyleDiagnosticAnalyzerBase.cs @@ -71,9 +71,16 @@ private void HandleVariableDeclaration(SyntaxNodeAnalysisContext context) State state = null; var shouldAnalyze = false; var declarationStatement = context.Node; - var optionSet = context.Options.GetOptionSet(); - var semanticModel = context.SemanticModel; + var options = context.Options; + var syntaxTree = context.Node.SyntaxTree; var cancellationToken = context.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var semanticModel = context.SemanticModel; if (declarationStatement.IsKind(SyntaxKind.VariableDeclaration)) { diff --git a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs index dea2a67619853..9010f511be734 100644 --- a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs @@ -49,8 +49,15 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context) // out-vars are not supported prior to C# 7.0. return; } - - var optionSet = context.Options.GetOptionSet(); + var options = context.Options; + var syntaxTree = context.Node.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var option = optionSet.GetOption(CodeStyleOptions.PreferInlinedVariableDeclaration, argumentNode.Language); if (!option.Value) { @@ -99,7 +106,6 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context) } var semanticModel = context.SemanticModel; - var cancellationToken = context.CancellationToken; var outSymbol = semanticModel.GetSymbolInfo(argumentExpression, cancellationToken).Symbol; if (outSymbol?.Kind != SymbolKind.Local) { diff --git a/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs b/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs index d24f2056330ac..2b5de3857055c 100644 --- a/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs +++ b/src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs @@ -35,8 +35,16 @@ public override void Initialize(AnalysisContext context) private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext) { - var options = syntaxContext.Options.GetOptionSet(); - var styleOption = options.GetOption(CSharpCodeStyleOptions.PreferConditionalDelegateCall); + var options = syntaxContext.Options; + var syntaxTree = syntaxContext.Node.SyntaxTree; + var cancellationToken = syntaxContext.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var styleOption = optionSet.GetOption(CSharpCodeStyleOptions.PreferConditionalDelegateCall); if (!styleOption.Value) { // Bail immediately if the user has disabled this feature. diff --git a/src/Features/CSharp/Portable/UseExpressionBody/AbstractUseExpressionBodyDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/UseExpressionBody/AbstractUseExpressionBodyDiagnosticAnalyzer.cs index 3199b0750d89c..e40e2fa9cdb7b 100644 --- a/src/Features/CSharp/Portable/UseExpressionBody/AbstractUseExpressionBodyDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/UseExpressionBody/AbstractUseExpressionBodyDiagnosticAnalyzer.cs @@ -41,7 +41,16 @@ public override void Initialize(AnalysisContext context) private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) { - var diagnostic = AnalyzeSyntax(context.Options.GetOptionSet(), (TDeclaration)context.Node); + var options = context.Options; + var syntaxTree = context.Node.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var diagnostic = AnalyzeSyntax(optionSet, (TDeclaration)context.Node); if (diagnostic != null) { context.ReportDiagnostic(diagnostic); diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckDiagnosticAnalyzer.cs index 1ea00fb500de5..0dd709e0b2ebe 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpAsAndNullCheckDiagnosticAnalyzer.cs @@ -38,8 +38,16 @@ public override void Initialize(AnalysisContext context) private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext) { - var options = syntaxContext.Options.GetOptionSet(); - var styleOption = options.GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck); + var options = syntaxContext.Options; + var syntaxTree = syntaxContext.Node.SyntaxTree; + var cancellationToken = syntaxContext.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var styleOption = optionSet.GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck); if (!styleOption.Value) { // Bail immediately if the user has disabled this feature. diff --git a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs index ab3a159ae2abf..a976ad27e90ed 100644 --- a/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs @@ -44,8 +44,16 @@ public override void Initialize(AnalysisContext context) private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext) { - var options = syntaxContext.Options.GetOptionSet(); - var styleOption = options.GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck); + var options = syntaxContext.Options; + var syntaxTree = syntaxContext.Node.SyntaxTree; + var cancellationToken = syntaxContext.CancellationToken; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + + var styleOption = optionSet.GetOption(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck); if (!styleOption.Value) { // Bail immediately if the user has disabled this feature. diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index 63216b9469a3c..135affc516597 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -7,6 +7,8 @@ using Microsoft.CodeAnalysis.Options; using Roslyn.Utilities; using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.Diagnostics { @@ -118,9 +120,28 @@ public static string GetAnalyzerAssemblyName(this DiagnosticAnalyzer analyzer) return typeInfo.Assembly.GetName().Name; } - public static OptionSet GetOptionSet(this AnalyzerOptions analyzerOptions) + public static async Task GetDocumentOptionSetAsync(this AnalyzerOptions analyzerOptions, SyntaxTree syntaxTree, CancellationToken cancellationToken) { - return (analyzerOptions as WorkspaceAnalyzerOptions)?.Workspace.Options; + var workspace = (analyzerOptions as WorkspaceAnalyzerOptions)?.Workspace; + if (workspace == null) + { + return null; + } + + var documentId = workspace.CurrentSolution.GetDocumentId(syntaxTree); + if (documentId == null) + { + return workspace.Options; + } + + var document = workspace.CurrentSolution.GetDocument(documentId); + if (document == null) + { + return workspace.Options; + } + + var documentOptionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + return documentOptionSet ?? workspace.Options; } internal static void OnAnalyzerException_NoTelemetryLogging( diff --git a/src/Features/Core/Portable/Diagnostics/Analyzers/PreferFrameworkTypeDiagnosticAnalyzerBase.cs b/src/Features/Core/Portable/Diagnostics/Analyzers/PreferFrameworkTypeDiagnosticAnalyzerBase.cs index b7d5714deb47b..415fd742a929f 100644 --- a/src/Features/Core/Portable/Diagnostics/Analyzers/PreferFrameworkTypeDiagnosticAnalyzerBase.cs +++ b/src/Features/Core/Portable/Diagnostics/Analyzers/PreferFrameworkTypeDiagnosticAnalyzerBase.cs @@ -74,14 +74,15 @@ public override void Initialize(AnalysisContext context) protected void AnalyzeNode(SyntaxNodeAnalysisContext context) { - var optionSet = context.Options.GetOptionSet(); + var syntaxTree = context.Node.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); if (optionSet == null) { return; } - + var semanticModel = context.SemanticModel; - var cancellationToken = context.CancellationToken; var language = semanticModel.Language; // if the user never prefers this style, do not analyze at all. diff --git a/src/Features/Core/Portable/Diagnostics/Analyzers/SimplifyTypeNamesDiagnosticAnalyzerBase.cs b/src/Features/Core/Portable/Diagnostics/Analyzers/SimplifyTypeNamesDiagnosticAnalyzerBase.cs index fd2f2fc5c18a0..c79c033a7fc10 100644 --- a/src/Features/Core/Portable/Diagnostics/Analyzers/SimplifyTypeNamesDiagnosticAnalyzerBase.cs +++ b/src/Features/Core/Portable/Diagnostics/Analyzers/SimplifyTypeNamesDiagnosticAnalyzerBase.cs @@ -91,12 +91,14 @@ public bool OpenFileOnly(Workspace workspace) protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, AnalyzerOptions analyzerOptions, out Diagnostic diagnostic, CancellationToken cancellationToken) { diagnostic = default(Diagnostic); - - var optionSet = analyzerOptions.GetOptionSet(); - string diagnosticId; - - TextSpan issueSpan; - if (!CanSimplifyTypeNameExpressionCore(model, node, optionSet, out issueSpan, out diagnosticId, cancellationToken)) + var syntaxTree = node.SyntaxTree; + var optionSet = analyzerOptions.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return false; + } + + if (!CanSimplifyTypeNameExpressionCore(model, node, optionSet, out var issueSpan, out string diagnosticId, cancellationToken)) { return false; } diff --git a/src/Features/Core/Portable/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs b/src/Features/Core/Portable/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs index 35af5d8e2d364..17381d0564501 100644 --- a/src/Features/Core/Portable/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/QualifyMemberAccess/AbstractQualifyMemberAccessDiagnosticAnalyzer.cs @@ -72,8 +72,9 @@ private void AnalyzeOperation(OperationAnalysisContext context) return; } - // get the option - var optionSet = context.Options.GetOptionSet(); + var syntaxTree = context.Operation.Syntax.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); if (optionSet == null) { return; diff --git a/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionDiagnosticAnalyzer.cs index 6413e9f98e742..79ca3bfe5f02a 100644 --- a/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionDiagnosticAnalyzer.cs @@ -37,7 +37,14 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) { var conditionalExpression = (TConditionalExpressionSyntax)context.Node; - var optionSet = context.Options.GetOptionSet(); + var syntaxTree = context.Node.SyntaxTree; + var cancellationTokan = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationTokan).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var option = optionSet.GetOption(CodeStyleOptions.PreferCoalesceExpression, conditionalExpression.Language); if (!option.Value) { diff --git a/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs index e8898d53b2b9a..8a283892adf2a 100644 --- a/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs @@ -40,7 +40,14 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) { var conditionalExpression = (TConditionalExpressionSyntax)context.Node; - var optionSet = context.Options.GetOptionSet(); + var syntaxTree = context.Node.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var option = optionSet.GetOption(CodeStyleOptions.PreferCoalesceExpression, conditionalExpression.Language); if (!option.Value) { @@ -114,7 +121,6 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) return; } - var cancellationToken = context.CancellationToken; var type = semanticModel.GetTypeInfo(conditionExpression, cancellationToken); if (!nullableType.Equals(type.Type?.OriginalDefinition)) diff --git a/src/Features/Core/Portable/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs index 534a1db1555d0..ebfcfc4839edf 100644 --- a/src/Features/Core/Portable/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs @@ -61,11 +61,16 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context, INamedTypeSymbol ien return; } - var cancellationToken = context.CancellationToken; var objectCreationExpression = (TObjectCreationExpressionSyntax)context.Node; var language = objectCreationExpression.Language; + var syntaxTree = objectCreationExpression.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } - var optionSet = context.Options.GetOptionSet(); var option = optionSet.GetOption(CodeStyleOptions.PreferCollectionInitializer, language); if (!option.Value) { diff --git a/src/Features/Core/Portable/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs index 488252399072c..3709e45afe43b 100644 --- a/src/Features/Core/Portable/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs @@ -51,7 +51,14 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) return; } - var optionSet = context.Options.GetOptionSet(); + var syntaxTree = conditionalExpression.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var option = optionSet.GetOption(CodeStyleOptions.PreferNullPropagation, conditionalExpression.Language); if (!option.Value) { diff --git a/src/Features/Core/Portable/UseObjectInitializer/AbstractUseObjectInitializerDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseObjectInitializer/AbstractUseObjectInitializerDiagnosticAnalyzer.cs index 74b98cb000d7e..c64175d670707 100644 --- a/src/Features/Core/Portable/UseObjectInitializer/AbstractUseObjectInitializerDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseObjectInitializer/AbstractUseObjectInitializerDiagnosticAnalyzer.cs @@ -53,10 +53,16 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context) return; } + var syntaxTree = context.Node.SyntaxTree; + var cancellationToken = context.CancellationToken; + var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var objectCreationExpression = (TObjectCreationExpressionSyntax)context.Node; var language = objectCreationExpression.Language; - - var optionSet = context.Options.GetOptionSet(); var option = optionSet.GetOption(CodeStyleOptions.PreferObjectInitializer, language); if (!option.Value) { diff --git a/src/Features/Core/Portable/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs b/src/Features/Core/Portable/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs index cde6a9277b061..7877169541e6b 100644 --- a/src/Features/Core/Portable/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/UseThrowExpression/AbstractUseThrowExpressionDiagnosticAnalyzer.cs @@ -73,8 +73,13 @@ private void AnalyzeOperation(OperationAnalysisContext context) var throwOperation = (IThrowStatement)context.Operation; var throwStatement = throwOperation.Syntax; - - var optionSet = context.Options.GetOptionSet(); + var options = context.Options; + var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); + if (optionSet == null) + { + return; + } + var option = optionSet.GetOption(CodeStyleOptions.PreferThrowExpression, throwStatement.Language); if (!option.Value) { diff --git a/src/Workspaces/CSharp/Portable/CodeStyle/CSharpCodeStyleOptions.cs b/src/Workspaces/CSharp/Portable/CodeStyle/CSharpCodeStyleOptions.cs index e361aff04bede..a302fdc009cae 100644 --- a/src/Workspaces/CSharp/Portable/CodeStyle/CSharpCodeStyleOptions.cs +++ b/src/Workspaces/CSharp/Portable/CodeStyle/CSharpCodeStyleOptions.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections; using System.Collections.Generic; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Options; +using static Microsoft.CodeAnalysis.CodeStyle.CodeStyleHelpers; namespace Microsoft.CodeAnalysis.CSharp.CodeStyle { @@ -11,51 +11,77 @@ internal static class CSharpCodeStyleOptions { // TODO: get sign off on public api changes. public static readonly Option UseVarWhenDeclaringLocals = new Option(nameof(CodeStyleOptions), nameof(UseVarWhenDeclaringLocals), defaultValue: true, - storageLocations: new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseVarWhenDeclaringLocals")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_var_for_locals", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseVarWhenDeclaringLocals")}); public static readonly Option> UseImplicitTypeForIntrinsicTypes = new Option>(nameof(CodeStyleOptions), nameof(UseImplicitTypeForIntrinsicTypes), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeForIntrinsicTypes")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_var_for_built_in_types", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeForIntrinsicTypes")}); public static readonly Option> UseImplicitTypeWhereApparent = new Option>(nameof(CodeStyleOptions), nameof(UseImplicitTypeWhereApparent), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeWhereApparent")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_var_when_type_is_apparent", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeWhereApparent")}); public static readonly Option> UseImplicitTypeWherePossible = new Option>(nameof(CodeStyleOptions), nameof(UseImplicitTypeWherePossible), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeWherePossible")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_var_elsewhere", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.UseImplicitTypeWherePossible")}); public static readonly Option> PreferConditionalDelegateCall = new Option>(nameof(CodeStyleOptions), nameof(PreferConditionalDelegateCall), defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.PreferConditionalDelegateCall")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_conditional_delegate_call", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.CSharp.Specific.PreferConditionalDelegateCall")}); public static readonly Option> PreferPatternMatchingOverAsWithNullCheck = new Option>( nameof(CodeStyleOptions), nameof(PreferPatternMatchingOverAsWithNullCheck), defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferPatternMatchingOverAsWithNullCheck)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_pattern_matching_over_as_with_null_check", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferPatternMatchingOverAsWithNullCheck)}")}); public static readonly Option> PreferPatternMatchingOverIsWithCastCheck = new Option>( nameof(CodeStyleOptions), nameof(PreferPatternMatchingOverIsWithCastCheck), defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferPatternMatchingOverIsWithCastCheck)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_pattern_matching_over_is_with_cast_check", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferPatternMatchingOverIsWithCastCheck)}")}); public static readonly Option> PreferExpressionBodiedConstructors = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedConstructors), defaultValue: CodeStyleOptions.FalseWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedConstructors)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_constructors", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedConstructors)}")}); public static readonly Option> PreferExpressionBodiedMethods = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedMethods), defaultValue: CodeStyleOptions.FalseWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedMethods)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_methods", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedMethods)}")}); public static readonly Option> PreferExpressionBodiedOperators = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedOperators), defaultValue: CodeStyleOptions.FalseWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedOperators)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_operators", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedOperators)}")}); public static readonly Option> PreferExpressionBodiedProperties = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedProperties), defaultValue: CodeStyleOptions.TrueWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedProperties)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_properties", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedProperties)}")}); public static readonly Option> PreferExpressionBodiedIndexers = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedIndexers), defaultValue: CodeStyleOptions.TrueWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedIndexers)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_indexers", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedIndexers)}")}); public static readonly Option> PreferExpressionBodiedAccessors = new Option>( nameof(CodeStyleOptions), nameof(PreferExpressionBodiedAccessors), defaultValue: CodeStyleOptions.TrueWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedAccessors)}")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_expression_bodied_accessors", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferExpressionBodiedAccessors)}")}); public static IEnumerable>> GetCodeStyleOptions() { diff --git a/src/Workspaces/Core/Portable/CodeStyle/CodeStyleHelpers.cs b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleHelpers.cs new file mode 100644 index 0000000000000..a6115dc462ebd --- /dev/null +++ b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleHelpers.cs @@ -0,0 +1,29 @@ +namespace Microsoft.CodeAnalysis.CodeStyle +{ + internal static class CodeStyleHelpers + { + public static CodeStyleOption ParseEditorConfigCodeStyleOption(string arg) + { + var args = arg.Split(':'); + if (args.Length != 2) + { + return CodeStyleOption.Default; + } + + bool isEnabled = false; + if (!bool.TryParse(args[0], out isEnabled)) + { + return CodeStyleOption.Default; + } + + switch (args[1].Trim()) + { + case "none": return new CodeStyleOption(value: isEnabled, notification: NotificationOption.None); + case "suggestion": return new CodeStyleOption(value: isEnabled, notification: NotificationOption.Suggestion); + case "warning": return new CodeStyleOption(value: isEnabled, notification: NotificationOption.Warning); + case "error": return new CodeStyleOption(value: isEnabled, notification: NotificationOption.Error); + default: return CodeStyleOption.Default; + } + } + } +} diff --git a/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOptions.cs b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOptions.cs index 717324fca677c..380218adcd84f 100644 --- a/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOptions.cs +++ b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOptions.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.CodeAnalysis.Options; +using static Microsoft.CodeAnalysis.CodeStyle.CodeStyleHelpers; namespace Microsoft.CodeAnalysis.CodeStyle { @@ -20,55 +21,73 @@ public class CodeStyleOptions /// This option says if we should simplify away the . or . in field access expressions. /// public static readonly PerLanguageOption> QualifyFieldAccess = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(QualifyFieldAccess), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyFieldAccess")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_qualification_for_field", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyFieldAccess")}); /// /// This option says if we should simplify away the . or . in property access expressions. /// public static readonly PerLanguageOption> QualifyPropertyAccess = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(QualifyPropertyAccess), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyPropertyAccess")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_qualification_for_property", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyPropertyAccess")}); /// /// This option says if we should simplify away the . or . in method access expressions. /// public static readonly PerLanguageOption> QualifyMethodAccess = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(QualifyMethodAccess), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyMethodAccess")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_qualification_for_method", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyMethodAccess")}); /// /// This option says if we should simplify away the . or . in event access expressions. /// public static readonly PerLanguageOption> QualifyEventAccess = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(QualifyEventAccess), defaultValue: CodeStyleOption.Default, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyEventAccess")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_qualification_for_event", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.QualifyEventAccess")}); /// /// This option says if we should prefer keyword for Intrinsic Predefined Types in Declarations /// public static readonly PerLanguageOption> PreferIntrinsicPredefinedTypeKeywordInDeclaration = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(PreferIntrinsicPredefinedTypeKeywordInDeclaration), defaultValue: TrueWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferIntrinsicPredefinedTypeKeywordInDeclaration")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_predefined_type_for_locals_parameters_members", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferIntrinsicPredefinedTypeKeywordInDeclaration")}); /// /// This option says if we should prefer keyword for Intrinsic Predefined Types in Member Access Expression /// public static readonly PerLanguageOption> PreferIntrinsicPredefinedTypeKeywordInMemberAccess = new PerLanguageOption>(nameof(CodeStyleOptions), nameof(PreferIntrinsicPredefinedTypeKeywordInMemberAccess), defaultValue: TrueWithNoneEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferIntrinsicPredefinedTypeKeywordInMemberAccess")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_predefined_type_for_member_access", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferIntrinsicPredefinedTypeKeywordInMemberAccess")}); internal static readonly PerLanguageOption> PreferThrowExpression = new PerLanguageOption>( nameof(CodeStyleOptions), nameof(PreferThrowExpression), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferThrowExpression")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_throw_expression", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferThrowExpression")}); internal static readonly PerLanguageOption> PreferObjectInitializer = new PerLanguageOption>( nameof(CodeStyleOptions), nameof(PreferObjectInitializer), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferObjectInitializer")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_object_initializer", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferObjectInitializer")}); internal static readonly PerLanguageOption> PreferCollectionInitializer = new PerLanguageOption>( nameof(CodeStyleOptions), nameof(PreferCollectionInitializer), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferCollectionInitializer")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_collection_initializer", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferCollectionInitializer")}); internal static readonly PerLanguageOption PreferObjectInitializer_FadeOutCode = new PerLanguageOption( nameof(CodeStyleOptions), @@ -86,18 +105,24 @@ public class CodeStyleOptions nameof(CodeStyleOptions), nameof(PreferCoalesceExpression), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferCoalesceExpression")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_coalesce_expression", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferCoalesceExpression") }); internal static readonly PerLanguageOption> PreferNullPropagation = new PerLanguageOption>( nameof(CodeStyleOptions), nameof(PreferNullPropagation), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferNullPropagation")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("dotnet_style_null_propagation", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferNullPropagation") }); internal static readonly PerLanguageOption> PreferInlinedVariableDeclaration = new PerLanguageOption>( nameof(CodeStyleOptions), nameof(PreferInlinedVariableDeclaration), defaultValue: TrueWithSuggestionEnforcement, - storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferInlinedVariableDeclaration")); + storageLocations: new OptionStorageLocation[]{ + new EditorConfigStorageLocation("csharp_style_inlined_variable_declaration", ParseEditorConfigCodeStyleOption), + new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferInlinedVariableDeclaration") }); } } \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index 28b4c3355d4c1..3b4f751569fcb 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -341,6 +341,7 @@ + @@ -1096,4 +1097,4 @@ - + \ No newline at end of file