Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
2addfa50
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
2addfa50
编写于
3月 03, 2020
作者:
M
msftbot[bot]
提交者:
GitHub
3月 03, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #42117 from CyrusNajmabadi/conflictMarkerFixAll
Add 'fix all' support for picking conflict-marker regions.
上级
8c0c2126
b70d43b2
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
510 addition
and
66 deletion
+510
-66
src/EditorFeatures/CSharpTest/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs
...ConflictMarkerResolution/ConflictMarkerResolutionTests.cs
+142
-0
src/EditorFeatures/VisualBasicTest/ConflictMarkerResolution/ConflictMarkerResolutionTests.vb
...ConflictMarkerResolution/ConflictMarkerResolutionTests.vb
+112
-0
src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs
...MarkerResolution/AbstractConflictMarkerCodeFixProvider.cs
+145
-55
src/Features/Core/Portable/ConflictMarkerResolution/ConflictMarkerFixAllProvider.cs
.../ConflictMarkerResolution/ConflictMarkerFixAllProvider.cs
+30
-0
src/Features/Core/Portable/FeaturesResources.resx
src/Features/Core/Portable/FeaturesResources.resx
+3
-0
src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
+5
-0
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
+5
-0
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/DocumentBasedFixAllProvider.cs
...s/Workspace/Core/CodeFixes/DocumentBasedFixAllProvider.cs
+13
-11
未找到文件。
src/EditorFeatures/CSharpTest/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs
浏览文件 @
2addfa50
...
...
@@ -8,6 +8,7 @@
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Roslyn.Test.Utilities
;
using
Xunit
;
namespace
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConflictMarkerResolution
...
...
@@ -448,6 +449,147 @@ static void Main2(string[] args)
}
}
}"
,
index
:
2
);
}
[
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)]
public
async
Task
TestFixAll1
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
namespace N
{
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
{
}
=======
class Program2
{
}
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
{
}
=======
class Program4
{
}
>>>>>>> This is theirs!
}"
,
@"
using System;
namespace N
{
class Program
{
}
class Program3
{
}
}"
,
index
:
0
);
}
[
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)]
public
async
Task
TestFixAll2
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
namespace N
{
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
{
}
=======
class Program2
{
}
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
{
}
=======
class Program4
{
}
>>>>>>> This is theirs!
}"
,
@"
using System;
namespace N
{
class Program2
{
}
class Program4
{
}
}"
,
index
:
1
);
}
[
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)]
public
async
Task
TestFixAll3
()
{
await
TestInRegularAndScript1Async
(
@"
using System;
namespace N
{
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
{
}
=======
class Program2
{
}
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
{
}
=======
class Program4
{
}
>>>>>>> This is theirs!
}"
,
@"
using System;
namespace N
{
class Program
{
}
class Program2
{
}
class Program3
{
}
class Program4
{
}
}"
,
index
:
2
);
}
}
...
...
src/EditorFeatures/VisualBasicTest/ConflictMarkerResolution/ConflictMarkerResolutionTests.vb
浏览文件 @
2addfa50
...
...
@@ -126,6 +126,118 @@ namespace N
Console.WriteLine(
""
Their section
""
)
end sub
end class
end namespace"
,
index
:
=
2
)
End
Function
<
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)
>
Public
Async
Function
TestFixAll1
()
As
Task
Await
TestInRegularAndScript1Async
(
"
imports System
namespace N
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
end class
=======
class Program2
end class
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
end class
=======
class Program4
end class
>>>>>>> This is theirs!
end namespace"
,
"
imports System
namespace N
class Program
end class
class Program3
end class
end namespace"
,
index
:
=
0
)
End
Function
<
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)
>
Public
Async
Function
TestFixAll2
()
As
Task
Await
TestInRegularAndScript1Async
(
"
imports System
namespace N
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
end class
=======
class Program2
end class
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
end class
=======
class Program4
end class
>>>>>>> This is theirs!
end namespace"
,
"
imports System
namespace N
class Program2
end class
class Program4
end class
end namespace"
,
index
:
=
1
)
End
Function
<
WorkItem
(
21107
,
"https://github.com/dotnet/roslyn/issues/21107"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsResolveConflictMarker
)
>
Public
Async
Function
TestFixAll3
()
As
Task
Await
TestInRegularAndScript1Async
(
"
imports System
namespace N
{|FixAllInDocument:<<<<<<<|} This is mine!
class Program
end class
=======
class Program2
end class
>>>>>>> This is theirs!
<<<<<<< This is mine!
class Program3
end class
=======
class Program4
end class
>>>>>>> This is theirs!
end namespace"
,
"
imports System
namespace N
class Program
end class
class Program2
end class
class Program3
end class
class Program4
end class
end namespace"
,
index
:
=
2
)
End
Function
End
Class
...
...
src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs
浏览文件 @
2addfa50
...
...
@@ -6,18 +6,25 @@
using
System
;
using
System.Collections.Immutable
;
using
System.Diagnostics
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Text
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.ConflictMarkerResolution
{
internal
abstract
class
AbstractResolveConflictMarkerCodeFixProvider
:
CodeFixProvider
internal
abstract
partial
class
AbstractResolveConflictMarkerCodeFixProvider
:
CodeFixProvider
{
private
const
string
TakeTopEquivalenceKey
=
nameof
(
TakeTopEquivalenceKey
);
private
const
string
TakeBottomEquivalenceKey
=
nameof
(
TakeBottomEquivalenceKey
);
private
const
string
TakeBothEquivalenceKey
=
nameof
(
TakeBothEquivalenceKey
);
private
static
readonly
int
s_mergeConflictLength
=
"<<<<<<<"
.
Length
;
private
readonly
ISyntaxKinds
_syntaxKinds
;
...
...
@@ -29,15 +36,11 @@ internal abstract class AbstractResolveConflictMarkerCodeFixProvider : CodeFixPr
_syntaxKinds
=
syntaxKinds
;
}
public
override
FixAllProvider
?
GetFixAllProvider
()
{
// Fix All is not currently supported for this code fix
// https://github.com/dotnet/roslyn/issues/34461
return
null
;
}
public
override
ImmutableArray
<
string
>
FixableDiagnosticIds
{
get
;
}
public
override
FixAllProvider
GetFixAllProvider
()
=>
new
ConflictMarkerFixAllProvider
(
this
);
public
override
async
Task
RegisterCodeFixesAsync
(
CodeFixContext
context
)
{
var
cancellationToken
=
context
.
CancellationToken
;
...
...
@@ -46,17 +49,24 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
startTrivia
=
root
.
FindTrivia
(
context
.
Span
.
Start
);
if
(!
IsConflictMarker
(
text
,
startTrivia
,
'<'
))
{
return
;
}
var
conflictTrivia
=
TryGetConflictTrivia
(
text
,
startTrivia
);
if
(
conflictTrivia
==
null
)
return
;
var
(
equalsTrivia
,
endTrivia
)
=
conflictTrivia
.
Value
;
RegisterCodeFixes
(
context
,
startTrivia
,
equalsTrivia
,
endTrivia
);
}
private
(
SyntaxTrivia
equalsTrivia
,
SyntaxTrivia
endTrivia
)?
TryGetConflictTrivia
(
SourceText
text
,
SyntaxTrivia
startTrivia
)
{
var
token
=
startTrivia
.
Token
;
while
(
true
)
{
var
index
=
GetEqualsConflictMarkerIndex
(
text
,
token
);
var
index
=
GetEqualsConflictMarkerIndex
(
text
,
token
,
afterPosition
:
startTrivia
.
SpanStart
);
if
(
index
>=
0
)
{
var
leadingTrivia
=
token
.
LeadingTrivia
;
...
...
@@ -74,8 +84,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
_syntaxKinds
.
DisabledTextTrivia
==
disabledTrivia
.
RawKind
&&
IsConflictMarker
(
text
,
endTrivia
,
'>'
))
{
RegisterCodeFixes
(
context
,
startTrivia
,
equalsTrivia
,
endTrivia
);
return
;
return
(
equalsTrivia
,
endTrivia
);
}
}
...
...
@@ -90,8 +99,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
if
(
_syntaxKinds
.
EndOfLineTrivia
==
endOfLineTrivia
.
RawKind
&&
IsConflictMarker
(
text
,
endTrivia
,
'>'
))
{
RegisterCodeFixes
(
context
,
startTrivia
,
equalsTrivia
,
endTrivia
);
return
;
return
(
equalsTrivia
,
endTrivia
);
}
}
}
...
...
@@ -99,7 +107,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
token
=
token
.
GetNextToken
(
includeZeroWidth
:
true
);
if
(
token
.
RawKind
==
0
)
{
return
;
return
null
;
}
}
}
...
...
@@ -125,77 +133,99 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
context
.
RegisterCodeFix
(
new
MyCodeAction
(
takeTopText
,
c
=>
TakeTopAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
)),
c
=>
TakeTopAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
),
TakeTopEquivalenceKey
),
context
.
Diagnostics
);
context
.
RegisterCodeFix
(
new
MyCodeAction
(
takeBottomText
,
c
=>
TakeBottomAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
)),
c
=>
TakeBottomAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
),
TakeBottomEquivalenceKey
),
context
.
Diagnostics
);
context
.
RegisterCodeFix
(
new
MyCodeAction
(
FeaturesResources
.
Take_both
,
c
=>
TakeBothAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
)),
c
=>
TakeBothAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
c
),
TakeBothEquivalenceKey
),
context
.
Diagnostics
);
}
private
async
Task
<
Document
>
TakeTop
Async
(
private
async
Task
<
Document
>
AddEdits
Async
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPos
,
Action
<
SourceText
,
ArrayBuilder
<
TextChange
>,
int
,
int
,
int
>
addEdits
,
CancellationToken
cancellationToken
)
{
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
bottomEnd
=
GetEndIncludingLineBreak
(
text
,
endPo
s
);
var
newText
=
text
.
Replace
(
TextSpan
.
FromBounds
(
equalsPos
,
bottomEnd
),
""
);
using
var
_
=
ArrayBuilder
<
TextChange
>.
GetInstance
(
out
var
edit
s
);
addEdits
(
text
,
edits
,
startPos
,
equalsPos
,
endPos
);
var
startEnd
=
GetEndIncludingLineBreak
(
text
,
startPos
);
var
finaltext
=
newText
.
Replace
(
TextSpan
.
FromBounds
(
startPos
,
startEnd
),
""
);
return
document
.
WithText
(
finaltext
);
var
finalText
=
text
.
WithChanges
(
edits
);
return
document
.
WithText
(
finalText
);
}
private
async
Task
<
Document
>
TakeBottomAsync
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPo
s
,
CancellationToken
cancellationToken
)
private
static
void
AddTopEdits
(
SourceText
text
,
ArrayBuilder
<
TextChange
>
edit
s
,
int
startPos
,
int
equalsPos
,
int
endPos
)
{
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
// Delete the line containing <<<<<<<
var
startEnd
=
GetEndIncludingLineBreak
(
text
,
startPos
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
startPos
,
startEnd
),
""
));
// Remove the chunk of text (inclusive) from ======= through >>>>>>>
var
bottomEnd
=
GetEndIncludingLineBreak
(
text
,
endPos
);
var
newText
=
text
.
Replace
(
TextSpan
.
FromBounds
(
endPos
,
bottomEnd
),
""
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
equalsPos
,
bottomEnd
),
""
));
}
private
static
void
AddBottomEdits
(
SourceText
text
,
ArrayBuilder
<
TextChange
>
edits
,
int
startPos
,
int
equalsPos
,
int
endPos
)
{
// Remove the chunk of text (inclusive) from <<<<<<< through =======
var
equalsEnd
=
GetEndIncludingLineBreak
(
text
,
equalsPos
);
var
finaltext
=
newText
.
Replace
(
TextSpan
.
FromBounds
(
startPos
,
equalsEnd
),
""
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
startPos
,
equalsEnd
),
""
)
);
return
document
.
WithText
(
finaltext
);
// Delete the line containing >>>>>>>
var
bottomEnd
=
GetEndIncludingLineBreak
(
text
,
endPos
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
endPos
,
bottomEnd
),
""
));
}
private
async
Task
<
Document
>
TakeBothAsync
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPo
s
,
CancellationToken
cancellationToken
)
private
static
void
AddBothEdits
(
SourceText
text
,
ArrayBuilder
<
TextChange
>
edit
s
,
int
startPos
,
int
equalsPos
,
int
endPos
)
{
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
// Delete the line containing <<<<<<<
var
startEnd
=
GetEndIncludingLineBreak
(
text
,
startPos
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
startPos
,
startEnd
),
""
));
// Delete the line containing =======
var
equalsEnd
=
GetEndIncludingLineBreak
(
text
,
equalsPos
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
equalsPos
,
equalsEnd
),
""
));
// Delete the line containing >>>>>>>
var
bottomEnd
=
GetEndIncludingLineBreak
(
text
,
endPos
);
var
newText
=
text
.
Replace
(
TextSpan
.
FromBounds
(
endPos
,
bottomEnd
),
""
);
edits
.
Add
(
new
TextChange
(
TextSpan
.
FromBounds
(
endPos
,
bottomEnd
),
""
));
}
var
equalsEnd
=
GetEndIncludingLineBreak
(
text
,
equalsPos
);
newText
=
newText
.
Replace
(
TextSpan
.
FromBounds
(
equalsPos
,
equalsEnd
),
""
);
private
Task
<
Document
>
TakeTopAsync
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPos
,
CancellationToken
cancellationToken
)
=>
AddEditsAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
AddTopEdits
,
cancellationToken
);
var
startEnd
=
GetEndIncludingLineBreak
(
text
,
startPos
);
var
finaltext
=
newText
.
Replace
(
TextSpan
.
FromBounds
(
startPos
,
startEnd
),
""
);
private
Task
<
Document
>
TakeBottomAsync
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPos
,
CancellationToken
cancellationToken
)
=>
AddEditsAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
AddBottomEdits
,
cancellationToken
);
return
document
.
WithText
(
finaltext
);
}
private
Task
<
Document
>
TakeBothAsync
(
Document
document
,
int
startPos
,
int
equalsPos
,
int
endPos
,
CancellationToken
cancellationToken
)
=>
AddEditsAsync
(
document
,
startPos
,
equalsPos
,
endPos
,
AddBothEdits
,
cancellationToken
);
private
int
GetEndIncludingLineBreak
(
SourceText
text
,
int
position
)
private
static
int
GetEndIncludingLineBreak
(
SourceText
text
,
int
position
)
=>
text
.
Lines
.
GetLineFromPosition
(
position
).
SpanIncludingLineBreak
.
End
;
private
int
GetEqualsConflictMarkerIndex
(
SourceText
text
,
SyntaxToken
token
)
private
int
GetEqualsConflictMarkerIndex
(
SourceText
text
,
SyntaxToken
token
,
int
afterPosition
)
{
if
(
token
.
HasLeadingTrivia
)
{
var
i
=
0
;
foreach
(
var
trivia
in
token
.
LeadingTrivia
)
{
if
(
IsConflictMarker
(
text
,
trivia
,
'='
))
if
(
trivia
.
SpanStart
>=
afterPosition
&&
IsConflictMarker
(
text
,
trivia
,
'='
))
{
return
i
;
}
...
...
@@ -207,11 +237,6 @@ private int GetEqualsConflictMarkerIndex(SourceText text, SyntaxToken token)
return
-
1
;
}
private
SyntaxTrivia
GetEqualsConflictMarker
(
SyntaxToken
token
)
{
throw
new
NotImplementedException
();
}
private
bool
IsConflictMarker
(
SourceText
text
,
SyntaxTrivia
trivia
,
char
ch
)
{
return
...
...
@@ -220,10 +245,75 @@ private bool IsConflictMarker(SourceText text, SyntaxTrivia trivia, char ch)
text
[
trivia
.
SpanStart
]
==
ch
;
}
private
async
Task
<
SyntaxNode
>
FixAllAsync
(
Document
document
,
ImmutableArray
<
Diagnostic
>
diagnostics
,
string
equivalenceKey
,
CancellationToken
cancellationToken
)
{
Debug
.
Assert
(
equivalenceKey
==
TakeTopEquivalenceKey
||
equivalenceKey
==
TakeBottomEquivalenceKey
||
equivalenceKey
==
TakeBothEquivalenceKey
);
// Process diagnostics in order so we produce edits in the right order.
var
orderedDiagnostics
=
diagnostics
.
OrderBy
(
(
d1
,
d2
)
=>
d1
.
Location
.
SourceSpan
.
Start
-
d2
.
Location
.
SourceSpan
.
Start
).
ToImmutableArray
();
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
root
=
await
document
.
GetRequiredSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
// Create a single array of edits to apply. Then walk over all the
// conflict-marker-regions we want to fix and add the edits for each
// region into that array. Then apply the array just once to get the
// final document.
using
var
_
=
ArrayBuilder
<
TextChange
>.
GetInstance
(
out
var
edits
);
foreach
(
var
diagnostic
in
diagnostics
)
{
var
startTrivia
=
root
.
FindTrivia
(
diagnostic
.
Location
.
SourceSpan
.
Start
);
// We'll be called on all the conflict marker diagnostics (i.e. for <<<<<<< =======
// and >>>>>>>). We only care about the <<<<<<< ones as that controls which chunks
// we'll be processing.
if
(!
IsConflictMarker
(
text
,
startTrivia
,
'<'
))
continue
;
var
conflictTrivia
=
TryGetConflictTrivia
(
text
,
startTrivia
);
if
(
conflictTrivia
==
null
)
continue
;
var
startPos
=
startTrivia
.
SpanStart
;
var
equalsPos
=
conflictTrivia
.
Value
.
equalsTrivia
.
SpanStart
;
var
endPos
=
conflictTrivia
.
Value
.
endTrivia
.
SpanStart
;
switch
(
equivalenceKey
)
{
case
TakeTopEquivalenceKey
:
AddTopEdits
(
text
,
edits
,
startPos
,
equalsPos
,
endPos
);
continue
;
case
TakeBottomEquivalenceKey
:
AddBottomEdits
(
text
,
edits
,
startPos
,
equalsPos
,
endPos
);
continue
;
case
TakeBothEquivalenceKey
:
AddBothEdits
(
text
,
edits
,
startPos
,
equalsPos
,
endPos
);
continue
;
default
:
throw
ExceptionUtilities
.
UnexpectedValue
(
equivalenceKey
);
}
}
var
finalText
=
text
.
WithChanges
(
edits
);
var
finalDoc
=
document
.
WithText
(
finalText
);
return
await
finalDoc
.
GetRequiredSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
}
private
class
MyCodeAction
:
CodeAction
.
DocumentChangeAction
{
public
MyCodeAction
(
string
title
,
Func
<
CancellationToken
,
Task
<
Document
>>
createChangedDocument
)
:
base
(
title
,
createChangedDocument
)
public
MyCodeAction
(
string
title
,
Func
<
CancellationToken
,
Task
<
Document
>>
createChangedDocument
,
string
equivalenceKey
)
:
base
(
title
,
createChangedDocument
,
equivalenceKey
)
{
}
}
...
...
src/Features/Core/Portable/ConflictMarkerResolution/ConflictMarkerFixAllProvider.cs
0 → 100644
浏览文件 @
2addfa50
// 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.
#
nullable
enable
using
System.Collections.Immutable
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.CodeStyle
;
namespace
Microsoft.CodeAnalysis.ConflictMarkerResolution
{
internal
abstract
partial
class
AbstractResolveConflictMarkerCodeFixProvider
{
private
class
ConflictMarkerFixAllProvider
:
DocumentBasedFixAllProvider
{
private
readonly
AbstractResolveConflictMarkerCodeFixProvider
_codeFixProvider
;
public
ConflictMarkerFixAllProvider
(
AbstractResolveConflictMarkerCodeFixProvider
codeFixProvider
)
=>
_codeFixProvider
=
codeFixProvider
;
protected
override
string
CodeActionTitle
=>
FeaturesResources
.
Resolve_conflict_markers
;
protected
override
Task
<
SyntaxNode
>
FixAllInDocumentAsync
(
FixAllContext
fixAllContext
,
Document
document
,
ImmutableArray
<
Diagnostic
>
diagnostics
)
=>
_codeFixProvider
.
FixAllAsync
(
document
,
diagnostics
,
fixAllContext
.
CodeActionEquivalenceKey
,
fixAllContext
.
CancellationToken
);
}
}
}
src/Features/Core/Portable/FeaturesResources.resx
浏览文件 @
2addfa50
...
...
@@ -1762,4 +1762,7 @@ This version used in: {2}</value>
<data
name=
"Implement_explicitly"
xml:space=
"preserve"
>
<value>
Implement explicitly
</value>
</data>
<data
name=
"Resolve_conflict_markers"
xml:space=
"preserve"
>
<value>
Resolve conflict markers
</value>
</data>
</root>
\ No newline at end of file
src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Místo {0} použijte {1}
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Hrubá úprava
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.de.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
"{0}" durch "{1}" ersetzen
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Grobe Bearbeitung
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.es.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Reemplazar "{0}" por "{1}"
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Edición superficial
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Remplacer '{0}' par '{1}'
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Modification non applicable
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.it.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Sostituisci '{0}' con '{1}'
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Modifica non applicabile
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
'{0}' を '{1}' に置き換える
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Rude 編集
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
'{0}'을(를) '{1}'(으)로 바꾸기
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
편집 다시 실행
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Zamień element „{0}” na element „{1}”
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Edycja reguły
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Substituir '{0}' por '{1}'
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Edição rudimentar
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
Замените '{0}' на '{1}'
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
Грубая редакция
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
'{0}' öğesini '{1}' ile değiştir
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
İşlenmemiş düzenleme
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
将 "{0}" 替换为 "{1}"
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
原始编辑
</target>
...
...
src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf
浏览文件 @
2addfa50
...
...
@@ -547,6 +547,11 @@
<target
state=
"translated"
>
將 ‘{0}’ 取代為 ‘{1}'
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"Resolve_conflict_markers"
>
<source>
Resolve conflict markers
</source>
<target
state=
"new"
>
Resolve conflict markers
</target>
<note
/>
</trans-unit>
<trans-unit
id=
"RudeEdit"
>
<source>
Rude edit
</source>
<target
state=
"translated"
>
粗略編輯
</target>
...
...
src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/DocumentBasedFixAllProvider.cs
浏览文件 @
2addfa50
...
...
@@ -8,6 +8,8 @@
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Roslyn.Utilities
;
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
...
...
@@ -92,28 +94,28 @@ private async Task<Solution> GetSolutionFixesAsync(FixAllContext fixAllContext,
{
var
documentDiagnosticsToFix
=
await
FixAllContextHelper
.
GetDocumentDiagnosticsToFixAsync
(
fixAllContext
,
progressTrackerOpt
:
null
).
ConfigureAwait
(
false
);
var
solution
=
fixAllContext
.
Solution
;
var
newDocuments
=
new
List
<
Task
<
SyntaxNode
>>(
documents
.
Length
);
using
var
_
=
PooledDictionary
<
DocumentId
,
Task
<
SyntaxNode
>>.
GetInstance
(
out
var
documentIdToNewNode
);
foreach
(
var
document
in
documents
)
{
// Don't bother examining any documents that aren't in the list of docs that
// actually have diagnostics.
if
(!
documentDiagnosticsToFix
.
TryGetValue
(
document
,
out
var
diagnostics
))
{
newDocuments
.
Add
(
document
.
GetSyntaxRootAsync
(
fixAllContext
.
CancellationToken
));
continue
;
}
newDocuments
.
Add
(
FixAllInDocumentAsync
(
fixAllContext
,
document
,
diagnostics
));
documentIdToNewNode
.
Add
(
document
.
Id
,
FixAllInDocumentAsync
(
fixAllContext
,
document
,
diagnostics
));
}
for
(
var
i
=
0
;
i
<
documents
.
Length
;
i
++)
// Allow the processing of all the documents to happen concurrently.
await
Task
.
WhenAll
(
documentIdToNewNode
.
Values
).
ConfigureAwait
(
false
);
var
solution
=
fixAllContext
.
Solution
;
foreach
(
var
(
docId
,
syntaxNodeTask
)
in
documentIdToNewNode
)
{
var
newDocumentRoot
=
await
newDocuments
[
i
]
.
ConfigureAwait
(
false
);
var
newDocumentRoot
=
await
syntaxNodeTask
.
ConfigureAwait
(
false
);
if
(
newDocumentRoot
==
null
)
{
continue
;
}
solution
=
solution
.
WithDocumentSyntaxRoot
(
doc
uments
[
i
].
Id
,
newDocumentRoot
);
solution
=
solution
.
WithDocumentSyntaxRoot
(
docId
,
newDocumentRoot
);
}
return
solution
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录