public static void ComputeRefactoring(RefactoringContext context, StringConcatenationExpressionInfo concatenationInfo)
        {
            StringConcatenationAnalysis analysis = concatenationInfo.Analyze();

            if (analysis.ContainsNonStringLiteral)
            {
                if (analysis.ContainsStringLiteral || analysis.ContainsInterpolatedString)
                {
                    context.RegisterRefactoring(
                        "Join string expressions",
                        cancellationToken => ToInterpolatedStringAsync(context.Document, concatenationInfo, cancellationToken),
                        RefactoringIdentifiers.JoinStringExpressions);
                }
            }
            else if (analysis.ContainsStringLiteral)
            {
                context.RegisterRefactoring(
                    "Join string literals",
                    cancellationToken => ToStringLiteralAsync(context.Document, concatenationInfo, multiline: false, cancellationToken: cancellationToken),
                    RefactoringIdentifiers.JoinStringExpressions);

                if (concatenationInfo.BinaryExpression
                    .DescendantTrivia(concatenationInfo.Span ?? concatenationInfo.BinaryExpression.Span)
                    .Any(f => f.IsEndOfLineTrivia()))
                {
                    context.RegisterRefactoring(
                        "Join string literals into multiline string literal",
                        cancellationToken => ToStringLiteralAsync(context.Document, concatenationInfo, multiline: true, cancellationToken: cancellationToken),
                        EquivalenceKey.Join(RefactoringIdentifiers.JoinStringExpressions, "Multiline"));
                }
            }
        }
Example #2
0
        public async Task Test_Method_OutParameter()
        {
            await VerifyRefactoringAsync(@"
interface IFoo
{
    void M(object p);
}

class C : IFoo
{
    public void [||]M(object p, out object p2)
    {
        p2 = null;
    }
}
", @"
interface IFoo
{
    void M(object p, out object p2);
}

class C : IFoo
{
    public void M(object p, out object p2)
    {
        p2 = null;
    }
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "M:IFoo.M(System.Object)"));
        }
Example #3
0
        public async Task Test_Method_Parameter_WithDefaultValue()
        {
            await VerifyRefactoringAsync(@"
interface IFoo
{
    void M(object p);
}

class C : IFoo
{
    public void [||]M(object p, int p2 = 1)
    {
        p2 = 0;
    }
}
", @"
interface IFoo
{
    void M(object p, int p2 = 1);
}

class C : IFoo
{
    public void M(object p, int p2 = 1)
    {
        p2 = 0;
    }
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "M:IFoo.M(System.Object)"));
        }
Example #4
0
        public async Task Test_Method_Generic()
        {
            await VerifyRefactoringAsync(@"
interface IFoo<T>
{
    void M(T p);
}

class C : IFoo<string>
{
    public void [||]M(string p, object p2)
    {
    }
}
", @"
interface IFoo<T>
{
    void M(T p, object p2);
}

class C : IFoo<string>
{
    public void M(string p, object p2)
    {
    }
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "M:IFoo`1.M(`0)"));
        }
Example #5
0
        public async Task TestNoRefactoring_VirtualMethodToPrivate()
        {
            await VerifyNoRefactoringAsync(@"
class C
{
    [||]public virtual string M() => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Private)));
        }
Example #6
0
        public async Task TestNoRefactoring_AbstractMethodToPrivate()
        {
            await VerifyNoRefactoringAsync(@"
abstract class C
{
    [||]public abstract string M();
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Private)));
        }
        private static void RegisterRefactoring(RefactoringContext context, SyntaxNode node)
        {
            context.RegisterRefactoring(
                "Add type parameter",
                ct => RefactorAsync(context.Document, node, ConstraintKind.None, ct),
                RefactoringIdentifiers.AddTypeParameter);

            context.RegisterRefactoring(
                "Add type parameter with type constraint",
                ct => RefactorAsync(context.Document, node, ConstraintKind.Type, ct),
                EquivalenceKey.Join(RefactoringIdentifiers.AddTypeParameter, "WithTypeConstraint"));
        }
Example #8
0
        public async Task Test_Method()
        {
            await VerifyRefactoringAsync(@"
class C
{
    [||]public string M() => null;
}
", @"
class C
{
    internal string M() => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Internal)));
        }
Example #9
0
        private static void RegisterAddCastExpressionRefactoring(
            RefactoringContext context,
            ExpressionSyntax expression,
            ITypeSymbol destinationType,
            SemanticModel semanticModel)
        {
            CodeAction codeAction = CodeActionFactory.AddCastExpression(
                context.Document,
                expression,
                destinationType,
                semanticModel,
                equivalenceKey: EquivalenceKey.Join(RefactoringIdentifiers.AddCastExpression, SymbolDisplay.ToDisplayString(destinationType)));

            context.RegisterRefactoring(codeAction);
        }
