Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Apr 24, 2022
1 parent 6f0c6da commit 8a9fe7c
Show file tree
Hide file tree
Showing 28 changed files with 265 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
Expand All @@ -27,12 +28,11 @@ public static (string title, string equivalenceKey) GetInfo(NamespaceDeclaration
_ => throw ExceptionUtilities.UnexpectedValue(preference),
};

public static bool CanOfferUseBlockScoped(OptionSet optionSet, BaseNamespaceDeclarationSyntax declaration, bool forAnalyzer)
public static bool CanOfferUseBlockScoped(CodeStyleOption2<NamespaceDeclarationPreference> option, BaseNamespaceDeclarationSyntax declaration, bool forAnalyzer)
{
if (declaration is not FileScopedNamespaceDeclarationSyntax)
return false;

var option = optionSet.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations);
var userPrefersRegularNamespaces = option.Value == NamespaceDeclarationPreference.BlockScoped;
var analyzerDisabled = option.Notification.Severity == ReportDiagnostic.Suppress;
var forRefactoring = !forAnalyzer;
Expand All @@ -44,11 +44,11 @@ public static bool CanOfferUseBlockScoped(OptionSet optionSet, BaseNamespaceDecl
return canOffer;
}

internal static bool CanOfferUseFileScoped(OptionSet optionSet, CompilationUnitSyntax root, BaseNamespaceDeclarationSyntax declaration, bool forAnalyzer)
=> CanOfferUseFileScoped(optionSet, root, declaration, forAnalyzer, root.SyntaxTree.Options.LanguageVersion());
internal static bool CanOfferUseFileScoped(CodeStyleOption2<NamespaceDeclarationPreference> option, CompilationUnitSyntax root, BaseNamespaceDeclarationSyntax declaration, bool forAnalyzer)
=> CanOfferUseFileScoped(option, root, declaration, forAnalyzer, root.SyntaxTree.Options.LanguageVersion());

internal static bool CanOfferUseFileScoped(
OptionSet optionSet,
CodeStyleOption2<NamespaceDeclarationPreference> option,
CompilationUnitSyntax root,
BaseNamespaceDeclarationSyntax declaration,
bool forAnalyzer,
Expand All @@ -63,7 +63,6 @@ internal static bool CanOfferUseFileScoped(
if (version < LanguageVersion.CSharp10)
return false;

var option = optionSet.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations);
var userPrefersFileScopedNamespaces = option.Value == NamespaceDeclarationPreference.FileScoped;
var analyzerDisabled = option.Notification.Severity == ReportDiagnostic.Suppress;
var forRefactoring = !forAnalyzer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private void AnalyzeNamespace(SyntaxNodeAnalysisContext context)
var tree = declaration.SyntaxTree;
var option = optionSet.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations);

if (!ConvertNamespaceAnalysis.CanOfferUseBlockScoped(optionSet, declaration, forAnalyzer: true))
if (!ConvertNamespaceAnalysis.CanOfferUseBlockScoped(option, declaration, forAnalyzer: true))
return null;

// if the diagnostic is hidden, show it anywhere from the `namespace` keyword through the name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private void AnalyzeNamespace(SyntaxNodeAnalysisContext context)
var tree = declaration.SyntaxTree;
var option = optionSet.GetOption(CSharpCodeStyleOptions.NamespaceDeclarations);

if (!ConvertNamespaceAnalysis.CanOfferUseFileScoped(optionSet, root, declaration, forAnalyzer: true))
if (!ConvertNamespaceAnalysis.CanOfferUseFileScoped(option, root, declaration, forAnalyzer: true))
return null;

// if the diagnostic is hidden, show it anywhere from the `namespace` keyword through the name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ protected override async Task FixAllAsync(

var namespaceDecl = (BaseNamespaceDeclarationSyntax)diagnostic.AdditionalLocations[0].FindNode(cancellationToken);

var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(CSharpSyntaxFormatting.Instance, fallbackOptions, cancellationToken).ConfigureAwait(false);
var converted = await ConvertAsync(document, namespaceDecl, formattingOptions, cancellationToken).ConfigureAwait(false);
var options = await document.GetCSharpCodeFixOptionsProviderAsync(fallbackOptions, cancellationToken).ConfigureAwait(false);
var converted = await ConvertAsync(document, namespaceDecl, options.GetFormattingOptions(), cancellationToken).ConfigureAwait(false);

