예제 #1
0
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                node = (BlockSyntax)base.VisitBlock(node);

                SyntaxList <StatementSyntax> statements = node.Statements;

                var ifStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)) as IfStatementSyntax;

                if (ifStatement != null &&
                    IsFixable(ifStatement) &&
                    ((BlockSyntax)ifStatement.Parent).Statements.IsLastStatement(ifStatement, skipLocalFunction: true))
                {
                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(block.WithStatements(SingletonList(_jumpStatement)))
                                                       .WithFormatterAnnotation();

                    int index = statements.IndexOf(ifStatement);

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
예제 #2
0
        private static SyntaxNode ToMultiLine(SyntaxNode node, SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses)
        {
            TypeParameterConstraintClauseSyntax first = constraintClauses.First();

            SyntaxToken previousToken = node.FindToken(first.FullSpan.Start - 1);

            node = node.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(NewLine())));

            SyntaxTriviaList leadingTrivia = node
                                             .FindToken(node.SpanStart)
                                             .LeadingTrivia;

            SyntaxTriviaList trivia = IncreaseIndentation(leadingTrivia.LastOrDefault());

            int count = constraintClauses.Count;

            for (int i = 0; i < count; i++)
            {
                TypeParameterConstraintClauseSyntax newNode = constraintClauses[i].WithLeadingTrivia(trivia);

                if (i < count - 1)
                {
                    newNode = newNode.WithTrailingTrivia(NewLine());
                }

                constraintClauses = constraintClauses.ReplaceAt(i, newNode);
            }

            return(WithConstraintClauses(node, constraintClauses));
        }
        private static GenericInfo ToMultiLine(GenericInfo info)
        {
            SyntaxNode declaration = info.Node;
            SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = info.ConstraintClauses;

            TypeParameterConstraintClauseSyntax first = constraintClauses.First();

            SyntaxToken previousToken = declaration.FindToken(first.FullSpan.Start - 1);

            declaration = declaration.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(NewLine())));

            SyntaxTriviaList leadingTrivia = declaration
                                             .FindToken(declaration.SpanStart)
                                             .LeadingTrivia;

            SyntaxTriviaList trivia = IncreaseIndentation(leadingTrivia.LastOrDefault());

            int count = constraintClauses.Count;

            for (int i = 0; i < count; i++)
            {
                TypeParameterConstraintClauseSyntax newNode = constraintClauses[i].WithLeadingTrivia(trivia);

                if (i < count - 1)
                {
                    newNode = newNode.WithTrailingTrivia(NewLine());
                }

                constraintClauses = constraintClauses.ReplaceAt(i, newNode);
            }

            return(SyntaxInfo.GenericInfo(declaration).WithConstraintClauses(constraintClauses));
        }
        private static GenericInfo ToSingleLine(GenericInfo info)
        {
            SyntaxNode declaration = info.Node;

            SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses = info.ConstraintClauses;

            SyntaxToken previousToken = declaration.FindToken(constraintClauses.First().FullSpan.Start - 1);

            declaration = declaration.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(ElasticSpace)));

            int count = constraintClauses.Count;

            for (int i = 0; i < count; i++)
            {
                TypeParameterConstraintClauseSyntax constraintClause = constraintClauses[i];

                TextSpan?span = null;

                if (i == count - 1)
                {
                    span = TextSpan.FromBounds(constraintClause.FullSpan.Start, constraintClause.Span.End);
                }

                TypeParameterConstraintClauseSyntax newNode = constraintClause
                                                              .RemoveWhitespace(span)
                                                              .WithFormatterAnnotation();

                constraintClauses = constraintClauses.ReplaceAt(i, newNode);
            }

            return(SyntaxInfo.GenericInfo(declaration).WithConstraintClauses(constraintClauses));
        }
        private static SyntaxList <TNode> Swap <TNode>(
            SyntaxList <TNode> list,
            int index1,
            int index2) where TNode : SyntaxNode
        {
            TNode first  = list[index1];
            TNode second = list[index2];

            SyntaxTriviaList firstLeading  = first.GetLeadingTrivia();
            SyntaxTriviaList secondLeading = second.GetLeadingTrivia();

            if (firstLeading.IsEmptyOrWhitespace() &&
                secondLeading.IsEmptyOrWhitespace())
            {
                first  = first.WithLeadingTrivia(secondLeading);
                second = second.WithLeadingTrivia(firstLeading);
            }

            SyntaxTriviaList firstTrailing  = first.GetTrailingTrivia();
            SyntaxTriviaList secondTrailing = second.GetTrailingTrivia();

            if (firstTrailing.IsEmptyOrWhitespace() &&
                secondTrailing.IsEmptyOrWhitespace())
            {
                first  = first.WithTrailingTrivia(secondTrailing);
                second = second.WithTrailingTrivia(firstTrailing);
            }

            return(list
                   .ReplaceAt(index1, second)
                   .ReplaceAt(index2, first));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            SwitchSectionSyntax section,
            SyntaxListSelection <SwitchLabelSyntax> selectedLabels,
            CancellationToken cancellationToken)
        {
            SyntaxList <SwitchLabelSyntax> labels = section.Labels;

            int lastIndex = selectedLabels.LastIndex;

            if (selectedLabels.Last() == labels.Last())
            {
                lastIndex--;
            }

            var switchStatement = (SwitchStatementSyntax)section.Parent;

            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

            int index = sections.IndexOf(section);

            SyntaxList <SwitchSectionSyntax> newSections = sections
                                                           .ReplaceAt(index, section.RemoveNodes(labels.Take(lastIndex + 1), SyntaxRemoveOptions.KeepNoTrivia))
                                                           .InsertRange(index, CreateSwitchSections(section, selectedLabels, lastIndex));

            SwitchStatementSyntax newSwitchStatement = switchStatement.WithSections(newSections);

            return(document.ReplaceNodeAsync(switchStatement, newSwitchStatement, cancellationToken));
        }
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                _block = node;

                if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement &&
                    IsFixable(ifStatement))
                {
                    SyntaxList <StatementSyntax> statements = node.Statements;

                    int index = statements.IndexOf(ifStatement);

                    ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);

                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(block.WithStatements(SingletonList(_jumpStatement)))
                                                       .WithFormatterAnnotation();

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
예제 #8
0
        private static SyntaxNode ToSingleLine(SyntaxNode node, SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses)
        {
            SyntaxToken previousToken = node.FindToken(constraintClauses.First().FullSpan.Start - 1);

            node = node.ReplaceToken(previousToken, previousToken.WithTrailingTrivia(TriviaList(ElasticSpace)));

            int count = constraintClauses.Count;

            for (int i = 0; i < count; i++)
            {
                TypeParameterConstraintClauseSyntax constraintClause = constraintClauses[i];

                TextSpan?span = null;

                if (i == count - 1)
                {
                    span = TextSpan.FromBounds(constraintClause.FullSpan.Start, constraintClause.Span.End);
                }

                TypeParameterConstraintClauseSyntax newNode = constraintClause
                                                              .RemoveWhitespaceOrEndOfLineTrivia(span)
                                                              .WithFormatterAnnotation();

                constraintClauses = constraintClauses.ReplaceAt(i, newNode);
            }

            return(WithConstraintClauses(node, constraintClauses));
        }
