-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Closed
Copy link
Description
When working on formatting for .razor files, I noticed something odd. Under certain conditions, GetTextChanges would return invalid edits. I'm not sure exactly under what conditions. I was able to come up with a (somewhat) minimal repro.
Version Used:
Microsoft.CodeAnalysis 3.4.0
dotnet 3.1.101
Steps to Reproduce:
dotnet new console -o SourceTextBugcd SourceTextBug- Replace
Program.cscontent with the following,
Program.cs
using System;
using Microsoft.CodeAnalysis.Text;
namespace SourceTextBug
{
class Program
{
static void Main(string[] args)
{
var content = @"@functions{
public class Foo
{
void Method()
{
}
}
}";
Console.WriteLine("Initial:");
Console.WriteLine(content);
Console.WriteLine();
var text = SourceText.From(content);
var edits1 = new TextChange[]
{
new TextChange(new TextSpan(39, 0), " "),
new TextChange(new TextSpan(42, 0), " "),
new TextChange(new TextSpan(57, 0), " "),
new TextChange(new TextSpan(58, 0), "\r\n"),
new TextChange(new TextSpan(64, 2), " "),
new TextChange(new TextSpan(69, 0), " "),
};
var changedText = text.WithChanges(edits1);
Console.WriteLine("After first set of edits:");
Console.WriteLine(changedText.ToString());
Console.WriteLine();
var edits2 = new TextChange[]
{
new TextChange(new TextSpan(35, 4), string.Empty),
new TextChange(new TextSpan(46, 4), string.Empty),
new TextChange(new TextSpan(73, 4), string.Empty),
new TextChange(new TextSpan(88, 0), " "),
new TextChange(new TextSpan(90, 4), string.Empty),
new TextChange(new TextSpan(105, 4), string.Empty),
};
var changedText2 = changedText.WithChanges(edits2);
Console.WriteLine("After second set of edits:");
Console.WriteLine(changedText2.ToString());
Console.WriteLine();
Console.WriteLine("Diff of final text vs original:");
var changes = changedText2.GetTextChanges(text);
foreach (var change in changes)
{
Console.WriteLine(change);
}
}
}
}<PackageReference Include="Microsoft.CodeAnalysis" Version="3.4.0" />`dotnet run
Expected Behavior:
The set of TextChanges produced should be valid and not overlap.
Actual Behavior:
Overlapping changes are produced.
Output
Initial:
@functions{
public class Foo
{
void Method()
{
}
}
}
After first set of edits:
@functions{
public class Foo
{
void Method()
{
}
}
}
After second set of edits:
@functions{
public class Foo
{
void Method()
{
}
}
}
Diff of final text vs original:
TextChange: { [35..39), " " }
TextChange: { [42..42), " " }
TextChange: { [57..57), " " }
TextChange: { [58..58), "
" }
TextChange: { [64..66), " }
" }
TextChange: { [62..66), "" }
TextChange: { [69..69), " " }
TextChange: { [73..77), "" }
Notice the two overlapping edits,
[64..66) and [62..66)
Reactions are currently unavailable