Example #10
0
        public async Task Test_MultipleDeclarations_AnyImplicit()
        {
            await VerifyRefactoringAsync(@"
class C
{
[|    private object M1() => null;
    object M2() => null;|]
}
", @"
class C
{
    private object M1() => null;
    private object M2() => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Private)));
        }
Example #11
0
        public async Task Test_MultipleDeclarations()
        {
            await VerifyRefactoringAsync(@"
class C
{
[|    public override string ToString() => null;
    internal string M() => null;|]
}
", @"
class C
{
    public override string ToString() => null;
    public string M() => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Public)));
        }
        private static void RegisterAddCastExpressionRefactoring(
            RefactoringContext context,
            ExpressionSyntax expression,
            ITypeSymbol destinationType,
            SemanticModel semanticModel)
        {
            string typeDisplayString = SymbolDisplay.ToDisplayString(destinationType, SymbolDisplayFormats.Default);

            context.RegisterRefactoring(
                $"Cast to '{typeDisplayString}'",
                cancellationToken =>
            {
                return(AddCastExpressionRefactoring.RefactorAsync(
                           context.Document,
                           expression,
                           destinationType,
                           semanticModel,
                           cancellationToken));
            },
                EquivalenceKey.Join(RefactoringIdentifiers.AddCastExpression, typeDisplayString));
        }
Example #13
0
        public async Task Test_OverrideMethod()
        {
            await VerifyRefactoringAsync(@"
class B
{
    public virtual string M() => null;
}
class C : B
{
    [||]public override string M() => null;
}
", @"
class B
{
    internal virtual string M() => null;
}
class C : B
{
    internal override string M() => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, nameof(Accessibility.Internal)));
        }
Example #14
0
        public async Task Test_ToMultilineStringLiteral()
        {
            await VerifyRefactoringAsync(@"
class C
{
    void M()
    {
        string s = null;
        s = [|""\r\n"" +
"" ""|];
    }
}
", @"
class C
{
    void M()
    {
        string s = null;
        s = @""
 "";
    }
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "Multiline"));
        }
Example #15
0
        public async Task Test_Indexer()
        {
            await VerifyRefactoringAsync(@"
interface IFoo
{
    object this[object p] { get; }
}

class C : IFoo
{
    public object [||]this[object p, object p2] => null;
}
", @"
interface IFoo
{
    object this[object p, object p2] { get; }
}

class C : IFoo
{
    public object this[object p, object p2] => null;
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "P:IFoo.Item(System.Object)"));
        }
Example #16
0
        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.UseConditionalExpressionInsteadOfIf,
                        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) &&
                    isTopmostIf &&
                    context.Span.IsEmptyAndContainedInSpan(ifKeyword))
                {
                    InvertIfRefactoring.ComputeRefactoring(context, ifStatement);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceIfWithSwitch) &&
                    isTopmostIf)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ReplaceIfWithSwitchRefactoring.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);
            }
        }
        public static void ComputeRefactoring(RefactoringContext context, MemberDeclarationSyntax member)
        {
            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(member.Parent);

            if (!info.Success)
            {
                return;
            }

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            if (members.Count <= 1)
            {
                return;
            }

            int index = IndexOfMemberToSwap(member, members, context.Span);

            if (index == -1)
            {
                return;
            }

            SyntaxTree tree = member.SyntaxTree;

            FileLinePositionSpan fileLinePositionSpan = tree.GetLineSpan(context.Span, context.CancellationToken);

            int startLine = fileLinePositionSpan.StartLine();
            int endLine   = fileLinePositionSpan.EndLine();

            if (startLine <= tree.GetEndLine(members[index].TrimmedSpan(), context.CancellationToken))
            {
                return;
            }

            if (endLine >= tree.GetStartLine(members[index + 1].TrimmedSpan(), context.CancellationToken))
            {
                return;
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveMemberDeclarations))
            {
                context.RegisterRefactoring(
                    "Remove members above",
                    ct => ReplaceMembersAsync(context.Document, info, members.Skip(index + 1), ct),
                    EquivalenceKey.Join(RefactoringIdentifiers.RemoveMemberDeclarations, "Above"));

                context.RegisterRefactoring(
                    "Remove members below",
                    ct => ReplaceMembersAsync(context.Document, info, members.Take(index + 1), ct),
                    EquivalenceKey.Join(RefactoringIdentifiers.RemoveMemberDeclarations, "Below"));
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapMemberDeclarations))
            {
                context.RegisterRefactoring(
                    "Swap members",
                    ct => SwapMembersAsync(context.Document, info, index, ct),
                    RefactoringIdentifiers.SwapMemberDeclarations);
            }
        }