editor.ReplaceNode(
editor.OriginalRoot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,45 @@
using Microsoft.CodeAnalysis.CSharp.LanguageServices;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Shared.Extensions;

#if CODE_STYLE
using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions;
#else
using Microsoft.CodeAnalysis.Options;
#endif
using Microsoft.CodeAnalysis.CodeActions;

namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase
{
internal partial class HideBaseCodeFixProvider
{
private class AddNewKeywordAction : CodeActions.CodeAction
private class AddNewKeywordAction : CodeAction
{
private readonly Document _document;
private readonly SyntaxNode _node;
private readonly CodeActionOptionsProvider _fallbackOptions;

public override string Title => CSharpCodeFixesResources.Hide_base_member;

public AddNewKeywordAction(Document document, SyntaxNode node)
public AddNewKeywordAction(Document document, SyntaxNode node, CodeActionOptionsProvider fallbackOptions)
{
_document = document;
_node = node;
_fallbackOptions = fallbackOptions;
}

protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
var root = await _document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var options = await _document.GetCSharpCodeFixOptionsProviderAsync(_fallbackOptions, cancellationToken).ConfigureAwait(false);

#if CODE_STYLE
var options = _document.Project.AnalyzerOptions.GetAnalyzerOptionSet(_node.SyntaxTree, cancellationToken);
#else
var options = await _document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
#endif

var newNode = GetNewNode(_node, options);
var newNode = GetNewNode(_node, options.PreferredModifierOrder.Value);
var newRoot = root.ReplaceNode(_node, newNode);

return _document.WithSyntaxRoot(newRoot);
}

private static SyntaxNode GetNewNode(SyntaxNode node, OptionSet options)
private static SyntaxNode GetNewNode(SyntaxNode node, string preferredModifierOrder)
{
var syntaxFacts = CSharpSyntaxFacts.Instance;
var modifiers = syntaxFacts.GetModifiers(node);
var newModifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.NewKeyword));

var option = options.GetOption(CSharpCodeStyleOptions.PreferredModifierOrder);
if (!CSharpOrderModifiersHelper.Instance.TryGetOrComputePreferredOrder(option.Value, out var preferredOrder) ||
if (!CSharpOrderModifiersHelper.Instance.TryGetOrComputePreferredOrder(preferredModifierOrder, out var preferredOrder) ||
!AbstractOrderModifiersHelpers.IsOrdered(preferredOrder, modifiers))
{
return syntaxFacts.WithModifiers(node, newModifiers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Shared.Extensions;
Expand Down Expand Up @@ -45,7 +46,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
if (originalNode == null)
return;

context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics);
context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode, context.GetOptionsProvider()), context.Diagnostics);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,7 @@ protected override async Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken)
{
#if CODE_STYLE
var optionSet = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(editor.OriginalRoot.SyntaxTree, cancellationToken);
#else
var optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
#endif
var options = await document.GetCSharpCodeFixOptionsProviderAsync(fallbackOptions, cancellationToken).ConfigureAwait(false);

// Gather all statements to be removed
// We need this to find the statements we can safely attach trivia to
Expand Down Expand Up @@ -93,7 +89,7 @@ await editor.ApplyExpressionLevelSemanticEditsAsync(
(_1, _2, _3) => true,
(semanticModel, currentRoot, t, currentNode)
=> ReplaceIdentifierWithInlineDeclaration(
optionSet, semanticModel, currentRoot, t.declarator,
options, semanticModel, currentRoot, t.declarator,
t.identifier, currentNode, declarationsToRemove, document.Project.Solution.Workspace.Services,
cancellationToken),
cancellationToken).ConfigureAwait(false);
Expand All @@ -116,7 +112,7 @@ private static (VariableDeclaratorSyntax declarator, IdentifierNameSyntax identi
}

private static SyntaxNode ReplaceIdentifierWithInlineDeclaration(
OptionSet options, SemanticModel semanticModel,
CSharpCodeFixOptionsProvider options, SemanticModel semanticModel,
SyntaxNode currentRoot, VariableDeclaratorSyntax declarator,
IdentifierNameSyntax identifier, SyntaxNode currentNode,
HashSet<StatementSyntax> declarationsToRemove,
Expand Down Expand Up @@ -261,7 +257,7 @@ private static SyntaxNode ReplaceIdentifierWithInlineDeclaration(
}

public static TypeSyntax GenerateTypeSyntaxOrVar(
ITypeSymbol symbol, OptionSet options)
ITypeSymbol symbol, CSharpCodeFixOptionsProvider options)
{
var useVar = IsVarDesired(symbol, options);

Expand All @@ -274,16 +270,16 @@ public static TypeSyntax GenerateTypeSyntaxOrVar(
: symbol.GenerateTypeSyntax();
}

private static bool IsVarDesired(ITypeSymbol type, OptionSet options)
private static bool IsVarDesired(ITypeSymbol type, CSharpCodeFixOptionsProvider options)
{
// If they want it for intrinsics, and this is an intrinsic, then use var.
if (type.IsSpecialType() == true)
{
return options.GetOption(CSharpCodeStyleOptions.VarForBuiltInTypes).Value;
return options.VarForBuiltInTypes.Value;
}

// If they want "var" whenever possible, then use "var".
return options.GetOption(CSharpCodeStyleOptions.VarElsewhere).Value;
return options.VarElsewhere.Value;
}

private static DeclarationExpressionSyntax GetDeclarationExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Utilities;

#if CODE_STYLE
using OptionSet = Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptions;
#else
using Microsoft.CodeAnalysis.Options;
#endif

namespace Microsoft.CodeAnalysis.CSharp.MisplacedUsingDirectives
{
/// <summary>
Expand Down Expand Up @@ -64,19 +58,13 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var compilationUnit = (CompilationUnitSyntax)syntaxRoot;

#if CODE_STYLE
var options = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(syntaxRoot.SyntaxTree, cancellationToken);
#else
var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
#endif
var simplifierOptions = await document.GetSimplifierOptionsAsync(CSharpSimplification.Instance, context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false);

var codeStyleOption = options.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement);
var options = await document.GetCSharpCodeFixOptionsProviderAsync(context.GetOptionsProvider(), cancellationToken).ConfigureAwait(false);
var simplifierOptions = options.GetSimplifierOptions();

// Read the preferred placement option and verify if it can be applied to this code file.
// There are cases where we will not be able to fix the diagnostic and the user will need to resolve
// it manually.
var (placement, preferPreservation) = DeterminePlacement(compilationUnit, codeStyleOption);
var (placement, preferPreservation) = DeterminePlacement(compilationUnit, options.PreferredUsingDirectivePlacement);
if (preferPreservation)
return;

Expand Down Expand Up @@ -153,7 +141,7 @@ private static async Task<Document> GetTransformedDocumentAsync(

// Simplify usings now that they have been moved and are in the proper context.
#if CODE_STYLE
#pragma warning disable RS0030 // Do not used banned APIs
#pragma warning disable RS0030 // Do not used banned APIs (ReduceAsync with SimplifierOptions isn't public)
return await Simplifier.ReduceAsync(newDocument, Simplifier.Annotation, optionSet: null, cancellationToken).ConfigureAwait(false);
#pragma warning restore
#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,20 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
context.RegisterCodeFix(
CodeAction.Create(
CSharpCodeFixesResources.Place_statement_on_following_line,
c => UpdateDocumentAsync(document, diagnostic, c),
c => FixAllAsync(document, ImmutableArray.Create(diagnostic), context.GetOptionsProvider(), c),
nameof(CSharpCodeFixesResources.Place_statement_on_following_line)),
context.Diagnostics);
return Task.CompletedTask;
}

private static Task<Document> UpdateDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
=> FixAllAsync(document, ImmutableArray.Create(diagnostic), cancellationToken);

public static async Task<Document> FixAllAsync(Document document, ImmutableArray<Diagnostic> diagnostics, CancellationToken cancellationToken)
public static async Task<Document> FixAllAsync(Document document, ImmutableArray<Diagnostic> diagnostics, CodeActionOptionsProvider codeActionOptionsProvider, CancellationToken cancellationToken)
{
var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var editor = new SyntaxEditor(root, document.Project.Solution.Workspace.Services);

#if CODE_STYLE
var options = document.Project.AnalyzerOptions.GetAnalyzerOptionSet(editor.OriginalRoot.SyntaxTree, cancellationToken);
#else
var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
#endif
var options = await document.GetCSharpCodeFixOptionsProviderAsync(codeActionOptionsProvider, cancellationToken).ConfigureAwait(false);

var endOfLineTrivia = SyntaxFactory.ElasticEndOfLine(options.GetOption(FormattingOptions2.NewLine, LanguageNames.CSharp));
var endOfLineTrivia = SyntaxFactory.ElasticEndOfLine(options.NewLine);

foreach (var diagnostic in diagnostics)
FixOne(editor, diagnostic, endOfLineTrivia, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeCleanup;
using Microsoft.CodeAnalysis.CSharp.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.CSharp.Simplification;

Expand All @@ -23,5 +24,6 @@ internal static class CSharpCodeActionOptions
CSharpSyntaxFormattingOptions.Default,
CSharpSimplifierOptions.Default,
AddImportPlacementOptions.Default),
CSharpCodeGenerationOptions.Default);
CSharpCodeGenerationOptions.Default,
CSharpIdeCodeStyleOptions.Default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.CodeAnalysis.CodeCleanup;
using Microsoft.CodeAnalysis.ImplementType;
using Microsoft.CodeAnalysis.VisualBasic.CodeGeneration;
using Microsoft.CodeAnalysis.VisualBasic.CodeStyle;
using Microsoft.CodeAnalysis.VisualBasic.Formatting;
using Microsoft.CodeAnalysis.VisualBasic.Simplification;

Expand All @@ -24,7 +25,8 @@ internal static class VisualBasicCodeActionOptions
VisualBasicSyntaxFormattingOptions.Default,
VisualBasicSimplifierOptions.Default,
AddImportPlacementOptions.Default),
VisualBasicCodeGenerationOptions.Default);
VisualBasicCodeGenerationOptions.Default,
VisualBasicIdeCodeStyleOptions.Default);

public static CodeActionOptions WithWrappingColumn(this CodeActionOptions options, int value)
=> options with { WrappingColumn = value };
Expand Down
Loading

0 comments on commit 8a9fe7c

Please sign in to comment.