Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
b696b896
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,发现更多精彩内容 >>
提交
b696b896
编写于
9月 17, 2019
作者:
G
Gen Lu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for FixAll
上级
aac69302
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
130 addition
and
23 deletion
+130
-23
src/EditorFeatures/CSharpTest/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProviderTests.cs
...PassInCapturedVariablesAsArgumentsCodeFixProviderTests.cs
+56
-0
src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticHelper.cs
.../MakeLocalFunctionStatic/MakeLocalFunctionStaticHelper.cs
+17
-6
src/Features/CSharp/Portable/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs
...atic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs
+57
-17
未找到文件。
src/EditorFeatures/CSharpTest/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProviderTests.cs
浏览文件 @
b696b896
...
...
@@ -406,6 +406,62 @@ static int AddLocal(int @static)
}"
,
parseOptions
:
CSharp8ParseOptions
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsMakeLocalFunctionStatic
)]
public
async
Task
TestFixAll
()
{
await
TestInRegularAndScriptAsync
(
@"class C
{
int M(int x)
{
int y = 10;
var m = AddLocal(1, 2);
return AddLocal(m, m);
static int AddLocal(int a, int b)
{
return a + b + x + y;
}
}
int N(int x)
{
int y = 10;
return AddLocal(AddLocal(1, 2), AddLocal(3, 4));
static int AddLocal(int a, int b)
{
return AddLocal(a, b) + {|FixAllInDocument:|}x + y;
}
}
}"
,
@"class C
{
int M(int x)
{
int y = 10;
var m = AddLocal(1, 2, x, y);
return AddLocal(m, m, x, y);
static int AddLocal(int a, int b, int x, int y)
{
return a + b + x + y;
}
}
int N(int x)
{
int y = 10;
return AddLocal(AddLocal(1, 2, x, y), AddLocal(3, 4, x, y), x, y);
static int AddLocal(int a, int b, int x, int y)
{
return AddLocal(a, b, x, y) + x + y;
}
}
}"
,
parseOptions
:
CSharp8ParseOptions
);
}
}
}
src/Features/CSharp/Portable/MakeLocalFunctionStatic/MakeLocalFunctionStaticHelper.cs
浏览文件 @
b696b896
...
...
@@ -41,6 +41,20 @@ public static bool CanMakeLocalFunctionStatic(ImmutableArray<ISymbol> captures)
LocalFunctionStatementSyntax
localFunction
,
ImmutableArray
<
ISymbol
>
captures
,
CancellationToken
cancellationToken
)
{
var
root
=
(
await
document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
syntaxEditor
=
new
SyntaxEditor
(
root
,
document
.
Project
.
Solution
.
Workspace
);
await
MakeLocalFunctionStaticAsync
(
document
,
semanticModel
,
localFunction
,
captures
,
syntaxEditor
,
cancellationToken
).
ConfigureAwait
(
false
);
return
document
.
WithSyntaxRoot
(
syntaxEditor
.
GetChangedRoot
());
}
public
static
async
Task
MakeLocalFunctionStaticAsync
(
Document
document
,
SemanticModel
semanticModel
,
LocalFunctionStatementSyntax
localFunction
,
ImmutableArray
<
ISymbol
>
captures
,
SyntaxEditor
syntaxEditor
,
CancellationToken
cancellationToken
)
{
var
root
=
(
await
document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
localFunctionSymbol
=
semanticModel
.
GetDeclaredSymbol
(
localFunction
,
cancellationToken
);
...
...
@@ -52,7 +66,7 @@ public static bool CanMakeLocalFunctionStatic(ImmutableArray<ISymbol> captures)
// Now we need to find all the refereces to the local function that we might need to fix.
var
shouldWarn
=
false
;
using
var
builderDisposer
=
ArrayBuilder
<
InvocationExpressionSyntax
>.
GetInstance
(
out
var
builder
);
using
var
builderDisposer
=
ArrayBuilder
<
InvocationExpressionSyntax
>.
GetInstance
(
out
var
invocations
);
foreach
(
var
referencedSymbol
in
referencedSymbols
)
{
...
...
@@ -70,7 +84,7 @@ public static bool CanMakeLocalFunctionStatic(ImmutableArray<ISymbol> captures)
if
(
identifierNode
.
Parent
is
InvocationExpressionSyntax
invocation
)
{
builder
.
Add
(
invocation
);
invocations
.
Add
(
invocation
);
}
else
{
...
...
@@ -82,10 +96,9 @@ public static bool CanMakeLocalFunctionStatic(ImmutableArray<ISymbol> captures)
}
var
parameterAndCapturedSymbols
=
CreateParameterSymbols
(
captures
);
var
syntaxEditor
=
new
SyntaxEditor
(
root
,
document
.
Project
.
Solution
.
Workspace
);
// Fix all invocations by passing in additional arguments.
foreach
(
var
invocation
in
builder
)
foreach
(
var
invocation
in
invocations
)
{
syntaxEditor
.
ReplaceNode
(
invocation
,
...
...
@@ -157,8 +170,6 @@ public static bool CanMakeLocalFunctionStatic(ImmutableArray<ISymbol> captures)
return
AddStaticModifier
(
localFunctionWithNewParameters
,
CSharpSyntaxGenerator
.
Instance
);
});
return
document
.
WithSyntaxRoot
(
syntaxEditor
.
GetChangedRoot
());
}
public
static
SyntaxNode
AddStaticModifier
(
SyntaxNode
localFunction
,
SyntaxGenerator
generator
)
...
...
src/Features/CSharp/Portable/MakeLocalFunctionStatic/PassInCapturedVariablesAsArgumentsCodeFixProvider.cs
浏览文件 @
b696b896
...
...
@@ -11,27 +11,62 @@
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.
Shared.Extensions
;
using
Microsoft.CodeAnalysis.
Editing
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.CSharp.MakeLocalFunctionStatic
{
[
ExportCodeFixProvider
(
LanguageNames
.
CSharp
,
Name
=
nameof
(
PassInCapturedVariablesAsArgumentsCodeFixProvider
)),
Shared
]
internal
sealed
class
PassInCapturedVariablesAsArgumentsCodeFixProvider
:
CodeFixProvider
internal
sealed
class
PassInCapturedVariablesAsArgumentsCodeFixProvider
:
SyntaxEditorBased
CodeFixProvider
{
// "CS8421: A static local function can't contain a reference to <variable>."
public
override
ImmutableArray
<
string
>
FixableDiagnosticIds
=>
ImmutableArray
.
Create
(
"CS8421"
);
public
override
FixAllProvider
?
GetFixAllProvider
()
internal
override
CodeFixCategory
CodeFixCategory
=>
CodeFixCategory
.
Compile
;
public
override
Task
RegisterCodeFixesAsync
(
CodeFixContext
context
)
{
return
null
;
var
diagnostic
=
context
.
Diagnostics
.
First
();
return
WrapFixAsync
(
context
.
Document
,
ImmutableArray
.
Create
(
diagnostic
),
(
document
,
semanticModel
,
localFunction
,
captures
,
cancellationToken
)
=>
{
context
.
RegisterCodeFix
(
new
MyCodeAction
(
c
=>
MakeLocalFunctionStaticHelper
.
MakeLocalFunctionStaticAsync
(
document
,
semanticModel
,
localFunction
,
captures
,
c
)),
diagnostic
);
return
Task
.
CompletedTask
;
},
context
.
CancellationToken
);
}
public
override
async
Task
RegisterCodeFixesAsync
(
CodeFixContext
context
)
protected
override
Task
FixAllAsync
(
Document
document
,
ImmutableArray
<
Diagnostic
>
diagnostics
,
SyntaxEditor
editor
,
CancellationToken
cancellationToken
)
=>
WrapFixAsync
(
document
,
diagnostics
,
(
d
,
semanticModel
,
localFunction
,
captures
,
token
)
=>
MakeLocalFunctionStaticHelper
.
MakeLocalFunctionStaticAsync
(
d
,
semanticModel
,
localFunction
,
captures
,
editor
,
token
),
cancellationToken
);
private
static
async
Task
WrapFixAsync
(
Document
document
,
ImmutableArray
<
Diagnostic
>
diagnostics
,
Func
<
Document
,
SemanticModel
,
LocalFunctionStatementSyntax
,
ImmutableArray
<
ISymbol
>,
CancellationToken
,
Task
>
fixer
,
CancellationToken
cancellationToken
)
{
var
diagnostic
=
context
.
Diagnostics
.
First
();
var
diagnosticSpan
=
diagnostic
.
Location
.
SourceSpan
;
var
root
=
(
await
context
.
Document
.
GetSyntaxRootAsync
(
context
.
CancellationToken
).
ConfigureAwait
(
false
))!;
var
root
=
(
await
document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
// Even when the language version doesn't support staic local function, the compiler will still
// generate this error. So we need to check to make sure we don't provide incorrect fix.
...
...
@@ -40,22 +75,27 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
return
;
}
var
localFunction
=
root
.
FindNode
(
diagnosticSpan
).
AncestorsAndSelf
().
OfType
<
LocalFunctionStatementSyntax
>().
FirstOrDefault
();
if
(
localFunction
==
null
)
var
localFunctions
=
diagnostics
.
Select
(
d
=>
root
.
FindNode
(
d
.
Location
.
SourceSpan
).
AncestorsAndSelf
().
OfType
<
LocalFunctionStatementSyntax
>().
FirstOrDefault
())
.
Where
(
n
=>
n
!=
null
)
.
Distinct
()
.
ToImmutableArrayOrEmpty
();
if
(
localFunctions
.
Length
==
0
)
{
return
;
}
var
document
=
context
.
Document
;
var
cancellationToken
=
context
.
CancellationToken
;
var
semanticModel
=
(
await
document
.
GetSemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
if
(
MakeLocalFunctionStaticHelper
.
TryGetCaputuredSymbols
(
localFunction
,
semanticModel
,
out
var
captures
)
&&
MakeLocalFunctionStaticHelper
.
CanMakeLocalFunctionStatic
(
captures
))
foreach
(
var
localFunction
in
localFunctions
)
{
context
.
RegisterCodeFix
(
new
MyCodeAction
(
c
=>
MakeLocalFunctionStaticHelper
.
MakeLocalFunctionStaticAsync
(
document
,
semanticModel
,
localFunction
,
captures
,
c
)),
diagnostic
);
if
(
MakeLocalFunctionStaticHelper
.
TryGetCaputuredSymbols
(
localFunction
,
semanticModel
,
out
var
captures
)
&&
MakeLocalFunctionStaticHelper
.
CanMakeLocalFunctionStatic
(
captures
))
{
await
fixer
(
document
,
semanticModel
,
localFunction
,
captures
,
cancellationToken
).
ConfigureAwait
(
false
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录