예제 #9
0
        public static Task <Document> RefactorAsync(
            Document document,
            AssignmentExpressionSyntax assignmentExpression,
            CancellationToken cancellationToken)
        {
            var statement = (StatementSyntax)assignmentExpression.Parent;

            StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            statements = statements.RemoveAt(index);

            var returnStatement = (ReturnStatementSyntax)statement.NextStatementOrDefault();

            IEnumerable <SyntaxTrivia> trivia = statementsInfo
                                                .Node
                                                .DescendantTrivia(TextSpan.FromBounds(statement.SpanStart, returnStatement.SpanStart))
                                                .Where(f => !f.IsWhitespaceOrEndOfLineTrivia());

            trivia = statement
                     .GetLeadingTrivia()
                     .Concat(trivia);

            returnStatement = returnStatement
                              .WithExpression(assignmentExpression.Right.WithTriviaFrom(returnStatement.Expression))
                              .WithLeadingTrivia(trivia);

            statements = statements.ReplaceAt(index, returnStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, statements, cancellationToken));
        }
예제 #10
0
        public static async Task <Document> RefactorAsync(
            Document document,
            LockStatementSyntax lockStatement,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (lockStatement == null)
            {
                throw new ArgumentNullException(nameof(lockStatement));
            }

            MemberDeclarationSyntax containingMember = lockStatement.FirstAncestorOrSelf <MemberDeclarationSyntax>();

            if (containingMember != null)
            {
                var containingDeclaration = (MemberDeclarationSyntax)containingMember
                                            .Ancestors()
                                            .FirstOrDefault(f => f.IsKind(
                                                                SyntaxKind.ClassDeclaration,
                                                                SyntaxKind.InterfaceDeclaration,
                                                                SyntaxKind.StructDeclaration));

                if (containingDeclaration != null)
                {
                    SyntaxList <MemberDeclarationSyntax> members = containingDeclaration.GetMembers();

                    int index = members.IndexOf(containingMember);

                    SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    string name = Identifier.EnsureUniqueMemberName(LockObjectName, lockStatement.Expression.SpanStart, semanticModel, cancellationToken);

                    LockStatementSyntax newLockStatement = lockStatement
                                                           .WithExpression(IdentifierName(Identifier(name).WithRenameAnnotation()));

                    MemberDeclarationSyntax newContainingMember = containingMember
                                                                  .ReplaceNode(lockStatement, newLockStatement);

                    bool isStatic = containingMember.GetModifiers().Contains(SyntaxKind.StaticKeyword);

                    FieldDeclarationSyntax field = CreateFieldDeclaration(name, isStatic).WithFormatterAnnotation();

                    SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(index, newContainingMember);

                    newMembers = Inserter.InsertMember(newMembers, field);

                    MemberDeclarationSyntax newNode = containingDeclaration.SetMembers(newMembers);

                    return(await document.ReplaceNodeAsync(containingDeclaration, newNode, cancellationToken).ConfigureAwait(false));
                }
            }

            return(document);
        }
