Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a623e787
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,体验更适合开发者的 AI 搜索 >>
提交
a623e787
编写于
7月 15, 2019
作者:
P
Petr Houska
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move invertIf to helpers + tests.
上级
da262c1c
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
239 addition
and
39 deletion
+239
-39
src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs
src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs
+117
-0
src/EditorFeatures/CSharpTest/RefactoringHelpers/RefactoringHelpersTests.cs
.../CSharpTest/RefactoringHelpers/RefactoringHelpersTests.cs
+78
-0
src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs
...ortable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs
+0
-7
src/Features/Core/Portable/CodeRefactorings/AbstractRefactoringHelpersService.cs
...ble/CodeRefactorings/AbstractRefactoringHelpersService.cs
+9
-0
src/Features/Core/Portable/CodeRefactorings/IRefactoringHelpersService.cs
...e/Portable/CodeRefactorings/IRefactoringHelpersService.cs
+1
-0
src/Features/Core/Portable/InvertIf/AbstractInvertIfCodeRefactoringProvider.cs
...table/InvertIf/AbstractInvertIfCodeRefactoringProvider.cs
+3
-20
src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb
...f/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb
+0
-6
src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb
.../VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb
+0
-6
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
...arp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
+12
-0
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
...anguageServices/SyntaxFactsService/ISyntaxFactsService.cs
+1
-0
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
...ortable/LanguageServices/VisualBasicSyntaxFactsService.vb
+18
-0
未找到文件。
src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs
浏览文件 @
a623e787
...
...
@@ -479,6 +479,123 @@ void Goo()
}"
);
}
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvertIf
)]
public
async
Task
TestMultiline_IfElseIfElseSelection1
()
{
await
TestInRegularAndScriptAsync
(
@"class A
{
void Goo()
{
[|if (a)
{
a();
}
else if (b)
{
b();
}
else
{
c();
}|]
}
}"
,
@"class A
{
void Goo()
{
if (!a)
{
if (b)
{
b();
}
else
{
c();
}
}
else
{
a();
}
}
}"
);
}
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvertIf
)]
public
async
Task
TestMultiline_IfElseIfElseSelection2
()
{
await
TestInRegularAndScriptAsync
(
@"class A
{
void Goo()
{
[|if (a)
{
a();
}|]
else if (b)
{
b();
}
else
{
c();
}
}
}"
,
@"class A
{
void Goo()
{
if (!a)
{
if (b)
{
b();
}
else
{
c();
}
}
else
{
a();
}
}
}"
);
}
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvertIf
)]
public
async
Task
TestMultilineMissing_IfElseIfElseSubSelection
()
{
await
TestMissingInRegularAndScriptAsync
(
@"class A
{
void Goo()
{
if (a)
{
a();
}
[|else if (b)
{
b();
}
else
{
c();
}|]
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvertIf
)]
public
async
Task
TestMultiline_IfElse
()
{
...
...
src/EditorFeatures/CSharpTest/RefactoringHelpers/RefactoringHelpersTests.cs
浏览文件 @
a623e787
...
...
@@ -1187,5 +1187,83 @@ C LocalFunction(C c)
await
TestMissingAsync
<
LocalDeclarationStatementSyntax
>(
testText
);
}
#
endregion
#
region
Test
Ifs
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
]
public
async
Task
TestMultiline_IfElseIfElseSelection1
()
{
await
TestAsync
<
IfStatementSyntax
>(
@"class A
{
void Goo()
{
{|result:[|if (a)
{
a();
}|]
else if (b)
{
b();
}
else
{
c();
}|}
}
}"
);
}
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
]
public
async
Task
TestMultiline_IfElseIfElseSelection2
()
{
await
TestAsync
<
IfStatementSyntax
>(
@"class A
{
void Goo()
{
{|result:[|if (a)
{
a();
}
else if (b)
{
b();
}
else
{
c();
}|]|}
}
}"
);
}
[
WorkItem
(
35525
,
"https://github.com/dotnet/roslyn/issues/35525"
)]
[
Fact
]
public
async
Task
TestMissingMultiline_IfElseIfElseSelection
()
{
await
TestMissingAsync
<
IfStatementSyntax
>(
@"class A
{
void Goo()
{
if (a)
{
a();
}
[|else if (b)
{
b();
}
else
{
c();
}|]
}
}"
);
}
#
endregion
}
}
src/Features/CSharp/Portable/InvertIf/CSharpInvertIfCodeRefactoringProvider.cs
浏览文件 @
a623e787
...
...
@@ -58,13 +58,6 @@ protected override StatementSyntax GetEmptyEmbeddedStatement()
protected
override
StatementSyntax
GetElseBody
(
IfStatementSyntax
ifNode
)
=>
ifNode
.
Else
.
Statement
;
protected
override
TextSpan
GetHeaderSpan
(
IfStatementSyntax
ifNode
)
{
return
TextSpan
.
FromBounds
(
ifNode
.
IfKeyword
.
SpanStart
,
ifNode
.
CloseParenToken
.
Span
.
End
);
}
protected
override
bool
CanControlFlowOut
(
SyntaxNode
node
)
{
switch
(
node
.
Kind
())
...
...
src/Features/Core/Portable/CodeRefactorings/AbstractRefactoringHelpersService.cs
浏览文件 @
a623e787
...
...
@@ -13,6 +13,9 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings
{
internal
abstract
class
AbstractRefactoringHelpersService
:
IRefactoringHelpersService
{
public
async
Task
<
TSyntaxNode
>
TryGetSelectedNodeAsync
<
TSyntaxNode
>(
CodeRefactoringContext
context
)
where
TSyntaxNode
:
SyntaxNode
=>
await
TryGetSelectedNodeAsync
<
TSyntaxNode
>(
context
.
Document
,
context
.
Span
,
context
.
CancellationToken
).
ConfigureAwait
(
false
);
public
async
Task
<
TSyntaxNode
>
TryGetSelectedNodeAsync
<
TSyntaxNode
>(
Document
document
,
TextSpan
selection
,
CancellationToken
cancellationToken
)
where
TSyntaxNode
:
SyntaxNode
{
...
...
@@ -389,6 +392,12 @@ protected virtual IEnumerable<SyntaxNode> ExtractNodesIfInHeader(SyntaxNode root
{
yield
return
localDeclaration
;
}
// Header: `if(...)`{ };
if
(
syntaxFacts
.
IsOnIfStatementHeader
(
root
,
location
,
out
var
ifStatement
))
{
yield
return
ifStatement
;
}
}
}
}
src/Features/Core/Portable/CodeRefactorings/IRefactoringHelpersService.cs
浏览文件 @
a623e787
...
...
@@ -34,5 +34,6 @@ internal interface IRefactoringHelpersService : ILanguageService
/// </para>
/// </summary>
Task
<
TSyntaxNode
>
TryGetSelectedNodeAsync
<
TSyntaxNode
>(
Document
document
,
TextSpan
selection
,
CancellationToken
cancellationToken
)
where
TSyntaxNode
:
SyntaxNode
;
Task
<
TSyntaxNode
>
TryGetSelectedNodeAsync
<
TSyntaxNode
>(
CodeRefactoringContext
context
)
where
TSyntaxNode
:
SyntaxNode
;
}
}
src/Features/Core/Portable/InvertIf/AbstractInvertIfCodeRefactoringProvider.cs
浏览文件 @
a623e787
...
...
@@ -37,30 +37,14 @@ private enum InvertIfStyle
public
sealed
override
async
Task
ComputeRefactoringsAsync
(
CodeRefactoringContext
context
)
{
var
textSpan
=
context
.
Span
;
if
(!
textSpan
.
IsEmpty
)
{
return
;
}
var
document
=
context
.
Document
;
var
cancellationToken
=
context
.
CancellationToken
;
var
root
=
await
document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
token
=
root
.
FindToken
(
textSpan
.
Start
);
var
ifNode
=
token
.
GetAncestor
<
TIfStatementSyntax
>();
if
(
ifNode
==
null
)
{
return
;
}
if
(
ifNode
.
OverlapsHiddenPosition
(
cancellationToken
))
{
return
;
}
var
helperService
=
document
.
GetLanguageService
<
IRefactoringHelpersService
>();
var
ifNode
=
await
helperService
.
TryGetSelectedNodeAsync
<
TIfStatementSyntax
>(
context
).
ConfigureAwait
(
false
);
var
headerSpan
=
GetHeaderSpan
(
ifNode
);
if
(!
headerSpan
.
IntersectsWith
(
textSpan
))
if
(
ifNode
==
null
||
ifNode
.
OverlapsHiddenPosition
(
cancellationToken
))
{
return
;
}
...
...
@@ -417,7 +401,6 @@ private ImmutableArray<StatementRange> GetSubsequentStatementRanges(TIfStatement
protected
abstract
StatementRange
GetIfBodyStatementRange
(
TIfStatementSyntax
ifNode
);
protected
abstract
SyntaxNode
GetCondition
(
TIfStatementSyntax
ifNode
);
protected
abstract
TextSpan
GetHeaderSpan
(
TIfStatementSyntax
ifNode
);
protected
abstract
IEnumerable
<
TStatementSyntax
>
UnwrapBlock
(
TEmbeddedStatement
ifBody
);
protected
abstract
TEmbeddedStatement
GetIfBody
(
TIfStatementSyntax
ifNode
);
...
...
src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.MultiLine.vb
浏览文件 @
a623e787
...
...
@@ -14,12 +14,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertIf
Public
Sub
New
()
End
Sub
Protected
Overrides
Function
GetHeaderSpan
(
ifNode
As
MultiLineIfBlockSyntax
)
As
TextSpan
Return
TextSpan
.
FromBounds
(
ifNode
.
IfStatement
.
IfKeyword
.
SpanStart
,
ifNode
.
IfStatement
.
Condition
.
Span
.
End
)
End
Function
Protected
Overrides
Function
IsElseless
(
ifNode
As
MultiLineIfBlockSyntax
)
As
Boolean
Return
ifNode
.
ElseBlock
Is
Nothing
End
Function
...
...
src/Features/VisualBasic/Portable/InvertIf/VisualBasicInvertIfCodeRefactoringProvider.SingleLine.vb
浏览文件 @
a623e787
...
...
@@ -14,12 +14,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.InvertIf
Public
Sub
New
()
End
Sub
Protected
Overrides
Function
GetHeaderSpan
(
ifNode
As
SingleLineIfStatementSyntax
)
As
TextSpan
Return
TextSpan
.
FromBounds
(
ifNode
.
IfKeyword
.
SpanStart
,
ifNode
.
Condition
.
Span
.
End
)
End
Function
Protected
Overrides
Function
IsElseless
(
ifNode
As
SingleLineIfStatementSyntax
)
As
Boolean
Return
ifNode
.
ElseClause
Is
Nothing
End
Function
...
...
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
浏览文件 @
a623e787
...
...
@@ -1757,6 +1757,18 @@ public bool IsOnLocalDeclarationHeader(SyntaxNode root, int position, out Syntax
return
IsOnHeader
(
position
,
node
,
node
,
holes
:
initializersExpressions
);
}
public
bool
IsOnIfStatementHeader
(
SyntaxNode
root
,
int
position
,
out
SyntaxNode
ifStatement
)
{
var
node
=
TryGetAncestorForLocation
<
IfStatementSyntax
>(
position
,
root
);
ifStatement
=
node
;
if
(
ifStatement
==
null
)
{
return
false
;
}
return
IsOnHeader
(
position
,
node
,
node
.
CloseParenToken
);
}
public
bool
IsBetweenTypeMembers
(
SourceText
sourceText
,
SyntaxNode
root
,
int
position
)
{
var
token
=
root
.
FindToken
(
position
);
...
...
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
浏览文件 @
a623e787
...
...
@@ -418,6 +418,7 @@ internal interface ISyntaxFactsService : ILanguageService
bool
IsOnMethodHeader
(
SyntaxNode
root
,
int
position
,
out
SyntaxNode
method
);
bool
IsOnLocalFunctionHeader
(
SyntaxNode
root
,
int
position
,
out
SyntaxNode
localFunction
);
bool
IsOnLocalDeclarationHeader
(
SyntaxNode
root
,
int
position
,
out
SyntaxNode
localDeclaration
);
bool
IsOnIfStatementHeader
(
SyntaxNode
root
,
int
position
,
out
SyntaxNode
ifStatement
);
bool
IsBetweenTypeMembers
(
SourceText
sourceText
,
SyntaxNode
root
,
int
position
);
// Walks the tree, starting from contextNode, looking for the first construct
...
...
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
浏览文件 @
a623e787
...
...
@@ -1796,6 +1796,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
IsOnHeader
(
position
,
node
,
node
,
initializersExpressions
)
End
Function
Public
Function
IsOnIfStatementHeader
(
root
As
SyntaxNode
,
position
As
Integer
,
ByRef
ifStatement
As
SyntaxNode
)
As
Boolean
Implements
ISyntaxFactsService
.
IsOnIfStatementHeader
ifStatement
=
Nothing
Dim
multipleLineNode
=
TryGetAncestorForLocation
(
Of
MultiLineIfBlockSyntax
)(
position
,
root
)
If
multipleLineNode
IsNot
Nothing
Then
ifStatement
=
multipleLineNode
Return
IsOnHeader
(
position
,
multipleLineNode
.
IfStatement
,
multipleLineNode
.
IfStatement
)
End
If
Dim
singleLineNode
=
TryGetAncestorForLocation
(
Of
SingleLineIfStatementSyntax
)(
position
,
root
)
If
singleLineNode
IsNot
Nothing
Then
ifStatement
=
singleLineNode
Return
IsOnHeader
(
position
,
singleLineNode
,
singleLineNode
.
Condition
)
End
If
Return
False
End
Function
Public
Function
IsBetweenTypeMembers
(
sourceText
As
SourceText
,
root
As
SyntaxNode
,
position
As
Integer
)
As
Boolean
Implements
ISyntaxFactsService
.
IsBetweenTypeMembers
Dim
token
=
root
.
FindToken
(
position
)
Dim
typeDecl
=
token
.
GetAncestor
(
Of
TypeBlockSyntax
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录