Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
44f672fd
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,发现更多精彩内容 >>
未验证
提交
44f672fd
编写于
4月 09, 2019
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Addressed PR feedback.
上级
cdc368d1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
63 addition
and
54 deletion
+63
-54
src/Compilers/CSharp/Portable/BoundTree/NullabilityRewriter.cs
...ompilers/CSharp/Portable/BoundTree/NullabilityRewriter.cs
+12
-7
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
...pilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
+12
-28
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
...arp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
+0
-12
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
+5
-7
src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs
...harp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs
+34
-0
未找到文件。
src/Compilers/CSharp/Portable/BoundTree/NullabilityRewriter.cs
浏览文件 @
44f672fd
...
...
@@ -36,7 +36,8 @@ private BoundNode VisitBinaryOperatorBase(BoundBinaryOperatorBase binaryOperator
{
stack
.
Push
(
currentBinary
);
currentBinary
=
currentBinary
.
Left
as
BoundBinaryOperatorBase
;
}
while
(
currentBinary
!=
null
);
}
while
(
currentBinary
!=
null
);
Debug
.
Assert
(
stack
.
Count
>
0
);
var
leftChild
=
(
BoundExpression
)
Visit
(
stack
.
Peek
().
Left
);
...
...
@@ -49,12 +50,15 @@ private BoundNode VisitBinaryOperatorBase(BoundBinaryOperatorBase binaryOperator
var
right
=
(
BoundExpression
)
Visit
(
currentBinary
.
Right
);
var
type
=
foundInfo
?
infoAndType
.
Type
:
currentBinary
.
Type
;
#pragma warning disable IDE0055 // Fix formatting
// PROTOTYPE(nullable-api): We'll need to update the symbols for the internal methods/operators used in the binary operators
currentBinary
=
currentBinary
switch
{
BoundBinaryOperator
binary
=>
(
BoundBinaryOperatorBase
)
binary
.
Update
(
binary
.
OperatorKind
,
binary
.
ConstantValueOpt
,
binary
.
MethodOpt
,
binary
.
ResultKind
,
leftChild
,
right
,
type
),
BoundUserDefinedConditionalLogicalOperator
logical
=>
logical
.
Update
(
logical
.
OperatorKind
,
logical
.
LogicalOperator
,
logical
.
TrueOperator
,
logical
.
FalseOperator
,
logical
.
ResultKind
,
leftChild
,
right
,
type
),
_
=>
throw
ExceptionUtilities
.
UnexpectedValue
(
currentBinary
.
Kind
),
};
{
BoundBinaryOperator
binary
=>
(
BoundBinaryOperatorBase
)
binary
.
Update
(
binary
.
OperatorKind
,
binary
.
ConstantValueOpt
,
binary
.
MethodOpt
,
binary
.
ResultKind
,
leftChild
,
right
,
type
),
BoundUserDefinedConditionalLogicalOperator
logical
=>
logical
.
Update
(
logical
.
OperatorKind
,
logical
.
LogicalOperator
,
logical
.
TrueOperator
,
logical
.
FalseOperator
,
logical
.
ResultKind
,
leftChild
,
right
,
type
),
_
=>
throw
ExceptionUtilities
.
UnexpectedValue
(
currentBinary
.
Kind
),
};
#pragma warning restore IDE0055 // Fix formatting
if
(
foundInfo
)
{
...
...
@@ -62,7 +66,8 @@ private BoundNode VisitBinaryOperatorBase(BoundBinaryOperatorBase binaryOperator
}
leftChild
=
currentBinary
;
}
while
(
stack
.
Count
>
0
);
}
while
(
stack
.
Count
>
0
);
Debug
.
Assert
(
currentBinary
!=
null
);
return
currentBinary
;
...
...
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
浏览文件 @
44f672fd
...
...
@@ -1590,11 +1590,11 @@ private BoundNode GetBoundLambdaOrQuery(CSharpSyntaxNode lambdaOrQuery)
using
(
_nodeMapLock
.
DisposableWrite
())
{
BoundNode
boundOuterExpression
=
this
.
Bind
(
incrementalBinder
,
nodeToBind
,
_ignoredDiagnostics
);
nodes
=
GuardedAddBoundTreeAndGetBoundNodeFromMap
(
lambdaOrQuery
,
boundOuterExpression
);
// If we're here, nullable analysis must be off, or we're in an error scenario and didn't find any
// nodes from this binding.
Debug
.
Assert
(!
EnableNullableAnalysis
||
nodes
.
IsDefaultOrEmpty
);
// PROTOTYPE(nullable-api): Rewrite the above node and add a test that hits this path with nullable
// enabled
nodes
=
GuardedAddBoundTreeAndGetBoundNodeFromMap
(
lambdaOrQuery
,
boundOuterExpression
);
}
if
(!
nodes
.
IsDefaultOrEmpty
)
...
...
@@ -1623,17 +1623,10 @@ private BoundNode GetBoundLambdaOrQuery(CSharpSyntaxNode lambdaOrQuery)
{
BoundNode
boundOuterExpression
=
this
.
Bind
(
incrementalBinder
,
lambdaOrQuery
,
_ignoredDiagnostics
);
if
(
EnableNullableAnalysis
)
{
boundOuterExpression
=
RewriteNullableBoundNodes
(
boundOuterExpression
,
incrementalBinder
.
Conversions
,
_ignoredDiagnostics
);
}
// PROTOTYPE(nullable-api): We need to do a rewrite here, and create a test that can hit this.
#if DEBUG
else
{
var
diagnostics
=
new
DiagnosticBag
();
_
=
RewriteNullableBoundNodes
(
boundOuterExpression
,
incrementalBinder
.
Conversions
,
diagnostics
);
diagnostics
.
Free
();
}
var
diagnostics
=
new
DiagnosticBag
();
_
=
RewriteNullableBoundNodes
(
boundOuterExpression
,
incrementalBinder
.
Conversions
,
diagnostics
);
#endif
nodes
=
GuardedAddBoundTreeAndGetBoundNodeFromMap
(
lambdaOrQuery
,
boundOuterExpression
);
...
...
@@ -1822,7 +1815,8 @@ private void EnsureRootBoundForNullabilityIfNecessary()
DiagnosticBag
diagnostics
=
_ignoredDiagnostics
;
// If we're in DEBUG mode, always enable the analysis, but throw away the results
if
(!
EnableNullableAnalysis
)
// PROTOTYPE(nullable-api): Disable speculative semantic models for now.
if
(!
EnableNullableAnalysis
||
IsSpeculativeSemanticModel
)
{
#if DEBUG
diagnostics
=
new
DiagnosticBag
();
...
...
@@ -1835,17 +1829,13 @@ private void EnsureRootBoundForNullabilityIfNecessary()
if
(
_guardedNodeMap
.
ContainsKey
(
Root
)
#if DEBUG
// In DEBUG mode, we don't want to increase test run times
by an insane length o
f
//
time, so if
nullable analysis isn't enabled and some node has already been bound
// In DEBUG mode, we don't want to increase test run times
, so i
f
// nullable analysis isn't enabled and some node has already been bound
// we assume we've already done this test binding and just return
||
(!
EnableNullableAnalysis
&&
_guardedNodeMap
.
Count
>
0
)
#endif
)
{
#if DEBUG
if
(!
EnableNullableAnalysis
)
diagnostics
.
Free
();
#endif
return
;
}
...
...
@@ -1858,7 +1848,7 @@ private void EnsureRootBoundForNullabilityIfNecessary()
// then take that state and run analysis on the statement or expression being speculated on.
// Currently, it will return incorrect info because it's just running analysis on the speculated
// part.
var
binder
=
GetEnclosingBinder
(
GetAdjustedNodePosition
(
Root
));
var
binder
=
GetEnclosingBinder
(
GetAdjustedNodePosition
(
GetBindableSyntaxNode
(
Root
)
));
var
boundRoot
=
Bind
(
binder
,
Root
,
diagnostics
);
boundRoot
=
RewriteNullableBoundNodes
(
boundRoot
,
binder
.
Conversions
,
diagnostics
);
...
...
@@ -1866,12 +1856,6 @@ private void EnsureRootBoundForNullabilityIfNecessary()
{
GuardedAddBoundTreeForStandaloneSyntax
(
Root
,
boundRoot
);
}
#if DEBUG
else
{
diagnostics
.
Free
();
}
#endif
}
protected
abstract
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
);
...
...
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs
浏览文件 @
44f672fd
...
...
@@ -70,18 +70,6 @@ public override BoundNode VisitDeconstructionAssignmentOperator(BoundDeconstruct
return
null
;
}
public
override
BoundNode
VisitNewT
(
BoundNewT
node
)
{
// https://github.com/dotnet/roslyn/issues/33387 We're not currently
// examining child nodes correctly
if
(
node
.
InitializerExpressionOpt
!=
null
)
{
VerifyExpression
(
node
.
InitializerExpressionOpt
,
overrideSkippedExpression
:
true
);
}
return
null
;
}
public
override
BoundNode
VisitBadExpression
(
BoundBadExpression
node
)
{
// Regardless of what the BadExpression is, we need to add all of its direct children to the visited map. They
...
...
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
浏览文件 @
44f672fd
...
...
@@ -1557,16 +1557,14 @@ private TypeWithState VisitRefExpression(BoundExpression expr, TypeWithAnnotatio
private
bool
TryGetReturnType
(
out
TypeWithAnnotations
type
)
{
var
method
=
_symbol
as
MethodSymbol
;
var
nullableReturnType
=
(
_methodSignatureOpt
??
method
)?.
ReturnTypeWithAnnotations
;
Debug
.
Assert
(!
nullableReturnType
.
HasValue
||
(
object
)
nullableReturnType
.
Value
!=
LambdaSymbol
.
ReturnTypeIsBeingInferred
);
if
(!
nullableReturnType
.
HasValue
)
if
(
method
is
null
)
{
type
=
default
;
return
false
;
}
var
returnType
=
nullableReturnType
.
Value
;
var
returnType
=
(
_methodSignatureOpt
??
method
).
ReturnTypeWithAnnotations
;
Debug
.
Assert
((
object
)
returnType
!=
LambdaSymbol
.
ReturnTypeIsBeingInferred
);
if
(
returnType
.
SpecialType
==
SpecialType
.
System_Void
)
{
...
...
@@ -5187,9 +5185,9 @@ public override BoundNode VisitFixedLocalCollectionInitializer(BoundFixedLocalCo
}
VisitRvalue
(
initializer
);
if
(
initializer
.
Kind
==
BoundKind
.
AddressOfOperator
)
if
(
node
.
Expression
.
Kind
==
BoundKind
.
AddressOfOperator
)
{
SetResultType
(
initializer
,
new
TypeWithState
(
initializer
.
Type
,
ResultType
.
State
));
SetResultType
(
node
.
Expression
,
new
TypeWithState
(
node
.
Expression
.
Type
,
ResultType
.
State
));
}
SetNotNullResult
(
node
);
return
null
;
...
...
src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs
浏览文件 @
44f672fd
...
...
@@ -627,5 +627,39 @@ void verifyCompilation(CSharpCompilation compilation)
AssertEx
.
Equal
(
expectedNullabilities
,
members
.
Select
(
nullabilityFunc
));
}
}
[
Fact
]
public
void
LambdaBody_01
()
{
var
source
=
@"
using System;
class C
{
void M(Action a)
{
M(() =>
{
object? o = null;
if (o == null) return;
o.ToString();
});
}
}
"
;
var
comp
=
CreateCompilation
(
source
,
options
:
WithNonNullTypesTrue
());
comp
.
VerifyDiagnostics
();
var
syntaxTree
=
comp
.
SyntaxTrees
[
0
];
var
root
=
syntaxTree
.
GetRoot
();
var
model
=
comp
.
GetSemanticModel
(
syntaxTree
);
var
invocation
=
root
.
DescendantNodes
().
OfType
<
InvocationExpressionSyntax
>().
Last
();
var
typeInfo
=
model
.
GetTypeInfo
(((
MemberAccessExpressionSyntax
)
invocation
.
Expression
).
Expression
);
Assert
.
Equal
(
PublicNullableFlowState
.
NotNull
,
typeInfo
.
Nullability
.
FlowState
);
// PROTOTYPE(nullable-api): This is incorrect. o should be Annotated, as you can assign
// null without a warning.
Assert
.
Equal
(
PublicNullableAnnotation
.
NotAnnotated
,
typeInfo
.
Nullability
.
Annotation
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录