예제 #11
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            string fieldName = StringUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            fieldName = NameGenerator.Default.EnsureUniqueMemberName(
                fieldName,
                semanticModel,
                propertyDeclaration.SpanStart,
                cancellationToken: cancellationToken);

            FieldDeclarationSyntax fieldDeclaration = CreateBackingField(propertyDeclaration, fieldName)
                                                      .WithFormatterAnnotation();

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandPropertyAndAddBackingField(propertyDeclaration, fieldName);

            newPropertyDeclaration = newPropertyDeclaration
                                     .WithModifiers(newPropertyDeclaration.Modifiers.Replace(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword))
                                     .WithTriviaFrom(propertyDeclaration)
                                     .WithFormatterAnnotation();

            MemberDeclarationListInfo info = SyntaxInfo.MemberDeclarationListInfo(propertyDeclaration.Parent);

            SyntaxList <MemberDeclarationSyntax> members = info.Members;

            int propertyIndex = info.IndexOf(propertyDeclaration);

            if (IsReadOnlyAutoProperty(propertyDeclaration))
            {
                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

                ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(propertySymbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                IdentifierNameSyntax newNode = IdentifierName(fieldName);

                MemberDeclarationListInfo newInfo = SyntaxInfo.MemberDeclarationListInfo(info.Parent.ReplaceNodes(nodes, (f, _) => newNode.WithTriviaFrom(f)));

                members = newInfo.Members;
            }

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(propertyIndex, newPropertyDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, fieldDeclaration);

            return(await document.ReplaceMembersAsync(info, newMembers, cancellationToken).ConfigureAwait(false));
        }
예제 #12
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            string fieldName = StringUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            fieldName = NameGenerator.Default.EnsureUniqueMemberName(
                fieldName,
                semanticModel,
                propertyDeclaration.SpanStart,
                cancellationToken: cancellationToken);

            FieldDeclarationSyntax fieldDeclaration = CreateBackingField(propertyDeclaration, fieldName)
                                                      .WithFormatterAnnotation();

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandPropertyAndAddBackingField(propertyDeclaration, fieldName);

            newPropertyDeclaration = ExpandPropertyRefactoring.ReplaceAbstractWithVirtual(newPropertyDeclaration);

            newPropertyDeclaration = newPropertyDeclaration
                                     .WithTriviaFrom(propertyDeclaration)
                                     .WithFormatterAnnotation();

            var parentMember = (MemberDeclarationSyntax)propertyDeclaration.Parent;
            SyntaxList <MemberDeclarationSyntax> members = parentMember.GetMembers();

            int propertyIndex = members.IndexOf(propertyDeclaration);

            if (IsReadOnlyAutoProperty(propertyDeclaration))
            {
                IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

                ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(propertySymbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                IdentifierNameSyntax newNode = IdentifierName(fieldName);

                MemberDeclarationSyntax newParentMember = parentMember.ReplaceNodes(nodes, (f, g) => newNode.WithTriviaFrom(f));

                members = newParentMember.GetMembers();
            }

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(propertyIndex, newPropertyDeclaration);

            newMembers = newMembers.InsertMember(fieldDeclaration, MemberDeclarationComparer.ByKind);

            return(await document.ReplaceNodeAsync(parentMember, parentMember.WithMembers(newMembers), cancellationToken).ConfigureAwait(false));
        }
예제 #13
0
        public static async Task <Document> RefactorAsync(
            Document document,
            LockStatementSyntax lockStatement,
            CancellationToken cancellationToken = default)
        {
            MemberDeclarationSyntax containingMember = lockStatement.FirstAncestor <MemberDeclarationSyntax>();

            Debug.Assert(containingMember != null);

            if (containingMember == null)
            {
                return(document);
            }

            TypeDeclarationSyntax containingType = containingMember.FirstAncestor <TypeDeclarationSyntax>();

            Debug.Assert(containingType != null);

            if (containingType == null)
            {
                return(document);
            }

            SyntaxList <MemberDeclarationSyntax> members = containingType.Members;

            int index = members.IndexOf(containingMember);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            string name = NameGenerator.Default.EnsureUniqueLocalName(
                LockObjectName,
                semanticModel,
                lockStatement.Expression.SpanStart,
                cancellationToken: cancellationToken);

            LockStatementSyntax newLockStatement = lockStatement
                                                   .WithExpression(IdentifierName(Identifier(name).WithRenameAnnotation()));

            MemberDeclarationSyntax newContainingMember = containingMember
                                                          .ReplaceNode(lockStatement, newLockStatement);

            bool isStatic = SyntaxInfo.ModifierListInfo(containingMember).IsStatic;

            FieldDeclarationSyntax field = CreateFieldDeclaration(name, isStatic).WithFormatterAnnotation();

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(index, newContainingMember);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, field);

            MemberDeclarationSyntax newNode = containingType.WithMembers(newMembers);

            return(await document.ReplaceNodeAsync(containingType, newNode, cancellationToken).ConfigureAwait(false));
        }
