private static async Task <Document> RefactorAsync( Document document, InterpolatedStringExpressionSyntax interpolatedString, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); int position = interpolatedString.SpanStart; bool isVerbatim = interpolatedString.IsVerbatim(); ExpressionSyntax newNode = null; SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; InterpolatedStringContentSyntax content1 = contents[0]; InterpolatedStringContentSyntax content2 = contents[1]; if (content1.Kind() == SyntaxKind.InterpolatedStringText) { ExpressionSyntax expression1 = GetExpression((InterpolatedStringTextSyntax)content1, isVerbatim); ExpressionSyntax expression2 = ((InterpolationSyntax)content2).Expression; newNode = CreateAddExpression(expression1, expression2, position, semanticModel, cancellationToken, isLeft: false); } else if (content2.Kind() == SyntaxKind.InterpolatedStringText) { ExpressionSyntax expression1 = ((InterpolationSyntax)content1).Expression; ExpressionSyntax expression2 = GetExpression((InterpolatedStringTextSyntax)content2, isVerbatim); newNode = CreateAddExpression(expression1, expression2, position, semanticModel, cancellationToken, isLeft: true); } else { ExpressionSyntax expression1 = ((InterpolationSyntax)content1).Expression; ExpressionSyntax expression2 = ((InterpolationSyntax)content2).Expression; bool isLiteral = expression1 is LiteralExpressionSyntax; BinaryExpressionSyntax addExpression = CreateAddExpression(expression1, expression2, position, semanticModel, cancellationToken, isLeft: !isLiteral); newNode = CreateAddExpression(addExpression.Left, addExpression.Right, position, semanticModel, cancellationToken, isLeft: isLiteral); } for (int i = 2; i < contents.Count; i++) { InterpolatedStringContentSyntax content = contents[i]; ExpressionSyntax expression = (content.Kind() == SyntaxKind.InterpolatedStringText) ? GetExpression((InterpolatedStringTextSyntax)content, isVerbatim) : ((InterpolationSyntax)content).Expression; newNode = CreateAddExpression(newNode, expression, position, semanticModel, cancellationToken, isLeft: false); } newNode = newNode.Parenthesize().WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(interpolatedString, newNode, cancellationToken).ConfigureAwait(false)); }
private static bool TryEvaluateInterpolatedString(InterpolatedStringExpressionSyntax interpolation, out string result) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolation.Contents; var builder = new StringBuilder(); for (int i = 0; i < contents.Count; i++) { InterpolatedStringContentSyntax content = contents[i]; if (content is InterpolationSyntax interpolationSyntax && TryEvaluateString(interpolationSyntax.Expression, out string text)) { builder.Append(text); }
private Statement GetStatement(InterpolatedStringContentSyntax interpolatedStringContentSyntax) { if (interpolatedStringContentSyntax is InterpolationSyntax interpolationSyntax) { return(statementInterpreterHandler.GetStatement(interpolationSyntax.Expression)); } else { var stringTextSyntax = (InterpolatedStringTextSyntax)interpolatedStringContentSyntax; return(new ConstantStatement(stringTextSyntax.TextToken.Text)); } }
static string GetInterpolatedText(InterpolatedStringContentSyntax contentSyntax, SemanticModel model) { if (contentSyntax is InterpolatedStringTextSyntax interpolatedStringTextSyntax) { return(interpolatedStringTextSyntax.TextToken.Text); } if (contentSyntax is InterpolationSyntax interpolationSyntax) { return(GetStringValue(interpolationSyntax.Expression, model)); } return(contentSyntax.GetType().Name); }
public static InterpolatedStringContentConversion Create(InterpolatedStringContentSyntax content, bool isVerbatim) { if (content == null) { throw new ArgumentNullException(nameof(content)); } InterpolatedStringContentConversion conversion; if (!TryCreate(content, isVerbatim, out conversion)) { throw new ArgumentException("", nameof(content)); } return(conversion); }
public CSharpSyntaxNode Convert(TemplateExpression node) { SyntaxList <InterpolatedStringContentSyntax> contents = new SyntaxList <InterpolatedStringContentSyntax>(); InterpolatedStringContentSyntax head = node.Head.ToCsNode <InterpolatedStringContentSyntax>(); if (head != null) { contents = contents.Add(head); } foreach (Node templateSpan in node.TemplateSpans) { var content = templateSpan.ToCsNode <SyntaxList <InterpolatedStringContentSyntax> >(); contents = contents.AddRange(content); } return(SyntaxFactory.InterpolatedStringExpression(SyntaxFactory.Token(SyntaxKind.InterpolatedStringStartToken), contents)); }
public static bool CanRefactor(InterpolatedStringExpressionSyntax interpolatedString) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; if (contents.Count == 1) { InterpolatedStringContentSyntax content = contents[0]; if (content.IsKind(SyntaxKind.Interpolation)) { var interpolation = (InterpolationSyntax)content; if (interpolation?.IsMissing == false) { return(true); } } } return(false); }
public TameInterpolatedStringContentSyntax(InterpolatedStringContentSyntax node) { Node = node; AddChildren(); }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var cancellationToken = context.CancellationToken; var semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken); if (semanticModel == null) { return; } var tree = await context.Document.GetSyntaxRootAsync(cancellationToken); if (tree == null) { return; } var node = tree.FindNode(context.Span); if (!(node is MethodDeclarationSyntax methodDeclarationSyntax)) { return; } var method = ModelExtensions.GetDeclaredSymbol(semanticModel, methodDeclarationSyntax) as IMethodSymbol; if (method == null || method.IsStatic || method.IsAbstract || method.ContainingType.TypeKind != TypeKind.Class) { return; } var diagnosticScopeType = semanticModel.Compilation.GetTypeByMetadataName(AzureCorePipelineDiagnosticScopeTypeName); var clientDiagnosticsType = semanticModel.Compilation.GetTypeByMetadataName(AzureCorePipelineClientDiagnosticsTypeName); var exceptionType = semanticModel.Compilation.GetTypeByMetadataName(SystemExceptionTypeName); if (diagnosticScopeType == null || clientDiagnosticsType == null || exceptionType == null) { return; } string clientDiagnosticsMember = null; foreach (var member in method.ContainingType.GetMembers()) { if ((member is IFieldSymbol fieldSymbol && SymbolEqualityComparer.Default.Equals(clientDiagnosticsType, fieldSymbol.Type)) || (member is IPropertySymbol propertySymbol && SymbolEqualityComparer.Default.Equals(clientDiagnosticsType, propertySymbol.Type)) ) { clientDiagnosticsMember = member.Name; } } if (clientDiagnosticsMember == null) { return; } Task <Document> AddDiagnosticScope() { var generator = SyntaxGenerator.GetGenerator(context.Document); var preconditions = new List <StatementSyntax>(); var mainLogic = new List <SyntaxNode>(); IEnumerable <StatementSyntax> statements; if (methodDeclarationSyntax.Body != null) { statements = methodDeclarationSyntax.Body.Statements; } else if (methodDeclarationSyntax.ExpressionBody != null) { statements = new [] { (StatementSyntax)generator.ReturnStatement(methodDeclarationSyntax.ExpressionBody.Expression) }; } else { return(Task.FromResult(context.Document)); } foreach (var statement in statements) { if (mainLogic.Count > 0 || IncludeInScopeBody(statement)) { mainLogic.Add(statement); } else { preconditions.Add(statement); } } // Trim Async off the scope name var scopeName = method.Name; if (scopeName.EndsWith(AsyncSuffix)) { scopeName = scopeName.Substring(0, scopeName.Length - AsyncSuffix.Length); } // $"{nameof(Type}}.{nameof(Method)}" var interpolatedStringParts = new InterpolatedStringContentSyntax[] { Interpolation((ExpressionSyntax)generator.NameOfExpression(generator.IdentifierName(method.ContainingType.Name))), InterpolatedStringText(Token(SyntaxTriviaList.Empty, SyntaxKind.InterpolatedStringTextToken, ".", ".", SyntaxTriviaList.Empty)), Interpolation((ExpressionSyntax)generator.NameOfExpression(generator.IdentifierName(scopeName))) }; var initializer = generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName(clientDiagnosticsMember), "CreateScope"), InterpolatedStringExpression( Token(SyntaxKind.InterpolatedStringStartToken), List(interpolatedStringParts), Token(SyntaxKind.InterpolatedStringEndToken) ) ); var declaration = (LocalDeclarationStatementSyntax)generator.LocalDeclarationStatement(diagnosticScopeType, ScopeVariableName, initializer); declaration = declaration.WithUsingKeyword(Token(SyntaxKind.UsingKeyword)); preconditions.Add(declaration); preconditions.Add( (StatementSyntax)generator.ExpressionStatement( generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName(ScopeVariableName), "Start")))); preconditions.Add( (StatementSyntax)generator.TryCatchStatement( mainLogic, generator.CatchClause(exceptionType, "ex", new[] { generator.ExpressionStatement( generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName(ScopeVariableName), "Failed"), generator.Argument(generator.IdentifierName("ex")))), generator.ThrowStatement() }) )); var newMethodDeclaration = methodDeclarationSyntax.WithExpressionBody(null) .WithBody(Block(preconditions)) .WithSemicolonToken(default);
public static InterpolatedStringContentConversion Create(InterpolatedStringContentSyntax content, bool isVerbatim) { if (content == null) { throw new ArgumentNullException(nameof(content)); } SyntaxKind kind = content.Kind(); switch (kind) { case SyntaxKind.Interpolation: { var interpolation = (InterpolationSyntax)content; InterpolationAlignmentClauseSyntax alignmentClause = interpolation.AlignmentClause; InterpolationFormatClauseSyntax formatClause = interpolation.FormatClause; if (alignmentClause != null || formatClause != null) { var sb = new StringBuilder(); sb.Append("\"{0"); if (alignmentClause != null) { sb.Append(','); sb.Append(alignmentClause.Value.ToString()); } if (formatClause != null) { sb.Append(':'); sb.Append(formatClause.FormatStringToken.Text); } sb.Append("}\""); return(new InterpolatedStringContentConversion(kind, "AppendFormat", SeparatedList(new ArgumentSyntax[] { Argument(ParseExpression(sb.ToString())), Argument(interpolation.Expression) }))); } else { return(new InterpolatedStringContentConversion(kind, "Append", SingletonSeparatedList(Argument(interpolation.Expression)))); } } case SyntaxKind.InterpolatedStringText: { var interpolatedStringText = (InterpolatedStringTextSyntax)content; string text = interpolatedStringText.TextToken.Text; text = (isVerbatim) ? "@\"" + text + "\"" : "\"" + text + "\""; ExpressionSyntax stringLiteral = ParseExpression(text); return(new InterpolatedStringContentConversion(kind, "Append", SingletonSeparatedList(Argument(stringLiteral)))); } default: { throw new ArgumentException("", nameof(content)); } } }
Refactor(InterpolatedStringContentSyntax content, bool isVerbatim) { if (content == null) { throw new ArgumentNullException(nameof(content)); } SyntaxKind kind = content.Kind(); switch (kind) { case SyntaxKind.Interpolation: { var interpolation = (InterpolationSyntax)content; InterpolationAlignmentClauseSyntax alignmentClause = interpolation.AlignmentClause; InterpolationFormatClauseSyntax formatClause = interpolation.FormatClause; if (alignmentClause != null || formatClause != null) { StringBuilder sb = StringBuilderCache.GetInstance(); sb.Append("\"{0"); if (alignmentClause != null) { sb.Append(','); sb.Append(alignmentClause.Value.ToString()); } if (formatClause != null) { sb.Append(':'); sb.Append(formatClause.FormatStringToken.Text); } sb.Append("}\""); ExpressionSyntax expression = ParseExpression(StringBuilderCache.GetStringAndFree(sb)); return(kind, "AppendFormat", ImmutableArray.Create(Argument(expression), Argument(interpolation.Expression))); } else { return(kind, "Append", ImmutableArray.Create(Argument(interpolation.Expression))); } } case SyntaxKind.InterpolatedStringText: { var interpolatedStringText = (InterpolatedStringTextSyntax)content; string text = interpolatedStringText.TextToken.Text; text = StringUtility.ReplaceDoubleBracesWithSingleBrace(text); text = (isVerbatim) ? "@\"" + text + "\"" : "\"" + text + "\""; ExpressionSyntax stringLiteral = ParseExpression(text); return(kind, "Append", ImmutableArray.Create(Argument(stringLiteral))); } default: { throw new ArgumentException("", nameof(content)); } } }
public static bool TryCreate(InterpolatedStringContentSyntax content, bool isVerbatim, out InterpolatedStringContentConversion conversion) { switch (content?.Kind()) { case SyntaxKind.Interpolation: { var interpolation = (InterpolationSyntax)content; InterpolationAlignmentClauseSyntax alignmentClause = interpolation.AlignmentClause; InterpolationFormatClauseSyntax formatClause = interpolation.FormatClause; if (alignmentClause != null || formatClause != null) { var sb = new StringBuilder(); sb.Append("\"{0"); if (alignmentClause != null) { sb.Append(','); sb.Append(alignmentClause.Value.ToString()); } if (formatClause != null) { sb.Append(':'); sb.Append(formatClause.FormatStringToken.Text); } sb.Append("}\""); conversion = new InterpolatedStringContentConversion("AppendFormat", SeparatedList(new ArgumentSyntax[] { Argument(ParseExpression(sb.ToString())), Argument(interpolation.Expression) })); return(true); } else { conversion = new InterpolatedStringContentConversion("Append", SingletonSeparatedList(Argument(interpolation.Expression))); return(true); } } case SyntaxKind.InterpolatedStringText: { var interpolatedStringText = (InterpolatedStringTextSyntax)content; string text = interpolatedStringText.TextToken.Text; text = (isVerbatim) ? "@\"" + text + "\"" : "\"" + text + "\""; ExpressionSyntax stringLiteral = ParseExpression(text); conversion = new InterpolatedStringContentConversion("Append", SingletonSeparatedList(Argument(stringLiteral))); return(true); } } conversion = default(InterpolatedStringContentConversion); return(false); }