Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ private static IEnumerable<string> GetLinesTexts(TextLineCollection textLines)
sourceTextsBuilder.AddRange(sourceTexts);

var compositeText = (CompositeText)CompositeText.ToSourceText(sourceTextsBuilder, sourceText, adjustSegments: false);
sourceTextsBuilder.Free();

yield return (sourceText, compositeText);
}
}
Expand Down
52 changes: 52 additions & 0 deletions src/Compilers/Core/CodeAnalysisTest/Text/SubTextTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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.

using Microsoft.CodeAnalysis.Text;
using Xunit;

namespace Microsoft.CodeAnalysis.UnitTests.Text
{
public class SubTextTests
{
[Theory]
[InlineData("abcdefghijkl")]
[InlineData(["\r\r\r\r\r\r\r\r\r\r\r\r"])]
[InlineData(["\n\n\n\n\n\n\n\n\n\n\n\n"])]
[InlineData(["\r\n\r\n\r\n\r\n\r\n\r\n"])]
[InlineData(["\n\r\n\r\n\r\n\r\n\r\n\r"])]
[InlineData(["a\r\nb\r\nc\r\nd\r\n"])]
[InlineData(["\ra\n\rb\n\rc\n\rd\n"])]
[InlineData(["\na\r\nb\r\nc\r\nd\r"])]
[InlineData(["ab\r\ncd\r\nef\r\n"])]
[InlineData(["ab\r\r\ncd\r\r\nef"])]
[InlineData(["ab\n\n\rcd\n\n\ref"])]
[InlineData(["ab\u0085cdef\u2028ijkl\u2029op"])]
[InlineData(["\u0085\u2028\u2029\u0085\u2028\u2029\u0085\u2028\u2029\u0085\u2028\u2029"])]
public void SubTextTestAllPossibleSubstrings(string contents)
{
var fullStringText = SourceText.From(contents);
for (var start = 0; start < contents.Length; start++)
{
for (var end = start + 1; end <= contents.Length; end++)
{
var stringText = SourceText.From(contents[start..end]);
var subText = new SubText(fullStringText, new TextSpan(start, length: end - start));

Assert.Equal(stringText.Length, subText.Length);
for (var i = 0; i < stringText.Length; i++)
{
Assert.Equal(stringText.Lines.IndexOf(i), subText.Lines.IndexOf(i));
}

Assert.Equal(stringText.Lines.Count, subText.Lines.Count);
for (var i = 0; i < stringText.Lines.Count; i++)
{
Assert.Equal(stringText.Lines[i].ToString(), subText.Lines[i].ToString());
Assert.Equal(stringText.Lines[i].EndIncludingLineBreak, subText.Lines[i].EndIncludingLineBreak);
}
}
}
}
}
}
17 changes: 1 addition & 16 deletions src/Compilers/Core/Portable/Text/SubText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ private sealed class SubTextLineInfo : TextLineCollection
private readonly SubText _subText;
private readonly int _startLineNumberInUnderlyingText;
private readonly int _lineCount;
private readonly bool _startsWithinSplitCRLF;
private readonly bool _endsWithinSplitCRLF;

public SubTextLineInfo(SubText subText)
Expand All @@ -116,14 +115,6 @@ public SubTextLineInfo(SubText subText)
_startLineNumberInUnderlyingText = startLineInUnderlyingText.LineNumber;
_lineCount = (endLineInUnderlyingText.LineNumber - _startLineNumberInUnderlyingText) + 1;

var underlyingSpanStart = _subText.UnderlyingSpan.Start;
if (underlyingSpanStart == startLineInUnderlyingText.End + 1 &&
underlyingSpanStart == startLineInUnderlyingText.EndIncludingLineBreak - 1)
{
Debug.Assert(_subText.UnderlyingText[underlyingSpanStart - 1] == '\r' && _subText.UnderlyingText[underlyingSpanStart] == '\n');
_startsWithinSplitCRLF = true;
}

var underlyingSpanEnd = _subText.UnderlyingSpan.End;
if (underlyingSpanEnd == endLineInUnderlyingText.End + 1 &&
underlyingSpanEnd == endLineInUnderlyingText.EndIncludingLineBreak - 1)
Expand Down Expand Up @@ -151,7 +142,7 @@ public override TextLine this[int lineNumber]
// Special case splitting the CRLF at the end as the UnderlyingText doesn't view the position
// after between the \r and \n as on a new line whereas this subtext doesn't contain the \n
// and needs to view that position as on a new line.
return TextLine.FromSpanUnsafe(_subText, new TextSpan(_subText.UnderlyingSpan.End, 0));
return TextLine.FromSpanUnsafe(_subText, new TextSpan(_subText.UnderlyingSpan.Length, 0));
}

var underlyingTextLine = _subText.UnderlyingText.Lines[lineNumber + _startLineNumberInUnderlyingText];
Expand Down Expand Up @@ -210,12 +201,6 @@ public override int IndexOf(int position)
var underlyingPosition = position + _subText.UnderlyingSpan.Start;
var underlyingLineNumber = _subText.UnderlyingText.Lines.IndexOf(underlyingPosition);

if (_startsWithinSplitCRLF && position != 0)
{
// The \n contributes a line to the count in this subtext, but not in the UnderlyingText.
underlyingLineNumber += 1;
}

return underlyingLineNumber - _startLineNumberInUnderlyingText;
}
}
Expand Down