예제 #14
0
        public static Task <Document> RefactorAsync(
            Document document,
            UnsafeStatementSyntax unsafeStatement,
            CancellationToken cancellationToken)
        {
            SyntaxToken keyword = unsafeStatement.UnsafeKeyword;

            BlockSyntax block = unsafeStatement.Block;

            SyntaxToken openBrace  = block.OpenBraceToken;
            SyntaxToken closeBrace = block.CloseBraceToken;

            SyntaxList <StatementSyntax> statements = block.Statements;

            StatementSyntax firstStatement = statements.First();

            IEnumerable <SyntaxTrivia> leadingTrivia = keyword
                                                       .TrailingTrivia.EmptyIfWhitespace()
                                                       .Concat(openBrace.LeadingTrivia.EmptyIfWhitespace())
                                                       .Concat(openBrace.TrailingTrivia.EmptyIfWhitespace())
                                                       .Concat(firstStatement.GetLeadingTrivia().EmptyIfWhitespace());

            leadingTrivia = keyword.LeadingTrivia.AddRange(leadingTrivia);

            statements = statements.ReplaceAt(0, firstStatement.WithLeadingTrivia(leadingTrivia));

            StatementSyntax lastStatement = statements.Last();

            IEnumerable <SyntaxTrivia> trailingTrivia = lastStatement
                                                        .GetTrailingTrivia().EmptyIfWhitespace()
                                                        .Concat(closeBrace.LeadingTrivia.EmptyIfWhitespace())
                                                        .Concat(closeBrace.TrailingTrivia.EmptyIfWhitespace());

            trailingTrivia = closeBrace.TrailingTrivia.InsertRange(0, trailingTrivia);

            statements = statements.ReplaceAt(statements.Count - 1, lastStatement.WithTrailingTrivia(trailingTrivia));

            return(document.ReplaceNodeAsync(unsafeStatement, statements, cancellationToken));
        }
예제 #15
0
        private static Task <Document> RemoveBracesAsync(
            Document document,
            BlockSyntax block,
            CancellationToken cancellationToken)
        {
            var switchSection = (SwitchSectionSyntax)block.Parent;

            SyntaxList <StatementSyntax> statements = block.Statements;

            SyntaxTriviaList leadingTrivia = block.OpenBraceToken.LeadingTrivia;

            leadingTrivia = AddTriviaIfNecessary(leadingTrivia, block.OpenBraceToken.TrailingTrivia);
            leadingTrivia = AddTriviaIfNecessary(leadingTrivia, statements[0].GetLeadingTrivia());

            SyntaxTriviaList trailingTrivia = statements.Last().GetTrailingTrivia();

            trailingTrivia = AddTriviaIfNecessary(trailingTrivia, block.CloseBraceToken.LeadingTrivia);
            trailingTrivia = AddTriviaIfNecessary(trailingTrivia, block.CloseBraceToken.TrailingTrivia);

            trailingTrivia = trailingTrivia.TrimEnd().Add(CSharpFactory.NewLine());

            var switchStatement = (SwitchStatementSyntax)switchSection.Parent;

            if (!switchStatement.Sections.IsLast(switchSection))
            {
                trailingTrivia = trailingTrivia.Add(CSharpFactory.NewLine());
            }

            SyntaxList <StatementSyntax> newStatements = statements.ReplaceAt(0, statements[0].WithLeadingTrivia(leadingTrivia));

            newStatements = newStatements.ReplaceAt(newStatements.Count - 1, newStatements.Last().WithTrailingTrivia(trailingTrivia));

            SwitchSectionSyntax newSwitchSection = switchSection
                                                   .WithStatements(newStatements)
                                                   .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(switchSection, newSwitchSection, cancellationToken));

            SyntaxTriviaList AddTriviaIfNecessary(SyntaxTriviaList trivia, SyntaxTriviaList triviaToAdd)
            {
                if (triviaToAdd.Any(f => f.IsKind(SyntaxKind.SingleLineCommentTrivia)))
                {
                    trivia = trivia.AddRange(triviaToAdd);
                }

                return(trivia);
            }
        }
