public static async Task ComputeRefactoringsAsync(RefactoringContext context, SyntaxToken token) { if (context.IsAnyRefactoringEnabled( RefactoringDescriptors.JoinStringExpressions, RefactoringDescriptors.UseStringBuilderInsteadOfConcatenation) && context.Span.IsEmptyAndContainedInSpan(token) && token.IsParentKind(SyntaxKind.AddExpression)) { var addExpression = (BinaryExpressionSyntax)token.Parent; while (addExpression.IsParentKind(SyntaxKind.AddExpression)) { addExpression = (BinaryExpressionSyntax)addExpression.Parent; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(addExpression, semanticModel, context.CancellationToken); if (concatenationInfo.Success) { if (context.IsRefactoringEnabled(RefactoringDescriptors.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenationInfo); } if (context.IsRefactoringEnabled(RefactoringDescriptors.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenationInfo); } } } }
public static void ComputeRefactoring(RefactoringContext context, StringConcatenationExpressionInfo concatenationInfo) { if (concatenationInfo.ContainsNonLiteralExpression) { if (concatenationInfo.ContainsLiteralExpression || concatenationInfo.ContainsInterpolatedStringExpression) { context.RegisterRefactoring( "Join string expressions", cancellationToken => ToInterpolatedStringAsync(context.Document, concatenationInfo, cancellationToken)); } } else if (concatenationInfo.ContainsLiteralExpression) { context.RegisterRefactoring( "Join string literals", cancellationToken => ToStringLiteralAsync(context.Document, concatenationInfo, multiline: false, cancellationToken: cancellationToken)); if (concatenationInfo.OriginalExpression .DescendantTrivia(concatenationInfo.Span ?? concatenationInfo.OriginalExpression.Span) .Any(f => f.IsEndOfLineTrivia())) { context.RegisterRefactoring( "Join string literals into multiline string literal", cancellationToken => ToStringLiteralAsync(context.Document, concatenationInfo, multiline: true, cancellationToken: cancellationToken)); } } }
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")); } } }
public static async Task <Document> RefactorAsync( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(binaryExpression, semanticModel, cancellationToken); StringConcatenationAnalysis analysis = concatenationInfo.Analyze(); ExpressionSyntax newNode; if (analysis.ContainsStringLiteral) { if (analysis.ContainsVerbatimExpression && concatenationInfo.ContainsMultiLineExpression()) { newNode = concatenationInfo.ToMultiLineStringLiteralExpression(); } else { newNode = concatenationInfo.ToStringLiteralExpression(); } } else { newNode = concatenationInfo.ToInterpolatedStringExpression(); } newNode = newNode.WithTriviaFrom(binaryExpression); return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public static void AnalyzeAddExpression(SyntaxNodeAnalysisContext context) { SyntaxNode node = context.Node; if (node.ContainsDiagnostics) { return; } if (node.SpanContainsDirectives()) { return; } var addExpression = (BinaryExpressionSyntax)node; StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(addExpression, context.SemanticModel, context.CancellationToken); if (concatenationInfo.Success && !concatenationInfo.ContainsNonSpecificExpression && (concatenationInfo.ContainsLiteralExpression ^ concatenationInfo.ContainsInterpolatedStringExpression) && (concatenationInfo.ContainsRegular ^ concatenationInfo.ContainsVerbatim) && (concatenationInfo.ContainsVerbatim || addExpression.IsSingleLine(includeExteriorTrivia: false, cancellationToken: context.CancellationToken))) { context.ReportDiagnostic(DiagnosticDescriptors.JoinStringExpressions, addExpression); } }
private static Task <Document> RefactorAsync( Document document, StringConcatenationExpressionInfo concatenationInfo, ExpressionSyntax expression, CancellationToken cancellationToken) { if (concatenationInfo.Span.HasValue) { TextSpan span = concatenationInfo.Span.Value; int start = concatenationInfo.BinaryExpression.SpanStart; string s = concatenationInfo.BinaryExpression.ToString(); s = s.Remove(span.Start - start) + expression + s.Substring(span.End - start); expression = SyntaxFactory.ParseExpression(s); } expression = expression .WithTriviaFrom(concatenationInfo.BinaryExpression) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(concatenationInfo.BinaryExpression, expression, cancellationToken)); }
private static void RegisterRefactoring(RefactoringContext context, StringConcatenationExpressionInfo concatenationInfo, StatementSyntax statement) { context.RegisterRefactoring( "Use StringBuilder instead of concatenation", cancellationToken => RefactorAsync(context.Document, concatenationInfo, statement, cancellationToken), RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation); }
private static Task <Document> ToInterpolatedStringAsync( Document document, StringConcatenationExpressionInfo concatenationInfo, CancellationToken cancellationToken) { InterpolatedStringExpressionSyntax newExpression = concatenationInfo.ToInterpolatedStringExpression(); return(RefactorAsync(document, concatenationInfo, newExpression, cancellationToken)); }
private static bool ContainsMultiLine(StringConcatenationExpressionInfo concatenationInfo, CancellationToken cancellationToken) { foreach (ExpressionSyntax expression in concatenationInfo.Expressions) { if (expression.IsMultiLine(includeExteriorTrivia: false, cancellationToken: cancellationToken)) { return(true); } } return(false); }
public static Task <Document> ToStringLiteralAsync( Document document, StringConcatenationExpressionInfo concatenationInfo, bool multiline, CancellationToken cancellationToken = default(CancellationToken)) { ExpressionSyntax newExpression = (multiline) ? concatenationInfo.ToMultiLineStringLiteralExpression() : concatenationInfo.ToStringLiteralExpression(); return(RefactorAsync(document, concatenationInfo, newExpression, cancellationToken)); }
public static void ComputeRefactoring(RefactoringContext context, StringConcatenationExpressionInfo concatenationInfo) { BinaryExpressionSyntax expression = concatenationInfo.OriginalExpression; switch (expression.Parent.Kind()) { case SyntaxKind.SimpleAssignmentExpression: case SyntaxKind.AddAssignmentExpression: { var assignment = (AssignmentExpressionSyntax)expression.Parent; if (assignment.IsParentKind(SyntaxKind.ExpressionStatement) && assignment.Right == expression) { RegisterRefactoring(context, concatenationInfo, (StatementSyntax)assignment.Parent); } break; } case SyntaxKind.EqualsValueClause: { var equalsValue = (EqualsValueClauseSyntax)expression.Parent; if (equalsValue.IsParentKind(SyntaxKind.VariableDeclarator)) { var variableDeclarator = (VariableDeclaratorSyntax)equalsValue.Parent; if (variableDeclarator.IsParentKind(SyntaxKind.VariableDeclaration)) { var variableDeclaration = (VariableDeclarationSyntax)variableDeclarator.Parent; if (variableDeclaration.IsParentKind(SyntaxKind.LocalDeclarationStatement) && variableDeclaration.Variables.Count == 1) { RegisterRefactoring(context, concatenationInfo, (StatementSyntax)variableDeclaration.Parent); } } } break; } } }
public static async Task <Document> RefactorAsync( Document document, BinaryExpressionSyntax binaryExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(binaryExpression, semanticModel, cancellationToken); if (concatenationInfo.Success) { ExpressionSyntax newNode = null; if (concatenationInfo.ContainsLiteralExpression) { if (concatenationInfo.ContainsVerbatim && ContainsMultiLine(concatenationInfo, cancellationToken)) { newNode = concatenationInfo.ToMultilineStringLiteral(); } else { newNode = concatenationInfo.ToStringLiteral(); } } else { newNode = concatenationInfo.ToInterpolatedString(); } newNode = newNode.WithTriviaFrom(binaryExpression); return(await document.ReplaceNodeAsync(binaryExpression, newNode, cancellationToken).ConfigureAwait(false)); } Debug.Fail(binaryExpression.ToString()); return(document); }
public static void ComputeRefactoring(RefactoringContext context, StringConcatenationExpressionInfo concatenationInfo) { BinaryExpressionSyntax binaryExpression = concatenationInfo.BinaryExpression; if (binaryExpression.IsParentKind(SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression)) { var assignment = (AssignmentExpressionSyntax)binaryExpression.Parent; if (assignment.IsParentKind(SyntaxKind.ExpressionStatement) && assignment.Right == binaryExpression) { RegisterRefactoring(context, concatenationInfo, (StatementSyntax)assignment.Parent); } } else { SingleLocalDeclarationStatementInfo info = SyntaxInfo.SingleLocalDeclarationStatementInfo(binaryExpression); if (info.Success) { RegisterRefactoring(context, concatenationInfo, info.Statement); } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, BinaryExpressionSyntax binaryExpression) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateOperator)) { SyntaxToken operatorToken = binaryExpression.OperatorToken; if (operatorToken.Span.Contains(context.Span) && NegateOperatorRefactoring.CanBeNegated(operatorToken)) { context.RegisterRefactoring( "Negate operator", cancellationToken => NegateOperatorRefactoring.RefactorAsync(context.Document, operatorToken, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatBinaryExpression)) { FormatBinaryExpressionRefactoring.ComputeRefactorings(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateBinaryExpression)) { NegateBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCoalesceExpression) && binaryExpression.OperatorToken.Span.Contains(context.Span)) { ExpandCoalesceExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.JoinStringExpressions, RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation) && context.Span.IsBetweenSpans(binaryExpression) && binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(binaryExpression, semanticModel, context.CancellationToken); if (concatenationInfo.Success) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenationInfo); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenationInfo); } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapExpressionsInBinaryExpression) && context.Span.IsBetweenSpans(binaryExpression)) { SwapExpressionsInBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceAsWithCast) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(binaryExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (ReplaceAsWithCastRefactoring.CanRefactor(binaryExpression, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( "Replace as with cast", cancellationToken => ReplaceAsWithCastRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken)); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.NegateIsExpression)) { NegateIsExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.Span.IsContainedInSpanOrBetweenSpans(binaryExpression.OperatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceEqualsExpressionWithStringEquals)) { await ReplaceEqualsExpressionWithStringEqualsRefactoring.ComputeRefactoringAsync(context, binaryExpression).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrEmpty, RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrWhiteSpace)) { await ReplaceEqualsExpressionRefactoring.ComputeRefactoringsAsync(context, binaryExpression).ConfigureAwait(false); } } if (!context.Span.IsBetweenSpans(binaryExpression) && context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExtractExpressionFromCondition, RefactoringIdentifiers.JoinStringExpressions)) { BinaryExpressionSelection binaryExpressionSelection = BinaryExpressionSelection.Create(binaryExpression, context.Span); if (binaryExpressionSelection.Expressions.Length > 1) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExtractExpressionFromCondition)) { ExtractConditionRefactoring.ComputeRefactoring(context, binaryExpressionSelection); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions) && binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenation = SyntaxInfo.StringConcatenationExpressionInfo(binaryExpressionSelection, semanticModel, context.CancellationToken); if (concatenation.Success) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenation); } } } } }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, BinaryExpressionSyntax binaryExpression) { SyntaxToken operatorToken = binaryExpression.OperatorToken; if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertOperator) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(operatorToken) && InvertOperatorRefactoring.CanBeInverted(operatorToken)) { context.RegisterRefactoring( "Invert operator", cancellationToken => InvertOperatorRefactoring.RefactorAsync(context.Document, operatorToken, cancellationToken), RefactoringIdentifiers.InvertOperator); } if (context.Span.IsEmptyAndContainedInSpan(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertBinaryExpression)) { InvertBinaryExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.SwapBinaryOperands)) { SwapBinaryOperandsRefactoring.ComputeRefactoring(context, binaryExpression); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatBinaryExpression)) { FormatBinaryExpressionRefactoring.ComputeRefactorings(context, binaryExpression); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandCoalesceExpression) && operatorToken.Span.Contains(context.Span)) { ExpandCoalesceExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ExtractExpressionFromCondition, RefactoringIdentifiers.JoinStringExpressions, RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation) && !context.Span.IsEmpty && binaryExpression.IsKind(SyntaxKind.AddExpression, SyntaxKind.LogicalAndExpression, SyntaxKind.LogicalOrExpression)) { ExpressionChain chain = binaryExpression.AsChain(context.Span); ExpressionChain.Enumerator en = chain.GetEnumerator(); if (en.MoveNext() && en.MoveNext()) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExtractExpressionFromCondition)) { ExtractConditionRefactoring.ComputeRefactoring(context, chain); } if (binaryExpression.IsKind(SyntaxKind.AddExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo(chain, semanticModel, context.CancellationToken); if (concatenationInfo.Success) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.JoinStringExpressions)) { JoinStringExpressionsRefactoring.ComputeRefactoring(context, concatenationInfo); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseStringBuilderInsteadOfConcatenation)) { UseStringBuilderInsteadOfConcatenationRefactoring.ComputeRefactoring(context, concatenationInfo); } } } } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceAsWithCast) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(binaryExpression)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (ReplaceAsWithCastAnalysis.IsFixable(binaryExpression, semanticModel, context.CancellationToken)) { context.RegisterRefactoring( ReplaceAsWithCastRefactoring.Title, cancellationToken => ReplaceAsWithCastRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken), RefactoringIdentifiers.ReplaceAsWithCast); } } if (context.IsRefactoringEnabled(RefactoringIdentifiers.InvertIsExpression)) { InvertIsExpressionRefactoring.ComputeRefactoring(context, binaryExpression); } if (context.Span.IsContainedInSpanOrBetweenSpans(operatorToken)) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceEqualsExpressionWithStringEquals)) { await ReplaceEqualsExpressionWithStringEqualsRefactoring.ComputeRefactoringAsync(context, binaryExpression).ConfigureAwait(false); } if (context.IsAnyRefactoringEnabled( RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrEmpty, RefactoringIdentifiers.ReplaceEqualsExpressionWithStringIsNullOrWhiteSpace)) { await ReplaceEqualsExpressionRefactoring.ComputeRefactoringsAsync(context, binaryExpression).ConfigureAwait(false); } } }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { INamedTypeSymbol stringBuilderSymbol = context.GetTypeByMetadataName(MetadataNames.System_Text_StringBuilder); if (stringBuilderSymbol != null) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; if (context.SemanticModel.TryGetMethodInfo(invocationExpression, out MethodInfo methodInfo, context.CancellationToken) && !methodInfo.IsExtensionMethod && methodInfo.ContainingType?.Equals(stringBuilderSymbol) == true) { ImmutableArray <IParameterSymbol> parameters = methodInfo.Parameters; SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; if (parameters.Length == 1 && arguments.Count == 1 && methodInfo.IsName("Append", "AppendLine")) { ArgumentSyntax argument = arguments.First(); ExpressionSyntax expression = argument.Expression; SyntaxKind expressionKind = expression.Kind(); switch (expressionKind) { case SyntaxKind.InterpolatedStringExpression: { context.ReportDiagnostic(DiagnosticDescriptors.OptimizeStringBuilderAppendCall, argument, methodInfo.Name); return; } case SyntaxKind.AddExpression: { StringConcatenationExpressionInfo concatenationInfo = SyntaxInfo.StringConcatenationExpressionInfo((BinaryExpressionSyntax)expression, context.SemanticModel, context.CancellationToken); if (concatenationInfo.Success) { context.ReportDiagnostic(DiagnosticDescriptors.OptimizeStringBuilderAppendCall, argument, methodInfo.Name); return; } break; } default: { if (expressionKind == SyntaxKind.InvocationExpression && IsFixable((InvocationExpressionSyntax)expression, context.SemanticModel, context.CancellationToken)) { context.ReportDiagnostic(DiagnosticDescriptors.OptimizeStringBuilderAppendCall, argument, methodInfo.Name); return; } if (methodInfo.IsName("Append") && parameters.Length == 1 && parameters[0].Type.IsObject() && context.SemanticModel.GetTypeSymbol(argument.Expression, context.CancellationToken).IsValueType) { context.ReportDiagnostic(DiagnosticDescriptors.AvoidBoxingOfValueType, argument); return; } break; } } } else if (parameters.Length > 1 && methodInfo.IsName("Insert") && methodInfo.HasParameters(SpecialType.System_Int32, SpecialType.System_Object) && context.SemanticModel .GetTypeSymbol(arguments[1].Expression, context.CancellationToken) .IsValueType) { context.ReportDiagnostic(DiagnosticDescriptors.AvoidBoxingOfValueType, arguments[1]); } } } }
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()) }; ImmutableArray <ExpressionSyntax> expressions = concatenationInfo.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.MethodName), ArgumentList(conversion.Arguments)); } } else { newInvocation = SimpleMemberInvocationExpression( newInvocation ?? stringBuilderName, IdentifierName("Append"), Argument(expressions[i].WithoutTrivia())); } } statements.Add(ExpressionStatement(newInvocation)); statements.Add(statement .ReplaceNode(concatenationInfo.OriginalExpression, 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)); } }