Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
38edea5e
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,发现更多精彩内容 >>
提交
38edea5e
编写于
2月 11, 2016
作者:
B
Balaji Krishnan
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #8586 from balajikris/TestDelegateInvoke
More test coverage for delegate invoke with conditional access
上级
9e2594ae
9c19b196
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
292 addition
and
7 deletion
+292
-7
src/EditorFeatures/CSharpTest/Diagnostics/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs
...itionalAccess/InvokeDelegateWithConditionalAccessTests.cs
+287
-3
src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
...onalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
+5
-4
未找到文件。
src/EditorFeatures/CSharpTest/Diagnostics/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs
浏览文件 @
38edea5e
...
...
@@ -150,7 +150,7 @@ void Foo()
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingWithMultipleVariables
()
public
async
Task
TestMissing
OnDeclaration
WithMultipleVariables
()
{
await
TestMissingAsync
(
@"class C
...
...
@@ -163,13 +163,47 @@ void Foo()
{
v();
}
else {}
}
}"
);
}
/// <remarks>
/// With multiple variables in the same declaration, the fix _is not_ offered on the declaration
/// itself, but _is_ offered on the invocation pattern.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingIfUsedOutside
()
public
async
Task
TestLocationWhereOfferedWithMultipleVariables
()
{
await
TestAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a, x = a;
[||]if (v != null)
{
v();
}
}
}"
,
@"class C
{
System.Action a;
void Foo()
{
var v = a, x = a;
v?.Invoke();
}
}"
);
}
/// <remarks>
/// If we have a variable declaration and if it is read/written outside the delegate
/// invocation pattern, the fix is not offered on the declaration.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnDeclarationIfUsedOutside
()
{
await
TestMissingAsync
(
@"class C
...
...
@@ -188,6 +222,42 @@ void Foo()
}"
);
}
/// <remarks>
/// If we have a variable declaration and if it is read/written outside the delegate
/// invocation pattern, the fix is not offered on the declaration but is offered on
/// the invocation pattern itself.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestLocationWhereOfferedIfUsedOutside
()
{
await
TestAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
[||]if (v != null)
{
v();
}
v = null;
}
}"
,
@"class C
{
System.Action a;
void Foo()
{
var v = a;
v?.Invoke();
v = null;
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestSimpleForm1
()
{
...
...
@@ -348,5 +418,219 @@ void Foo()
}
}"
,
compareTokens
:
false
);
}
/// <remarks>
/// tests locations where the fix is offered.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestFixOfferedOnIf
()
{
await
TestAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
[||]if (v != null)
{
v();
}
}
}"
,
@"
class C
{
System.Action a;
void Foo()
{
a?.Invoke();
}
}"
);
}
/// <remarks>
/// tests locations where the fix is offered.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestFixOfferedInsideIf
()
{
await
TestAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
if (v != null)
{
[||]v();
}
}
}"
,
@"
class C
{
System.Action a;
void Foo()
{
a?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnConditionalInvocation
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
[||]var v = a;
v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnConditionalInvocation2
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
[||]v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnConditionalInvocation3
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
[||]a?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnNonNullCheckExpressions
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
if (v == a)
{
[||]v();
}
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnNonNullCheckExpressions2
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
if (v == null)
{
[||]v();
}
}
}"
);
}
/// <remarks>
/// if local declaration is not immediately preceding the invocation pattern,
/// the fix is not offered on the declaration.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestLocalNotImmediatelyPrecedingNullCheckAndInvokePattern
()
{
await
TestMissingAsync
(
@"class C
{
System.Action a;
void Foo()
{
[||]var v = a;
int x;
if (v != null)
{
v();
}
}
}"
);
}
/// <remarks>
/// if local declaration is not immediately preceding the invocation pattern,
/// the fix is not offered on the declaration but is offered on the invocation pattern itself.
/// </remarks>
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestLocalDNotImmediatelyPrecedingNullCheckAndInvokePattern2
()
{
await
TestAsync
(
@"class C
{
System.Action a;
void Foo()
{
var v = a;
int x;
[||]if (v != null)
{
v();
}
}
}"
,
@"class C
{
System.Action a;
void Foo()
{
var v = a;
int x;
v?.Invoke();
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsInvokeDelegateWithConditionalAccess
)]
public
async
Task
TestMissingOnFunc
()
{
await
TestMissingAsync
(
@"class C
{
System.Func<int> a;
int Foo()
{
var v = a;
[||]if (v != null)
{
return v();
}
}
}"
);
}
}
}
\ No newline at end of file
src/Features/CSharp/Portable/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessAnalyzer.cs
浏览文件 @
38edea5e
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Threading
;
...
...
@@ -128,6 +127,8 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
Location
.
Create
(
tree
,
TextSpan
.
FromBounds
(
expressionStatement
.
Span
.
End
,
ifStatement
.
Span
.
End
)),
additionalLocations
,
properties
));
}
return
true
;
}
}
...
...
@@ -150,8 +151,8 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
return
false
;
}
if
(!
IsN
otEquals
Expression
(
condition
.
Left
,
condition
.
Right
)
&&
!
IsN
otEquals
Expression
(
condition
.
Right
,
condition
.
Left
))
if
(!
IsN
ullCheck
Expression
(
condition
.
Left
,
condition
.
Right
)
&&
!
IsN
ullCheck
Expression
(
condition
.
Right
,
condition
.
Left
))
{
return
false
;
}
...
...
@@ -244,7 +245,7 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
return
true
;
}
private
bool
IsN
otEquals
Expression
(
ExpressionSyntax
left
,
ExpressionSyntax
right
)
=>
private
bool
IsN
ullCheck
Expression
(
ExpressionSyntax
left
,
ExpressionSyntax
right
)
=>
left
.
IsKind
(
SyntaxKind
.
IdentifierName
)
&&
right
.
IsKind
(
SyntaxKind
.
NullLiteralExpression
);
public
DiagnosticAnalyzerCategory
GetAnalyzerCategory
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录