예제 #16
0
        public static Task <Document> RefactorAsync(
            Document document,
            UnsafeStatementSyntax unsafeStatement,
            SyntaxNode containingNode,
            CancellationToken cancellationToken)
        {
            SyntaxToken keyword = unsafeStatement.UnsafeKeyword;

            BlockSyntax block = unsafeStatement.Block;

            SyntaxList <StatementSyntax> statements = block.Statements;

            SyntaxNode newNode = null;

            int count = statements.Count;

            if (count == 0)
            {
                newNode = containingNode.RemoveNode(unsafeStatement);
            }
            else
            {
                StatementSyntax first = statements.First();
                StatementSyntax last  = statements.Last();

                SyntaxTriviaList leadingTrivia = keyword.LeadingTrivia
                                                 .AddRange(keyword.TrailingTrivia.EmptyIfWhitespace())
                                                 .AddRange(block.GetLeadingTrivia().EmptyIfWhitespace())
                                                 .AddRange(block.OpenBraceToken.TrailingTrivia.EmptyIfWhitespace())
                                                 .AddRange(first.GetLeadingTrivia().EmptyIfWhitespace());

                SyntaxTriviaList trailingTrivia = last.GetTrailingTrivia().EmptyIfWhitespace()
                                                  .AddRange(block.CloseBraceToken.LeadingTrivia.EmptyIfWhitespace())
                                                  .AddRange(block.GetTrailingTrivia());

                statements = statements
                             .ReplaceAt(0, first.WithLeadingTrivia(leadingTrivia))
                             .ReplaceAt(count - 1, last.WithTrailingTrivia(trailingTrivia));

                newNode = containingNode.ReplaceNode(unsafeStatement, statements.Select(f => f.WithFormatterAnnotation()));
            }

            newNode = newNode.InsertModifier(SyntaxKind.UnsafeKeyword);

            return(document.ReplaceNodeAsync(containingNode, newNode, cancellationToken));
        }
            public override SyntaxNode VisitBlock(BlockSyntax node)
            {
                _block = node;

                if (node.LastStatementOrDefault(skipLocalFunction: true) is IfStatementSyntax ifStatement &&
                    IsFixable(ifStatement))
                {
                    SyntaxList <StatementSyntax> statements = node.Statements;

                    int index = statements.IndexOf(ifStatement);

                    if (_recursive)
                    {
                        ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);
                    }

                    var block = (BlockSyntax)ifStatement.Statement;

                    ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition);

                    BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement));

                    if (!block
                        .Statements
                        .First()
                        .GetLeadingTrivia()
                        .Any(f => f.IsEndOfLineTrivia()))
                    {
                        newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine()));
                    }

                    IfStatementSyntax newIfStatement = ifStatement
                                                       .WithCondition(newCondition)
                                                       .WithStatement(newBlock)
                                                       .WithFormatterAnnotation();

                    SyntaxList <StatementSyntax> newStatements = statements
                                                                 .ReplaceAt(index, newIfStatement)
                                                                 .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                    node = node.WithStatements(newStatements);
                }

                return(node);
            }
            private SyntaxNode Rewrite(StatementsInfo statementsInfo, IfStatementSyntax ifStatement)
            {
                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(ifStatement);

                ExpressionSyntax newCondition = LogicalNegationHelper.LogicallyNegate(ifStatement.Condition, _semanticModel, _cancellationToken);

                if (_recursive)
                {
                    ifStatement = (IfStatementSyntax)VisitIfStatement(ifStatement);
                }

                var block = (BlockSyntax)ifStatement.Statement;

                BlockSyntax newBlock = block.WithStatements(SingletonList(_jumpStatement));

                if (!block
                    .Statements
                    .First()
                    .GetLeadingTrivia()
                    .Any(f => f.IsEndOfLineTrivia()))
                {
                    newBlock = newBlock.WithCloseBraceToken(newBlock.CloseBraceToken.AppendToTrailingTrivia(NewLine()));
                }

                IfStatementSyntax newIfStatement = ifStatement
                                                   .WithCondition(newCondition)
                                                   .WithStatement(newBlock)
                                                   .WithFormatterAnnotation();

                if (statements.Last().Kind().IsJumpStatementOrYieldBreakStatement() &&
                    block.Statements.Last().Kind().IsJumpStatementOrYieldBreakStatement())
                {
                    statements = statements.RemoveAt(statements.Count - 1);
                }

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .ReplaceAt(index, newIfStatement)
                                                             .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation()));

                return(statementsInfo.WithStatements(newStatements).Node);
            }
