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

Properly support merge conflicts with empty sections.

上级 46a8a989
......@@ -157,5 +157,137 @@ static void Main2(string[] args)
}
}", index: 2, ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)]
public async Task TestEmptyTop_TakeTop()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
=======
class Program2
{
static void Main2(string[] args)
{
Program2 p;
Console.WriteLine(""Their section"");
}
}
>>>>>>> This is theirs!
}",
@"
using System;
namespace N
{
}", index: 0, ignoreTrivia: false);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)]
public async Task TestEmptyTop_TakeBottom()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
=======
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 TestEmptyBottom_TakeTop()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My 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 TestEmptyBottom_TakeBottom()
{
await TestInRegularAndScript1Async(
@"
using System;
namespace N
{
[|<<<<<<<|] This is mine!
class Program
{
static void Main(string[] args)
{
Program p;
Console.WriteLine(""My section"");
}
}
=======
>>>>>>> This is theirs!
}",
@"
using System;
namespace N
{
}", index: 1, ignoreTrivia: false);
}
}
}
......@@ -45,12 +45,6 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
while (true)
{
token = token.GetNextToken(includeZeroWidth: true);
if (token.RawKind == 0)
{
return;
}
var index = GetEqualsConflictMarkerIndex(text, token);
if (index >= 0)
{
......@@ -58,6 +52,8 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
if (index + 3 < token.LeadingTrivia.Count)
{
// normal case where there us =====, then dead code, then >>>>>>
var equalsTrivia = leadingTrivia[index];
var endOfLineTrivia = leadingTrivia[index + 1];
var disabledTrivia = leadingTrivia[index + 2];
......@@ -67,38 +63,69 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
IsDisabledText(disabledTrivia) &&
IsConflictMarker(text, endTrivia, '>'))
{
var topText = startTrivia.ToString().Substring(s_mergeConflictLength).Trim();
var takeTopText = string.IsNullOrWhiteSpace(topText)
? FeaturesResources.Take_top
: string.Format(FeaturesResources.Take_0, topText);
var bottomText = endTrivia.ToString().Substring(s_mergeConflictLength).Trim();
var takeBottomText = string.IsNullOrWhiteSpace(bottomText)
? FeaturesResources.Take_bottom
: string.Format(FeaturesResources.Take_0, bottomText);
var startSpan = startTrivia.Span;
var equalsSpan = equalsTrivia.Span;
var endSpan = endTrivia.Span;
context.RegisterCodeFix(
new MyCodeAction(takeTopText,
c => TakeTopAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(takeBottomText,
c => TakeBottomAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(FeaturesResources.Take_both,
c => TakeBothAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
RegisterCodeFixes(context, startTrivia, equalsTrivia, endTrivia);
return;
}
}
if (index + 2 < token.LeadingTrivia.Count)
{
// case where there is ===== followed by >>>>>> on the next line.
var equalsTrivia = leadingTrivia[index];
var endOfLineTrivia = leadingTrivia[index + 1];
var endTrivia = leadingTrivia[index + 2];
if (IsEndOfLine(endOfLineTrivia) &&
IsConflictMarker(text, endTrivia, '>'))
{
RegisterCodeFixes(context, startTrivia, equalsTrivia, endTrivia);
return;
}
}
}
token = token.GetNextToken(includeZeroWidth: true);
if (token.RawKind == 0)
{
return;
}
}
}
private void RegisterCodeFixes(
CodeFixContext context, SyntaxTrivia startTrivia, SyntaxTrivia equalsTrivia, SyntaxTrivia endTrivia)
{
var document = context.Document;
var topText = startTrivia.ToString().Substring(s_mergeConflictLength).Trim();
var takeTopText = string.IsNullOrWhiteSpace(topText)
? FeaturesResources.Take_top
: string.Format(FeaturesResources.Take_0, topText);
var bottomText = endTrivia.ToString().Substring(s_mergeConflictLength).Trim();
var takeBottomText = string.IsNullOrWhiteSpace(bottomText)
? FeaturesResources.Take_bottom
: string.Format(FeaturesResources.Take_0, bottomText);
var startSpan = startTrivia.Span;
var equalsSpan = equalsTrivia.Span;
var endSpan = endTrivia.Span;
context.RegisterCodeFix(
new MyCodeAction(takeTopText,
c => TakeTopAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(takeBottomText,
c => TakeBottomAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
context.RegisterCodeFix(
new MyCodeAction(FeaturesResources.Take_both,
c => TakeBothAsync(document, startSpan, equalsSpan, endSpan, c)),
context.Diagnostics);
}
private async Task<Document> TakeTopAsync(
Document document, TextSpan startSpan, TextSpan equalsSpan, TextSpan endSpan,
CancellationToken cancellationToken)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册