Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
5bb48dbd
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,发现更多精彩内容 >>
未验证
提交
5bb48dbd
编写于
10月 19, 2018
作者:
C
Charles Stoner
提交者:
GitHub
10月 19, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Set null state on dereference (#30564)
上级
c20eae14
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
803 addition
and
208 deletion
+803
-208
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
+22
-0
src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
...s/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
+1
-1
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
...rp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
+779
-206
src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs
...ToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs
+1
-1
未找到文件。
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
浏览文件 @
5bb48dbd
...
...
@@ -1354,6 +1354,8 @@ public override BoundNode VisitArrayAccess(BoundArrayAccess node)
Debug
.
Assert
(!
IsConditionalState
);
Debug
.
Assert
(!
node
.
Expression
.
Type
.
IsValueType
);
// https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null
// after indices have been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
node
.
Expression
);
var
type
=
_resultType
.
TypeSymbol
as
ArrayTypeSymbol
;
...
...
@@ -1943,6 +1945,8 @@ public override BoundNode VisitCall(BoundCall node)
if
(
receiverOpt
!=
null
&&
method
.
MethodKind
!=
MethodKind
.
Constructor
)
{
VisitRvalue
(
receiverOpt
);
// https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null
// after arguments have been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
receiverOpt
);
// Update method based on inferred receiver type: see https://github.com/dotnet/roslyn/issues/29605.
}
...
...
@@ -3303,6 +3307,10 @@ public override BoundNode VisitMethodGroup(BoundMethodGroup node)
if
(
receiverOpt
!=
null
)
{
VisitRvalue
(
receiverOpt
);
// https://github.com/dotnet/roslyn/issues/30563: Should not check receiver here.
// That check should be handled when applying the method group conversion,
// when we have a specific method, to avoid reporting null receiver warnings
// for extension method delegates.
CheckPossibleNullReceiver
(
receiverOpt
);
}
...
...
@@ -3672,6 +3680,8 @@ public override BoundNode VisitIndexerAccess(BoundIndexerAccess node)
{
var
receiverOpt
=
node
.
ReceiverOpt
;
VisitRvalue
(
receiverOpt
);
// https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null
// after indices have been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
receiverOpt
);
// https://github.com/dotnet/roslyn/issues/29964 Update indexer based on inferred receiver type.
...
...
@@ -3698,6 +3708,8 @@ private void VisitMemberAccess(BoundExpression receiverOpt, Symbol member, bool
if
(!
member
.
IsStatic
)
{
member
=
AsMemberOfResultType
(
member
);
// https://github.com/dotnet/roslyn/issues/30598: For l-values, mark receiver as not null
// after RHS has been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
receiverOpt
);
}
...
...
@@ -4206,6 +4218,8 @@ public override BoundNode VisitEventAssignmentOperator(BoundEventAssignmentOpera
var
receiverOpt
=
node
.
ReceiverOpt
;
if
(!
node
.
Event
.
IsStatic
)
{
// https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null
// after arguments have been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
receiverOpt
);
}
VisitRvalue
(
node
.
Argument
);
...
...
@@ -4294,6 +4308,8 @@ public override BoundNode VisitDynamicIndexerAccess(BoundDynamicIndexerAccess no
{
var
receiver
=
node
.
ReceiverOpt
;
VisitRvalue
(
receiver
);
// https://github.com/dotnet/roslyn/issues/30598: Mark receiver as not null
// after indices have been visited, and only if the receiver has not changed.
CheckPossibleNullReceiver
(
receiver
);
VisitArgumentsEvaluate
(
node
.
Arguments
,
node
.
ArgumentRefKindsOpt
);
...
...
@@ -4309,6 +4325,7 @@ public override BoundNode VisitDynamicIndexerAccess(BoundDynamicIndexerAccess no
private
void
CheckPossibleNullReceiver
(
BoundExpression
receiverOpt
)
{
Debug
.
Assert
(!
this
.
IsConditionalState
);
if
(
receiverOpt
!=
null
&&
this
.
State
.
Reachable
)
{
#if DEBUG
...
...
@@ -4320,6 +4337,11 @@ private void CheckPossibleNullReceiver(BoundExpression receiverOpt)
!
resultType
.
IsValueType
)
{
ReportDiagnostic
(
ErrorCode
.
WRN_NullReferenceReceiver
,
receiverOpt
.
Syntax
);
int
slot
=
MakeSlot
(
receiverOpt
);
if
(
slot
>
0
)
{
this
.
State
[
slot
]
=
true
;
}
}
}
}
...
...
src/Compilers/CSharp/Portable/FlowAnalysis/PreciseAbstractFlowPass.cs
浏览文件 @
5bb48dbd
...
...
@@ -312,7 +312,7 @@ protected override bool ConvertInsufficientExecutionStackExceptionToCancelledByS
/// <summary>
/// A pending branch. These are created for a return, break, continue, goto statement,
/// yield return, yield break, await expression, await foreach/using, and if PreciseAbstractFlowPass.trackExceptions
/// yield return, yield break, await expression, await foreach/using, and if PreciseAbstractFlowPass.
_
trackExceptions
/// is true for other
/// constructs that can cause an exception to be raised such as a throw statement or method
/// invocation.
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
浏览文件 @
5bb48dbd
...
...
@@ -8403,15 +8403,15 @@ struct S2
// (53,18): warning CS8602: Possible dereference of a null reference.
// CL1 y7 = x7.P1;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x7").WithLocation(53, 18),
// (54,18):
warning CS8600: Converting null literal or possible null value to non-nullable type
.
// (54,18):
hidden CS8607: Expression is probably never null
.
// CL1 z7 = x7?.P1;
Diagnostic(ErrorCode.
WRN_ConvertingNullableToNonNullable, "x7?.P1
").WithLocation(54, 18),
Diagnostic(ErrorCode.
HDN_ExpressionIsProbablyNeverNull, "x7
").WithLocation(54, 18),
// (64,18): warning CS8602: Possible dereference of a null reference.
// CL1 u8 = x8.M1();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x8").WithLocation(64, 18),
// (65,18):
warning CS8600: Converting null literal or possible null value to non-nullable type
.
// (65,18):
hidden CS8607: Expression is probably never null
.
// CL1 z8 = x8?.M1();
Diagnostic(ErrorCode.
WRN_ConvertingNullableToNonNullable, "x8?.M1()
").WithLocation(65, 18),
Diagnostic(ErrorCode.
HDN_ExpressionIsProbablyNeverNull, "x8
").WithLocation(65, 18),
// (71,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// u9 = x9;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "x9").WithLocation(71, 14),
...
...
@@ -10208,23 +10208,20 @@ public void Main(string? s)
s.ToString(); // ok
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null;
}
", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/29855: there should only be
two diagnostics
// https://github.com/dotnet/roslyn/issues/29855: there should only be
one diagnostic
c.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // ok
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13)
);
}
...
...
@@ -10247,23 +10244,20 @@ public void Main(string? s)
s.ToString(); // warn
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null;
}
", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/29855: there should only be
two diagnostics
// https://github.com/dotnet/roslyn/issues/29855: there should only be
one diagnostic
c.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // ok
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13)
);
}
...
...
@@ -10286,23 +10280,20 @@ public void Main(string? s)
s.ToString(); // ok
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null;
}
", NotNullWhenFalseAttributeDefinition }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/29855: there should only be
two diagnostics
// https://github.com/dotnet/roslyn/issues/29855: there should only be
one diagnostic
c.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // ok
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13)
);
}
...
...
@@ -10371,8 +10362,8 @@ public void Main(string? s)
s2.ToString(); // warn 3
}
s.ToString(); //
warn 4
s2.ToString(); //
warn 5
s.ToString(); //
ok
s2.ToString(); //
ok
}
public static bool M([NotNullWhenTrue] string? s, out string? s2) => throw null;
}
...
...
@@ -10387,13 +10378,7 @@ public void Main(string? s)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(14, 13),
// (15,13): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13),
// (18,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(18, 9),
// (19,9): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(19, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13)
);
}
...
...
@@ -10418,7 +10403,7 @@ public void Main(string? s)
}
s.ToString(); // ok
s2.ToString(); //
warn 3
s2.ToString(); //
ok
}
public static bool M([EnsuresNotNull] string? s, out string? s2) => throw null;
}
...
...
@@ -10430,10 +10415,7 @@ public void Main(string? s)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(10, 13),
// (15,13): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13),
// (19,9): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(19, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13)
);
}
...
...
@@ -10627,7 +10609,7 @@ public void Main(string key)
s/*T:string?*/.ToString(); // warn 2
}
s.ToString(); //
warn 3
s.ToString(); //
ok
}
public static bool TryGetValue(string key, out string? value) => throw null;
}
...
...
@@ -10641,10 +10623,7 @@ public void Main(string key)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 13),
// (15,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(15, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 13)
);
}
...
...
@@ -11513,7 +11492,7 @@ public void Main(string key)
s.ToString(); // warn
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public static bool TryGetValue(string key, [NotNullWhenTrue] out string? value) => throw null;
}
...
...
@@ -11522,10 +11501,7 @@ public void Main(string key)
c.VerifyDiagnostics(
// (13,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(13, 13)
);
VerifyAnnotationsAndMetadata(c, "C.Main", None);
...
...
@@ -11959,7 +11935,7 @@ public void Main(string? s)
s.ToString(); // ok
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null;
}
...
...
@@ -11968,10 +11944,7 @@ public void Main(string? s)
c.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13)
);
VerifyAnnotationsAndMetadata(c, "C.Main", None);
...
...
@@ -12014,8 +11987,8 @@ void Main(string? s, string? s2)
s2.ToString(); // ok
}
s.ToString(); //
warn 3
s2.ToString(); //
warn 4
s.ToString(); //
ok
s2.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s, [NotNullWhenFalse] string? s2) => throw null;
}
...
...
@@ -12027,13 +12000,7 @@ void Main(string? s, string? s2)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (10,13): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(10, 13),
// (18,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(18, 9),
// (19,9): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(19, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(10, 13)
);
VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", NotNullWhenFalse, NotNullWhenFalse);
...
...
@@ -12059,8 +12026,8 @@ void Main(string? s, string? s2)
s2.ToString(); // warn 2
}
s.ToString(); //
warn 3
s2.ToString(); //
warn 4
s.ToString(); //
ok
s2.ToString(); //
ok
}
public static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s, [NotNullWhenTrue] string? s2) => throw null;
}
...
...
@@ -12072,13 +12039,7 @@ void Main(string? s, string? s2)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (15,13): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13),
// (18,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(18, 9),
// (19,9): warning CS8602: Possible dereference of a null reference.
// s2.ToString(); // warn 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(19, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(15, 13)
);
VerifyAnnotationsAndMetadata(c, "C.MyIsNullOrEmpty", NotNullWhenFalse, NotNullWhenTrue);
...
...
@@ -12102,7 +12063,7 @@ void Main(string? s, int x)
s.ToString(); // ok
}
s.ToString(); //
warn 2
s.ToString(); //
ok
}
public bool this[[NotNullWhenFalse] string? s, int x] => throw null;
}
...
...
@@ -12111,10 +12072,7 @@ void Main(string? s, int x)
c.VerifyDiagnostics(
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13),
// (16,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(16, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13)
);
}
...
...
@@ -12129,7 +12087,7 @@ void Main(string? s)
{
if (Method(s, s.ToString())) // warn 1
{
s.ToString(); //
warn 2
s.ToString(); //
ok
}
else
{
...
...
@@ -12143,10 +12101,7 @@ void Main(string? s)
c.VerifyDiagnostics(
// (7,23): warning CS8602: Possible dereference of a null reference.
// if (Method(s, s.ToString())) // warn 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(7, 23),
// (9,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(9, 13)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(7, 23)
);
}
...
...
@@ -12199,7 +12154,7 @@ void Main(string? s)
s.ToString(); // warn 2
}
s.ToString(); //
warn 3
s.ToString(); //
ok
}
static bool MyIsNullOrEmpty([NotNullWhenFalse] string? s) => throw null;
}
...
...
@@ -12217,10 +12172,7 @@ void Main(string? s)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 13),
// (15,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(15, 9)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 13)
);
VerifyAnnotations(c, "C.MyIsNullOrEmpty", None);
...
...
@@ -13470,7 +13422,7 @@ public class C
{
void M(Delegate d, string? s)
{
s.ToString(); // warn
if (s != string.Empty)
s.ToString(); // warn
d.BeginInvoke(s, null, null);
s.ToString(); // warn 2
}
...
...
@@ -13478,9 +13430,9 @@ void M(Delegate d, string? s)
", EnsuresNotNullAttributeDefinition }, options: WithNonNullTypesTrue());
c.VerifyDiagnostics(
// (8,
9
): warning CS8602: Possible dereference of a null reference.
// s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8,
9
),
// (8,
32
): warning CS8602: Possible dereference of a null reference.
//
if (s != string.Empty)
s.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8,
32
),
// (9,26): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// d.BeginInvoke(s, null, null);
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(9, 26),
...
...
@@ -13488,7 +13440,7 @@ void M(Delegate d, string? s)
// d.BeginInvoke(s, null, null);
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(9, 32),
// (10,9): warning CS8602: Possible dereference of a null reference.
// s.ToString(); //
ok
// s.ToString(); //
warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(10, 9)
);
}
...
...
@@ -15138,14 +15090,39 @@ void Test(object? x)
{
x.ToString(); // warn 3
}
}
}
" }, options: WithNonNullTypesTrue());
c.VerifyTypes();
c.VerifyDiagnostics(
// (8,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(8, 13),
// (9,13): warning CS8602: Possible dereference of a null reference.
// c /*T:object?*/ .ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(13, 13)
);
}
[Fact]
public void ConditionalBranching_IsVarDeclarationPattern_Discard()
{
CSharpCompilation c = CreateCompilation(new[] { @"
class C
{
void Test(object? x)
{
if (x is var _)
{
x.ToString(); // warn
4
x.ToString(); // warn
1
}
else
{
x.ToString(); // warn
5
x.ToString(); // warn
2
}
}
}
...
...
@@ -15156,18 +15133,9 @@ void Test(object? x)
// (8,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(8, 13),
// (9,13): warning CS8602: Possible dereference of a null reference.
// c /*T:object?*/ .ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(9, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(13, 13),
// (18,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(18, 13),
// (22,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(22, 13)
// (12,13): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // warn 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(12, 13)
);
}
...
...
@@ -17262,8 +17230,8 @@ CL1 Test2(CL1? x2, CL1 y2, CL1? z2)
{
x2 = z2;
x2.M1(); // 2
y2 =
x
2;
y2.M2(
x
2);
y2 =
z
2;
y2.M2(
y
2);
if (i == 1)
{
...
...
@@ -17290,20 +17258,11 @@ class CL1
// x2.M1(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x2").WithLocation(28, 13),
// (29,18): warning CS8600: Converting null literal or possible null value to non-nullable type.
// y2 =
x
2;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "
x
2").WithLocation(29, 18),
// y2 =
z
2;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "
z
2").WithLocation(29, 18),
// (30,13): warning CS8602: Possible dereference of a null reference.
// y2.M2(x2);
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y2").WithLocation(30, 13),
// (30,19): warning CS8604: Possible null reference argument for parameter 'x' in 'void CL1.M2(CL1 x)'.
// y2.M2(x2);
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "x2").WithArguments("x", "void CL1.M2(CL1 x)").WithLocation(30, 19),
// (34,24): warning CS8603: Possible null reference return.
// return x2;
Diagnostic(ErrorCode.WRN_NullReferenceReturn, "x2").WithLocation(34, 24),
// (38,16): warning CS8603: Possible null reference return.
// return y2;
Diagnostic(ErrorCode.WRN_NullReferenceReturn, "y2").WithLocation(38, 16));
// y2.M2(y2);
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y2").WithLocation(30, 13));
}
[Fact]
...
...
@@ -18376,18 +18335,12 @@ void Test9()
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u6").WithLocation(39, 9),
// (40,9): warning CS8602: Possible dereference of a null reference.
// u6[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u6").WithLocation(40, 9),
// (40,9): warning CS8602: Possible dereference of a null reference.
// u6[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u6[0]").WithLocation(40, 9),
// (40,22): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u6[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(40, 22),
// (41,9): warning CS8602: Possible dereference of a null reference.
// u6[0][0,0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u6").WithLocation(41, 9),
// (41,9): warning CS8602: Possible dereference of a null reference.
// u6[0][0,0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u6[0]").WithLocation(41, 9),
// (46,27): warning CS8600: Converting null literal or possible null value to non-nullable type.
// object [][,] u7 = null;
...
...
@@ -18398,9 +18351,6 @@ void Test9()
// (47,17): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u7[0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(47, 17),
// (48,9): warning CS8602: Possible dereference of a null reference.
// u7[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u7").WithLocation(48, 9),
// (48,22): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u7[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(48, 22),
...
...
@@ -18410,32 +18360,20 @@ void Test9()
// (54,17): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u8[0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(54, 17),
// (55,9): warning CS8602: Possible dereference of a null reference.
// u8[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u8").WithLocation(55, 9),
// (55,22): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u8[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(55, 22),
// (56,9): warning CS8602: Possible dereference of a null reference.
// u8[0][0,0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u8").WithLocation(56, 9),
// (62,9): warning CS8602: Possible dereference of a null reference.
// u9[0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u9").WithLocation(62, 9),
// (63,9): warning CS8602: Possible dereference of a null reference.
// u9[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u9").WithLocation(63, 9),
// (63,9): warning CS8602: Possible dereference of a null reference.
// u9[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u9[0]").WithLocation(63, 9),
// (63,22): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// u9[0][0,0] = null;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(63, 22),
// (64,9): warning CS8602: Possible dereference of a null reference.
// u9[0][0,0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u9").WithLocation(64, 9),
// (64,9): warning CS8602: Possible dereference of a null reference.
// u9[0][0,0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u9[0]").WithLocation(64, 9)
);
}
...
...
@@ -21751,10 +21689,7 @@ static void F()
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(8, 22),
// (13,17): warning CS8602: Possible dereference of a null reference.
// s2.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(13, 17),
// (14,24): warning CS8603: Possible null reference return.
// return s2;
Diagnostic(ErrorCode.WRN_NullReferenceReturn, "s2").WithLocation(14, 24));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s2").WithLocation(13, 17));
}
/// <summary>
...
...
@@ -36452,8 +36387,8 @@ static void F(object? x, object? y)
t.Item1.Item1.ToString();
t.Item1.Item2.ToString();
t.Item2.ToString();
t.Item1.x.ToString();
t.Item1.y.ToString();
t.Item1.x.ToString();
// warning already reported for t.Item1.Item1
t.Item1.y.ToString();
// warning already reported for t.Item1.Item2
t.z.ToString();
}
}
...
...
@@ -36470,16 +36405,7 @@ static void F(object? x, object? y)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item1.Item2").WithLocation(9, 13),
// (10,13): warning CS8602: Possible dereference of a null reference.
// t.Item2.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item2").WithLocation(10, 13),
// (11,13): warning CS8602: Possible dereference of a null reference.
// t.Item1.x.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item1.x").WithLocation(11, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// t.Item1.y.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item1.y").WithLocation(12, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// t.z.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.z").WithLocation(13, 13));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item2").WithLocation(10, 13));
}
[Fact]
...
...
@@ -36493,17 +36419,19 @@ static void F(object? x, object? y)
{
if (y != null)
{
(object? _1, object? _2, object? _3, object? _4, object? _5, object? _6, object? _7, object? _8, object? _9
) t = (null, null, null, null, null, null, null, x
, y);
(object? _1, object? _2, object? _3, object? _4, object? _5, object? _6, object? _7, object? _8, object? _9
, object? _10) t = (null, null, null, null, null, null, null, x, null
, y);
t._7.ToString();
t._8.ToString();
t._9.ToString();
t.Rest.Item1.ToString();
t.Rest.Item1.ToString(); // warning already reported for t._8
t.Rest.Item2.ToString();
t._9.ToString(); // warning already reported for t.Rest.Item2
t._10.ToString();
t.Rest.Item3.ToString();
}
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/29970: Should not report warning for `t._
9` or `t.Rest.Item2
`.
// https://github.com/dotnet/roslyn/issues/29970: Should not report warning for `t._
10` or `t.Rest.Item3
`.
comp.VerifyDiagnostics(
// (8,13): warning CS8602: Possible dereference of a null reference.
// t._7.ToString();
...
...
@@ -36511,15 +36439,12 @@ static void F(object? x, object? y)
// (9,13): warning CS8602: Possible dereference of a null reference.
// t._8.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t._8").WithLocation(9, 13),
// (10,13): warning CS8602: Possible dereference of a null reference.
// t._9.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t._9").WithLocation(10, 13),
// (11,13): warning CS8602: Possible dereference of a null reference.
// t.Rest.Item1.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Rest.Item1").WithLocation(11, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// t.Rest.Item2.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Rest.Item2").WithLocation(12, 13));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Rest.Item2").WithLocation(11, 13),
// (13,13): warning CS8602: Possible dereference of a null reference.
// t._10.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t._10").WithLocation(13, 13));
}
[Fact]
...
...
@@ -37013,6 +36938,8 @@ static void F(object x)
y = x;
x.ToString(); // 3
y.ToString(); // 4
x = null;
y = x;
if (x == null) return;
if (y == null) return;
x.ToString(); // 5
...
...
@@ -37032,7 +36959,13 @@ static void F(object x)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(10, 9),
// (11,9): warning CS8602: Possible dereference of a null reference.
// y.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(11, 9));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(11, 9),
// (12,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// x = null;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(12, 13),
// (13,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// y = x;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "x").WithLocation(13, 13));
}
[Fact]
...
...
@@ -37071,7 +37004,13 @@ static void M(C c)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c.F").WithLocation(12, 9),
// (13,9): warning CS8602: Possible dereference of a null reference.
// c.P.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c.P").WithLocation(13, 9));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c.P").WithLocation(13, 9),
// (14,13): hidden CS8606: Result of the comparison is possibly always false.
// if (c.F == null) return;
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysFalse, "c.F == null").WithLocation(14, 13),
// (15,13): hidden CS8606: Result of the comparison is possibly always false.
// if (c.P == null) return;
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysFalse, "c.P == null").WithLocation(15, 13));
}
[Fact]
...
...
@@ -37089,14 +37028,16 @@ public void TrackUnannotatedFieldsAndProperties()
var source1 =
@"class P
{
static void M(C c)
static void M(C c
, object? o
)
{
c.F.ToString();
c.P.ToString();
c.F =
null
;
c.P =
null
;
c.F =
o
;
c.P =
o
;
c.F.ToString(); // 1
c.P.ToString(); // 2
c.F = o;
c.P = o;
if (c.F == null) return;
if (c.P == null) return;
c.F.ToString();
...
...
@@ -38246,7 +38187,10 @@ static void F(IEnumerable<A> e)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(16, 13),
// (19,13): warning CS8602: Possible dereference of a null reference.
// z.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "z").WithLocation(19, 13));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "z").WithLocation(19, 13),
// (20,17): hidden CS8605: Result of the comparison is possibly always true.
// if (z != null) z.ToString();
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue, "z != null").WithLocation(20, 17));
}
[WorkItem(23493, "https://github.com/dotnet/roslyn/issues/23493")]
...
...
@@ -40316,23 +40260,23 @@ class C<T>
{
internal T field = default;
static void F(C<T> a)
static void F(C<T> a
, bool c
)
{
a.field.ToString();
if (a.field != null) a.field.ToString();
if (c)
a.field.ToString();
else
if (a.field != null) a.field.ToString();
C<T> b = new C<T>();
b.field.ToString();
if (b.field != null) b.field.ToString();
if (c)
b.field.ToString();
else
if (b.field != null) b.field.ToString();
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (8,
9
): warning CS8602: Possible dereference of a null reference.
// a.field.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.field").WithLocation(8,
9
),
// (11,
9
): warning CS8602: Possible dereference of a null reference.
// b.field.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "b.field").WithLocation(11,
9
)
// (8,
16
): warning CS8602: Possible dereference of a null reference.
//
if (c)
a.field.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.field").WithLocation(8,
16
),
// (11,
16
): warning CS8602: Possible dereference of a null reference.
//
if (c)
b.field.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "b.field").WithLocation(11,
16
)
);
}
...
...
@@ -41323,14 +41267,14 @@ class B
static void F4<T>(T t4) where T : I<T>?
{
t4.P.ToString(); // 7 and 8
t4.P = default; // 9
and 10
t4 = default; // 1
1
t4.P = default; // 9
t4 = default; // 1
0
}
static void F5<T>(T t5) where T : I<T?>
{
t5.P.ToString(); // 1
2 and 13
t5.P = default; // 1
4 and 15
t5 = default; // 1
6
t5.P.ToString(); // 1
1 and 12
t5.P = default; // 1
3 and 14
t5 = default; // 1
5
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
...
...
@@ -41348,38 +41292,35 @@ class B
// (16,14): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t2 = default; // 3
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(16, 14),
// (21,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// t3 = default; // 6
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "default").WithLocation(21, 14),
// (21,14): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t3 = default; // 6
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(21, 14),
// (21,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// t3 = default; // 6
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "default").WithLocation(21, 14),
// (25,9): warning CS8602: Possible dereference of a null reference.
// t4.P.ToString(); // 7 and 8
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t4").WithLocation(25, 9),
// (25,9): warning CS8602: Possible dereference of a null reference.
// t4.P.ToString(); // 7 and 8
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t4.P").WithLocation(25, 9),
// (26,9): warning CS8602: Possible dereference of a null reference.
// t4.P = default; // 9 and 10
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t4").WithLocation(26, 9),
// (26,16): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t4.P = default; // 9
and 10
// t4.P = default; // 9
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(26, 16),
// (27,14): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t4 = default; // 1
1
// t4 = default; // 1
0
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(27, 14),
// (31,9): warning CS8602: Possible dereference of a null reference.
// t5.P.ToString(); // 1
2 and 13
// t5.P.ToString(); // 1
1 and 12
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t5.P").WithLocation(31, 9),
// (32,16): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t5.P = default; // 1
4 and 15
// t5.P = default; // 1
3 and 14
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(32, 16),
// (33,14): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// t5 = default; // 1
6
// t5 = default; // 1
5
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(33, 14),
// (33,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// t5 = default; // 1
6
// t5 = default; // 1
5
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "default").WithLocation(33, 14)
);
}
...
...
@@ -47438,8 +47379,8 @@ static void F2<T>(T x2, T[] a2)
x2?.ToString();
if (x2 != null) x2.ToString();
T y2 = x2;
y2.ToString();
// warn 5
a2[0].ToString(); // warn
6
y2.ToString();
a2[0].ToString(); // warn
5
}
static void F3<T>() where T : new()
{
...
...
@@ -47466,14 +47407,23 @@ static T F4<T>(T x4)
// (11,9): warning CS8602: Possible dereference of a null reference.
// x1.ToString(); // warn 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x1").WithLocation(11, 9),
// (13,9): hidden CS8607: Expression is probably never null.
// x1?.ToString();
Diagnostic(ErrorCode.HDN_ExpressionIsProbablyNeverNull, "x1").WithLocation(13, 9),
// (14,13): hidden CS8605: Result of the comparison is possibly always true.
// if (x1 != null) x1.ToString();
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue, "x1 != null").WithLocation(14, 13),
// (18,9): warning CS8602: Possible dereference of a null reference.
// x2.ToString(); // warn 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x2").WithLocation(18, 9),
// (23,9): warning CS8602: Possible dereference of a null reference.
// y2.ToString(); // warn 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y2").WithLocation(23, 9),
// (20,9): hidden CS8607: Expression is probably never null.
// x2?.ToString();
Diagnostic(ErrorCode.HDN_ExpressionIsProbablyNeverNull, "x2").WithLocation(20, 9),
// (21,13): hidden CS8605: Result of the comparison is possibly always true.
// if (x2 != null) x2.ToString();
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue, "x2 != null").WithLocation(21, 13),
// (24,9): warning CS8602: Possible dereference of a null reference.
// a2[0].ToString(); // warn
6
// a2[0].ToString(); // warn
5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a2[0]").WithLocation(24, 9));
}
...
...
@@ -50702,5 +50652,628 @@ class A
Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("A.E1").WithLocation(18, 25)
);
}
[WorkItem(23270, "https://github.com/dotnet/roslyn/issues/23270")]
[Fact]
public void NotNullAfterDereference_01()
{
var source =
@"class Program
{
static void F(object? x)
{
x.ToString(); // 1
object? y;
y.ToString();
y = null;
y.ToString(); // 2
x.ToString();
y.ToString();
x = y;
if (y != null)
{
x.ToString();
}
x.ToString();
y.ToString();
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (5,9): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(5, 9),
// (7,9): error CS0165: Use of unassigned local variable 'y'
// y.ToString();
Diagnostic(ErrorCode.ERR_UseDefViolation, "y").WithArguments("y").WithLocation(7, 9),
// (9,9): warning CS8602: Possible dereference of a null reference.
// y.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(9, 9),
// (13,13): hidden CS8605: Result of the comparison is possibly always true.
// if (y != null)
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue, "y != null").WithLocation(13, 13));
}
[Fact]
public void NotNullAfterDereference_02()
{
var source =
@"class Program
{
static void F<T>(T x)
{
x.ToString(); // 1
T y;
y.ToString();
y = default;
y.ToString(); // 2
x.ToString();
y.ToString();
x = y;
if (y != null)
{
x.ToString();
}
x.ToString();
y.ToString();
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (5,9): warning CS8602: Possible dereference of a null reference.
// x.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(5, 9),
// (7,9): error CS0165: Use of unassigned local variable 'y'
// y.ToString();
Diagnostic(ErrorCode.ERR_UseDefViolation, "y").WithArguments("y").WithLocation(7, 9),
// (8,13): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// y = default;
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "default").WithLocation(8, 13),
// (9,9): warning CS8602: Possible dereference of a null reference.
// y.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(9, 9),
// (13,13): hidden CS8605: Result of the comparison is possibly always true.
// if (y != null)
Diagnostic(ErrorCode.HDN_NullCheckIsProbablyAlwaysTrue, "y != null").WithLocation(13, 13));
}
[Fact]
public void NotNullAfterDereference_03()
{
var source =
@"class C
{
void F1(C x) { }
static void G1(C? x)
{
x?.F1(x);
x!.F1(x); // 1
x.F1(x); // 2
x.F1(x);
}
static void G2(C? y)
{
y?.F2(y);
y!.F2(y); // 3
y.F2(y); // 4, 5
y.F2(y); // 6, 7
}
}
static class E
{
internal static void F2(this C x, C y) { }
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8604: Possible null reference argument for parameter 'x' in 'void C.F1(C x)'.
// x!.F1(x); // 1
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "x").WithArguments("x", "void C.F1(C x)").WithLocation(7, 15),
// (8,9): warning CS8602: Possible dereference of a null reference.
// x.F1(x); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(8, 9),
// (14,15): warning CS8604: Possible null reference argument for parameter 'y' in 'void E.F2(C x, C y)'.
// y!.F2(y); // 3
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("y", "void E.F2(C x, C y)").WithLocation(14, 15),
// (15,9): warning CS8604: Possible null reference argument for parameter 'x' in 'void E.F2(C x, C y)'.
// y.F2(y); // 4, 5
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("x", "void E.F2(C x, C y)").WithLocation(15, 9),
// (15,14): warning CS8604: Possible null reference argument for parameter 'y' in 'void E.F2(C x, C y)'.
// y.F2(y); // 4, 5
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("y", "void E.F2(C x, C y)").WithLocation(15, 14),
// (16,9): warning CS8604: Possible null reference argument for parameter 'x' in 'void E.F2(C x, C y)'.
// y.F2(y); // 6, 7
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("x", "void E.F2(C x, C y)").WithLocation(16, 9),
// (16,14): warning CS8604: Possible null reference argument for parameter 'y' in 'void E.F2(C x, C y)'.
// y.F2(y); // 6, 7
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("y", "void E.F2(C x, C y)").WithLocation(16, 14));
}
[Fact]
public void NotNullAfterDereference_04()
{
var source =
@"class Program
{
static void F<T>(bool b, string? s)
{
int n;
if (b)
{
n = s/*T:string?*/.Length; // 1
n = s/*T:string!*/.Length;
}
n = b ? s/*T:string?*/.Length + // 2
s/*T:string!*/.Length : 0;
n = s/*T:string?*/.Length; // 3
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (8,17): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 17),
// (12,17): warning CS8602: Possible dereference of a null reference.
// n = b ? s/*T:string?*/.Length + // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(12, 17),
// (14,13): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(14, 13));
comp.VerifyTypes();
}
[Fact]
public void NotNullAfterDereference_05()
{
var source =
@"class Program
{
static void F(string? s)
{
int n;
try
{
n = s/*T:string?*/.Length; // 1
try
{
n = s/*T:string!*/.Length;
}
finally
{
n = s/*T:string!*/.Length;
}
}
catch (System.IO.IOException)
{
n = s/*T:string?*/.Length; // 2
}
catch
{
n = s/*T:string?*/.Length; // 3
}
finally
{
n = s/*T:string?*/.Length; // 4
}
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (8,17): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(8, 17),
// (20,17): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(20, 17),
// (24,17): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(24, 17),
// (28,17): warning CS8602: Possible dereference of a null reference.
// n = s/*T:string?*/.Length; // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s").WithLocation(28, 17));
comp.VerifyTypes();
}
[Fact]
public void NotNullAfterDereference_06()
{
var source =
@"class C
{
object F = default!;
static void G(C? c)
{
c.F = c;
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// One warning only, rather than one warning for dereference of c.F
// and another warning for assignment c.F = c.
comp.VerifyDiagnostics(
// (6,9): warning CS8602: Possible dereference of a null reference.
// c.F = c;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c").WithLocation(6, 9));
}
[Fact]
public void NotNullAfterDereference_Call()
{
var source =
@"#pragma warning disable 0649
class C
{
object? y;
void F(object? o)
{
}
static void G(C? x)
{
x.F(x = null); // 1
x.F(x.y); // 2, 3
x.F(x.y);
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for x.F(x.y).
comp.VerifyDiagnostics(
// (10,9): warning CS8602: Possible dereference of a null reference.
// x.F(x = null); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(10, 9),
// (11,9): warning CS8602: Possible dereference of a null reference.
// x.F(x.y); // 2, 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(11, 9));
}
[Fact]
public void NotNullAfterDereference_Array()
{
var source =
@"class Program
{
static int F(object? o) => 0;
static void G(object[]? x, object[] y)
{
object z;
z = x[F(x = null)]; // 1
z = x[x.Length]; // 2, 3
z = x[x.Length];
y[F(y = null)] = 1;
y[y.Length] = 2; // 4, 5
y[y.Length] = 3;
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for x[x.Length] and y[y.Length].
comp.VerifyDiagnostics(
// (7,13): warning CS8602: Possible dereference of a null reference.
// z = x[F(x = null)]; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(7, 13),
// (8,13): warning CS8602: Possible dereference of a null reference.
// z = x[x.Length]; // 2, 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(8, 13),
// (10,17): warning CS8600: Converting null literal or possible null value to non-nullable type.
// y[F(y = null)] = 1;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(10, 17),
// (11,9): warning CS8602: Possible dereference of a null reference.
// y[y.Length] = 2; // 4, 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(11, 9));
}
[Fact]
public void NotNullAfterDereference_Indexer()
{
var source =
@"#pragma warning disable 0649
class C
{
object? F;
object this[object? o]
{
get { return 1; }
set { }
}
static void G(C? x, C y)
{
object z;
z = x[x = null]; // 1
z = x[x.F]; // 2, 3
z = x[x.F];
y[y = null] = 1;
y[y.F] = 2; // 4, 5
y[y.F] = 3;
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for x[x.F] and y[y.F].
comp.VerifyDiagnostics(
// (13,13): warning CS8602: Possible dereference of a null reference.
// z = x[x = null]; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(13, 13),
// (14,13): warning CS8602: Possible dereference of a null reference.
// z = x[x.F]; // 2, 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(14, 13),
// (16,15): warning CS8600: Converting null literal or possible null value to non-nullable type.
// y[y = null] = 1;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(16, 15),
// (17,9): warning CS8602: Possible dereference of a null reference.
// y[y.F] = 2; // 4, 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(17, 9));
}
[Fact]
public void NotNullAfterDereference_Field()
{
var source =
@"#pragma warning disable 0649
#pragma warning disable 8618
class C
{
object? F;
static object? G(object? o) => o;
static void M(C? x, C? y)
{
object? o;
o = x.F; // 1
o = x.F;
y.F = G(y = null); // 2
y.F = G(y.F); // 3, 4
y.F = G(y.F);
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for y.F = G(y.F).
comp.VerifyDiagnostics(
// (10,13): warning CS8602: Possible dereference of a null reference.
// o = x.F; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(10, 13),
// (12,9): warning CS8602: Possible dereference of a null reference.
// y.F = G(y = null); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(12, 9),
// (13,9): warning CS8602: Possible dereference of a null reference.
// y.F = G(y.F); // 3, 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(13, 9));
}
[Fact]
public void NotNullAfterDereference_Property()
{
var source =
@"#pragma warning disable 0649
#pragma warning disable 8618
class C
{
object? P { get; set; }
static object? F(object? o) => o;
static void M(C? x, C? y)
{
object? o;
o = x.P; // 1
o = x.P;
y.P = F(y = null); // 2
y.P = F(y.P); // 3, 4
y.P = F(y.P);
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for y.P = F(y.P).
comp.VerifyDiagnostics(
// (10,13): warning CS8602: Possible dereference of a null reference.
// o = x.F; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(10, 13),
// (12,9): warning CS8602: Possible dereference of a null reference.
// y.F = G(y = null); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(12, 9),
// (13,9): warning CS8602: Possible dereference of a null reference.
// y.F = G(y.F); // 3, 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(13, 9));
}
[Fact]
public void NotNullAfterDereference_Event()
{
var source =
@"#pragma warning disable 0649
#pragma warning disable 8618
delegate void D();
class C
{
event D E;
D F;
static D G(C? c) => throw null;
static void M(C? x, C? y, C? z)
{
x.E(); // 1
x.E();
y.E += G(y = null); // 2
y.E += y.F; // 3, 4
y.E += y.F;
y.E();
z.E = null; // 5
z.E();
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for y.E += y.F.
comp.VerifyDiagnostics(
// (11,9): warning CS8602: Possible dereference of a null reference.
// x.E(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(11, 9),
// (13,9): warning CS8602: Possible dereference of a null reference.
// y.E += G(y = null); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(13, 9),
// (14,9): warning CS8602: Possible dereference of a null reference.
// y.E += y.F; // 3, 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(14, 9),
// (17,9): warning CS8602: Possible dereference of a null reference.
// z.E = null; // 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "z").WithLocation(17, 9),
// (17,15): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// z.E = null; // 5
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(17, 15),
// (18,9): warning CS8602: Possible dereference of a null reference.
// z.E();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "z.E").WithLocation(18, 9));
}
[Fact]
public void NotNullAfterDereference_Dynamic()
{
var source =
@"class Program
{
static void F(dynamic? d)
{
d.ToString(); // 1
d.ToString();
}
static void G(dynamic? x, dynamic? y)
{
object z;
z = x[x = null]; // 2
z = x[x.F]; // 3, 4
z = x[x.F];
y[y = null] = 1;
y[y.F] = 2; // 5, 6
y[y.F] = 3;
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30598: Should report two warnings for x[x.F] and y[y.F].
comp.VerifyDiagnostics(
// (5,9): warning CS8602: Possible dereference of a null reference.
// d.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "d").WithLocation(5, 9),
// (11,13): warning CS8602: Possible dereference of a null reference.
// z = x[x = null]; // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(11, 13),
// (12,13): warning CS8602: Possible dereference of a null reference.
// z = x[x.F]; // 3, 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(12, 13),
// (14,9): warning CS8602: Possible dereference of a null reference.
// y[y = null] = 1;
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(14, 9),
// (15,9): warning CS8602: Possible dereference of a null reference.
// y[y.F] = 2; // 5, 6
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(15, 9));
}
[WorkItem(30563, "https://github.com/dotnet/roslyn/issues/30563")]
[Fact]
public void NotNullAfterDereference_MethodGroup_01()
{
var source =
@"delegate void D();
class C
{
void F1() { }
static void F(C? x, C? y)
{
D d;
d = x.F1; // warning
d = y.F2; // ok
}
}
static class E
{
internal static void F2(this C? c) { }
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30563: Should not report "CS8602: Possible dereference" for y.F2.
comp.VerifyDiagnostics(
// (8,13): warning CS8602: Possible dereference of a null reference.
// d = x.F1; // warning
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(8, 13),
// (9,13): warning CS8602: Possible dereference of a null reference.
// d = y.F2; // ok
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(9, 13));
}
[WorkItem(30563, "https://github.com/dotnet/roslyn/issues/30563")]
[Fact]
public void NotNullAfterDereference_MethodGroup_02()
{
var source =
@"delegate void D1(int i);
delegate void D2();
class C
{
void F(int i) { }
static void F1(D1 d) { }
static void F2(D2 d) { }
static void G(C? x, C? y)
{
F1(x.F); // 1
F1(x.F);
F2(y.F); // 2
F2(y.F); // 3
}
}
static class E
{
internal static void F(this C x) { }
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30563: Should not report "CS8602: Possible dereference"
// for F2(y.F). Should report "CS8604: Possible null reference argument" instead.
comp.VerifyDiagnostics(
// (10,12): warning CS8602: Possible dereference of a null reference.
// F1(x.F); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(10, 12),
// (12,12): warning CS8602: Possible dereference of a null reference.
// F2(y.F); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y").WithLocation(12, 12));
}
[WorkItem(30562, "https://github.com/dotnet/roslyn/issues/30562")]
[Fact]
public void NotNullAfterDereference_ForEach()
{
var source =
@"class Enumerable
{
public System.Collections.IEnumerator GetEnumerator() => throw null;
}
class Program
{
static void F1(object[]? x1, object[]? y1)
{
foreach (var x in x1) { } // 1
foreach (var x in x1) { }
foreach (var y in y1) { } // 2
y1.GetEnumerator();
}
static void F2(Enumerable? x2, Enumerable? y2)
{
foreach (var x in x2) { } // 3
foreach (var x in x2) { }
y2.GetEnumerator(); // 4
foreach (var y in y2) { }
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/30562: Should not report second warning in each case.
comp.VerifyDiagnostics(
// (9,27): warning CS8602: Possible dereference of a null reference.
// foreach (var x in x1) { } // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x1").WithLocation(9, 27),
// (10,27): warning CS8602: Possible dereference of a null reference.
// foreach (var x in x1) { }
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x1").WithLocation(10, 27),
// (11,27): warning CS8602: Possible dereference of a null reference.
// foreach (var y in y1) { } // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y1").WithLocation(11, 27),
// (12,9): warning CS8602: Possible dereference of a null reference.
// y1.GetEnumerator();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y1").WithLocation(12, 9),
// (16,27): warning CS8602: Possible dereference of a null reference.
// foreach (var x in x2) { } // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x2").WithLocation(16, 27),
// (17,27): warning CS8602: Possible dereference of a null reference.
// foreach (var x in x2) { }
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x2").WithLocation(17, 27),
// (18,9): warning CS8602: Possible dereference of a null reference.
// y2.GetEnumerator(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y2").WithLocation(18, 9));
}
}
}
src/Features/CSharp/Portable/ConvertForEachToFor/CSharpConvertForEachToForCodeRefactoringProvider.cs
浏览文件 @
5bb48dbd
...
...
@@ -25,7 +25,7 @@ internal sealed class CSharpConvertForEachToForCodeRefactoringProvider :
protected
override
ForEachStatementSyntax
GetForEachStatement
(
TextSpan
selection
,
SyntaxToken
token
)
{
var
foreachStatement
=
token
.
Parent
.
FirstAncestorOrSelf
<
ForEachStatementSyntax
>();
//
PROTOTYPE(async-streams)
: Add tests for this scenario
//
https://github.com/dotnet/roslyn/issues/30584
: Add tests for this scenario
if
(
foreachStatement
==
null
||
foreachStatement
.
AwaitKeyword
!=
default
)
{
return
null
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录