예제 #19
0
        private static Task <Document> RemoveRedundantAssignmentBeforeReturnStatementAsync(
            Document document,
            AssignmentExpressionSyntax assignmentExpression,
            CancellationToken cancellationToken)
        {
            var statement = (StatementSyntax)assignmentExpression.Parent;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(statement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(statement);

            statements = statements.RemoveAt(index);

            var returnStatement = (ReturnStatementSyntax)statement.NextStatement();

            SyntaxTriviaList trivia = statementsInfo
                                      .Parent
                                      .DescendantTrivia(TextSpan.FromBounds(statement.SpanStart, returnStatement.SpanStart))
                                      .ToSyntaxTriviaList()
                                      .EmptyIfWhitespace();

            trivia = statement
                     .GetLeadingTrivia()
                     .AddRange(trivia);

            returnStatement = returnStatement
                              .WithExpression(assignmentExpression.Right.WithTriviaFrom(returnStatement.Expression))
                              .WithLeadingTrivia(trivia)
                              .WithFormatterAnnotation();

            statements = statements.ReplaceAt(index, returnStatement);

            return(document.ReplaceStatementsAsync(statementsInfo, statements, cancellationToken));
        }
        private static async Task <Document> UsePatternMatchingAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            IsKindExpressionInfo isKindExpression = IsKindExpressionInfo.Create(ifStatement.Condition, semanticModel, cancellationToken: cancellationToken);

            switch (isKindExpression.Style)
            {
            case IsKindExpressionStyle.IsKind:
            case IsKindExpressionStyle.IsKindConditional:
            case IsKindExpressionStyle.Kind:
            case IsKindExpressionStyle.KindConditional:
            {
                var block = (BlockSyntax)ifStatement.Statement;

                IsPatternExpressionSyntax isPatternExpression = CreateIsPatternExpression(block.Statements[0]);

                BlockSyntax newBlock = block.WithStatements(block.Statements.RemoveAt(0));

                IfStatementSyntax newIfStatement = ifStatement.Update(
                    ifStatement.IfKeyword,
                    ifStatement.OpenParenToken,
                    isPatternExpression,
                    ifStatement.CloseParenToken,
                    newBlock,
                    ifStatement.Else);

                newIfStatement = newIfStatement.WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(ifStatement, newIfStatement, cancellationToken).ConfigureAwait(false));
            }

            case IsKindExpressionStyle.NotIsKind:
            case IsKindExpressionStyle.NotIsKindConditional:
            case IsKindExpressionStyle.NotKind:
            case IsKindExpressionStyle.NotKindConditional:
            {
                StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(ifStatement);

                SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

                int index = statements.IndexOf(ifStatement);

                IsPatternExpressionSyntax isPatternExpression = CreateIsPatternExpression(statements[index + 1]);

                IfStatementSyntax newIfStatement = ifStatement.WithCondition(LogicalNotExpression(isPatternExpression.Parenthesize()).WithTriviaFrom(ifStatement.Condition));

                SyntaxList <StatementSyntax> newStatements = statements
                                                             .ReplaceAt(index, newIfStatement)
                                                             .RemoveAt(index + 1);

                return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
            }

            default:
            {
                throw new InvalidOperationException();
            }
            }

            IsPatternExpressionSyntax CreateIsPatternExpression(StatementSyntax statement)
            {
                SingleLocalDeclarationStatementInfo localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statement);

                var castExpression = (CastExpressionSyntax)localInfo.Value;

                return(IsPatternExpression(
                           isKindExpression.Expression,
                           DeclarationPattern(castExpression.Type, SingleVariableDesignation(localInfo.Identifier))));
            }
        }
