提交 8a68e887 编写于 作者: C CyrusNajmabadi

Properly preserve newlines in merge section.

上级 8fc51455
......@@ -289,5 +289,164 @@ namespace N
{
}", index: 1, ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)]
public async Task TestTakeTop_WhitespaceInSection()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
=======
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
>>>>>>> This is theirs!
}",
@"
using System;
namespace N
{
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
}", index: 0, ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)]
public async Task TestTakeBottom1_WhitespaceInSection()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
=======
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
>>>>>>> This is theirs!
}",
@"
using System;
namespace N
{
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
}", index: 1, ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)]
public async Task TestTakeBoth_WhitespaceInSection()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
=======
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
>>>>>>> This is theirs!
}",
@"
using System;
namespace N
{
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
}", index: 2, ignoreTrivia: false);
}
}
}
......@@ -24,8 +24,5 @@ protected override bool IsDisabledText(SyntaxTrivia trivia)
protected override bool IsEndOfLine(SyntaxTrivia trivia)
=> trivia.Kind() == SyntaxKind.EndOfLineTrivia;
protected override bool IsNewLine(char ch)
=> SyntaxFacts.IsNewLine(ch);
}
}
......@@ -18,7 +18,6 @@ protected AbstractResolveConflictMarkerCodeFixProvider(string diagnosticId)
FixableDiagnosticIds = ImmutableArray.Create(diagnosticId);
}
protected abstract bool IsNewLine(char ch);
protected abstract bool IsEndOfLine(SyntaxTrivia trivia);
protected abstract bool IsDisabledText(SyntaxTrivia trivia);
protected abstract bool IsConflictMarker(SyntaxTrivia trivia);
......@@ -108,91 +107,74 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
? FeaturesResources.Take_bottom
: string.Format(FeaturesResources.Take_0, bottomText);
var startSpan = startTrivia.Span;
var equalsSpan = equalsTrivia.Span;
var endSpan = endTrivia.Span;
var lessThanPosition = startTrivia.SpanStart;
var equalsPosition = equalsTrivia.SpanStart;
var greaterThanPosition = endTrivia.SpanStart;
context.RegisterCodeFix(
new MyCodeAction(takeTopText,
c => TakeTopAsync(document, startSpan, equalsSpan, endSpan, c)),
c => TakeTopAsync(document, lessThanPosition, equalsPosition, greaterThanPosition, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(takeBottomText,
c => TakeBottomAsync(document, startSpan, equalsSpan, endSpan, c)),
c => TakeBottomAsync(document, lessThanPosition, equalsPosition, greaterThanPosition, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(FeaturesResources.Take_both,
c => TakeBothAsync(document, startSpan, equalsSpan, endSpan, c)),
c => TakeBothAsync(document, lessThanPosition, equalsPosition, greaterThanPosition, c)),
context.Diagnostics);
}
private async Task<Document> TakeTopAsync(
Document document, TextSpan startSpan, TextSpan equalsSpan, TextSpan endSpan,
Document document, int lessThanPos, int equalsPos, int greaterThanPos,
CancellationToken cancellationToken)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var bottomEnd = GetEndIncludingNewLines(text, endSpan.End);
var newText = text.Replace(TextSpan.FromBounds(equalsSpan.Start, bottomEnd), "");
var bottomEnd = GetEndIncludingLineBreak(text, greaterThanPos);
var newText = text.Replace(TextSpan.FromBounds(equalsPos, bottomEnd), "");
var startEnd = GetEndIncludingNewLines(text, startSpan.End);
var finaltext = newText.Replace(TextSpan.FromBounds(startSpan.Start, startEnd), "");
var startEnd = GetEndIncludingLineBreak(text, lessThanPos);
var finaltext = newText.Replace(TextSpan.FromBounds(lessThanPos, startEnd), "");
return document.WithText(finaltext);
}
private async Task<Document> TakeBottomAsync(
Document document, TextSpan startSpan, TextSpan equalsSpan, TextSpan endSpan,
Document document, int lessThanPos, int equalsPos, int greaterThanPos,
CancellationToken cancellationToken)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var bottomEnd = GetEndIncludingNewLines(text, endSpan.End);
var newText = text.Replace(TextSpan.FromBounds(endSpan.Start, bottomEnd), "");
var bottomEnd = GetEndIncludingLineBreak(text, greaterThanPos);
var newText = text.Replace(TextSpan.FromBounds(greaterThanPos, bottomEnd), "");
var equalsEnd = GetEndIncludingNewLines(text, equalsSpan.End);
var finaltext = newText.Replace(TextSpan.FromBounds(startSpan.Start, equalsEnd), "");
var equalsEnd = GetEndIncludingLineBreak(text, equalsPos);
var finaltext = newText.Replace(TextSpan.FromBounds(lessThanPos, equalsEnd), "");
return document.WithText(finaltext);
}
private async Task<Document> TakeBothAsync(
Document document,
TextSpan startSpan, TextSpan equalsSpan, TextSpan endSpan,
Document document, int lessThanPos, int equalsPos, int greaterThanPos,
CancellationToken cancellationToken)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var bottomEnd = GetEndIncludingNewLines(text, endSpan.End);
var newText = text.Replace(TextSpan.FromBounds(endSpan.Start, bottomEnd), "");
var bottomEnd = GetEndIncludingLineBreak(text, greaterThanPos);
var newText = text.Replace(TextSpan.FromBounds(greaterThanPos, bottomEnd), "");
var equalsEnd = GetEndIncludingNewLines(text, equalsSpan.End);
newText = newText.Replace(TextSpan.FromBounds(equalsSpan.Start, equalsEnd), "");
var equalsEnd = GetEndIncludingLineBreak(text, equalsPos);
newText = newText.Replace(TextSpan.FromBounds(equalsPos, equalsEnd), "");
var startEnd = GetEndIncludingNewLines(text, startSpan.End);
var finaltext = newText.Replace(TextSpan.FromBounds(startSpan.Start, startEnd), "");
var startEnd = GetEndIncludingLineBreak(text, lessThanPos);
var finaltext = newText.Replace(TextSpan.FromBounds(lessThanPos, startEnd), "");
return document.WithText(finaltext);
}
private int GetEndIncludingNewLines(SourceText text, int position)
{
var endPosition = position;
// Skip the text until we get to the newlines.
while (endPosition < text.Length && !IsNewLine(text[endPosition]))
{
endPosition++;
}
// Skip the newlines.
while (endPosition < text.Length && IsNewLine(text[endPosition]))
{
endPosition++;
}
return endPosition;
}
private int GetEndIncludingLineBreak(SourceText text, int position)
=> text.Lines.GetLineFromPosition(position).SpanIncludingLineBreak.End;
private int GetEqualsConflictMarkerIndex(SourceText text, SyntaxToken token)
{
......
......@@ -26,9 +26,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConflictMarkerResolution
Protected Overrides Function IsEndOfLine(trivia As SyntaxTrivia) As Boolean
Return trivia.Kind() = SyntaxKind.EndOfLineTrivia
End Function
Protected Overrides Function IsNewLine(ch As Char) As Boolean
Return SyntaxFacts.IsNewLine(ch)
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册