未验证 提交 725ea66b 编写于 作者: J Joseph Musser 提交者: GitHub

Fixed SourceText.Write for spans that don't start at 0 (#41986)

* Failing tests for writing with a range starting > 0

* Fixed SourceText.Write for spans that don't start at 0

* Math.Min is redundant with CheckSubSpan

* TextSpan guarantees that Start >= 0

* TextSpan guarantees that Start <= End

* Assert is preferred over comment
上级 0d63ed38
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
......@@ -302,5 +304,54 @@ public void TryReadByteOrderMark()
TestTryReadByteOrderMark(expectedEncoding: null, expectedPreambleLength: 0, data: new byte[] { 0xfe });
TestTryReadByteOrderMark(expectedEncoding: Encoding.BigEndianUnicode, expectedPreambleLength: 2, data: new byte[] { 0xfe, 0xff });
}
[Fact]
[WorkItem(41903, "https://github.com/dotnet/roslyn/issues/41903")]
public void WriteWithRangeStartingLaterThanZero()
{
var sourceText = SourceText.From("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
var writer = new StringWriter();
sourceText.Write(writer, TextSpan.FromBounds(1, sourceText.Length));
Assert.Equal("BCDEFGHIJKLMNOPQRSTUVWXYZ", writer.ToString());
}
public static IEnumerable<object[]> AllRanges(int totalLength) =>
from start in Enumerable.Range(0, totalLength)
from length in Enumerable.Range(0, totalLength - start)
select new object[] { new TextSpan(start, length) };
[Theory]
[MemberData(nameof(AllRanges), 10)]
[WorkItem(41903, "https://github.com/dotnet/roslyn/issues/41903")]
public void WriteWithAllRanges(TextSpan span)
{
const string Text = "0123456789";
var sourceText = SourceText.From(Text);
var writer = new StringWriter();
sourceText.Write(writer, span);
Assert.Equal(Text.Substring(span.Start, span.Length), writer.ToString());
}
[Fact]
public void WriteWithSpanStartingAfterEndThrowsOutOfRange()
{
var ex = Assert.ThrowsAny<ArgumentOutOfRangeException>(() =>
SourceText.From("ABC").Write(TextWriter.Null, TextSpan.FromBounds(4, 4)));
Assert.Equal("span", ex.ParamName);
}
[Fact]
public void WriteWithSpanEndingAfterEndThrowsOutOfRange()
{
var ex = Assert.ThrowsAny<ArgumentOutOfRangeException>(() =>
SourceText.From("ABC").Write(TextWriter.Null, TextSpan.FromBounds(2, 4)));
Assert.Equal("span", ex.ParamName);
}
}
}
......@@ -469,7 +469,9 @@ public virtual SourceTextContainer Container
internal void CheckSubSpan(TextSpan span)
{
if (span.Start < 0 || span.Start > this.Length || span.End > this.Length)
Debug.Assert(0 <= span.Start && span.Start <= span.End);
if (span.End > this.Length)
{
throw new ArgumentOutOfRangeException(nameof(span));
}
......@@ -535,13 +537,13 @@ public virtual void Write(TextWriter writer, TextSpan span, CancellationToken ca
var buffer = s_charArrayPool.Allocate();
try
{
int offset = Math.Min(this.Length, span.Start);
int length = Math.Min(this.Length, span.End) - offset;
while (offset < length)
int offset = span.Start;
int end = span.End;
while (offset < end)
{
cancellationToken.ThrowIfCancellationRequested();
int count = Math.Min(buffer.Length, length - offset);
int count = Math.Min(buffer.Length, end - offset);
this.CopyTo(offset, buffer, 0, count);
writer.Write(buffer, 0, count);
offset += count;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册