private static InvocationExpressionSyntax ConvertInterpolatedStringExpressionToInvocationExpression(
            InterpolatedStringExpressionSyntax interpolatedString,
            MemberInvocationExpressionInfo invocationInfo,
            SemanticModel semanticModel)
        {
            bool isVerbatim = interpolatedString.IsVerbatim();

            bool isAppendLine = string.Equals(invocationInfo.NameText, "AppendLine", StringComparison.Ordinal);

            InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression;

            InvocationExpressionSyntax newExpression = null;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

            for (int i = 0; i < contents.Count; i++)
            {
                InterpolatedStringContentConversion conversion = InterpolatedStringContentConversion.Create(contents[i], isVerbatim);

                string methodName = conversion.MethodName;
                SeparatedSyntaxList <ArgumentSyntax> arguments = conversion.Arguments;

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    string.Equals(methodName, "Append", StringComparison.Ordinal) &&
                    (conversion.Kind == SyntaxKind.InterpolatedStringText ||
                     semanticModel.IsImplicitConversion(((InterpolationSyntax)contents[i]).Expression, semanticModel.Compilation.GetSpecialType(SpecialType.System_String))))
                {
                    methodName = "AppendLine";
                }

                if (newExpression == null)
                {
                    newExpression = invocation
                                    .ReplaceNode(invocationInfo.Name, IdentifierName(methodName).WithTriviaFrom(invocationInfo.Name))
                                    .WithArgumentList(invocation.ArgumentList.WithArguments(arguments).WithoutTrailingTrivia());
                }
                else
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName(methodName),
                        ArgumentList(arguments));
                }

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    !string.Equals(methodName, "AppendLine", StringComparison.Ordinal))
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName("AppendLine"),
                        ArgumentList());
                }
            }

            return(newExpression);
        }
        private static InvocationExpressionSyntax ConvertInterpolatedStringExpressionToInvocationExpression(
            InterpolatedStringExpressionSyntax interpolatedString,
            MemberInvocationExpression memberInvocation)
        {
            bool isVerbatim = interpolatedString.IsVerbatim();

            bool isAppendLine = string.Equals(memberInvocation.NameText, "AppendLine", StringComparison.Ordinal);

            InvocationExpressionSyntax invocation = memberInvocation.InvocationExpression;

            InvocationExpressionSyntax newExpression = null;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

            for (int i = 0; i < contents.Count; i++)
            {
                InterpolatedStringContentConversion conversion = InterpolatedStringContentConversion.Create(contents[i], isVerbatim);

                string name = conversion.Name;
                SeparatedSyntaxList <ArgumentSyntax> arguments = conversion.Arguments;

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    !string.Equals(name, "AppendFormat", StringComparison.Ordinal))
                {
                    name = "AppendLine";
                }

                if (newExpression == null)
                {
                    newExpression = invocation
                                    .ReplaceNode(memberInvocation.Name, IdentifierName(name).WithTriviaFrom(memberInvocation.Name))
                                    .WithArgumentList(invocation.ArgumentList.WithArguments(arguments).WithoutTrailingTrivia());
                }
                else
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName(name),
                        ArgumentList(arguments));
                }

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    string.Equals(name, "AppendFormat", StringComparison.Ordinal))
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName("AppendLine"),
                        ArgumentList());
                }
            }

            return(newExpression);
        }
Example #3
0
        private static async Task <Document> RefactorAsync(
            Document document,
            StringConcatenationExpression concatenation,
            StatementSyntax statement,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.StringBuilderVariable, semanticModel, statement.SpanStart, cancellationToken: cancellationToken);

            IdentifierNameSyntax stringBuilderName = IdentifierName(name);

            TypeSyntax type = semanticModel.GetTypeByMetadataName(MetadataNames.System_Text_StringBuilder).ToMinimalTypeSyntax(semanticModel, statement.SpanStart);

            var statements = new List <StatementSyntax>()
            {
                LocalDeclarationStatement(VarType(), Identifier(name).WithRenameAnnotation(), ObjectCreationExpression(type, ArgumentList())).WithLeadingTrivia(statement.GetLeadingTrivia())
            };

            ImmutableArray <ExpressionSyntax> expressions = concatenation.Expressions;

            ExpressionSyntax newInvocation = null;

            for (int i = 0; i < expressions.Length; i++)
            {
                if (expressions[i].IsKind(SyntaxKind.InterpolatedStringExpression))
                {
                    var interpolatedString = (InterpolatedStringExpressionSyntax)expressions[i];

                    bool isVerbatim = interpolatedString.IsVerbatim();

                    SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

                    for (int j = 0; j < contents.Count; j++)
                    {
                        InterpolatedStringContentConversion conversion = InterpolatedStringContentConversion.Create(contents[j], isVerbatim);

                        newInvocation = SimpleMemberInvocationExpression(
                            newInvocation ?? stringBuilderName,
                            IdentifierName(conversion.Name),
                            ArgumentList(conversion.Arguments));
                    }
                }
                else
                {
                    newInvocation = SimpleMemberInvocationExpression(
                        newInvocation ?? stringBuilderName,
                        IdentifierName("Append"),
                        Argument(expressions[i].WithoutTrivia()));
                }
            }

            statements.Add(ExpressionStatement(newInvocation));

            statements.Add(statement
                           .ReplaceNode(concatenation.OriginalExpression, SimpleMemberInvocationExpression(stringBuilderName, IdentifierName("ToString")))
                           .WithTrailingTrivia(statement.GetTrailingTrivia())
                           .WithoutLeadingTrivia());

            if (EmbeddedStatementHelper.IsEmbeddedStatement(statement))
            {
                BlockSyntax block = Block(statements).WithFormatterAnnotation();

                return(await document.ReplaceNodeAsync(statement, block, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                for (int i = 0; i < statements.Count; i++)
                {
                    statements[i] = statements[i].WithFormatterAnnotation();
                }

                return(await document.ReplaceNodeAsync(statement, statements, cancellationToken).ConfigureAwait(false));
            }
        }