Repository: dotnet/roslyn
File: src/EditorFeatures/CSharp/SplitStringLiteral/SplitStringLiteralCommandHandler.cs (C#)

Code before:
        // First, we need to verify that we are only working with string literals.
        // Otherwise, let the editor handle all carets.
        foreach (var span in spans)
        {
            var spanStart = span.Start;
            var line = subjectBuffer.CurrentSnapshot.GetLineFromPosition(span.Start);
            if (!LineContainsQuote(line, span.Start))
                return false;
        }

        var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
        if (document == null)
            return false;

        var parsedDocument = ParsedDocument.CreateSynchronously(document, CancellationToken.None);
        var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: false);

        // We now go through the verified string literals and split each of them.
        // The list of spans is traversed in reverse order so we do not have to
        // deal with updating later caret positions to account for the added space
        // from splitting at earlier caret positions.
        // 
        // However, we need to track the new caret positions in the original forward order
        // for setting the multi-selection at the end. We use tracking points to automatically
        // adjust positions as the buffer changes.
        var trackingPoints = new ITrackingPoint[spans.Count];

        var currentIndex = spans.Count - 1;
        foreach (var span in spans.Reverse())
        {
            using var transaction = CaretPreservingEditTransaction.TryCreate(
                CSharpEditorResources.Split_string, textView, _undoHistoryRegistry, _editorOperationsFactoryService);

            var splitter = StringSplitter.TryCreate(parsedDocument, span.Start.Position, indentationOptions, cancellationToken);
            if (splitter is null ||
                !splitter.TrySplit(out var newRoot, out var newPosition))
            {
                return false;
            }

            // apply the change:
            var newDocument = parsedDocument.WithChangedRoot(newRoot, cancellationToken);
            var newSnapshot = subjectBuffer.ApplyChanges(newDocument.GetChanges(parsedDocument));
            parsedDocument = newDocument;

            // Create a tracking point for the new caret position.
            // Use Negative tracking mode so the caret stays before any text inserted at this position.
            trackingPoints[currentIndex] = newSnapshot.CreateTrackingPoint(newPosition, PointTrackingMode.Negative);

            transaction?.Complete();
            currentIndex--;

Review comment (suggestion):
@copilot please do `using var _ = ArrayBuilder<ITrackingPoint>.GetInstance(spans.Count, out var trackingPoints);` (or whatever the normal pattern is in this code for a pooled array of the right length. 

Code after:
        foreach (var span in spans)
        {
            var spanStart = span.Start;
            var line = subjectBuffer.CurrentSnapshot.GetLineFromPosition(span.Start);
            if (!LineContainsQuote(line, span.Start))
                return false;
        }

        var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
        if (document == null)
            return false;

        var parsedDocument = ParsedDocument.CreateSynchronously(document, CancellationToken.None);
        var indentationOptions = subjectBuffer.GetIndentationOptions(_editorOptionsService, document.Project.GetFallbackAnalyzerOptions(), parsedDocument.LanguageServices, explicitFormat: false);

        // We now go through the verified string literals and split each of them.
        // The list of spans is traversed in reverse order so we do not have to
        // deal with updating later caret positions to account for the added space
        // from splitting at earlier caret positions.
        // 
        // However, we need to track the new caret positions in the original forward order
        // for setting the multi-selection at the end. We use tracking points to automatically
        // adjust positions as the buffer changes.
        using var _ = PooledObjects.ArrayBuilder<ITrackingPoint>.GetInstance(spans.Count, fillWithValue: null!, out var trackingPoints);

        var currentIndex = spans.Count - 1;
        foreach (var span in spans.Reverse())
        {
            using var transaction = CaretPreservingEditTransaction.TryCreate(
                CSharpEditorResources.Split_string, textView, _undoHistoryRegistry, _editorOperationsFactoryService);

            var splitter = StringSplitter.TryCreate(parsedDocument, span.Start.Position, indentationOptions, cancellationToken);
            if (splitter is null ||
                !splitter.TrySplit(out var newRoot, out var newPosition))
            {
                return false;
            }

            // apply the change:
            var newDocument = parsedDocument.WithChangedRoot(newRoot, cancellationToken);
            var newSnapshot = subjectBuffer.ApplyChanges(newDocument.GetChanges(parsedDocument));
            parsedDocument = newDocument;

            // Create a tracking point for the new caret position.
            // Use Negative tracking mode so the caret stays before any text inserted at this position.
            trackingPoints[currentIndex] = newSnapshot.CreateTrackingPoint(newPosition, PointTrackingMode.Negative);

            transaction?.Complete();
            currentIndex--;
        }