Example #18
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, LiteralExpressionSyntax literalExpression)
        {
            StringLiteralExpressionInfo info = SyntaxInfo.StringLiteralExpressionInfo(literalExpression);

            Debug.Assert(info.Success);

            if (!info.Success)
            {
                return;
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.InsertStringInterpolation) &&
                context.SupportsCSharp6 &&
                context.Span.End < literalExpression.Span.End &&
                !CSharpUtility.IsPartOfExpressionThatMustBeConstant(literalExpression))
            {
                int startIndex = GetStartIndex(info, context.Span);

                if (startIndex != -1)
                {
                    context.RegisterRefactoring(
                        "Insert interpolation",
                        cancellationToken =>
                    {
                        return(ReplaceWithInterpolatedStringAsync(
                                   context.Document,
                                   literalExpression,
                                   startIndex,
                                   context.Span.Length,
                                   addNameOf: false,
                                   cancellationToken: cancellationToken));
                    },
                        RefactoringIdentifiers.InsertStringInterpolation);

                    if (!context.Span.IsEmpty)
                    {
                        SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                        string name = StringLiteralParser.Parse(literalExpression.Token.Text, startIndex, context.Span.Length, info.IsVerbatim, isInterpolatedText: false);

                        foreach (ISymbol symbol in semanticModel.LookupSymbols(literalExpression.SpanStart))
                        {
                            if (string.Equals(name, symbol.MetadataName, StringComparison.Ordinal))
                            {
                                context.RegisterRefactoring(
                                    "Insert interpolation with nameof",
                                    cancellationToken =>
                                {
                                    return(ReplaceWithInterpolatedStringAsync(
                                               context.Document,
                                               literalExpression,
                                               startIndex,
                                               context.Span.Length,
                                               addNameOf: true,
                                               cancellationToken: cancellationToken));
                                },
                                    EquivalenceKey.Join(RefactoringIdentifiers.InsertStringInterpolation, "WithNameOf"));

                                break;
                            }
                        }
                    }
                }
            }

            if (context.Span.IsBetweenSpans(literalExpression))
            {
                if (info.IsVerbatim)
                {
                    if (info.ContainsEscapeSequence)
                    {
                        if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceVerbatimStringLiteralWithRegularStringLiteral))
                        {
                            context.RegisterRefactoring(
                                "Replace verbatim string literal with regular string literal",
                                ct => ReplaceWithRegularStringLiteralAsync(context.Document, literalExpression, ct),
                                RefactoringIdentifiers.ReplaceVerbatimStringLiteralWithRegularStringLiteral);
                        }

                        if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceVerbatimStringLiteralWithRegularStringLiterals) &&
                            info.ContainsLinefeed)
                        {
                            context.RegisterRefactoring(
                                "Replace verbatim string literal with regular string literals",
                                ct => ReplaceWithRegularStringLiteralsAsync(context.Document, literalExpression, ct),
                                RefactoringIdentifiers.ReplaceVerbatimStringLiteralWithRegularStringLiterals);
                        }
                    }
                }
                else if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceRegularStringLiteralWithVerbatimStringLiteral) &&
                         info.ContainsEscapeSequence)
                {
                    context.RegisterRefactoring(
                        "Replace regular string literal with verbatim string literal",
                        ct => ReplaceWithVerbatimStringLiteralAsync(context.Document, literalExpression, ct),
                        RefactoringIdentifiers.ReplaceRegularStringLiteralWithVerbatimStringLiteral);
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringEmptyInsteadOfEmptyStringLiteral) &&
                CanReplaceWithStringEmpty(literalExpression))
            {
                context.RegisterRefactoring(
                    "Replace \"\" with 'string.Empty'",
                    ct => ReplaceWithStringEmptyAsync(context.Document, literalExpression, ct),
                    RefactoringIdentifiers.UseStringEmptyInsteadOfEmptyStringLiteral);
            }
        }
Example #19
0
        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))
            {
                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),
                                cancellationToken => RefactorAsync(context.Solution, memberDeclarations, accessibility, cancellationToken),
                                EquivalenceKey.Join(RefactoringIdentifiers.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),
                            cancellationToken => RefactorAsync(context.Solution, symbol, accessibility, cancellationToken),
                            EquivalenceKey.Join(RefactoringIdentifiers.ChangeAccessibility, accessibility.ToString()));
                    }
                }
                else if (SyntaxAccessibility.IsValidAccessibility(node, accessibility))
                {
                    context.RegisterRefactoring(
                        GetTitle(accessibility),
                        cancellationToken => RefactorAsync(context.Document, node, accessibility, cancellationToken),
                        EquivalenceKey.Join(RefactoringIdentifiers.ChangeAccessibility, accessibility.ToString()));
                }
            }

            ISymbol GetBaseSymbolOrDefault(SemanticModel semanticModel, CancellationToken cancellationToken)
            {
                if (modifiersInfo.GetKinds().Any(ModifierKinds.AbstractVirtualOverride))
                {
                    return(ChangeAccessibilityRefactoring.GetBaseSymbolOrDefault(node, semanticModel, cancellationToken));
                }

                return(null);
            }
        }
