| File: SplitStringLiteral\SimpleStringSplitter.cs | Web Access |
| Project: src\roslyn\src\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj (Microsoft.CodeAnalysis.CSharp.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.SplitStringLiteral; internal abstract partial class StringSplitter { private sealed class SimpleStringSplitter( ParsedDocument document, int position, SyntaxToken token, in IndentationOptions indentationOptions, CancellationToken cancellationToken) : StringSplitter(document, position, indentationOptions, cancellationToken) { private const char QuoteCharacter = '"'; private readonly SyntaxToken _token = token; // Don't split @"" strings. They already support directly embedding newlines. // Don't split UTF-8 strings if the cursor is after the quote. protected override bool CheckToken() => !_token.IsVerbatimStringLiteral() && !CursorIsAfterQuotesInUtf8String(); private bool CursorIsAfterQuotesInUtf8String() { return _token.IsKind(SyntaxKind.Utf8StringLiteralToken) && CursorPosition >= _token.Span.End - "u8".Length; } protected override SyntaxNode GetNodeToReplace() => _token.Parent; protected override BinaryExpressionSyntax CreateSplitString() { // TODO(cyrusn): Deal with the positoin being after a \ character var prefix = Document.Text.GetSubText(TextSpan.FromBounds(_token.SpanStart, CursorPosition)).ToString(); var suffix = Document.Text.GetSubText(TextSpan.FromBounds(CursorPosition, _token.Span.End)).ToString(); // If we're spliting a UTF-8 string we need to keep the u8 suffix on the first part. We copy whatever // the user had on the second part, for consistency. var firstTokenSuffix = _token.Kind() == SyntaxKind.Utf8StringLiteralToken ? Document.Text.GetSubText(TextSpan.FromBounds(_token.Span.End - "u8".Length, _token.Span.End)).ToString() : ""; var firstToken = SyntaxFactory.Token( _token.LeadingTrivia, _token.Kind(), text: prefix + QuoteCharacter + firstTokenSuffix, valueText: "", trailing: [SyntaxFactory.ElasticSpace]); var secondToken = SyntaxFactory.Token( default, _token.Kind(), text: QuoteCharacter + suffix, valueText: "", trailing: _token.TrailingTrivia); var leftExpression = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, firstToken); var rightExpression = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, secondToken); return SyntaxFactory.BinaryExpression( SyntaxKind.AddExpression, leftExpression, PlusNewLineToken, rightExpression.WithAdditionalAnnotations(RightNodeAnnotation)); } protected override int StringOpenQuoteLength() => "\"".Length; } }