예제 #21
0
        public static async Task <Document> RefactorAsync(
            Document document,
            PropertyDeclarationSyntax propertyDeclaration,
            bool prefixIdentifierWithUnderscore = true,
            CancellationToken cancellationToken = default)
        {
            string fieldName = StringUtility.ToCamelCase(
                propertyDeclaration.Identifier.ValueText,
                prefixWithUnderscore: prefixIdentifierWithUnderscore);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            fieldName = NameGenerator.Default.EnsureUniqueName(
                fieldName,
                semanticModel,
                propertyDeclaration.SpanStart);

            FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(
                (propertyDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword)) ? Modifiers.Private_Static() : Modifiers.Private(),
                propertyDeclaration.Type,
                fieldName,
                propertyDeclaration.Initializer).WithFormatterAnnotation();

            IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken);

            PropertyDeclarationSyntax newPropertyDeclaration = ExpandAccessors(document, propertyDeclaration, propertySymbol, fieldName, semanticModel)
                                                               .WithModifiers(propertyDeclaration.Modifiers.Replace(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword))
                                                               .WithTriviaFrom(propertyDeclaration)
                                                               .WithFormatterAnnotation();

            MemberDeclarationListInfo membersInfo = SyntaxInfo.MemberDeclarationListInfo(propertyDeclaration.Parent);

            SyntaxList <MemberDeclarationSyntax> members = membersInfo.Members;

            int propertyIndex = membersInfo.IndexOf(propertyDeclaration);

            AccessorListSyntax accessorList = propertyDeclaration.AccessorList;

            if (accessorList?.Getter()?.IsAutoImplemented() == true &&
                accessorList.Setter() == null)
            {
                ImmutableArray <SyntaxNode> nodes = await SyntaxFinder.FindReferencesAsync(propertySymbol, document, cancellationToken : cancellationToken).ConfigureAwait(false);

                IdentifierNameSyntax newNode = IdentifierName(fieldName);

                SyntaxNode newParent = membersInfo.Parent.ReplaceNodes(nodes, (node, _) =>
                {
                    if (node.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) &&
                        ((MemberAccessExpressionSyntax)node.Parent).Expression.IsKind(SyntaxKind.BaseExpression))
                    {
                        return(node);
                    }

                    return(newNode.WithTriviaFrom(node));
                });

                MemberDeclarationListInfo newMembersInfo = SyntaxInfo.MemberDeclarationListInfo(newParent);

                members = newMembersInfo.Members;
            }

            SyntaxList <MemberDeclarationSyntax> newMembers = members.ReplaceAt(propertyIndex, newPropertyDeclaration);

            newMembers = MemberDeclarationInserter.Default.Insert(newMembers, fieldDeclaration);

            return(await document.ReplaceMembersAsync(membersInfo, newMembers, cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            ImmutableArray <FieldInfo> fieldInfos,
            TypeDeclarationSyntax typeDeclaration,
            CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> members = typeDeclaration.Members;

            HashSet <string> reservedNames = null;

            for (int i = 0; i < members.Count; i++)
            {
                if (!(members[i] is ConstructorDeclarationSyntax constructorDeclaration))
                {
                    continue;
                }

                if (constructorDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword))
                {
                    continue;
                }

                ParameterListSyntax parameterList = constructorDeclaration.ParameterList;

                if (parameterList == null)
                {
                    continue;
                }

                BlockSyntax body = constructorDeclaration.Body;

                if (body == null)
                {
                    continue;
                }

                SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters;

                reservedNames?.Clear();

                ConstructorInitializerSyntax initializer  = null;
                ArgumentListSyntax           argumentList = null;
                var arguments = default(SeparatedSyntaxList <ArgumentSyntax>);

                if (constructorDeclaration.Initializer?.Kind() == SyntaxKind.ThisConstructorInitializer)
                {
                    initializer  = constructorDeclaration.Initializer;
                    argumentList = initializer.ArgumentList;
                    arguments    = argumentList.Arguments;
                }

                SyntaxList <StatementSyntax> statements = body.Statements;

                foreach (FieldInfo fieldInfo in fieldInfos)
                {
                    string parameterName = GetParameterName(fieldInfo.NameCamelCase, parameters, ref reservedNames);

                    parameters = parameters.Add(Parameter(fieldInfo.Type.WithoutTrivia(), parameterName));

                    if (initializer != null)
                    {
                        arguments = arguments.Add(Argument(IdentifierName(parameterName)));
                    }

                    statements = statements.Add(
                        SimpleAssignmentStatement(
                            SimpleMemberAccessExpression(ThisExpression(), IdentifierName(fieldInfo.Name)).WithSimplifierAnnotation(),
                            IdentifierName(parameterName)).WithFormatterAnnotation());
                }

                parameterList = parameterList.WithParameters(parameters).WithFormatterAnnotation();

                if (initializer != null)
                {
                    initializer = initializer
                                  .WithArgumentList(argumentList.WithArguments(arguments))
                                  .WithFormatterAnnotation();
                }

                body = body.WithStatements(statements);

                constructorDeclaration = constructorDeclaration.Update(
                    constructorDeclaration.AttributeLists,
                    constructorDeclaration.Modifiers,
                    constructorDeclaration.Identifier,
                    parameterList,
                    initializer,
                    body,
                    constructorDeclaration.SemicolonToken);

                members = members.ReplaceAt(i, constructorDeclaration);
            }

            TypeDeclarationSyntax newNode = typeDeclaration.WithMembers(members);

            return(document.ReplaceNodeAsync(typeDeclaration, newNode, cancellationToken));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            ExpressionStatementSyntax expressionStatement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            INamedTypeSymbol symbol = semanticModel.GetTypeByMetadataName(MetadataNames.System_Text_StringBuilder);

            var invocationExpression = (InvocationExpressionSyntax)expressionStatement.Expression;

            MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create(invocationExpression);

            ExpressionSyntax expression = GetFirstInvocationInMethodChain(memberInvocation, symbol, semanticModel, cancellationToken).Expression;

            StatementContainer statementContainer = StatementContainer.Create(expressionStatement);

            SyntaxList <StatementSyntax> statements = statementContainer.Statements;

            int index = statements.IndexOf(expressionStatement);

            string indentation = CSharpFormatter.GetIncreasedIndentation(expressionStatement, cancellationToken).ToString();

            var sb = new StringBuilder(invocationExpression.ToString());

            int j = index;

            while (j < statements.Count - 1)
            {
                StatementSyntax statement = statements[j + 1];

                if (!IsFixable(statement, expression, symbol, semanticModel, cancellationToken))
                {
                    break;
                }

                sb.AppendLine();
                sb.Append(indentation);
                sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement, symbol, semanticModel, cancellationToken));

                j++;
            }

            StatementSyntax lastStatement = statements[j];

            SyntaxList <StatementSyntax> newStatements = statements;

            while (j > index)
            {
                newStatements = newStatements.RemoveAt(j);
                j--;
            }

            ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString());

            SyntaxTriviaList trailingTrivia = statementContainer
                                              .Node
                                              .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End))
                                              .ToSyntaxTriviaList()
                                              .EmptyIfWhitespace()
                                              .AddRange(lastStatement.GetTrailingTrivia());

            ExpressionStatementSyntax newExpressionStatement = expressionStatement
                                                               .WithExpression(newInvocationExpression)
                                                               .WithLeadingTrivia(expressionStatement.GetLeadingTrivia())
                                                               .WithTrailingTrivia(trailingTrivia)
                                                               .WithFormatterAndSimplifierAnnotations();

            newStatements = newStatements.ReplaceAt(index, newExpressionStatement);

            return(await document.ReplaceNodeAsync(statementContainer.Node, statementContainer.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false));
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            UseMethodChainingAnalysis analysis,
            ExpressionStatementSyntax expressionStatement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            InvocationExpressionSyntax invocationExpression = GetInvocationExpression(expressionStatement);

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression);

            ITypeSymbol returnType = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken).ReturnType;

            string name = ((IdentifierNameSyntax)UseMethodChainingAnalysis.WalkDownMethodChain(invocationInfo).Expression).Identifier.ValueText;

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(expressionStatement);

            SyntaxList <StatementSyntax> statements = statementsInfo.Statements;

            int index = statements.IndexOf(expressionStatement);

            string indentation = SyntaxTriviaAnalysis.GetIncreasedIndentation(expressionStatement, cancellationToken);

            var sb = new StringBuilder(invocationExpression.ToString());

            int j = index;

            while (j < statements.Count - 1)
            {
                StatementSyntax statement = statements[j + 1];

                if (!analysis.IsFixableStatement(statement, name, returnType, semanticModel, cancellationToken))
                {
                    break;
                }

                sb.AppendLine();
                sb.Append(indentation);
                sb.Append(GetTextToAppend((ExpressionStatementSyntax)statement));

                j++;
            }

            StatementSyntax lastStatement = statements[j];

            SyntaxList <StatementSyntax> newStatements = statements;

            while (j > index)
            {
                newStatements = newStatements.RemoveAt(j);
                j--;
            }

            ExpressionSyntax newInvocationExpression = SyntaxFactory.ParseExpression(sb.ToString());

            SyntaxTriviaList trailingTrivia = statementsInfo
                                              .Parent
                                              .DescendantTrivia(TextSpan.FromBounds(invocationExpression.Span.End, lastStatement.Span.End))
                                              .ToSyntaxTriviaList()
                                              .EmptyIfWhitespace()
                                              .AddRange(lastStatement.GetTrailingTrivia());

            ExpressionStatementSyntax newExpressionStatement = expressionStatement
                                                               .ReplaceNode(invocationExpression, newInvocationExpression)
                                                               .WithLeadingTrivia(expressionStatement.GetLeadingTrivia())
                                                               .WithTrailingTrivia(trailingTrivia)
                                                               .WithFormatterAndSimplifierAnnotation();

            newStatements = newStatements.ReplaceAt(index, newExpressionStatement);

            return(await document.ReplaceStatementsAsync(statementsInfo, newStatements, cancellationToken).ConfigureAwait(false));
        }
        private static Task <Document> RefactorAsync(
            Document document,
            VariableDeclaratorSyntax variableDeclarator,
            TypeDeclarationSyntax typeDeclaration,
            CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> members = typeDeclaration.Members;

            string name          = variableDeclarator.Identifier.ValueText;
            string camelCaseName = StringUtility.ToCamelCase(name);

            HashSet <string> reservedNames = null;

            for (int i = 0; i < members.Count; i++)
            {
                if (!(members[i] is ConstructorDeclarationSyntax constructorDeclaration))
                {
                    continue;
                }

                if (constructorDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword))
                {
                    continue;
                }

                ParameterListSyntax parameterList = constructorDeclaration.ParameterList;

                if (parameterList == null)
                {
                    continue;
                }

                BlockSyntax body = constructorDeclaration.Body;

                if (body == null)
                {
                    continue;
                }

                SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters;

                reservedNames?.Clear();

                string parameterName = GetParameterName(camelCaseName, parameters, ref reservedNames);

                ParameterSyntax parameter = Parameter(((VariableDeclarationSyntax)variableDeclarator.Parent).Type.WithoutTrivia(), parameterName);

                parameterList = parameterList.WithParameters(parameters.Add(parameter)).WithFormatterAnnotation();

                ConstructorInitializerSyntax initializer = constructorDeclaration.Initializer;

                if (initializer?.Kind() == SyntaxKind.ThisConstructorInitializer)
                {
                    ArgumentListSyntax argumentList = initializer.ArgumentList;

                    if (argumentList != null)
                    {
                        SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments;

                        initializer = initializer.WithArgumentList(
                            argumentList.WithArguments(
                                arguments.Add(Argument(IdentifierName(parameterName))))).WithFormatterAnnotation();
                    }
                }

                body = body.WithStatements(
                    body.Statements.Add(
                        SimpleAssignmentStatement(
                            SimpleMemberAccessExpression(ThisExpression(), IdentifierName(name)).WithSimplifierAnnotation(),
                            IdentifierName(parameterName)).WithFormatterAnnotation()));

                constructorDeclaration = constructorDeclaration.Update(
                    constructorDeclaration.AttributeLists,
                    constructorDeclaration.Modifiers,
                    constructorDeclaration.Identifier,
                    parameterList,
                    initializer,
                    body,
                    constructorDeclaration.SemicolonToken);

                members = members.ReplaceAt(i, constructorDeclaration);
            }

            TypeDeclarationSyntax newNode = typeDeclaration.WithMembers(members);

            return(document.ReplaceNodeAsync(typeDeclaration, newNode, cancellationToken));
        }