public static async Task ComputeRefactoringAsync(RefactoringContext context, InvocationExpressionSyntax invocationExpression) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodSymbol = semanticModel.GetSymbolInfo(invocationExpression, context.CancellationToken).Symbol as IMethodSymbol; if (methodSymbol == null) { return; } INamedTypeSymbol enumerable = semanticModel.Compilation.GetTypeByMetadataName("System.Linq.Enumerable"); if (enumerable == null) { return; } int argumentIndex = (methodSymbol.ReducedFrom != null) ? 0 : 1; methodSymbol = methodSymbol.ReducedFrom ?? methodSymbol.ConstructedFrom; if (methodSymbol.Equals(GetMethod(enumerable, "Any"))) { ExpressionSyntax expression = GetExpression(invocationExpression, argumentIndex); if (expression != null) { context.RegisterRefactoring( "Replace 'Any' with 'All'", cancellationToken => { return(RefactorAsync( context.Document, invocationExpression, "All", expression, cancellationToken)); }); } } else if (methodSymbol.Equals(GetMethod(enumerable, "All"))) { ExpressionSyntax expression = GetExpression(invocationExpression, argumentIndex); if (expression != null) { context.RegisterRefactoring( "Replace 'All' with 'Any'", cancellationToken => { return(RefactorAsync( context.Document, invocationExpression, "Any", expression, cancellationToken)); }); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer) { if (initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) && initializer.IsParentKind(SyntaxKind.CollectionInitializerExpression)) { initializer = (InitializerExpressionSyntax)initializer.Parent; } if (context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer) || context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer.Expressions)) { SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions; if (context.IsRefactoringEnabled(RefactoringDescriptors.WrapInitializerExpressions) && expressions.Any() && !initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) && initializer.IsParentKind( SyntaxKind.ArrayCreationExpression, SyntaxKind.ImplicitArrayCreationExpression, SyntaxKind.ObjectCreationExpression, SyntaxKind.CollectionInitializerExpression, SyntaxKind.WithExpression)) { if (initializer.IsSingleLine(includeExteriorTrivia: false)) { context.RegisterRefactoring( "Wrap initializer expression", ct => SyntaxFormatter.ToMultiLineAsync(context.Document, initializer, ct), RefactoringDescriptors.WrapInitializerExpressions); } else if (expressions.All(expression => expression.IsSingleLine()) && initializer.DescendantTrivia(initializer.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia())) { context.RegisterRefactoring( "Unwrap initializer expressions", ct => SyntaxFormatter.ToSingleLineAsync( context.Document, initializer.Parent, TextSpan.FromBounds(initializer.OpenBraceToken.GetPreviousToken().Span.End, initializer.CloseBraceToken.Span.End), ct), RefactoringDescriptors.WrapInitializerExpressions); } } if (context.IsRefactoringEnabled(RefactoringDescriptors.AddAllPropertiesToInitializer) && initializer.IsKind(SyntaxKind.ObjectInitializerExpression, SyntaxKind.WithInitializerExpression) && AddAllPropertiesToInitializerRefactoring.IsApplicableSpan(initializer, context.Span)) { SemanticModel semanticModdel = await context.GetSemanticModelAsync().ConfigureAwait(false); AddAllPropertiesToInitializerRefactoring.ComputeRefactorings(context, initializer, semanticModdel); } await ExpandInitializerRefactoring.ComputeRefactoringsAsync(context, initializer).ConfigureAwait(false); if (context.IsRefactoringEnabled(RefactoringDescriptors.UseIndexInitializer) && context.SupportsCSharp6) { await UseIndexInitializerRefactoring.ComputeRefactoringAsync(context, initializer).ConfigureAwait(false); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, BinaryExpressionSyntax binaryExpression) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateOperator)) { SyntaxToken operatorToken = binaryExpression.OperatorToken; if (operatorToken.Span.Contains(context.Span) && NegateOperatorRefactoring.CanBeNegated(operatorToken)) { context.RegisterRefactoring( "Negate operator", cancellationToken => NegateOperatorRefactoring.RefactorAsync(context.Document, operatorToken, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatBinaryExpression)) { FormatBinaryExpressionRefactoring.ComputeRefactorings(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateBinaryExpression)) { NegateBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCoalesceExpression) && binaryExpression.OperatorToken.Span.Contains(context.Span)) { ExpandCoalesceExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.JoinStringExpressions, RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation) && context.Span.IsBetweenSpans(binaryExpression) && binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpression concatenation; if (StringConcatenationExpression.TryCreate(binaryExpression, semanticModel, out concatenation, context.CancellationToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenation); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenation); } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapExpressionsInBinaryExpression) && context.Span.IsBetweenSpans(binaryExpression)) { SwapExpressionsInBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceAsWithCast) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(binaryExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (ReplaceAsWithCastRefactoring.CanRefactor(binaryExpression, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( "Replace as with cast", cancellationToken => ReplaceAsWithCastRefactoring.RefactorAsync(context.Document, binaryExpression, context.CancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateIsExpression)) { NegateIsExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.Span.IsContainedInSpanOrBetweenSpans(binaryExpression.OperatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceEqualsExpressionWithStringEquals)) { await ReplaceEqualsExpressionWithStringEqualsRefactoring.ComputeRefactoringAsync(context, binaryExpression).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrEmpty, RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrWhiteSpace)) { await ReplaceEqualsExpressionRefactoring.ComputeRefactoringsAsync(context, binaryExpression).ConfigureAwait(false); } } if (!context.Span.IsBetweenSpans(binaryExpression) && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExtractExpressionFromCondition, RefactoringIdentifiers.JoinStringExpressions)) { BinaryExpressionSelection binaryExpressionSelection = BinaryExpressionSelection.Create(binaryExpression, context.Span); if (binaryExpressionSelection.Expressions.Length > 1) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExtractExpressionFromCondition)) { ExtractConditionRefactoring.ComputeRefactoring(context, binaryExpressionSelection); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions) && binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpression concatenation; if (StringConcatenationExpression.TryCreate(binaryExpressionSelection, semanticModel, out concatenation, context.CancellationToken)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenation); } } } } }
public static async Task <bool> CanRefactorAsync(RefactoringContext context, ForStatementSyntax forStatement) { VariableDeclaratorSyntax variableDeclarator = forStatement .Declaration? .Variables .SingleOrDefault(shouldThrow: false); if (variableDeclarator == null) { return(false); } if (variableDeclarator.Initializer?.Value?.IsNumericLiteralExpression("0") != true) { return(false); } ExpressionSyntax condition = forStatement.Condition; if (condition?.IsKind(SyntaxKind.LessThanExpression) != true) { return(false); } ExpressionSyntax right = ((BinaryExpressionSyntax)condition).Right; if (right?.IsKind(SyntaxKind.SimpleMemberAccessExpression) != true) { return(false); } var memberAccessExpression = (MemberAccessExpressionSyntax)right; string memberName = memberAccessExpression.Name?.Identifier.ValueText; if (memberName != "Count" && memberName != "Length") { return(false); } ExpressionSyntax expression = memberAccessExpression.Expression; if (expression == null) { return(false); } if (forStatement.Incrementors.SingleOrDefault(shouldThrow: false)?.IsKind(SyntaxKind.PostIncrementExpression) != true) { return(false); } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = semanticModel.GetSymbol(expression, context.CancellationToken); if (symbol == null) { return(false); } ISymbol variableSymbol = semanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken); ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(variableSymbol, context.Document, cancellationToken : context.CancellationToken).ConfigureAwait(false); TextSpan span = forStatement.Statement.Span; foreach (SyntaxNode node in nodes) { if (span.Contains(node.Span) && !IsElementAccess(node, symbol, semanticModel, context.CancellationToken)) { return(false); } } return(true); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, SyntaxToken modifier) { SyntaxNode node = modifier.Parent; if (node.IsKind(SyntaxKind.DestructorDeclaration)) { return; } ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(node); if (node.IsKind( SyntaxKind.ClassDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.RecordStructDeclaration)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var symbol = (INamedTypeSymbol)semanticModel.GetDeclaredSymbol(node, context.CancellationToken); ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; if (syntaxReferences.Length > 1) { ImmutableArray <MemberDeclarationSyntax> memberDeclarations = ImmutableArray.CreateRange( syntaxReferences, f => (MemberDeclarationSyntax)f.GetSyntax(context.CancellationToken)); foreach (Accessibility accessibility in AvailableAccessibilities) { if (accessibility != modifiersInfo.ExplicitAccessibility && SyntaxAccessibility.IsValidAccessibility(node, accessibility)) { context.RegisterRefactoring( GetTitle(accessibility), ct => RefactorAsync(context.Solution, memberDeclarations, accessibility, ct), RefactoringDescriptors.ChangeAccessibility, accessibility.ToString()); } } return; } } foreach (Accessibility accessibility in AvailableAccessibilities) { if (accessibility == modifiersInfo.ExplicitAccessibility) { continue; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = GetBaseSymbolOrDefault(semanticModel, context.CancellationToken); if (symbol != null) { if (SyntaxAccessibility.IsValidAccessibility(node, accessibility, ignoreOverride: true)) { context.RegisterRefactoring( GetTitle(accessibility), ct => RefactorAsync(context.Solution, symbol, accessibility, ct), RefactoringDescriptors.ChangeAccessibility, accessibility.ToString()); } } else if (SyntaxAccessibility.IsValidAccessibility(node, accessibility)) { context.RegisterRefactoring( GetTitle(accessibility), ct => RefactorAsync(context.Document, node, accessibility, ct), RefactoringDescriptors.ChangeAccessibility, accessibility.ToString()); } } ISymbol GetBaseSymbolOrDefault(SemanticModel semanticModel, CancellationToken cancellationToken) { if (modifiersInfo.GetFilter().HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) { return(ChangeAccessibilityRefactoring.GetBaseSymbolOrDefault(node, semanticModel, cancellationToken)); } return(null); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, ForEachStatementSyntax forEachStatement) { if (context.SupportsSemanticModel) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { await ChangeTypeAccordingToExpressionAsync(context, forEachStatement).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType)) { await ChangeTypeAsync(context, forEachStatement).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameIdentifierAccordingToTypeName)) { await RenameIdentifierAccordingToTypeNameAsync(context, forEachStatement).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceForEachWithFor) && context.Span.IsEmpty && ReplaceForEachWithForRefactoring.CanRefactor(forEachStatement, await context.GetSemanticModelAsync().ConfigureAwait(false), context.CancellationToken)) { context.RegisterRefactoring( "Replace foreach with for", cancellationToken => ReplaceForEachWithForRefactoring.RefactorAsync(context.Document, forEachStatement, cancellationToken)); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid) && context.Span.IsEmptyAndContainedInSpan(methodDeclaration)) { await ChangeMethodReturnTypeToVoidRefactoring.ComputeRefactoringAsync(context, methodDeclaration).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddTypeParameter)) { AddTypeParameterRefactoring.ComputeRefactoring(context, methodDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceMethodWithProperty) && methodDeclaration.HeaderSpan().Contains(context.Span) && ReplaceMethodWithPropertyRefactoring.CanRefactor(methodDeclaration)) { context.RegisterRefactoring( $"Replace '{methodDeclaration.Identifier.ValueText}' with property", cancellationToken => ReplaceMethodWithPropertyRefactoring.RefactorAsync(context.Document, methodDeclaration, cancellationToken), RefactoringIdentifiers.ReplaceMethodWithProperty); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ConvertBlockBodyToExpressionBody) && context.SupportsCSharp6 && ConvertBlockBodyToExpressionBodyRefactoring.CanRefactor(methodDeclaration, context.Span)) { context.RegisterRefactoring( ConvertBlockBodyToExpressionBodyRefactoring.Title, cancellationToken => ConvertBlockBodyToExpressionBodyRefactoring.RefactorAsync(context.Document, methodDeclaration, cancellationToken), RefactoringIdentifiers.ConvertBlockBodyToExpressionBody); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MakeMemberAbstract) && context.Span.IsEmptyAndContainedInSpan(methodDeclaration.Identifier)) { MakeMethodAbstractRefactoring.ComputeRefactoring(context, methodDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MakeMemberVirtual) && methodDeclaration.HeaderSpan().Contains(context.Span)) { MakeMethodVirtualRefactoring.ComputeRefactoring(context, methodDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CopyDocumentationCommentFromBaseMember) && methodDeclaration.HeaderSpan().Contains(context.Span) && !methodDeclaration.HasDocumentationComment()) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); CopyDocumentationCommentFromBaseMemberRefactoring.ComputeRefactoring(context, methodDeclaration, semanticModel); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameMethodAccordingToTypeName)) { await RenameMethodAccordingToTypeNameAsync(context, methodDeclaration).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddParameterToInterfaceMember) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(methodDeclaration.Identifier)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); foreach (CodeAction codeAction in AddParameterToInterfaceMemberRefactoring.ComputeRefactoringForImplicitImplementation( new CommonFixContext(context.Document, RefactoringIdentifiers.AddParameterToInterfaceMember, semanticModel, context.CancellationToken), methodDeclaration)) { context.RegisterRefactoring(codeAction); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddMemberToInterface) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(methodDeclaration.Identifier)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); AddMemberToInterfaceRefactoring.ComputeRefactoring(context, methodDeclaration, semanticModel); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement) { if (ifStatement.IsTopmostIf() && (context.Span.IsEmptyAndContainedInSpan(ifStatement.IfKeyword) || context.Span.IsBetweenSpans(ifStatement))) { if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf, RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf, RefactoringIdentifiers.SimplifyIf)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var options = new IfAnalysisOptions( useCoalesceExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf), useConditionalExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf), useBooleanExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.SimplifyIf), useExpression: false); foreach (IfRefactoring refactoring in IfRefactoring.Analyze(ifStatement, options, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapStatementsInIfElse)) { SwapStatementInIfElseRefactoring.ComputeRefactoring(context, ifStatement); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfWithSwitch)) { await ReplaceIfWithSwitchRefactoring.ComputeRefactoringAsync(context, ifStatement).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfStatement)) { SplitIfStatementRefactoring.ComputeRefactoring(context, ifStatement); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReduceIfNesting) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(ifStatement.IfKeyword)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ReduceIfNestingAnalysis analysis = ReduceIfNestingRefactoring.Analyze( ifStatement, semanticModel, options: ReduceIfNestingOptions.AllowNestedFix | ReduceIfNestingOptions.AllowIfInsideIfElse | ReduceIfNestingOptions.AllowLoop | ReduceIfNestingOptions.AllowSwitchSection, taskSymbol: semanticModel.GetTypeByMetadataName(MetadataNames.System_Threading_Tasks_Task), cancellationToken: context.CancellationToken); if (analysis.Success) { context.RegisterRefactoring( "Reduce if nesting", cancellationToken => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, false, cancellationToken)); if (ReduceIfNestingRefactoring.IsFixableRecursively(ifStatement, analysis.JumpKind)) { context.RegisterRefactoring( "Reduce if nesting (recursively)", cancellationToken => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, true, cancellationToken)); } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfElseWithIfReturn) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(ifStatement.IfKeyword)) { ReplaceIfElseWithIfReturnRefactoring.ComputeRefactoring(context, ifStatement); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, SyntaxToken token) { SyntaxNode parent = token.Parent; switch (parent.Kind()) { case SyntaxKind.MethodDeclaration: { var methodDeclaration = (MethodDeclarationSyntax)parent; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitResult result = RemoveAsyncAwaitAnalysis.Analyze(methodDeclaration, semanticModel, context.CancellationToken); ComputeRefactoring(context, token, result); return; } case SyntaxKind.LocalFunctionStatement: { var localFunction = (LocalFunctionStatementSyntax)parent; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitResult result = RemoveAsyncAwaitAnalysis.Analyze(localFunction, semanticModel, context.CancellationToken); ComputeRefactoring(context, token, result); return; } case SyntaxKind.ParenthesizedLambdaExpression: { var parenthesizedLambda = (ParenthesizedLambdaExpressionSyntax)parent; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitResult result = RemoveAsyncAwaitAnalysis.Analyze(parenthesizedLambda, semanticModel, context.CancellationToken); ComputeRefactoring(context, token, result); return; } case SyntaxKind.SimpleLambdaExpression: { var simpleLambda = (SimpleLambdaExpressionSyntax)parent; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitResult result = RemoveAsyncAwaitAnalysis.Analyze(simpleLambda, semanticModel, context.CancellationToken); ComputeRefactoring(context, token, result); return; } case SyntaxKind.AnonymousMethodExpression: { var anonymousMethod = (AnonymousMethodExpressionSyntax)parent; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitResult result = RemoveAsyncAwaitAnalysis.Analyze(anonymousMethod, semanticModel, context.CancellationToken); ComputeRefactoring(context, token, result); return; } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, InterpolatedStringTextSyntax interpolatedStringText) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.InsertStringInterpolation) && interpolatedStringText.IsParentKind(SyntaxKind.InterpolatedStringExpression)) { TextSpan span = context.Span; var interpolatedString = (InterpolatedStringExpressionSyntax)interpolatedStringText.Parent; string text = interpolatedStringText.TextToken.Text; bool isVerbatim = interpolatedString.IsVerbatim(); if (StringLiteralParser.CanExtractSpan( text, span.Offset(-interpolatedStringText.SpanStart), isVerbatim, isInterpolatedText: true)) { context.RegisterRefactoring( "Insert interpolation", cancellationToken => { return(InsertInterpolationRefactoring.RefactorAsync( context.Document, interpolatedString, span, addNameOf: false, cancellationToken: cancellationToken)); }); if (!span.IsEmpty) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); string name = StringLiteralParser.Parse( text, span.Start - interpolatedStringText.SpanStart, span.Length, isVerbatim: isVerbatim, isInterpolatedText: true); foreach (ISymbol symbol in semanticModel.LookupSymbols(interpolatedStringText.SpanStart)) { if (string.Equals(name, symbol.MetadataName, StringComparison.Ordinal)) { context.RegisterRefactoring( "Insert interpolation with nameof", cancellationToken => { return(InsertInterpolationRefactoring.RefactorAsync( context.Document, interpolatedString, span, addNameOf: true, cancellationToken: cancellationToken)); }); break; } } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementContainerSelection selectedStatements) { if (selectedStatements.Count > 1) { StatementSyntax lastStatement = selectedStatements.Last(); if (lastStatement.IsKind(SyntaxKind.WhileStatement)) { IEnumerable <StatementSyntax> statements = selectedStatements .Take(selectedStatements.EndIndex - selectedStatements.StartIndex); SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); List <LocalDeclarationStatementSyntax> localDeclarations = null; List <ExpressionSyntax> expressions = null; foreach (StatementSyntax statement in statements) { SyntaxKind kind = statement.Kind(); if (kind == SyntaxKind.LocalDeclarationStatement) { var localDeclaration = (LocalDeclarationStatementSyntax)statement; if (!IsAnySymbolReferenced(localDeclaration, selectedStatements.ToImmutableArray(), selectedStatements.EndIndex + 1, semanticModel, context.CancellationToken)) { (localDeclarations ?? (localDeclarations = new List <LocalDeclarationStatementSyntax>())).Add(localDeclaration); } else { return; } } else if (kind == SyntaxKind.ExpressionStatement) { var expressionStatement = (ExpressionStatementSyntax)statement; ExpressionSyntax expression = expressionStatement.Expression; if (expression != null) { if (CanBeInitializer(expression)) { (expressions ?? (expressions = new List <ExpressionSyntax>())).Add(expression); } else { return; } } } else { return; } } if (localDeclarations == null || expressions == null) { if (localDeclarations == null || localDeclarations .Select(f => f.Declaration) .Where(f => f != null) .Select(f => semanticModel.GetTypeSymbol(f.Type, context.CancellationToken)) .Distinct() .Count() == 1) { context.RegisterRefactoring( Title, cancellationToken => RefactorAsync(context.Document, localDeclarations, expressions, (WhileStatementSyntax)lastStatement, cancellationToken)); } } } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, ExpressionSyntax expression) { if (expression != null && context.SupportsSemanticModel) { MemberDeclarationSyntax declaration = GetContainingMethodOrPropertyOrIndexer(expression); if (declaration != null) { TypeSyntax memberType = GetMemberType(declaration); if (memberType != null) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol memberTypeSymbol = semanticModel .GetTypeInfo(memberType, context.CancellationToken) .Type; if (memberTypeSymbol != null) { ITypeSymbol expressionSymbol = semanticModel .GetTypeInfo(expression, context.CancellationToken) .Type; if (expressionSymbol?.IsErrorType() == false) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddBooleanComparison) && memberTypeSymbol.IsBoolean() && expressionSymbol.IsNamedType()) { var namedTypeSymbol = (INamedTypeSymbol)expressionSymbol; if (namedTypeSymbol?.IsNullableOf(SpecialType.System_Boolean) == true) { AddBooleanComparisonRefactoring.RegisterRefactoring(context, expression); } } ISymbol memberSymbol = semanticModel.GetDeclaredSymbol(declaration, context.CancellationToken); if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMemberTypeAccordingToReturnExpression)) { ITypeSymbol newType = GetMemberNewType(memberSymbol, memberTypeSymbol, expression, expressionSymbol, semanticModel, context.CancellationToken); if (newType?.IsErrorType() == false && !memberTypeSymbol.Equals(newType)) { if (newType.IsNamedType() && memberTypeSymbol.IsNamedType()) { var newNamedType = (INamedTypeSymbol)newType; INamedTypeSymbol orderedEnumerableSymbol = semanticModel.Compilation.GetTypeByMetadataName("System.Linq.IOrderedEnumerable`1"); if (newNamedType.ConstructedFrom == orderedEnumerableSymbol) { INamedTypeSymbol enumerableSymbol = semanticModel.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1"); if (enumerableSymbol != null && ((INamedTypeSymbol)memberTypeSymbol).ConstructedFrom != enumerableSymbol) { RegisterChangeType(context, declaration, memberType, enumerableSymbol.Construct(newNamedType.TypeArguments.ToArray())); } } } RegisterChangeType(context, declaration, memberType, newType); } } if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.AddCastExpression, RefactoringIdentifiers.CallToMethod) && !memberTypeSymbol.IsErrorType()) { ITypeSymbol castTypeSymbol = GetCastTypeSymbol(memberSymbol, memberTypeSymbol, expressionSymbol, semanticModel); if (castTypeSymbol != null) { ModifyExpressionRefactoring.ComputeRefactoring( context, expression, castTypeSymbol, semanticModel); } } } } } } } }
private static async Task ComputeRefactoringAsync(RefactoringContext context, ExpressionSyntax expression) { if (expression == null) { return; } if (!expression.IsKind(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression)) { return; } if (!context.Span.IsContainedInSpanOrBetweenSpans(expression)) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var methodSymbol = semanticModel.GetSymbol(expression, context.CancellationToken) as IMethodSymbol; if (methodSymbol == null) { return; } if (methodSymbol.IsImplicitlyDeclared) { return; } if (methodSymbol.PartialDefinitionPart != null) { return; } Debug.Assert(methodSymbol.DeclaringSyntaxReferences.Any()); SyntaxNode node = methodSymbol.GetSyntaxOrDefault(context.CancellationToken); switch (node) { case MethodDeclarationSyntax methodDeclaration: { if (methodDeclaration.ContainsYield()) { break; } context.RegisterRefactoring( Title, cancellationToken => RefactorAsync( context.Document, expression, methodDeclaration.Modifiers, methodDeclaration.ParameterList, methodDeclaration.BodyOrExpressionBody(), cancellationToken)); break; } case LocalFunctionStatementSyntax localFunction: { if (localFunction.ContainsYield()) { break; } context.RegisterRefactoring( Title, cancellationToken => RefactorAsync( context.Document, expression, localFunction.Modifiers, localFunction.ParameterList, localFunction.BodyOrExpressionBody(), cancellationToken)); break; } default: { Debug.Assert(node == null, node.Kind().ToString()); break; } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, SyntaxToken token) { switch (token.Parent) { case MethodDeclarationSyntax methodDeclaration: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitAnalysis analysis = RemoveAsyncAwaitAnalysis.Create(methodDeclaration, semanticModel, context.CancellationToken); if (analysis.Success) { RegisterRefactoring(context, token, analysis); } return; } case LocalFunctionStatementSyntax localFunction: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitAnalysis analysis = RemoveAsyncAwaitAnalysis.Create(localFunction, semanticModel, context.CancellationToken); if (analysis.Success) { RegisterRefactoring(context, token, analysis); } return; } case ParenthesizedLambdaExpressionSyntax parenthesizedLambda: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitAnalysis analysis = RemoveAsyncAwaitAnalysis.Create(parenthesizedLambda, semanticModel, context.CancellationToken); if (analysis.Success) { RegisterRefactoring(context, token, analysis); } return; } case SimpleLambdaExpressionSyntax simpleLambda: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitAnalysis analysis = RemoveAsyncAwaitAnalysis.Create(simpleLambda, semanticModel, context.CancellationToken); if (analysis.Success) { RegisterRefactoring(context, token, analysis); } return; } case AnonymousMethodExpressionSyntax anonymousMethod: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); RemoveAsyncAwaitAnalysis analysis = RemoveAsyncAwaitAnalysis.Create(anonymousMethod, semanticModel, context.CancellationToken); if (analysis.Success) { RegisterRefactoring(context, token, analysis); } return; } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, InvocationExpressionSyntax invocation) { if (invocation.IsParentKind(SyntaxKind.ExpressionStatement)) { return; } SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!invocationInfo.Success) { return; } switch (invocationInfo.NameText) { case "First": { if (invocationInfo.Arguments.Any()) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!UseElementAccessAnalysis.IsFixableFirst(invocationInfo, semanticModel, context.CancellationToken)) { break; } context.RegisterRefactoring( "Use [] instead of calling 'First'", ct => UseElementAccessInsteadOfEnumerableMethodRefactoring.UseElementAccessInsteadOfFirstAsync(context.Document, invocation, ct), RefactoringDescriptors.UseElementAccessInsteadOfLinqMethod); break; } case "Last": { if (invocationInfo.Arguments.Any()) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!UseElementAccessAnalysis.IsFixableLast(invocationInfo, semanticModel, context.CancellationToken)) { break; } string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, context.CancellationToken); if (propertyName == null) { break; } context.RegisterRefactoring( "Use [] instead of calling 'Last'", ct => UseElementAccessInsteadOfEnumerableMethodRefactoring.UseElementAccessInsteadOfLastAsync(context.Document, invocation, propertyName, ct), RefactoringDescriptors.UseElementAccessInsteadOfLinqMethod); break; } case "ElementAt": { if (invocationInfo.Arguments.SingleOrDefault(shouldThrow: false)?.Expression?.IsMissing != false) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!UseElementAccessAnalysis.IsFixableElementAt(invocationInfo, semanticModel, context.CancellationToken)) { break; } context.RegisterRefactoring( "Use [] instead of calling 'ElementAt'", ct => UseElementAccessInsteadOfEnumerableMethodRefactoring.UseElementAccessInsteadOfElementAtAsync(context.Document, invocation, ct), RefactoringDescriptors.UseElementAccessInsteadOfLinqMethod); break; } } }
private static async Task SyncPropertyNameAndBackingFieldNameAsync( RefactoringContext context, IdentifierNameSyntax identifierName) { if (IsQualified(identifierName) && !IsQualifiedWithThis(identifierName)) { return; } PropertyDeclarationSyntax propertyDeclaration = identifierName.FirstAncestor <PropertyDeclarationSyntax>(); if (propertyDeclaration == null) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var fieldSymbol = semanticModel.GetSymbol(identifierName, context.CancellationToken) as IFieldSymbol; if (fieldSymbol?.DeclaredAccessibility != Accessibility.Private) { return; } IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken); if (propertySymbol == null) { return; } if (fieldSymbol.IsStatic != propertySymbol.IsStatic) { return; } if (!SymbolEqualityComparer.Default.Equals(fieldSymbol.ContainingType, propertySymbol.ContainingType)) { return; } string newName = StringUtility.ToCamelCase(propertySymbol.Name, context.PrefixFieldIdentifierWithUnderscore); if (string.Equals(fieldSymbol.Name, newName, StringComparison.Ordinal)) { return; } if (!await MemberNameGenerator.IsUniqueMemberNameAsync( newName, fieldSymbol, context.Solution, cancellationToken: context.CancellationToken) .ConfigureAwait(false)) { return; } context.RegisterRefactoring( $"Rename '{fieldSymbol.Name}' to '{newName}'", ct => Renamer.RenameSymbolAsync(context.Solution, fieldSymbol, newName, default(OptionSet), ct), RefactoringDescriptors.SyncPropertyNameAndBackingFieldName); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, StatementsSelection selectedStatements) { if (selectedStatements.Count > 1) { StatementSyntax firstStatement = selectedStatements.First(); SemanticModel semanticModel = null; ISymbol symbol = null; ObjectCreationExpressionSyntax objectCreation = null; SyntaxKind kind = firstStatement.Kind(); if (kind == SyntaxKind.LocalDeclarationStatement) { var localDeclaration = (LocalDeclarationStatementSyntax)firstStatement; VariableDeclaratorSyntax variable = localDeclaration .Declaration? .Variables .SingleOrDefault(shouldthrow: false); objectCreation = variable?.Initializer?.Value as ObjectCreationExpressionSyntax; if (objectCreation != null) { semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); symbol = semanticModel.GetDeclaredSymbol(variable, context.CancellationToken); } } else if (kind == SyntaxKind.ExpressionStatement) { var expressionStatement = (ExpressionStatementSyntax)firstStatement; if (expressionStatement.Expression is AssignmentExpressionSyntax assignment) { objectCreation = assignment.Right as ObjectCreationExpressionSyntax; if (objectCreation != null) { semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); symbol = semanticModel.GetSymbol(assignment.Left, context.CancellationToken); } } } if (objectCreation != null && symbol?.IsErrorType() == false && selectedStatements .Skip(1) .All(f => IsValidAssignmentStatement(f, symbol, semanticModel, context.CancellationToken))) { context.RegisterRefactoring( "Collapse to initializer", cancellationToken => { return(RefactorAsync( context.Document, objectCreation, selectedStatements, cancellationToken)); }); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, VariableDeclarationSyntax variableDeclaration) { TypeSyntax type = variableDeclaration.Type; if (type?.Span.Contains(context.Span) == true && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ChangeExplicitTypeToVar, RefactoringIdentifiers.ChangeVarToExplicitType, RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeAnalysis analysis = CSharpTypeAnalysis.AnalyzeType(variableDeclaration, semanticModel, context.CancellationToken); if (analysis.IsExplicit) { if (analysis.SupportsImplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeExplicitTypeToVar)) { context.RegisterRefactoring(CodeActionFactory.ChangeTypeToVar(context.Document, type, equivalenceKey: RefactoringIdentifiers.ChangeExplicitTypeToVar)); } if (!variableDeclaration.ContainsDiagnostics && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression)) { ChangeTypeAccordingToExpression(context, variableDeclaration, analysis.Symbol, semanticModel); } } else if (analysis.SupportsExplicit && context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeVarToExplicitType)) { ITypeSymbol typeSymbol = analysis.Symbol; VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); if (variableDeclarator?.Initializer?.Value != null) { if (typeSymbol.OriginalDefinition.EqualsOrInheritsFromTaskOfT()) { Func <CancellationToken, Task <Document> > createChangedDocument = DocumentRefactoringFactory.ChangeTypeAndAddAwait( context.Document, variableDeclaration, variableDeclarator, typeSymbol, semanticModel, context.CancellationToken); if (createChangedDocument != null) { ITypeSymbol typeArgument = ((INamedTypeSymbol)typeSymbol).TypeArguments[0]; context.RegisterRefactoring( $"Change type to '{SymbolDisplay.ToMinimalDisplayString(typeArgument, semanticModel, type.SpanStart)}' and add 'await'", createChangedDocument, EquivalenceKey.Join(RefactoringIdentifiers.ChangeVarToExplicitType, "AddAwait")); } } typeSymbol = semanticModel.GetTypeSymbol(variableDeclarator.Initializer.Value, context.CancellationToken); if (typeSymbol != null) { context.RegisterRefactoring(CodeActionFactory.ChangeType(context.Document, type, typeSymbol, semanticModel, equivalenceKey: RefactoringIdentifiers.ChangeVarToExplicitType)); } } } } }
private static async Task RenameMethodAccordingToTypeNameAsync( RefactoringContext context, MethodDeclarationSyntax methodDeclaration) { TypeSyntax returnType = methodDeclaration.ReturnType; if (returnType?.IsVoid() != false) { return; } SyntaxToken identifier = methodDeclaration.Identifier; if (!context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(identifier)) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); ITypeSymbol typeSymbol = GetType(returnType, semanticModel, context.CancellationToken); if (typeSymbol == null) { return; } string newName = NameGenerator.CreateName(typeSymbol); if (string.IsNullOrEmpty(newName)) { return; } newName = "Get" + newName; if (methodSymbol.IsAsync) { newName += "Async"; } string oldName = identifier.ValueText; if (string.Equals(oldName, newName, StringComparison.Ordinal)) { return; } if (!await MemberNameGenerator.IsUniqueMemberNameAsync( newName, methodSymbol, context.Solution, cancellationToken: context.CancellationToken) .ConfigureAwait(false)) { return; } context.RegisterRefactoring( $"Rename '{oldName}' to '{newName}'", cancellationToken => Renamer.RenameSymbolAsync(context.Solution, methodSymbol, newName, default(OptionSet), cancellationToken), RefactoringIdentifiers.RenameMethodAccordingToTypeName); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer) { if (initializer.IsKind( SyntaxKind.ObjectInitializerExpression, SyntaxKind.CollectionInitializerExpression) && initializer.Expressions.Any()) { SyntaxNode parent = initializer.Parent; if (parent?.IsKind(SyntaxKind.ObjectCreationExpression) == true) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (CanExpand(initializer, semanticModel, context.CancellationToken)) { parent = parent.Parent; switch (parent?.Kind()) { case SyntaxKind.SimpleAssignmentExpression: { var assignmentExpression = (AssignmentExpressionSyntax)parent; ExpressionSyntax left = assignmentExpression.Left; if (left != null) { parent = assignmentExpression.Parent; if (parent?.IsKind(SyntaxKind.ExpressionStatement) == true) { RegisterRefactoring(context, (StatementSyntax)parent, initializer, left); } } break; } case SyntaxKind.EqualsValueClause: { var equalsValueClause = (EqualsValueClauseSyntax)parent; parent = equalsValueClause.Parent; if (parent?.IsKind(SyntaxKind.VariableDeclarator) == true) { parent = parent.Parent; if (parent?.IsKind(SyntaxKind.VariableDeclaration) == true) { parent = parent.Parent; if (parent?.IsKind(SyntaxKind.LocalDeclarationStatement) == true) { var variableDeclarator = (VariableDeclaratorSyntax)equalsValueClause.Parent; RegisterRefactoring( context, (StatementSyntax)parent, initializer, IdentifierName(variableDeclarator.Identifier.ValueText)); } } } break; } } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, MemberDeclarationListSelection selectedMembers) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeAccessibility) && !selectedMembers.Parent.IsKind(SyntaxKind.InterfaceDeclaration)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); AccessibilityFilter validAccessibilities = ChangeAccessibilityAnalysis.GetValidAccessibilityFilter(selectedMembers, semanticModel, context.CancellationToken); if (validAccessibilities != AccessibilityFilter.None) { bool canHaveMultipleDeclarations = CanHaveMultipleDeclarations(); TryRegisterRefactoring(validAccessibilities, Accessibility.Public, canHaveMultipleDeclarations); TryRegisterRefactoring(validAccessibilities, Accessibility.Internal, canHaveMultipleDeclarations); TryRegisterRefactoring(validAccessibilities, Accessibility.Protected, canHaveMultipleDeclarations); TryRegisterRefactoring(validAccessibilities, Accessibility.Private, canHaveMultipleDeclarations); } } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ConvertBlockBodyToExpressionBody, RefactoringIdentifiers.ConvertExpressionBodyToBlockBody)) { ConvertBodyAndExpressionBodyRefactoring.ComputeRefactoring(context, selectedMembers); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.InitializeFieldFromConstructor) && !selectedMembers.Parent.IsKind(SyntaxKind.InterfaceDeclaration)) { InitializeFieldFromConstructorRefactoring.ComputeRefactoring(context, selectedMembers); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddEmptyLineBetweenDeclarations)) { AddEmptyLineBetweenDeclarationsRefactoring.ComputeRefactoring(context, selectedMembers); } void TryRegisterRefactoring(AccessibilityFilter accessibilities, Accessibility accessibility, bool canHaveMultipleDeclarations) { if ((accessibilities & accessibility.GetAccessibilityFilter()) != 0) { if (canHaveMultipleDeclarations) { context.RegisterRefactoring( ChangeAccessibilityRefactoring.GetTitle(accessibility), async cancellationToken => { SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); return(await ChangeAccessibilityRefactoring.RefactorAsync(context.Document.Solution(), selectedMembers, accessibility, semanticModel, cancellationToken).ConfigureAwait(false)); }, _accessiblityIdentifierMap[accessibility]); } else { context.RegisterRefactoring( ChangeAccessibilityRefactoring.GetTitle(accessibility), cancellationToken => ChangeAccessibilityRefactoring.RefactorAsync(context.Document, selectedMembers, accessibility, cancellationToken), EquivalenceKey.Join(RefactoringIdentifiers.ChangeAccessibility, accessibility.ToString())); } } } bool CanHaveMultipleDeclarations() { foreach (MemberDeclarationSyntax member in selectedMembers) { switch (member.Kind()) { case SyntaxKind.ClassDeclaration: { if (((ClassDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)) { return(true); } break; } case SyntaxKind.InterfaceDeclaration: { if (((InterfaceDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)) { return(true); } break; } case SyntaxKind.RecordDeclaration: { if (((RecordDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)) { return(true); } break; } case SyntaxKind.StructDeclaration: { if (((StructDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword)) { return(true); } break; } case SyntaxKind.MethodDeclaration: { if (((MethodDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.PartialKeyword, SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword)) { return(true); } break; } case SyntaxKind.PropertyDeclaration: { if (((PropertyDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword)) { return(true); } break; } case SyntaxKind.IndexerDeclaration: { if (((IndexerDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword)) { return(true); } break; } case SyntaxKind.EventDeclaration: { if (((EventDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword)) { return(true); } break; } case SyntaxKind.EventFieldDeclaration: { if (((EventFieldDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword)) { return(true); } break; } } } return(false); } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, StructDeclarationSyntax structDeclaration) { SyntaxToken identifier = structDeclaration.Identifier; if (identifier.IsMissing) { return; } TextSpan span = identifier.Span; BaseListSyntax baseList = structDeclaration.BaseList; if (baseList != null) { span = TextSpan.FromBounds(span.Start, baseList.Span.End); } TypeParameterListSyntax typeParameterList = structDeclaration.TypeParameterList; if (typeParameterList != null) { span = TextSpan.FromBounds(span.Start, typeParameterList.Span.End); } if (!span.Contains(context.Span)) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); INamedTypeSymbol typeSymbol = semanticModel.GetDeclaredSymbol(structDeclaration, context.CancellationToken); if (typeSymbol?.IsErrorType() != false) { return; } foreach (INamedTypeSymbol interfaceSymbol in typeSymbol.AllInterfaces) { if (interfaceSymbol.HasMetadataName(MetadataNames.System_IEquatable_T) && interfaceSymbol.TypeArguments.Single().Equals(typeSymbol)) { return; } } INamedTypeSymbol equatableSymbol = semanticModel.GetTypeByMetadataName("System.IEquatable`1"); if (equatableSymbol == null) { return; } equatableSymbol = equatableSymbol.Construct(typeSymbol); context.RegisterRefactoring( GetTitle(equatableSymbol, semanticModel, structDeclaration.SpanStart), ct => RefactorAsync(context.Document, structDeclaration, typeSymbol, equatableSymbol, semanticModel, ct), RefactoringIdentifiers.ImplementIEquatableOfT); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, StatementListSelection selectedStatements) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInUsingStatement)) { var refactoring = new WrapStatements.WrapInUsingStatementRefactoring(); await refactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CollapseToInitializer)) { await CollapseToInitializerRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfStatements)) { MergeIfStatementsRefactoring.ComputeRefactorings(context, selectedStatements); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf, RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf, RefactoringIdentifiers.SimplifyIf)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); var options = new IfAnalysisOptions( useCoalesceExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf), useConditionalExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.UseConditionalExpressionInsteadOfIf), useBooleanExpression: context.IsRefactoringEnabled(RefactoringIdentifiers.SimplifyIf), useExpression: false); foreach (IfAnalysis analysis in IfAnalysis.Analyze(selectedStatements, options, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( analysis.Title, cancellationToken => IfRefactoring.RefactorAsync(context.Document, analysis, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeLocalDeclarations)) { await MergeLocalDeclarationsRefactoring.ComputeRefactoringsAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeAssignmentExpressionWithReturnStatement)) { MergeAssignmentExpressionWithReturnStatementRefactoring.ComputeRefactorings(context, selectedStatements); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CheckExpressionForNull)) { await CheckExpressionForNullRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceWhileWithFor)) { await ReplaceWhileWithForRefactoring.ComputeRefactoringAsync(context, selectedStatements).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInElseClause)) { WrapInElseClauseRefactoring.ComputeRefactoring(context, selectedStatements); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInCondition)) { context.RegisterRefactoring( WrapInIfStatementRefactoring.Title, ct => WrapInIfStatementRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.WrapInTryCatch)) { context.RegisterRefactoring( WrapInTryCatchRefactoring.Title, ct => WrapInTryCatchRefactoring.Instance.RefactorAsync(context.Document, selectedStatements, ct)); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, InvocationExpressionSyntax invocation) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocation); if (!invocationInfo.Success) { return; } switch (invocationInfo.NameText) { case "First": { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (invocationInfo.Arguments.Any()) { break; } if (!UseElementAccessInsteadOfFirstRefactoring.CanRefactor(invocationInfo, semanticModel, context.CancellationToken)) { break; } context.RegisterRefactoring( "Use [] instead of calling 'First'", cancellationToken => UseElementAccessInsteadOfFirstRefactoring.RefactorAsync(context.Document, invocation, cancellationToken)); break; } case "Last": { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (invocationInfo.Arguments.Any()) { break; } if (!UseElementAccessInsteadOfLastRefactoring.CanRefactor(invocationInfo, semanticModel, context.CancellationToken)) { break; } string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, context.CancellationToken); if (propertyName == null) { break; } context.RegisterRefactoring( "Use [] instead of calling 'Last'", cancellationToken => UseElementAccessInsteadOfLastRefactoring.RefactorAsync(context.Document, invocation, propertyName, cancellationToken)); break; } case "ElementAt": { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (invocationInfo.Arguments.Count != 1) { break; } if (!UseElementAccessInsteadOfElementAtRefactoring.CanRefactor(invocationInfo, semanticModel, context.CancellationToken)) { break; } context.RegisterRefactoring( "Use [] instead of calling 'ElementAt'", cancellationToken => UseElementAccessInsteadOfElementAtRefactoring.RefactorAsync(context.Document, invocation, cancellationToken)); break; } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, EventFieldDeclarationSyntax eventFieldDeclaration) { if (eventFieldDeclaration.IsParentKind(SyntaxKind.InterfaceDeclaration)) { return; } VariableDeclarationSyntax variableDeclaration = eventFieldDeclaration.Declaration; if (variableDeclaration == null) { return; } SemanticModel semanticModel = null; foreach (VariableDeclaratorSyntax variableDeclarator in variableDeclaration.Variables) { if (!context.Span.IsContainedInSpanOrBetweenSpans(variableDeclarator.Identifier)) { continue; } semanticModel = semanticModel ?? await context.GetSemanticModelAsync().ConfigureAwait(false); var eventSymbol = semanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken) as IEventSymbol; if (eventSymbol?.IsStatic != false) { continue; } INamedTypeSymbol containingType = eventSymbol.ContainingType; if (containingType == null) { return; } if (!(eventSymbol.Type is INamedTypeSymbol eventHandlerType)) { continue; } ITypeSymbol eventArgsSymbol = GetEventArgsSymbol(eventHandlerType, semanticModel); if (eventArgsSymbol == null) { continue; } string methodName = "On" + eventSymbol.Name; if (containingType.ContainsMember <IMethodSymbol>( $"On{eventSymbol.Name}", methodSymbol => eventArgsSymbol.Equals(methodSymbol.Parameters.SingleOrDefault(shouldThrow: false)?.Type))) { continue; } methodName = NameGenerator.Default.EnsureUniqueMemberName(methodName, containingType); context.RegisterRefactoring( $"Generate '{methodName}' method", cancellationToken => { return(RefactorAsync( context.Document, eventFieldDeclaration, eventSymbol, eventArgsSymbol, context.SupportsCSharp6, cancellationToken)); }); } }
public static async Task ComputeRefactoringAsync( RefactoringContext context, PropertyDeclarationSyntax property) { AccessorDeclarationSyntax setter = property.Setter(); if (setter == null) { return; } ExpressionSyntax expression = GetExpression(); if (expression == null) { return; } SimpleAssignmentExpressionInfo simpleAssignment = SyntaxInfo.SimpleAssignmentExpressionInfo(expression); if (!simpleAssignment.Success) { return; } if (!simpleAssignment.Left.IsKind(SyntaxKind.IdentifierName)) { return; } if (!(simpleAssignment.Right is IdentifierNameSyntax identifierName)) { return; } if (identifierName.Identifier.ValueText != "value") { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); INamedTypeSymbol containingType = semanticModel .GetDeclaredSymbol(property, context.CancellationToken)? .ContainingType; if (containingType == null) { return; } if (!containingType.Implements(MetadataNames.System_ComponentModel_INotifyPropertyChanged, allInterfaces: true)) { return; } IMethodSymbol methodSymbol = SymbolUtility.FindMethodThatRaisePropertyChanged(containingType, expression.SpanStart, semanticModel); if (methodSymbol == null) { return; } Document document = context.Document; context.RegisterRefactoring( "Notify when property change", ct => RefactorAsync(document, property, methodSymbol.Name, ct), RefactoringIdentifiers.NotifyWhenPropertyChange); ExpressionSyntax GetExpression() { BlockSyntax body = setter.Body; if (body != null) { if (body.Statements.SingleOrDefault(shouldThrow: false) is ExpressionStatementSyntax expressionStatement) { return(expressionStatement.Expression); } } else { return(setter.ExpressionBody?.Expression); } return(null); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, PropertyDeclarationSyntax propertyDeclaration) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplacePropertyWithMethod) && propertyDeclaration.HeaderSpan().Contains(context.Span)) { ReplacePropertyWithMethodRefactoring.ComputeRefactoring(context, propertyDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemovePropertyInitializer) && RemovePropertyInitializerRefactoring.CanRefactor(context, propertyDeclaration)) { context.RegisterRefactoring( "Remove property initializer", cancellationToken => RemovePropertyInitializerRefactoring.RefactorAsync(context.Document, propertyDeclaration, cancellationToken)); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExpandProperty, RefactoringIdentifiers.ExpandPropertyAndAddBackingField) && propertyDeclaration.Span.Contains(context.Span) && ExpandPropertyRefactoring.CanRefactor(propertyDeclaration)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandProperty)) { context.RegisterRefactoring( "Expand property", cancellationToken => ExpandPropertyRefactoring.RefactorAsync(context.Document, propertyDeclaration, cancellationToken)); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandPropertyAndAddBackingField)) { context.RegisterRefactoring( "Expand property and add backing field", cancellationToken => ExpandPropertyAndAddBackingFieldRefactoring.RefactorAsync(context.Document, propertyDeclaration, context.Settings.PrefixFieldIdentifierWithUnderscore, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.NotifyPropertyChanged) && await NotifyPropertyChangedRefactoring.CanRefactorAsync(context, propertyDeclaration).ConfigureAwait(false)) { context.RegisterRefactoring( "Notify property changed", cancellationToken => { return(NotifyPropertyChangedRefactoring.RefactorAsync( context.Document, propertyDeclaration, context.SupportsCSharp6, cancellationToken)); }); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MakeMemberAbstract) && propertyDeclaration.HeaderSpan().Contains(context.Span)) { MakePropertyAbstractRefactoring.ComputeRefactoring(context, propertyDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MakeMemberVirtual) && propertyDeclaration.HeaderSpan().Contains(context.Span)) { MakePropertyVirtualRefactoring.ComputeRefactoring(context, propertyDeclaration); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.CopyDocumentationCommentFromBaseMember) && propertyDeclaration.HeaderSpan().Contains(context.Span)) { await CopyDocumentationCommentFromBaseMemberRefactoring.ComputeRefactoringAsync(context, propertyDeclaration).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenamePropertyAccordingToTypeName)) { TypeSyntax type = propertyDeclaration.Type; if (type != null) { SyntaxToken identifier = propertyDeclaration.Identifier; if (context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(identifier)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); if (typeSymbol?.IsErrorType() == false) { string newName = NameGenerator.CreateName(typeSymbol); if (!string.IsNullOrEmpty(newName)) { string oldName = identifier.ValueText; newName = StringUtility.FirstCharToUpper(newName); if (!string.Equals(oldName, newName, StringComparison.Ordinal)) { ISymbol symbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken); if (await NameGenerator.IsUniqueMemberNameAsync( newName, symbol, context.Solution, cancellationToken: context.CancellationToken).ConfigureAwait(false)) { context.RegisterRefactoring( $"Rename '{oldName}' to '{newName}'", cancellationToken => Renamer.RenameSymbolAsync(context.Solution, symbol, newName, default(OptionSet), cancellationToken)); } } } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddMemberToInterface) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(propertyDeclaration.Identifier)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); AddMemberToInterfaceRefactoring.ComputeRefactoring(context, propertyDeclaration, semanticModel); } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, ConditionalExpressionSyntax conditionalExpression) { ExpressionSyntax expression = conditionalExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent.IsKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement)) { var statement = (StatementSyntax)parent; RegisterRefactoring(context, conditionalExpression, statement); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, statement, recursive: true); } } else if (parent is AssignmentExpressionSyntax assignment) { if (assignment.Parent is ExpressionStatementSyntax expressionStatement) { RegisterRefactoring(context, conditionalExpression, expressionStatement); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, expressionStatement, recursive: true); } } } else { SingleLocalDeclarationStatementInfo localDeclarationInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(expression); if (localDeclarationInfo.Success) { TypeSyntax type = localDeclarationInfo.Type; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!type.IsVar || semanticModel.GetTypeSymbol(type, context.CancellationToken)?.SupportsExplicitDeclaration() == true) { LocalDeclarationStatementSyntax statement = localDeclarationInfo.Statement; RegisterRefactoring(context, conditionalExpression, statement, semanticModel); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, statement, semanticModel, recursive: true); } } } } bool IsRecursive() { return(conditionalExpression .WhenFalse .WalkDownParentheses() .IsKind(SyntaxKind.ConditionalExpression)); } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, BinaryExpressionSyntax binaryExpression) { SyntaxToken operatorToken = binaryExpression.OperatorToken; if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertOperator) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(operatorToken) && InvertOperatorRefactoring.CanBeInverted(operatorToken)) { context.RegisterRefactoring( "Invert operator", cancellationToken => InvertOperatorRefactoring.RefactorAsync(context.Document, operatorToken, cancellationToken), RefactoringIdentifiers.InvertOperator); } if (context.Span.IsEmptyAndContainedInSpan(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertBinaryExpression)) { InvertBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapBinaryOperands)) { SwapBinaryOperandsRefactoring.ComputeRefactoring(context, binaryExpression); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatBinaryExpression)) { FormatBinaryExpressionRefactoring.ComputeRefactorings(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCoalesceExpression) && operatorToken.Span.Contains(context.Span)) { ExpandCoalesceExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExtractExpressionFromCondition, RefactoringIdentifiers.JoinStringExpressions, RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation) && !context.Span.IsEmpty && binaryExpression.IsKind(SyntaxKind.AddExpression, SyntaxKind.LogicalAndExpression, SyntaxKind.LogicalOrExpression)) { ExpressionChain chain = binaryExpression.AsChain(context.Span); ExpressionChain.Enumerator en = chain.GetEnumerator(); if (en.MoveNext() && en.MoveNext()) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExtractExpressionFromCondition)) { ExtractConditionRefactoring.ComputeRefactoring(context, chain); } if (binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(chain, semanticModel, context.CancellationToken); if (concatenationInfo.Success) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenationInfo); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenationInfo); } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceAsWithCast) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(binaryExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (ReplaceAsWithCastAnalysis.IsFixable(binaryExpression, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( ReplaceAsWithCastRefactoring.Title, cancellationToken => ReplaceAsWithCastRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken), RefactoringIdentifiers.ReplaceAsWithCast); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertIsExpression)) { InvertIsExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.Span.IsContainedInSpanOrBetweenSpans(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceEqualsExpressionWithStringEquals)) { await ReplaceEqualsExpressionWithStringEqualsRefactoring.ComputeRefactoringAsync(context, binaryExpression).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrEmpty, RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrWhiteSpace)) { await ReplaceEqualsExpressionRefactoring.ComputeRefactoringsAsync(context, binaryExpression).ConfigureAwait(false); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, IfStatementSyntax ifStatement) { SyntaxToken ifKeyword = ifStatement.IfKeyword; bool isTopmostIf = ifStatement.IsTopmostIf(); if (context.Span.IsEmptyAndContainedInSpan(ifKeyword) || context.Span.IsBetweenSpans(ifStatement)) { if (isTopmostIf && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.UseCoalesceExpressionInsteadOfIf, RefactoringIdentifiers.ConvertIfToConditionalOperator, RefactoringIdentifiers.SimplifyIf)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IfAnalysisOptions options = GetIfAnalysisOptions(context); foreach (IfAnalysis analysis in IfAnalysis.Analyze(ifStatement, options, semanticModel, context.CancellationToken)) { string refactoringId = GetRefactoringIdentifier(analysis); if (context.IsRefactoringEnabled(refactoringId)) { context.RegisterRefactoring( analysis.Title, ct => IfRefactoring.RefactorAsync(context.Document, analysis, ct), refactoringId); } } } if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.InvertIf, RefactoringIdentifiers.InvertIfElse) && context.Span.IsEmptyAndContainedInSpan(ifKeyword)) { InvertIfRefactoring.ComputeRefactoring(context, ifStatement); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ConvertIfToSwitch) && isTopmostIf) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ConvertIfToSwitchRefactoring.ComputeRefactoring(context, ifStatement, semanticModel); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfStatement)) { SplitIfStatementRefactoring.ComputeRefactoring(context, ifStatement); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.MergeIfWithParentIf) && isTopmostIf && context.Span.IsEmptyAndContainedInSpan(ifKeyword)) { MergeIfWithParentIfRefactoring.ComputeRefactoring(context, ifStatement); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertIf) && context.Span.IsEmptyAndContainedInSpan(ifKeyword)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ReduceIfNestingAnalysisResult analysis = ReduceIfNestingAnalysis.Analyze( ifStatement, semanticModel, options: ReduceIfNestingOptions.AllowNestedFix | ReduceIfNestingOptions.AllowIfInsideIfElse | ReduceIfNestingOptions.AllowLoop | ReduceIfNestingOptions.AllowSwitchSection, cancellationToken: context.CancellationToken); if (analysis.Success) { context.RegisterRefactoring( "Invert if", ct => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, false, ct), RefactoringIdentifiers.InvertIf); if (ReduceIfNestingAnalysis.IsFixableRecursively(ifStatement, analysis.JumpKind)) { context.RegisterRefactoring( "Invert if (recursively)", ct => ReduceIfNestingRefactoring.RefactorAsync(context.Document, ifStatement, analysis.JumpKind, true, ct), EquivalenceKey.Join(RefactoringIdentifiers.InvertIf, "Recursive")); } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SplitIfElse) && context.Span.IsEmptyAndContainedInSpan(ifKeyword)) { SplitIfElseRefactoring.ComputeRefactoring(context, ifStatement); } }