public static void ComputeRefactorings(RefactoringContext context, InterpolatedStringExpressionSyntax interpolatedString) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.InsertStringInterpolation) && context.Span.IsEmpty && InsertInterpolationRefactoring.CanRefactor(context, interpolatedString)) { context.RegisterRefactoring("Insert interpolation", cancellationToken => { return(InsertInterpolationRefactoring.RefactorAsync( context.Document, interpolatedString, context.Span, addNameOf: false, cancellationToken: cancellationToken)); }); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceInterpolatedStringWithStringLiteral) && ReplaceInterpolatedStringWithStringLiteralAnalysis.IsFixable(interpolatedString)) { context.RegisterRefactoring("Remove $", cancellationToken => { return(ReplaceInterpolatedStringWithStringLiteralRefactoring.RefactorAsync( context.Document, interpolatedString, cancellationToken)); }); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceInterpolatedStringWithInterpolationExpression) && interpolatedString.Span.Contains(context.Span) && ReplaceInterpolatedStringWithInterpolationExpressionRefactoring.CanRefactor(interpolatedString)) { ExpressionSyntax expression = ((InterpolationSyntax)(interpolatedString.Contents[0])).Expression; context.RegisterRefactoring( $"Replace interpolated string with '{expression}'", cancellationToken => { return(ReplaceInterpolatedStringWithInterpolationExpressionRefactoring.RefactorAsync( context.Document, interpolatedString, cancellationToken)); }); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceInterpolatedStringWithConcatenation) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(interpolatedString)) { ReplaceInterpolatedStringWithConcatenationRefactoring.ComputeRefactoring(context, interpolatedString); } if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceInterpolatedStringWithStringFormat) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(interpolatedString)) { ReplaceInterpolatedStringWithStringFormatRefactoring.ComputeRefactoring(context, interpolatedString); } }
public static async Task <Document> RefactorAsync( Document document, InterpolatedStringExpressionSyntax interpolatedString, CancellationToken cancellationToken = default(CancellationToken)) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (interpolatedString == null) { throw new ArgumentNullException(nameof(interpolatedString)); } SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); string s = UnescapeBraces(interpolatedString.ToString().Substring(1)); var newNode = (LiteralExpressionSyntax)SyntaxFactory.ParseExpression(s) .WithTriviaFrom(interpolatedString); SyntaxNode newRoot = root.ReplaceNode(interpolatedString, newNode); return(document.WithSyntaxRoot(newRoot)); }
public static Task <Document> RefactorAsync( Document document, InterpolatedStringExpressionSyntax interpolatedString, CancellationToken cancellationToken) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; ExpressionSyntax newNode = AddExpression( ((InterpolationSyntax)contents[0]).Expression.Parenthesize(), ((InterpolationSyntax)contents[1]).Expression.Parenthesize()); for (int i = 2; i < contents.Count; i++) { newNode = AddExpression( newNode, ((InterpolationSyntax)contents[i]).Expression.Parenthesize()); } newNode = newNode .WithTriviaFrom(interpolatedString) .Parenthesize() .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(interpolatedString, newNode, cancellationToken)); }
private static bool TryEvaluateString(ExpressionSyntax expression, out string result) { result = expression switch { // "text" LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.StringLiteralExpression => literal.Token.ValueText, // nameof(Identifier) InvocationExpressionSyntax invocation when invocation.Expression.GetText().ToString() == "nameof" => invocation.ArgumentList.Arguments[0].Expression.GetText().ToString(), // "A" + "B" BinaryExpressionSyntax binaryAdd when binaryAdd.Kind() == SyntaxKind.AddExpression => TryEvaluateString(binaryAdd.Left, out var left) && TryEvaluateString(binaryAdd.Right, out var right) ? left + right : null, // $"A {B} C" InterpolatedStringExpressionSyntax interpolation => TryEvaluateInterpolatedString(interpolation, out var interpolatedText) ? interpolatedText : null, _ => null }; return(result is not null); }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); InterpolatedStringExpressionSyntax interpolatedString = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <InterpolatedStringExpressionSyntax>(); if (interpolatedString == null) { return; } if (InterpolatedStringRefactoring.CanConvertToStringLiteral(interpolatedString)) { context.RegisterRefactoring("Convert to string literal", cancellationToken => { return(InterpolatedStringRefactoring.ConvertToStringLiteralAsync( context.Document, interpolatedString, cancellationToken)); }); } }
public static void ComputeRefactoring(RefactoringContext context, InterpolatedStringExpressionSyntax interpolatedString) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; if (contents.Count <= 1) { return; } foreach (InterpolatedStringContentSyntax content in contents) { if (content.Kind() == SyntaxKind.Interpolation) { var interpolation = (InterpolationSyntax)content; if (interpolation.AlignmentClause != null) { return; } if (interpolation.FormatClause != null) { return; } } } context.RegisterRefactoring( "Replace interpolated string with concatenation", cancellationToken => RefactorAsync(context.Document, interpolatedString, cancellationToken), RefactoringIdentifiers.ReplaceInterpolatedStringWithConcatenation); }
public static async Task <Document> RefactorAsync( Document document, InterpolatedStringExpressionSyntax interpolatedString, TextSpan span, CancellationToken cancellationToken = default(CancellationToken)) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); string s = interpolatedString.ToString(); int startIndex = span.Start - interpolatedString.SpanStart; s = s.Substring(0, startIndex) + "{" + s.Substring(startIndex, span.Length) + "}" + s.Substring(startIndex + span.Length); var newNode = (InterpolatedStringExpressionSyntax)ParseExpression(s) .WithTriviaFrom(interpolatedString); root = root.ReplaceNode(interpolatedString, newNode); return(document.WithSyntaxRoot(root)); }
private static void ProcessInterpolatedStringExpression(SourceText text, InterpolatedStringExpressionSyntax interpolatedString, ArrayBuilder <StringIndentationRegion> result, CancellationToken cancellationToken) { // Ignore strings with errors as we don't want to draw a line in a bad place that makes things even harder // to understand. if (interpolatedString.ContainsDiagnostics) { var errors = interpolatedString.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error); foreach (var error in errors) { if (!IsInHole(interpolatedString, error.Location.SourceSpan)) { return; } } } cancellationToken.ThrowIfCancellationRequested(); if (!TryGetIndentSpan(text, interpolatedString, out var offset, out var indentSpan)) { return; } using var _ = ArrayBuilder <TextSpan> .GetInstance(out var builder); foreach (var content in interpolatedString.Contents) { if (content is InterpolationSyntax interpolation && !IgnoreInterpolation(text, offset, interpolation)) { builder.Add(interpolation.Span); } } result.Add(new StringIndentationRegion(indentSpan, builder.ToImmutable())); }
public static bool IsFixable(InterpolatedStringExpressionSyntax interpolatedString) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; return(contents.Count == 0 || (contents.Count == 1 && contents[0].Kind() == SyntaxKind.InterpolatedStringText)); }
public static StringFormatConversion TryCreateConversion(InvocationExpressionSyntax formatCall) { var formatString = (formatCall.ArgumentList.Arguments.FirstOrDefault()?.Expression as LiteralExpressionSyntax)?.Token.ValueText; if (formatString == null) { return(None); } var arguments = formatCall.ArgumentList.Arguments.Skip(1).Select(arg => arg.Expression).ToList(); var parts = FormatStringParser.Parse(formatString, arguments); if (parts == null) { return(None); } InterpolatedStringExpressionSyntax interpolatedString = SyntaxFactory.InterpolatedStringExpression ( SyntaxFactory.Token(SyntaxKind.InterpolatedStringStartToken), SyntaxFactory.List <InterpolatedStringContentSyntax>(parts) ); return(new StringFormatConversion(formatCall, interpolatedString)); }
private bool TryInterpolatedStringExpression(InterpolatedStringExpressionSyntax interpolatedStringSyntax, IDom newItem, SemanticModel model, ref object value, ref LiteralKind literalKind, ref string constantIdentifier) { // this is a hack until interpolated strings stabilize if (interpolatedStringSyntax == null) { return(false); } var literal = interpolatedStringSyntax.ToFullString(); if (literal.StartsWith("\"")) { literal = literal.Substring(1); } if (literal.EndsWith("\"")) { literal = literal.Substring(0, literal.Length - 1); } var literalExpression = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Token(interpolatedStringSyntax.GetLeadingTrivia(), SyntaxKind.StringLiteralToken, literal, literal, interpolatedStringSyntax.GetTrailingTrivia())); return(TryLiteralExpression(literalExpression, newItem, model, ref value, ref literalKind, ref constantIdentifier)); }
public override Expression VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { Expression concatenated = null; foreach (var content in node.Contents) { Expression part; switch (content) { case InterpolationSyntax interpolation: if (_proofSemantics && !interpolation.Expression.IsEvaluatingToPrimitiveType(_semanticModel)) { throw new UnsupportedSyntaxException($"the interpolation '{interpolation}' of a string interpolation will not evaluate to a primitive type"); } part = interpolation.Expression.Accept(this); break; case InterpolatedStringTextSyntax text: // TODO not really necessary at this point as strings do not provide any information. part = new GenericLiteralExpression(); break; default: throw new UnsupportedSyntaxException($"interpolated string '{node}' contains unsupported content '{content}'"); } concatenated = concatenated == null ? part : new AddExpression(concatenated, part); } // Faulty formatted (aka syntax errors) string interpolations as well as empty strings may lead to an empty content list. return(concatenated ?? new GenericLiteralExpression()); }
public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { if (node.ShouldBePreserved()) { if (!_isPreservedBlock) { _isPreservedBlock = true; //if (!IsAtStartOfLine()) //{ ClearLineInfo(); node = node.WithLeadingTrivia(node.GetLeadingTrivia().Insert(0, SyntaxFactory.EndOfLine("\n").WithAdditionalAnnotations(new SyntaxAnnotation("MDK", "preserve")))); //} } return(node); } _isPreservedBlock = false; var span = node.GetLocation().GetLineSpan(); var endPosition = GetCharacterIndexFor(span.EndLinePosition); if (node.Span.Length < LineWidth && endPosition > LineWidth) { node = node.WithLeadingTrivia(SyntaxFactory.EndOfLine("\n").WithAdditionalAnnotations(new SyntaxAnnotation("MDK", "preserve"))); SetLineshift(span.EndLinePosition); } return(node); }
public override Ust VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { Expression[] expressions = node.Contents.Select(content => (Expression)VisitAndReturnNullIfError(content)).ToArray(); var result = new MultichildExpression(expressions, node.GetTextSpan()); return(result); }
/// <inheritdoc /> public override Expression VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { StringBuilder template = new StringBuilder(); Sequence <Expression> parameters = new Sequence <Expression>(); foreach (var content in node.Contents) { if (content is InterpolatedStringTextSyntax text) { template.Append(text.TextToken.ValueText); } else if (content is InterpolationSyntax interpolation) { template.Append('{'); template.Append(parameters.Count); template.Append('}'); parameters.Add(interpolation.Expression.Accept(this)); } else { throw new NotSupportedException(); } } return(Expression.Call( typeof(string).GetRuntimeMethod(nameof(string.Format), new[] { typeof(string), typeof(object[]) }), Expression.Constant(template.ToString()), Expression.NewArrayInit(typeof(object), parameters.ToArray()) )); }
private static SyntaxNode ToPlusOperators(InterpolatedStringExpressionSyntax expr) { return(GetContentExpressions(expr) .Aggregate((ae, content) => SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, ae, content) )); }
internal static void Run(SyntaxNodeAnalysisContext context, InterpolatedStringExpressionSyntax token) { //Check string string id = token.ToFullString(); if (string.IsNullOrWhiteSpace(id)) { return; } //Send to class Helper string sql = Helper.BuildSqlStringFromIdString(context, id); if (string.IsNullOrWhiteSpace(sql)) { return; } //Send to Class Parser List <string> errors = SqlParser.Parse(sql); if (errors.Count == 0) { return; } //Report Error string errorText = String.Join("\r\n", errors); var diagnostic = Diagnostic.Create(Rule, context.Node.GetLocation(), errorText); context.ReportDiagnostic(diagnostic); }
public static void ComputeRefactoring(RefactoringContext context, InterpolatedStringExpressionSyntax interpolatedString) { SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; if (contents.Count <= 1) { return; } foreach (InterpolatedStringContentSyntax content in contents) { if (content.Kind() == SyntaxKind.Interpolation) { var interpolation = (InterpolationSyntax)content; if (interpolation.AlignmentClause != null) { return; } if (interpolation.FormatClause != null) { return; } } } context.RegisterRefactoring( "Convert to concatenation", ct => RefactorAsync(context.Document, interpolatedString, ct), RefactoringDescriptors.ConvertInterpolatedStringToConcatenation); }
private static void GetFormatStringAndExpressionsFromInterpolation(InterpolatedStringExpressionSyntax interpolatedString, out InterpolatedStringExpressionSyntax format, out List <ExpressionSyntax> expressions) { var sb = new StringBuilder(); var replacements = new List <string>(); var interpolations = new List <ExpressionSyntax>(); foreach (var child in interpolatedString.Contents) { switch (child) { case InterpolatedStringTextSyntax text: sb.Append(text.TextToken.ToString()); break; case InterpolationSyntax interpolation: int argumentPosition = interpolations.Count; interpolations.Add(interpolation.Expression); sb.Append("{"); sb.Append(replacements.Count); sb.Append("}"); replacements.Add($"{{{ConversionName}{argumentPosition}{interpolation.AlignmentClause}{interpolation.FormatClause}}}"); break; } } format = (InterpolatedStringExpressionSyntax)SyntaxFactory.ParseExpression("$\"" + String.Format(sb.ToString(), replacements.ToArray()) + "\""); expressions = interpolations; }
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 InterpolatedStringExpressionSyntax ReplaceInterpolationWithStringLiteralInnerText( SeparatedSyntaxList <ArgumentSyntax> arguments, InterpolatedStringExpressionSyntax interpolatedString, string text) { var sb = new StringBuilder(); int pos = 0; SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; for (int i = 0; i < contents.Count; i++) { if (contents[i].Kind() != SyntaxKind.Interpolation) { continue; } var interpolation = (InterpolationSyntax)contents[i]; ExpressionSyntax expression = interpolation.Expression; if (expression?.Kind() != SyntaxKind.NumericLiteralExpression) { continue; } var index = (int)((LiteralExpressionSyntax)expression).Token.Value; if (index < 0) { continue; } if (index >= arguments.Count) { continue; } ExpressionSyntax argumentExpression = arguments[index + 1].Expression; if (argumentExpression.Kind() != SyntaxKind.StringLiteralExpression) { continue; } var literalExpression = (LiteralExpressionSyntax)argumentExpression; sb.Append(text, pos, interpolation.SpanStart - pos); sb.Append(StringUtility.DoubleBraces(literalExpression.GetStringLiteralInnerText())); pos = interpolation.Span.End; } sb.Append(text, pos, text.Length - pos); return((InterpolatedStringExpressionSyntax)ParseExpression(sb.ToString())); }
public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { var newNode = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Token(node.GetLeadingTrivia(), SyntaxKind.StringLiteralToken, "LITERAL", "LITERAL", node.GetTrailingTrivia())); return(base.VisitLiteralExpression(newNode)); }
public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { var interpolation = result.Find(node); return(interpolation != null ? (interpolation.Interpolate()).interpolated : base.VisitInterpolatedStringExpression(node)); }
public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { this.AppendCompileIssue(node, IssueType.Error, IssueId.StringInterpolation); _output.TrivialWrite('"'); _output.Write(node, node.Contents.ToFullString()); _output.TrivialWrite('"'); return node; }
public override SyntaxNode VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { this.AppendCompileIssue(node, IssueType.Error, IssueId.StringInterpolation); _output.TrivialWrite('"'); _output.Write(node, node.Contents.ToFullString()); _output.TrivialWrite('"'); return(node); }
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); }
public InterpolatedStringSplitter( Document document, int position, SyntaxTree syntaxTree, SyntaxNode root, SourceText sourceText, InterpolatedStringExpressionSyntax interpolatedStringExpression, bool useTabs, int tabSize, CancellationToken cancellationToken) : base(document, position, syntaxTree, root, sourceText, useTabs, tabSize, cancellationToken) { _interpolatedStringExpression = interpolatedStringExpression; }
private static Task <Document> ToInterpolatedStringAsync( Document document, StringConcatenationExpression concatenation, CancellationToken cancellationToken) { InterpolatedStringExpressionSyntax newExpression = concatenation.ToInterpolatedString(); return(RefactorAsync(document, concatenation, newExpression, cancellationToken)); }
public static bool IsVerbatim(this InterpolatedStringExpressionSyntax interpolatedString) { if (interpolatedString == null) { throw new ArgumentNullException(nameof(interpolatedString)); } return(interpolatedString.StringStartToken.ValueText.Contains("@")); }
public override Evaluation VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { foreach (InterpolatedStringContentSyntax content in node.Contents) { content.Accept <Evaluation>(this); } return(base.VisitInterpolatedStringExpression(node)); }
private Doc PrintInterpolatedStringExpressionSyntax( InterpolatedStringExpressionSyntax node) { return(ForceFlat( this.PrintSyntaxToken(node.StringStartToken), Concat(node.Contents.Select(this.Print).ToArray()), this.PrintSyntaxToken(node.StringEndToken) )); }
public InterpolatedStringSplitter( Document document, int position, SyntaxNode root, SourceText sourceText, InterpolatedStringExpressionSyntax interpolatedStringExpression, bool useTabs, int tabSize, CancellationToken cancellationToken) : base(document, position, root, sourceText, useTabs, tabSize, cancellationToken) { _interpolatedStringExpression = interpolatedStringExpression; }
public InterpolatedStringExpressionTranslation(InterpolatedStringExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { }
public override void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { base.VisitInterpolatedStringExpression(node); }
private InterpolatedStringExpressionSyntax ToVerbatimInterpolatedString(InterpolatedStringExpressionSyntax original) { var startToken = SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.InterpolatedStringStartToken, "$@\"", "$@\"", SyntaxTriviaList.Empty); var contents = original.Contents.ToArray(); for (int i = 0; i < contents.Length; i++) { var textContent = contents[i] as InterpolatedStringTextSyntax; if (textContent == null) continue; var textToken = textContent.TextToken; // InterpolatedStringTextSyntax.TextToken.ValueText is not unescape "{{" and "}}". //var newText = textToken.ValueText.Replace("\"", "\"\"").Replace("{", "{{").Replace("}", "}}"); // "\\r\\n" -> "\r\n" var unescapeToken = SyntaxFactory.ParseToken($"\"{textToken.Text}\""); var newText = unescapeToken.ValueText.Replace("\"", "\"\""); var newTextToken = SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.InterpolatedStringTextToken, newText, textToken.ValueText, SyntaxTriviaList.Empty); var newContent = SyntaxFactory.InterpolatedStringText(newTextToken); contents[i] = newContent; } return SyntaxFactory.InterpolatedStringExpression(startToken).AddContents(contents); }
public static InterpolatedStringExpressionSyntax Visit(InterpolatedStringExpressionSyntax interpolatedString, ImmutableArray<ExpressionSyntax> expandedArguments) { return (InterpolatedStringExpressionSyntax)new InterpolatedStringRewriter(expandedArguments).Visit(interpolatedString); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitInterpolatedStringExpression(node); }
private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSyntax node, DiagnosticBag diagnostics) { var builder = ArrayBuilder<BoundExpression>.GetInstance(); var stringType = GetSpecialType(SpecialType.System_String, diagnostics, node); var objectType = GetSpecialType(SpecialType.System_Object, diagnostics, node); var intType = GetSpecialType(SpecialType.System_Int32, diagnostics, node); foreach (var content in node.Contents) { switch (content.Kind()) { case SyntaxKind.Interpolation: { var interpolation = (InterpolationSyntax)content; var value = BindValue(interpolation.Expression, diagnostics, Binder.BindValueKind.RValue); // We need to ensure the argument is not a lambda, method group, etc. It isn't nice to wait until lowering, // when we perform overload resolution, to report a problem. So we do that check by calling // GenerateConversionForAssignment with objectType. However we want to preserve the original expression's // natural type so that overload resolution may select a specialized implementation of string.Format, // so we discard the result of that call and only preserve its diagnostics. var discarded = GenerateConversionForAssignment(objectType, value, diagnostics); BoundExpression alignment = null, format = null; if (interpolation.AlignmentClause != null) { alignment = GenerateConversionForAssignment(intType, BindValue(interpolation.AlignmentClause.Value, diagnostics, Binder.BindValueKind.RValue), diagnostics); var alignmentConstant = alignment.ConstantValue; if (alignmentConstant != null && !alignmentConstant.IsBad) { const int magnitudeLimit = 32767; // check that the magnitude of the alignment is "in range". int alignmentValue = alignmentConstant.Int32Value; // We do the arithmetic using negative numbers because the largest negative int has no corresponding positive (absolute) value. alignmentValue = (alignmentValue > 0) ? -alignmentValue : alignmentValue; if (alignmentValue < -magnitudeLimit) { diagnostics.Add(ErrorCode.WRN_AlignmentMagnitude, alignment.Syntax.Location, alignmentConstant.Int32Value, magnitudeLimit); } } else if (!alignment.HasErrors) { diagnostics.Add(ErrorCode.ERR_ConstantExpected, interpolation.AlignmentClause.Value.Location); } } if (interpolation.FormatClause != null) { var text = interpolation.FormatClause.FormatStringToken.ValueText; char lastChar; bool hasErrors = false; if (text.Length == 0) { diagnostics.Add(ErrorCode.ERR_EmptyFormatSpecifier, interpolation.FormatClause.Location); hasErrors = true; } else if (SyntaxFacts.IsWhitespace(lastChar = text[text.Length - 1]) || SyntaxFacts.IsNewLine(lastChar)) { diagnostics.Add(ErrorCode.ERR_TrailingWhitespaceInFormatSpecifier, interpolation.FormatClause.Location); hasErrors = true; } format = new BoundLiteral(interpolation.FormatClause, ConstantValue.Create(text), stringType, hasErrors); } builder.Add(new BoundStringInsert(interpolation, value, alignment, format, null)); continue; } case SyntaxKind.InterpolatedStringText: { var text = ((InterpolatedStringTextSyntax)content).TextToken.ValueText; builder.Add(new BoundLiteral(content, ConstantValue.Create(text, SpecialType.System_String), stringType)); continue; } default: throw ExceptionUtilities.UnexpectedValue(content.Kind()); } } return new BoundInterpolatedString(node, builder.ToImmutableAndFree(), stringType); }
/// <summary> /// Turn a (parsed) interpolated string nonterminal into an interpolated string token. /// </summary> /// <param name="interpolatedString"></param> static internal SyntaxToken RescanInterpolatedString(InterpolatedStringExpressionSyntax interpolatedString) { var text = interpolatedString.ToString(); var kind = SyntaxKind.InterpolatedStringToken; // TODO: scan the contents (perhaps using ScanInterpolatedStringLiteralContents) to reconstruct any lexical // errors such as // inside an expression hole return SyntaxFactory.Literal( interpolatedString.GetFirstToken().GetLeadingTrivia(), text, kind, text, interpolatedString.GetLastToken().GetTrailingTrivia()); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitInterpolatedStringExpression(node); }