Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
734f1d82
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,发现更多精彩内容 >>
未验证
提交
734f1d82
编写于
5月 10, 2019
作者:
C
Charles Stoner
提交者:
GitHub
5月 10, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Infer method group based on receiver nullability (#35601)
上级
eb04e507
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
783 addition
and
61 deletion
+783
-61
src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
+1
-1
src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
...ers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
+2
-2
src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
...s/CSharp/Portable/Compilation/InitializerSemanticModel.cs
+2
-2
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs
...ion/MemberSemanticModel.SpeculativeMemberSemanticModel.cs
+2
-2
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
...pilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
+3
-3
src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs
...rs/CSharp/Portable/Compilation/MethodBodySemanticModel.cs
+2
-2
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
+1
-1
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
+106
-42
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
...rp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
+664
-6
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Attributes.cs
浏览文件 @
734f1d82
...
...
@@ -193,7 +193,7 @@ private CSharpAttributeData GetAttribute(BoundAttribute boundAttribute, Diagnost
Debug
.
Assert
((
object
)
attributeType
!=
null
);
NullableWalker
.
AnalyzeIfNeeded
(
Compilation
,
boundAttribute
,
Conversions
,
diagnostics
);
NullableWalker
.
AnalyzeIfNeeded
(
this
,
boundAttribute
,
diagnostics
);
bool
hasErrors
=
boundAttribute
.
HasAnyErrors
;
...
...
src/Compilers/CSharp/Portable/Compilation/AttributeSemanticModel.cs
浏览文件 @
734f1d82
...
...
@@ -98,9 +98,9 @@ internal override BoundNode Bind(Binder binder, CSharpSyntaxNode node, Diagnosti
}
}
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
)
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Binder
binder
,
DiagnosticBag
diagnostics
)
{
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
symbol
:
null
,
boundRoot
,
conversions
,
diagnostics
);
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
symbol
:
null
,
boundRoot
,
binder
,
diagnostics
);
}
internal
override
bool
TryGetSpeculativeSemanticModelCore
(
SyntaxTreeSemanticModel
parentModel
,
int
position
,
ConstructorInitializerSyntax
constructorInitializer
,
out
SemanticModel
speculativeModel
)
...
...
src/Compilers/CSharp/Portable/Compilation/InitializerSemanticModel.cs
浏览文件 @
734f1d82
...
...
@@ -258,9 +258,9 @@ internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTre
return
false
;
}
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
)
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Binder
binder
,
DiagnosticBag
diagnostics
)
{
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
,
boundRoot
,
conversions
,
diagnostics
);
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
,
boundRoot
,
binder
,
diagnostics
);
}
}
}
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs
浏览文件 @
734f1d82
...
...
@@ -22,14 +22,14 @@ public SpeculativeMemberSemanticModel(SyntaxTreeSemanticModel parentSemanticMode
{
}
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
)
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Binder
binder
,
DiagnosticBag
diagnostics
)
{
// https://github.com/dotnet/roslyn/issues/35037: Speculative models are going to have to do something more advanced
// here. They will need to run nullable analysis up to the point that is being speculated on, and
// 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.
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
as
MethodSymbol
,
boundRoot
,
conversions
,
diagnostics
);
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
as
MethodSymbol
,
boundRoot
,
binder
,
diagnostics
);
}
internal
override
bool
TryGetSpeculativeSemanticModelCore
(
SyntaxTreeSemanticModel
parentModel
,
int
position
,
ConstructorInitializerSyntax
constructorInitializer
,
out
SemanticModel
speculativeModel
)
...
...
src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs
浏览文件 @
734f1d82
...
...
@@ -1625,7 +1625,7 @@ private BoundNode GetBoundLambdaOrQuery(CSharpSyntaxNode lambdaOrQuery)
// https://github.com/dotnet/roslyn/issues/35038: We need to do a rewrite here, and create a test that can hit this.
#if DEBUG
var
diagnostics
=
new
DiagnosticBag
();
_
=
RewriteNullableBoundNodes
(
boundOuterExpression
,
incrementalBinder
.
Conversions
,
diagnostics
);
_
=
RewriteNullableBoundNodes
(
boundOuterExpression
,
incrementalBinder
,
diagnostics
);
#endif
nodes
=
GuardedAddBoundTreeAndGetBoundNodeFromMap
(
lambdaOrQuery
,
boundOuterExpression
);
...
...
@@ -1850,7 +1850,7 @@ private void EnsureRootBoundForNullabilityIfNecessary()
// part.
var
binder
=
GetEnclosingBinder
(
GetAdjustedNodePosition
(
bindableRoot
));
var
boundRoot
=
Bind
(
binder
,
bindableRoot
,
diagnostics
);
boundRoot
=
RewriteNullableBoundNodes
(
boundRoot
,
binder
.
Conversions
,
diagnostics
);
boundRoot
=
RewriteNullableBoundNodes
(
boundRoot
,
binder
,
diagnostics
);
if
(
Compilation
.
NullableAnalysisEnabled
&&
!
IsSpeculativeSemanticModel
)
{
...
...
@@ -1858,7 +1858,7 @@ private void EnsureRootBoundForNullabilityIfNecessary()
}
}
protected
abstract
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
);
protected
abstract
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Binder
binder
,
DiagnosticBag
diagnostics
);
/// <summary>
/// Get all bounds nodes associated with a node, ordered from highest to lowest in the bound tree.
...
...
src/Compilers/CSharp/Portable/Compilation/MethodBodySemanticModel.cs
浏览文件 @
734f1d82
...
...
@@ -205,9 +205,9 @@ internal override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSemanticMode
return
false
;
}
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Conversions
conversions
,
DiagnosticBag
diagnostics
)
protected
override
BoundNode
RewriteNullableBoundNodes
(
BoundNode
boundRoot
,
Binder
binder
,
DiagnosticBag
diagnostics
)
{
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
,
boundRoot
,
conversions
,
diagnostics
);
return
NullableWalker
.
AnalyzeAndRewrite
(
Compilation
,
MemberSymbol
,
boundRoot
,
binder
,
diagnostics
);
}
}
}
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
浏览文件 @
734f1d82
...
...
@@ -1653,7 +1653,7 @@ internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationSt
// also run the nullable walker, and issue duplicate warnings. We should try to only run the pass
// once.
// https://github.com/dotnet/roslyn/issues/35041
methodBody
=
NullableWalker
.
AnalyzeAndRewrite
(
bodyBinder
.
Compilation
,
method
,
methodBody
,
bodyBinder
.
Conversions
,
new
DiagnosticBag
());
methodBody
=
NullableWalker
.
AnalyzeAndRewrite
(
bodyBinder
.
Compilation
,
method
,
methodBody
,
bodyBinder
,
new
DiagnosticBag
());
}
forSemanticModel
=
(
syntaxNode
,
methodBody
,
bodyBinder
);
...
...
src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
浏览文件 @
734f1d82
...
...
@@ -108,6 +108,11 @@ public VisitArgumentResult(VisitResult visitResult, Optional<LocalState> stateFo
/// </summary>
private
readonly
PooledDictionary
<
Symbol
,
TypeWithAnnotations
>
_variableTypes
=
PooledDictionary
<
Symbol
,
TypeWithAnnotations
>.
GetInstance
();
/// <summary>
/// Binder for symbol being analyzed.
/// </summary>
private
readonly
Binder
_binder
;
/// <summary>
/// Conversions with nullability and unknown matching any.
/// </summary>
...
...
@@ -308,12 +313,14 @@ protected override void Free()
bool
useMethodSignatureParameterTypes
,
MethodSymbol
methodSignatureOpt
,
BoundNode
node
,
Binder
binder
,
Conversions
conversions
,
ArrayBuilder
<(
BoundReturnStatement
,
TypeWithAnnotations
)>
returnTypesOpt
,
VariableState
initialState
,
Dictionary
<
BoundExpression
,
(
NullabilityInfo
,
TypeSymbol
)>
analyzedNullabilityMapOpt
)
:
base
(
compilation
,
symbol
,
node
,
EmptyStructTypeCache
.
CreatePrecise
(),
trackUnassignments
:
true
)
{
_binder
=
binder
;
_conversions
=
(
Conversions
)
conversions
.
WithNullability
(
true
);
_useMethodSignatureParameterTypes
=
(
object
)
methodSignatureOpt
!=
null
&&
useMethodSignatureParameterTypes
;
_methodSignatureOpt
=
methodSignatureOpt
;
...
...
@@ -387,10 +394,12 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
{
return
;
}
var
conversions
=
compilation
.
GetBinderFactory
(
node
.
SyntaxTree
).
GetBinder
(
node
.
Syntax
).
Conversions
;
var
binder
=
compilation
.
GetBinderFactory
(
node
.
SyntaxTree
).
GetBinder
(
node
.
Syntax
);
var
conversions
=
binder
.
Conversions
;
Analyze
(
compilation
,
method
,
node
,
binder
,
conversions
,
diagnostics
,
useMethodSignatureParameterTypes
:
false
,
...
...
@@ -404,7 +413,7 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
CSharpCompilation
compilation
,
Symbol
symbol
,
BoundNode
node
,
Conversions
conversions
,
Binder
binder
,
DiagnosticBag
diagnostics
)
{
var
analyzedNullabilities
=
PooledDictionary
<
BoundExpression
,
(
NullabilityInfo
,
TypeSymbol
)>.
GetInstance
();
...
...
@@ -413,7 +422,8 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
compilation
,
symbol
,
node
,
conversions
,
binder
,
binder
.
Conversions
,
diagnostics
,
useMethodSignatureParameterTypes
:
!(
methodSymbol
is
null
),
methodSignatureOpt
:
methodSymbol
,
...
...
@@ -434,17 +444,28 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
}
internal
static
void
AnalyzeIfNeeded
(
CSharpCompilation
compilation
,
Binder
binder
,
BoundAttribute
attribute
,
Conversions
conversions
,
DiagnosticBag
diagnostics
)
{
var
compilation
=
binder
.
Compilation
;
if
(
compilation
.
LanguageVersion
<
MessageID
.
IDS_FeatureNullableReferenceTypes
.
RequiredVersion
())
{
return
;
}
Analyze
(
compilation
,
null
,
attribute
,
conversions
,
diagnostics
,
useMethodSignatureParameterTypes
:
false
,
methodSignatureOpt
:
null
,
returnTypes
:
null
,
initialState
:
null
,
analyzedNullabilityMapOpt
:
null
);
Analyze
(
compilation
,
symbol
:
null
,
attribute
,
binder
,
binder
.
Conversions
,
diagnostics
,
useMethodSignatureParameterTypes
:
false
,
methodSignatureOpt
:
null
,
returnTypes
:
null
,
initialState
:
null
,
analyzedNullabilityMapOpt
:
null
);
}
internal
static
void
Analyze
(
...
...
@@ -461,6 +482,7 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
compilation
,
lambda
.
Symbol
,
lambda
.
Body
,
lambda
.
Binder
,
conversions
,
diagnostics
,
useMethodSignatureParameterTypes
:
!
lambda
.
UnboundLambda
.
HasExplicitlyTypedParameterList
,
...
...
@@ -474,6 +496,7 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
CSharpCompilation
compilation
,
Symbol
symbol
,
BoundNode
node
,
Binder
binder
,
Conversions
conversions
,
DiagnosticBag
diagnostics
,
bool
useMethodSignatureParameterTypes
,
...
...
@@ -489,6 +512,7 @@ protected override ImmutableArray<PendingBranch> Scan(ref bool badRegion)
useMethodSignatureParameterTypes
,
methodSignatureOpt
,
node
,
binder
,
conversions
,
returnTypes
,
initialState
,
...
...
@@ -1884,6 +1908,7 @@ private ArrayTypeSymbol VisitArrayInitializer(BoundArrayCreation node)
useMethodSignatureParameterTypes
:
false
,
methodSignatureOpt
:
null
,
node
,
binder
:
null
,
conversions
:
conversions
,
returnTypesOpt
:
null
,
initialState
:
null
,
...
...
@@ -2867,7 +2892,12 @@ private static bool HasImplicitTypeArguments(BoundExpression node)
// Unexpected syntax kind.
return
false
;
}
var
nameSyntax
=
Binder
.
GetNameSyntax
(((
InvocationExpressionSyntax
)
syntax
).
Expression
,
out
var
_
);
return
HasImplicitTypeArguments
(((
InvocationExpressionSyntax
)
syntax
).
Expression
);
}
private
static
bool
HasImplicitTypeArguments
(
SyntaxNode
syntax
)
{
var
nameSyntax
=
Binder
.
GetNameSyntax
(
syntax
,
out
_
);
if
(
nameSyntax
==
null
)
{
// Unexpected syntax kind.
...
...
@@ -3386,40 +3416,50 @@ private VariableState GetVariableState(Optional<LocalState> localState)
private
MethodSymbol
InferMethodTypeArguments
(
BoundCall
node
,
MethodSymbol
method
,
ImmutableArray
<
BoundExpression
>
arguments
)
{
return
InferMethodTypeArguments
(
node
.
BinderOpt
,
method
,
arguments
,
node
.
ArgumentRefKindsOpt
,
node
.
ArgsToParamsOpt
,
node
.
Expanded
);
}
private
MethodSymbol
InferMethodTypeArguments
(
Binder
binder
,
MethodSymbol
method
,
ImmutableArray
<
BoundExpression
>
arguments
,
ImmutableArray
<
RefKind
>
argumentRefKindsOpt
,
ImmutableArray
<
int
>
argsToParamsOpt
,
bool
expanded
)
{
Debug
.
Assert
(
binder
!=
null
);
Debug
.
Assert
(
method
.
IsGenericMethod
);
// https://github.com/dotnet/roslyn/issues/27961 OverloadResolution.IsMemberApplicableInNormalForm and
// IsMemberApplicableInExpandedForm use the least overridden method. We need to do the same here.
var
definition
=
method
.
ConstructedFrom
;
var
refKinds
=
ArrayBuilder
<
RefKind
>.
GetInstance
();
if
(
node
.
A
rgumentRefKindsOpt
!=
null
)
if
(
a
rgumentRefKindsOpt
!=
null
)
{
refKinds
.
AddRange
(
node
.
A
rgumentRefKindsOpt
);
refKinds
.
AddRange
(
a
rgumentRefKindsOpt
);
}
Debug
.
Assert
(
node
.
BinderOpt
!=
null
);
// https://github.com/dotnet/roslyn/issues/27961 Do we really need OverloadResolution.GetEffectiveParameterTypes?
// Aren't we doing roughly the same calculations in GetCorrespondingParameter?
OverloadResolution
.
GetEffectiveParameterTypes
(
definition
,
arguments
.
Length
,
node
.
A
rgsToParamsOpt
,
a
rgsToParamsOpt
,
refKinds
,
isMethodGroupConversion
:
false
,
// https://github.com/dotnet/roslyn/issues/27961 `allowRefOmittedArguments` should be
// false for constructors and several other cases (see Binder use). Should we
// capture the original value in the BoundCall?
allowRefOmittedArguments
:
true
,
binder
:
node
.
BinderOpt
,
expanded
:
node
.
E
xpanded
,
binder
:
binder
,
expanded
:
e
xpanded
,
parameterTypes
:
out
ImmutableArray
<
TypeWithAnnotations
>
parameterTypes
,
parameterRefKinds
:
out
ImmutableArray
<
RefKind
>
parameterRefKinds
);
refKinds
.
Free
();
HashSet
<
DiagnosticInfo
>
useSiteDiagnostics
=
null
;
var
result
=
MethodTypeInferrer
.
Infer
(
node
.
BinderOpt
,
binder
,
_conversions
,
definition
.
TypeParameters
,
definition
.
ContainingType
,
...
...
@@ -4213,23 +4253,16 @@ private static BoundConversion GetConversionIfApplicable(BoundExpression convers
{
case
ConversionKind
.
MethodGroup
:
{
var
receiverOpt
=
((
BoundMethodGroup
)
conversionOperand
)?.
ReceiverOpt
;
// https://github.com/dotnet/roslyn/issues/33637: Should update method based on inferred receiver type.
var
group
=
conversionOperand
as
BoundMethodGroup
;
var
delegateType
=
targetType
.
GetDelegateType
();
var
method
=
conversion
.
Method
;
if
(
TryGetMethodGroupReceiverNullability
(
receiverOpt
,
out
TypeWithState
receiverType
)
)
if
(
group
!=
null
)
{
if
(
conversion
.
IsExtensionMethod
)
{
CheckExtensionMethodThisNullability
(
receiverOpt
,
Conversion
.
Identity
,
method
.
Parameters
[
0
],
receiverType
);
}
else
{
CheckPossibleNullReceiver
(
receiverOpt
,
receiverType
,
checkNullableValueType
:
false
);
}
method
=
CheckMethodGroupReceiverNullability
(
group
,
delegateType
,
method
,
conversion
.
IsExtensionMethod
);
}
if
(
reportRemainingWarnings
)
{
ReportNullabilityMismatchWithTargetDelegate
(
diagnosticLocationOpt
,
targetType
.
GetDelegateType
()
,
method
,
conversion
.
IsExtensionMethod
);
ReportNullabilityMismatchWithTargetDelegate
(
diagnosticLocationOpt
,
delegateType
,
method
,
conversion
.
IsExtensionMethod
);
}
}
resultState
=
NullableFlowState
.
NotNull
;
...
...
@@ -4721,23 +4754,11 @@ public override BoundNode VisitDelegateCreationExpression(BoundDelegateCreationE
{
case
BoundMethodGroup
group
:
{
// https://github.com/dotnet/roslyn/issues/33637: Should update method based on inferred receiver type.
VisitMethodGroup
(
group
);
var
method
=
node
.
MethodOpt
;
if
(
method
is
object
)
{
var
receiverOpt
=
group
.
ReceiverOpt
;
if
(
receiverOpt
!=
null
)
{
VisitRvalue
(
receiverOpt
);
if
(
node
.
IsExtensionMethod
)
{
CheckExtensionMethodThisNullability
(
receiverOpt
,
Conversion
.
Identity
,
method
.
Parameters
[
0
],
ResultType
);
}
else
{
CheckPossibleNullReceiver
(
receiverOpt
);
}
}
method
=
CheckMethodGroupReceiverNullability
(
group
,
delegateType
,
method
,
node
.
IsExtensionMethod
);
if
(!
group
.
IsSuppressed
)
{
ReportNullabilityMismatchWithTargetDelegate
(
group
.
Syntax
.
Location
,
delegateType
,
method
,
node
.
IsExtensionMethod
);
...
...
@@ -4804,6 +4825,48 @@ private void SetMethodGroupReceiverNullability(BoundExpression receiver, TypeWit
_methodGroupReceiverMapOpt
[
receiver
]
=
type
;
}
private
MethodSymbol
CheckMethodGroupReceiverNullability
(
BoundMethodGroup
group
,
NamedTypeSymbol
delegateType
,
MethodSymbol
method
,
bool
invokedAsExtensionMethod
)
{
var
receiverOpt
=
group
.
ReceiverOpt
;
if
(
TryGetMethodGroupReceiverNullability
(
receiverOpt
,
out
TypeWithState
receiverType
))
{
var
syntax
=
group
.
Syntax
;
if
(!
invokedAsExtensionMethod
)
{
method
=
(
MethodSymbol
)
AsMemberOfType
(
receiverType
.
Type
,
method
);
}
if
(
method
.
IsGenericMethod
&&
HasImplicitTypeArguments
(
group
.
Syntax
))
{
var
arguments
=
ArrayBuilder
<
BoundExpression
>.
GetInstance
();
if
(
invokedAsExtensionMethod
)
{
arguments
.
Add
(
CreatePlaceholderIfNecessary
(
receiverOpt
,
receiverType
.
ToTypeWithAnnotations
()));
}
// Create placeholders for the arguments. (See Conversions.GetDelegateArguments()
// which is used for that purpose in initial binding.)
foreach
(
var
parameter
in
delegateType
.
DelegateInvokeMethod
.
Parameters
)
{
var
parameterType
=
parameter
.
TypeWithAnnotations
;
arguments
.
Add
(
new
BoundExpressionWithNullability
(
syntax
,
new
BoundParameter
(
syntax
,
parameter
),
parameterType
.
NullableAnnotation
,
parameterType
.
Type
));
}
method
=
InferMethodTypeArguments
(
_binder
,
method
,
arguments
.
ToImmutableAndFree
(),
argumentRefKindsOpt
:
default
,
argsToParamsOpt
:
default
,
expanded
:
false
);
}
if
(
invokedAsExtensionMethod
)
{
CheckExtensionMethodThisNullability
(
receiverOpt
,
Conversion
.
Identity
,
method
.
Parameters
[
0
],
receiverType
);
}
else
{
CheckPossibleNullReceiver
(
receiverOpt
,
receiverType
,
checkNullableValueType
:
false
);
}
if
(
ConstraintsHelper
.
RequiresChecking
(
method
))
{
CheckMethodConstraints
(
syntax
,
method
);
}
}
return
method
;
}
public
override
BoundNode
VisitLambda
(
BoundLambda
node
)
{
// It's possible to reach VisitLambda without having analyzed the lambda body in error scenarios,
...
...
@@ -4856,6 +4919,7 @@ public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatemen
Analyze
(
compilation
,
node
.
Symbol
,
body
,
_binder
,
_conversions
,
Diagnostics
,
useMethodSignatureParameterTypes
:
false
,
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs
浏览文件 @
734f1d82
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录