Example #20
0
        public async Task ComputeRefactoringsAsync(RefactoringContext context, TNode node)
        {
            if (!ValidateNode(node, context.Span))
            {
                return;
            }

            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            TSymbol symbol = GetMemberSymbol(node, semanticModel, context.CancellationToken);

            if (EqualityComparer <TSymbol> .Default.Equals(symbol, default(TSymbol)))
            {
                return;
            }

            TDeclaration declaration = await GetMemberDeclarationAsync(symbol, context.CancellationToken).ConfigureAwait(false);

            if (declaration == null)
            {
                return;
            }

            for (SyntaxNode parent = node.Parent; parent != null; parent = parent.Parent)
            {
                if (object.ReferenceEquals(declaration, parent))
                {
                    return;
                }
            }

            (ExpressionSyntax expression, SyntaxList <StatementSyntax> statements) = GetExpressionOrStatements(declaration);

            SyntaxNode nodeIncludingConditionalAccess = node.WalkUp(SyntaxKind.ConditionalAccessExpression);

            if (expression != null ||
                (statements.Any() && nodeIncludingConditionalAccess.IsParentKind(SyntaxKind.ExpressionStatement)))
            {
                ImmutableArray <ParameterInfo> parameterInfos = GetParameterInfos(node, symbol);

                if (parameterInfos.IsDefault)
                {
                    return;
                }

                INamedTypeSymbol enclosingType = semanticModel.GetEnclosingNamedType(node.SpanStart, context.CancellationToken);

                SemanticModel declarationSemanticModel = (node.SyntaxTree == declaration.SyntaxTree)
                    ? semanticModel
                    : await context.Solution.GetDocument(declaration.SyntaxTree).GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

                InlineRefactoring <TNode, TDeclaration, TSymbol> refactoring = CreateRefactoring(context.Document, nodeIncludingConditionalAccess, enclosingType, symbol, declaration, parameterInfos, semanticModel, declarationSemanticModel, context.CancellationToken);

                string title = CSharpFacts.GetTitle(declaration);

                if (expression != null)
                {
                    context.RegisterRefactoring($"Inline {title}", cancellationToken => refactoring.InlineAsync(nodeIncludingConditionalAccess, expression, cancellationToken), GetEquivalenceKey());

                    context.RegisterRefactoring($"Inline and remove {title}", cancellationToken => refactoring.InlineAndRemoveAsync(nodeIncludingConditionalAccess, expression, cancellationToken), EquivalenceKey.Join(GetEquivalenceKey(), "Remove"));
                }
                else
                {
                    var expressionStatement = (ExpressionStatementSyntax)nodeIncludingConditionalAccess.Parent;

                    context.RegisterRefactoring($"Inline {title}", cancellationToken => refactoring.InlineAsync(expressionStatement, statements, cancellationToken), GetEquivalenceKey());

                    context.RegisterRefactoring($"Inline and remove {title}", cancellationToken => refactoring.InlineAndRemoveAsync(expressionStatement, statements, cancellationToken), EquivalenceKey.Join(GetEquivalenceKey(), "Remove"));
                }
            }
        }
Example #21
0
        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);
            }
        }
Example #22
0
        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));
                        }
                    }
                }
            }
        }
Example #23
0
        public async Task Test_If_MultipleStatementsInIf_Recursive()
        {
            await VerifyRefactoringAsync(@"
class C
{
    void M(bool f1 = false, bool f2 = false, bool f3 = false)
    {
        [||]if (f1)
        {
            M1();
            return;
        }

        if (f2)
        {
            M2();
            return;
        }

        if (f3)
        {
            M3();
            return;
        }

        M();
    }

    void M1() => M();
    void M2() => M();
    void M3() => M();
}
", @"
class C
{
    void M(bool f1 = false, bool f2 = false, bool f3 = false)
    {
        if (!f1)
        {
            if (!f2)
            {
                if (!f3)
                {
                    M();
                }
                else
                {
                    M3();
                }
            }
            else
            {
                M2();
            }
        }
        else
        {
            M1();
        }
    }

    void M1() => M();
    void M2() => M();
    void M3() => M();
}
", equivalenceKey : EquivalenceKey.Join(RefactoringId, "Recursive"));
        }