private static async Task <Document> RefactorAsync( Document document, StringConcatenationExpressionInfo concatenationInfo, 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()) }; ExpressionSyntax newInvocation = null; foreach (ExpressionSyntax expression in concatenationInfo.Expressions(leftToRight: true)) { if (expression.IsKind(SyntaxKind.InterpolatedStringExpression)) { var interpolatedString = (InterpolatedStringExpressionSyntax)expression; bool isVerbatim = interpolatedString.IsVerbatim(); SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; for (int j = 0; j < contents.Count; j++) { (SyntaxKind contentKind, string methodName, ImmutableArray <ArgumentSyntax> arguments) = RefactoringUtility.ConvertInterpolatedStringToStringBuilderMethod(contents[j], isVerbatim); newInvocation = SimpleMemberInvocationExpression( newInvocation ?? stringBuilderName, IdentifierName(methodName), ArgumentList(arguments.ToSeparatedSyntaxList())); } } else { newInvocation = SimpleMemberInvocationExpression( newInvocation ?? stringBuilderName, IdentifierName("Append"), Argument(expression.WithoutTrivia())); } } statements.Add(ExpressionStatement(newInvocation)); statements.Add(statement .ReplaceNode(concatenationInfo.BinaryExpression, SimpleMemberInvocationExpression(stringBuilderName, IdentifierName("ToString"))) .WithTrailingTrivia(statement.GetTrailingTrivia()) .WithoutLeadingTrivia()); if (statement.IsEmbedded()) { 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)); } }
private static InvocationExpressionSyntax ConvertInterpolatedStringExpressionToInvocationExpression( InterpolatedStringExpressionSyntax interpolatedString, SimpleMemberInvocationExpressionInfo 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++) { (SyntaxKind contentKind, string methodName, ImmutableArray <ArgumentSyntax> arguments) = RefactoringUtility.ConvertInterpolatedStringToStringBuilderMethod(contents[i], isVerbatim); if (i == contents.Count - 1 && isAppendLine && string.Equals(methodName, "Append", StringComparison.Ordinal) && (contentKind == 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.ToSeparatedSyntaxList()).WithoutTrailingTrivia()); } else { newExpression = SimpleMemberInvocationExpression( newExpression, IdentifierName(methodName), ArgumentList(arguments.ToSeparatedSyntaxList())); } if (i == contents.Count - 1 && isAppendLine && !string.Equals(methodName, "AppendLine", StringComparison.Ordinal)) { newExpression = SimpleMemberInvocationExpression( newExpression, IdentifierName("AppendLine"), ArgumentList()); } } return(newExpression); }