Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
0e8418ed
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,发现更多精彩内容 >>
未验证
提交
0e8418ed
编写于
10月 05, 2017
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor delegate creation to deduplicate code.
上级
5c84eb70
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
77 addition
and
44 deletion
+77
-44
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb
...lBasic/Portable/Operations/VisualBasicOperationFactory.vb
+34
-43
src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IDelegateCreationExpression.vb
...IOperation/IOperationTests_IDelegateCreationExpression.vb
+43
-1
未找到文件。
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb
浏览文件 @
0e8418ed
...
...
@@ -525,16 +525,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim
isImplicit
As
Boolean
=
boundTryCast
.
WasCompilerGenerated
Dim
constantValue
As
[
Optional
]
(
Of
Object
)
=
ConvertToOptional
(
boundTryCast
.
ConstantValueOpt
)
Dim
conversionInformation
=
CreateConversionOpera
tion
(
boundTryCast
.
Operand
,
boundTryCast
.
ConversionKind
,
boundTryCast
.
Syntax
)
Dim
conversionInformation
=
CreateConversionOpera
nd
(
boundTryCast
.
Operand
,
boundTryCast
.
ConversionKind
,
boundTryCast
.
Syntax
,
boundTryCast
.
Type
)
Dim
methodSymbol
As
MethodSymbol
=
conversionInformation
.
methodSymbol
Dim
operand
As
Lazy
(
Of
IOperation
)
=
conversionInformation
.
operation
Dim
is
AddressOfDelegateCreation
As
Boolean
=
conversionInformation
.
isAddressOf
DelegateCreation
Dim
is
DelegateCreation
As
Boolean
=
conversionInformation
.
is
DelegateCreation
If
isAddressOfDelegateCreation
OrElse
((
boundTryCast
.
Operand
.
Kind
=
BoundKind
.
Lambda
OrElse
boundTryCast
.
Operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
boundTryCast
.
Operand
.
Kind
=
BoundKind
.
UnboundLambda
)
AndAlso
boundTryCast
.
Type
.
IsDelegateType
())
Then
If
isDelegateCreation
Then
' If this is a conversion from a lambda to a delegate type, or this is an AddressOf delegate creation
' as determined above, we return a DelegateCreationExpression, instead of returning a conversion expression
Return
New
LazyDelegateCreationExpression
(
operand
,
_semanticModel
,
syntax
,
type
,
constantValue
,
isImplicit
)
...
...
@@ -553,16 +549,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim
constantValue
As
[
Optional
]
(
Of
Object
)
=
ConvertToOptional
(
boundDirectCast
.
ConstantValueOpt
)
Dim
isImplicit
As
Boolean
=
boundDirectCast
.
WasCompilerGenerated
Dim
conversionInformation
=
CreateConversionOpera
tion
(
boundDirectCast
.
Operand
,
boundDirectCast
.
ConversionKind
,
boundDirectCast
.
Syntax
)
Dim
conversionInformation
=
CreateConversionOpera
nd
(
boundDirectCast
.
Operand
,
boundDirectCast
.
ConversionKind
,
boundDirectCast
.
Syntax
,
boundDirectCast
.
Type
)
Dim
methodSymbol
As
MethodSymbol
=
conversionInformation
.
methodSymbol
Dim
operand
As
Lazy
(
Of
IOperation
)
=
conversionInformation
.
operation
Dim
is
AddressOfDelegateCreation
As
Boolean
=
conversionInformation
.
isAddressOf
DelegateCreation
Dim
is
DelegateCreation
As
Boolean
=
conversionInformation
.
is
DelegateCreation
If
isAddressOfDelegateCreation
OrElse
((
boundDirectCast
.
Operand
.
Kind
=
BoundKind
.
Lambda
OrElse
boundDirectCast
.
Operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
boundDirectCast
.
Operand
.
Kind
=
BoundKind
.
UnboundLambda
)
AndAlso
boundDirectCast
.
Type
.
IsDelegateType
())
Then
If
isDelegateCreation
Then
' If this is a conversion from a lambda to a delegate type, or this is an AddressOf delegate creation
' as determined above, we return a DelegateCreationExpression, instead of returning a conversion expression
Return
New
LazyDelegateCreationExpression
(
operand
,
_semanticModel
,
syntax
,
type
,
constantValue
,
isImplicit
)
...
...
@@ -595,16 +587,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim
constantValue
As
[
Optional
]
(
Of
Object
)
=
ConvertToOptional
(
boundConversion
.
ConstantValueOpt
)
Dim
isImplicit
As
Boolean
=
boundConversion
.
WasCompilerGenerated
OrElse
Not
boundConversion
.
ExplicitCastInCode
Dim
conversionInformation
=
CreateConversionOpera
tion
(
boundConversion
.
Operand
,
boundConversion
.
ConversionKind
,
boundConversion
.
Syntax
)
Dim
conversionInformation
=
CreateConversionOpera
nd
(
boundConversion
.
Operand
,
boundConversion
.
ConversionKind
,
boundConversion
.
Syntax
,
boundConversion
.
Type
)
Dim
methodSymbol
As
MethodSymbol
=
conversionInformation
.
methodSymbol
Dim
operand
As
Lazy
(
Of
IOperation
)
=
conversionInformation
.
operation
Dim
is
AddressOfDelegateCreation
As
Boolean
=
conversionInformation
.
isAddressOf
DelegateCreation
Dim
is
DelegateCreation
As
Boolean
=
conversionInformation
.
is
DelegateCreation
If
isAddressOfDelegateCreation
OrElse
((
boundConversion
.
Operand
.
Kind
=
BoundKind
.
Lambda
OrElse
boundConversion
.
Operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
boundConversion
.
Operand
.
Kind
=
BoundKind
.
UnboundLambda
)
AndAlso
boundConversion
.
Type
.
IsDelegateType
())
Then
If
isDelegateCreation
Then
' If this is a conversion from a lambda to a delegate type, or this is an AddressOf delegate creation
' as determined above, we return a DelegateCreationExpression, instead of returning a conversion expression
Return
New
LazyDelegateCreationExpression
(
operand
,
_semanticModel
,
syntax
,
type
,
constantValue
,
isImplicit
)
...
...
@@ -617,48 +605,51 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return
New
LazyVisualBasicConversionExpression
(
operand
,
conversion
,
isExplicit
,
isTryCast
,
isChecked
,
_semanticModel
,
syntax
,
type
,
constantValue
,
isImplicit
)
End
Function
Private
Shared
Function
IsDelegateCreation
Syntax
(
conversionKind
As
ConversionKind
,
conversionSyntax
As
SyntaxNode
,
operandSyntax
As
SyntaxNode
)
As
Boolean
Private
Shared
Function
IsDelegateCreation
(
conversionKind
As
ConversionKind
,
conversionSyntax
As
SyntaxNode
,
operand
As
BoundNode
,
targetType
As
TypeSymbol
)
As
Boolean
' Any of the explicit cast types, as well as New DelegateType(AddressOf Method)
' Additionally, AddressOf, if the child AddressOf is the same SyntaxNode (ie, an implicit delegate creation
Dim
validConversionSyntax
=
conversionSyntax
.
Kind
()
=
SyntaxKind
.
CTypeExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
DirectCastExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
TryCastExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
ObjectCreationExpression
OrElse
(
conversionSyntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
AndAlso
ReferenceEquals
(
conversionSyntax
,
operandSyntax
))
' Additionally, AddressOf, if the child AddressOf is the same SyntaxNode (ie, an implicit delegate creation)
Dim
validAddressOfConversionSyntax
=
(
conversionSyntax
.
Kind
()
=
SyntaxKind
.
CTypeExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
DirectCastExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
TryCastExpression
OrElse
conversionSyntax
.
Kind
()
=
SyntaxKind
.
ObjectCreationExpression
OrElse
(
conversionSyntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
AndAlso
ReferenceEquals
(
conversionSyntax
,
operand
.
Syntax
)))
AndAlso
operand
.
Syntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
Dim
validOperandSyntax
=
operandSyntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
Dim
validLambdaConversionSyntax
=
operand
.
Kind
=
BoundKind
.
Lambda
OrElse
operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
operand
.
Kind
=
BoundKind
.
UnboundLambda
Return
validConversionSyntax
AndAlso
validOperandSyntax
Dim
validTargetType
=
targetType
.
IsDelegateType
()
Return
validTargetType
AndAlso
(
validAddressOfConversionSyntax
OrElse
validLambdaConversionSyntax
)
End
Function
''' <summary>
''' Creates the Lazy IOperation from a delegate creation operand or a bound conversion operand, handling when the conversion
''' is actually a delegate creation.
''' </summary>
Private
Function
CreateConversionOpera
tion
(
operand
As
BoundNode
,
conversionKind
As
ConversionKind
,
conversionSyntax
As
SyntaxNode
)
As
(
methodSymbol
As
MethodSymbol
,
operation
As
Lazy
(
Of
IOperation
),
is
AddressOf
DelegateCreation
As
Boolean
)
Private
Function
CreateConversionOpera
nd
(
operand
As
BoundNode
,
conversionKind
As
ConversionKind
,
conversionSyntax
As
SyntaxNode
,
targetType
As
TypeSymbol
)
As
(
methodSymbol
As
MethodSymbol
,
operation
As
Lazy
(
Of
IOperation
),
isDelegateCreation
As
Boolean
)
If
(
conversionKind
And
VisualBasic
.
ConversionKind
.
UserDefined
)
=
VisualBasic
.
ConversionKind
.
UserDefined
Then
Dim
userDefinedConversion
As
BoundUserDefinedConversion
=
DirectCast
(
operand
,
BoundUserDefinedConversion
)
Return
(
userDefinedConversion
.
Call
.
Method
,
New
Lazy
(
Of
IOperation
)(
Function
()
Create
(
userDefinedConversion
.
Operand
)),
isAddressOfDelegateCreation
:
=
False
)
ElseIf
IsDelegateCreationSyntax
(
conversionKind
,
conversionSyntax
,
operand
.
Syntax
)
Then
' In this scenario, we're a delegate creation expression involving an AddressOf.
Return
(
userDefinedConversion
.
Call
.
Method
,
New
Lazy
(
Of
IOperation
)(
Function
()
Create
(
userDefinedConversion
.
Operand
)),
isDelegateCreation
:
=
False
)
ElseIf
IsDelegateCreation
(
conversionKind
,
conversionSyntax
,
operand
,
targetType
)
Then
Dim
methodSymbol
As
MethodSymbol
=
Nothing
Dim
operandLazy
As
Lazy
(
Of
IOperation
)
If
operand
.
Kind
=
BoundKind
.
DelegateCreationExpression
Then
' If the child is a BoundDelegateCreationExpression, we don't want to generate a nested IDelegateCreationExpression.
' So, the operand for the conversion will be the child of the BoundDelegateCreationExpression.
operandLazy
=
New
Lazy
(
Of
IOperation
)(
Function
()
CreateBoundDelegateCreationExpressionChildOperation
(
DirectCast
(
operand
,
BoundDelegateCreationExpression
)))
Else
' This is an error scenario in which we have a delegate conversion, but it failed to bind correctly, so the child here
' is either a bad expression or a method group. Delegate to standard operation handling for this.
Debug
.
Assert
(
operand
.
Kind
=
BoundKind
.
MethodGroup
OrElse
operand
.
Kind
=
BoundKind
.
BadExpression
OrElse
operand
.
Kind
=
BoundKind
.
AddressOfOperator
)
' This is either a lambda, or an AddressOf error scenario in which we have a delegate conversion, but it failed to bind correctly.
' Delegate to standard operation handling for this.
operandLazy
=
New
Lazy
(
Of
IOperation
)(
Function
()
Create
(
operand
))
End
If
Return
(
methodSymbol
,
operandLazy
,
is
AddressOf
DelegateCreation
:
=
True
)
Return
(
methodSymbol
,
operandLazy
,
isDelegateCreation
:
=
True
)
Else
Dim
methodSymbol
As
MethodSymbol
=
Nothing
Return
(
methodSymbol
,
New
Lazy
(
Of
IOperation
)(
Function
()
Create
(
operand
)),
is
AddressOf
DelegateCreation
:
=
False
)
Return
(
methodSymbol
,
New
Lazy
(
Of
IOperation
)(
Function
()
Create
(
operand
)),
isDelegateCreation
:
=
False
)
End
If
End
Function
...
...
src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IDelegateCreationExpression.vb
浏览文件 @
0e8418ed
...
...
@@ -2090,6 +2090,49 @@ IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclaratio
VerifyOperationTreeAndDiagnosticsForTest
(
Of
LocalDeclarationStatementSyntax
)(
source
,
expectedOperationTree
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
)
>
<
Fact
()
>
Public
Sub
DelegateCreationExpression_ImplicitAddressOf_ConvertedToNonDelegateType
()
Dim
source
=
<
!
[
CDATA
[
Option Strict On
Imports
System
Module
M1
Class
C1
End
Class
Sub
Method1
()
Dim
a
As
String
=
AddressOf
Method2
'BIND:"Dim a As String = AddressOf Method2"
End
Sub
Sub
Method2
(
i
As
C1
)
End
Sub
End
Module
]]
>
.
Value
' We don't expect a delegate creation here. This is documenting that we still have a conversion expression when the target type
' isn't a delegate type
Dim
expectedOperationTree
=
<
!
[
CDATA
[
IVariableDeclarationStatement
(
1
declarations
)
(
OperationKind
.
VariableDeclarationStatement
,
IsInvalid
)
(
Syntax
:
'Dim a As St ... sOf Method2')
IVariableDeclaration
(
1
variables
)
(
OperationKind
.
VariableDeclaration
)
(
Syntax
:
'a')
Variables
:
Local_1
:
a
As
System
.
String
Initializer
:
IConversionExpression
(
Implicit
,
TryCast
:
False
,
Unchecked
)
(
OperationKind
.
ConversionExpression
,
Type
:
System
.
String
,
IsInvalid
,
IsImplicit
)
(
Syntax
:
'AddressOf Method2')
Conversion
:
CommonConversion
(
Exists
:
False
,
IsIdentity
:
False
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
Operand
:
IOperation
:
(
OperationKind
.
None
,
IsInvalid
)
(
Syntax
:
'AddressOf Method2')
Children
(
1
):
IOperation
:
(
OperationKind
.
None
,
IsInvalid
)
(
Syntax
:
'Method2')
Children
(
1
):
IInstanceReferenceExpression
(
OperationKind
.
InstanceReferenceExpression
,
Type
:
M1
,
IsInvalid
,
IsImplicit
)
(
Syntax
:
'Method2')
]]
>
.
Value
Dim
expectedDiagnostics
=
<
!
[
CDATA
[
BC30581
:
'AddressOf' expression cannot be converted to 'String' because 'String' is not a delegate type.
Dim
a
As
String
=
AddressOf
Method2
'BIND:"Dim a As String = AddressOf Method2"
~~~~~~~~~~~~~~~~~
]]
>
.
Value
VerifyOperationTreeAndDiagnosticsForTest
(
Of
LocalDeclarationStatementSyntax
)(
source
,
expectedOperationTree
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
)
>
<
Fact
()
>
Public
Sub
DelegateCreationExpression_CTypeAddressOf
()
...
...
@@ -3246,7 +3289,6 @@ BC30002: Type 'NonExistant' is not defined.
VerifyOperationTreeAndDiagnosticsForTest
(
Of
ObjectCreationExpressionSyntax
)(
source
,
expectedOperationTree
,
expectedDiagnostics
)
End
Sub
#End Region
#Region "Anonymous Delegates"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录