Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
5957e873
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,发现更多精彩内容 >>
未验证
提交
5957e873
编写于
12月 11, 2017
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use recursive approach to creating conversion operand.
上级
9bc4c921
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
91 addition
and
100 deletion
+91
-100
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb
...lBasic/Portable/Operations/VisualBasicOperationFactory.vb
+1
-1
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb
...ortable/Operations/VisualBasicOperationFactory_Methods.vb
+90
-99
未找到文件。
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory.vb
浏览文件 @
5957e873
...
...
@@ -551,7 +551,7 @@ Namespace Microsoft.CodeAnalysis.Operations
End
If
Dim
conversionInfo
=
GetConversionInfo
(
boundConversionOrCast
)
Dim
conversion
As
Conversion
=
conversionInfo
.
Conversion
Struct
Dim
conversion
As
Conversion
=
conversionInfo
.
Conversion
Dim
operand
As
Lazy
(
Of
IOperation
)
=
conversionInfo
.
Operation
If
conversionInfo
.
IsDelegateCreation
Then
...
...
src/Compilers/VisualBasic/Portable/Operations/VisualBasicOperationFactory_Methods.vb
浏览文件 @
5957e873
...
...
@@ -156,21 +156,6 @@ Namespace Microsoft.CodeAnalysis.Operations
Return
arguments
.
ToImmutableAndFree
()
End
Function
Private
Shared
Function
CreateConversion
(
expression
As
BoundExpression
)
As
Conversion
If
expression
.
Kind
=
BoundKind
.
Conversion
Then
Dim
conversion
=
DirectCast
(
expression
,
BoundConversion
)
Dim
conversionKind
=
conversion
.
ConversionKind
Dim
method
As
MethodSymbol
=
Nothing
If
conversionKind
.
HasFlag
(
VisualBasic
.
ConversionKind
.
UserDefined
)
AndAlso
conversion
.
Operand
.
Kind
=
BoundKind
.
UserDefinedConversion
Then
method
=
DirectCast
(
conversion
.
Operand
,
BoundUserDefinedConversion
).
Call
.
Method
End
If
Return
New
Conversion
(
KeyValuePair
.
Create
(
conversionKind
,
method
))
ElseIf
expression
.
Kind
=
BoundKind
.
TryCast
OrElse
expression
.
Kind
=
BoundKind
.
DirectCast
Then
Return
New
Conversion
(
KeyValuePair
.
Create
(
Of
ConversionKind
,
MethodSymbol
)(
DirectCast
(
expression
,
BoundConversionOrCast
).
ConversionKind
,
Nothing
))
End
If
Return
New
Conversion
(
Conversions
.
Identity
)
End
Function
Private
Function
DeriveArgument
(
index
As
Integer
,
argument
As
BoundExpression
,
...
...
@@ -448,82 +433,73 @@ Namespace Microsoft.CodeAnalysis.Operations
eventReference
,
Create
(
statement
.
Handler
),
adds
:
=
adds
,
semanticModel
:
=
_semanticModel
,
syntax
:
=
statement
.
Syntax
,
type
:
=
Nothing
,
constantValue
:
=
Nothing
,
isImplicit
:
=
True
)
End
Function
Private
Shared
Function
IsDelegateCreation
(
conversionSyntax
As
SyntaxNode
,
operand
As
BoundNode
,
targetType
As
TypeSymbol
)
As
Boolean
If
Not
targetType
.
IsDelegateType
()
Then
Return
False
End
If
' 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)
' In the case of AddressOf, the operand can be a BoundDelegateCreationExpression, a BoundAddressOfOperator, or
' a BoundBadExpression. For simplicity, we just do a syntax check to make sure it's an AddressOfExpression so
' we don't have to compare against all 3 BoundKinds
Dim
validAddressOfConversionSyntax
=
operand
.
Syntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
AndAlso
(
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
conversionSyntax
Is
operand
.
Syntax
))
Dim
validLambdaConversionNode
=
operand
.
Kind
=
BoundKind
.
Lambda
OrElse
operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
operand
.
Kind
=
BoundKind
.
UnboundLambda
Return
validAddressOfConversionSyntax
OrElse
validLambdaConversionNode
End
Function
#Region "Conversions"
''' <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
GetConversionInfo
(
boundConversion
As
BoundConversionOrCast
)
As
(
Operation
As
Lazy
(
Of
IOperation
),
ConversionStruct
As
Conversion
,
IsDelegateCreation
As
Boolean
)
)
As
(
Operation
As
Lazy
(
Of
IOperation
),
Conversion
As
Conversion
,
IsDelegateCreation
As
Boolean
)
Dim
conversion
=
CreateConversion
(
boundConversion
)
Dim
operand
As
BoundExpression
=
GetConversionOperand
(
boundConversion
)
Dim
operandLazy
As
Lazy
(
Of
IOperation
)
=
Nothing
Dim
boundOperand
=
GetConversionOperand
(
boundConversion
)
If
conversion
.
IsIdentity
AndAlso
boundConversion
.
ExplicitCastInCode
Then
Dim
adjustedInfo
=
TryGetAdjustedConversionInfo
(
boundConversion
,
boundOperand
)
If
adjustedInfo
.
Operation
IsNot
Nothing
Then
Return
(
Operation
:
=
New
Lazy
(
Of
IOperation
)(
Function
()
adjustedInfo
.
Operation
),
adjustedInfo
.
Conversion
,
adjustedInfo
.
IsDelegateCreation
)
End
If
End
If
Return
(
New
Lazy
(
Of
IOperation
)(
Function
()
CreateConversionOperand
(
boundOperand
)),
conversion
,
IsDelegateCreation
:
=
IsDelegateCreation
(
boundConversion
.
Syntax
,
boundOperand
,
boundConversion
.
Type
))
End
Function
Private
Function
TryGetAdjustedConversionInfo
(
topLevelConversion
As
BoundConversionOrCast
,
boundOperand
As
BoundExpression
)
As
(
Operation
As
IOperation
,
Conversion
As
Conversion
,
IsDelegateCreation
As
Boolean
)
' Dig through the bound tree to see if this is an artificial nested conversion. If so, let's erase the nested conversion.
' Artificial conversions are added on top of BoundConvertedTupleLiteral in Binder.ReclassifyTupleLiteral, or in
' ReclassifyUnboundLambdaExpression and the like. We need to use conversion information from the nested conversion
' because that is where the real conversion information is stored.
If
boundConversion
.
ExplicitCastInCode
AndAlso
conversion
.
IsIdentity
Then
Dim
nestedOperand
=
operand
While
nestedOperand
.
Kind
=
BoundKind
.
Parenthesized
nestedOperand
=
DirectCast
(
nestedOperand
,
BoundParenthesized
).
Expression
End
While
If
nestedOperand
.
Kind
=
boundConversion
.
Kind
Then
Dim
nestedConversion
=
DirectCast
(
nestedOperand
,
BoundConversionOrCast
)
nestedOperand
=
GetConversionOperand
(
nestedConversion
)
If
nestedConversion
.
Syntax
Is
nestedOperand
.
Syntax
AndAlso
nestedConversion
.
ExplicitCastInCode
AndAlso
nestedConversion
.
Type
<>
nestedOperand
.
Type
AndAlso
nestedConversion
.
Type
=
boundConversion
.
Type
Then
conversion
=
CreateConversion
(
nestedConversion
)
operandLazy
=
CreateNestedConversionOperand
(
operand
,
boundConversion
.
Syntax
)
operand
=
nestedOperand
End
If
ElseIf
nestedOperand
.
Syntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
AndAlso
boundConversion
.
Type
=
nestedOperand
.
Type
AndAlso
IsDelegateCreation
(
boundConversion
.
Syntax
,
nestedOperand
,
nestedOperand
.
Type
)
Then
conversion
=
New
Conversion
(
KeyValuePair
.
Create
(
Of
ConversionKind
,
MethodSymbol
)(
boundConversion
.
ConversionKind
,
Nothing
))
operandLazy
=
CreateNestedConversionOperand
(
operand
,
boundConversion
.
Syntax
)
operand
=
nestedOperand
If
boundOperand
.
Kind
=
BoundKind
.
Parenthesized
Then
Dim
adjustedInfo
=
TryGetAdjustedConversionInfo
(
topLevelConversion
,
DirectCast
(
boundOperand
,
BoundParenthesized
).
Expression
)
If
adjustedInfo
.
Operation
IsNot
Nothing
Then
Return
(
Operation
:
=
New
ParenthesizedExpression
(
adjustedInfo
.
Operation
,
_semanticModel
,
boundOperand
.
Syntax
,
adjustedInfo
.
Operation
.
Type
,
ConvertToOptional
(
boundOperand
.
ConstantValueOpt
),
boundOperand
.
WasCompilerGenerated
),
adjustedInfo
.
Conversion
,
adjustedInfo
.
IsDelegateCreation
)
End
If
End
If
ElseIf
boundOperand
.
Kind
=
topLevelConversion
.
Kind
Then
Dim
nestedConversion
=
DirectCast
(
boundOperand
,
BoundConversionOrCast
)
Dim
nestedOperand
As
BoundExpression
=
GetConversionOperand
(
nestedConversion
)
If
nestedConversion
.
Syntax
Is
nestedOperand
.
Syntax
AndAlso
nestedConversion
.
ExplicitCastInCode
AndAlso
topLevelConversion
.
Type
=
nestedConversion
.
Type
Then
Dim
conversionInfo
=
GetConversionInfo
(
nestedConversion
)
Return
(
Operation
:
=
conversionInfo
.
Operation
.
Value
,
conversionInfo
.
Conversion
,
conversionInfo
.
IsDelegateCreation
)
End
If
ElseIf
boundOperand
.
Syntax
.
IsKind
(
SyntaxKind
.
AddressOfExpression
)
AndAlso
topLevelConversion
.
Type
=
boundOperand
.
Type
AndAlso
IsDelegateCreation
(
topLevelConversion
.
Syntax
,
boundOperand
,
boundOperand
.
Type
)
Then
If
operandLazy
Is
Nothing
Then
operandLazy
=
New
Lazy
(
Of
IOperation
)(
Function
()
CreateConversionOperand
(
operand
))
Return
(
CreateConversionOperand
(
boundOperand
),
Conversion
:
=
Nothing
,
IsDelegateCreation
:
=
True
)
End
If
Return
(
operandLazy
,
conversion
,
IsDelegateCreation
(
boundConversion
.
Syntax
,
operand
,
boundConversion
.
Type
))
Return
Nothing
End
Function
''' <summary>
''' Gets the operand
and method symbol
from a BoundConversion, compensating for if the conversion is a user-defined conversion
''' Gets the operand from a BoundConversion, compensating for if the conversion is a user-defined conversion
''' </summary>
Private
Shared
Function
GetConversionOperand
(
boundConversion
As
BoundConversionOrCast
)
As
BoundExpression
If
(
boundConversion
.
ConversionKind
And
ConversionKind
.
UserDefined
)
=
ConversionKind
.
UserDefined
Then
...
...
@@ -534,33 +510,6 @@ Namespace Microsoft.CodeAnalysis.Operations
End
If
End
Function
Private
Function
CreateNestedConversionOperand
(
operand
As
BoundExpression
,
conversionSyntax
As
SyntaxNode
)
As
Lazy
(
Of
IOperation
)
Return
New
Lazy
(
Of
IOperation
)(
Function
()
CreateNestedConversionOperandCore
(
operand
))
End
Function
Private
Function
CreateNestedConversionOperandCore
(
operand
As
BoundExpression
)
As
IOperation
Select
Case
operand
.
Kind
Case
BoundKind
.
Parenthesized
Dim
boundParenthesized
=
DirectCast
(
operand
,
BoundParenthesized
)
' Because we're in a delegate creation scenario, the underlying expression actually doesn't have a type.
Dim
operandOperation
=
CreateNestedConversionOperandCore
(
boundParenthesized
.
Expression
)
Return
New
ParenthesizedExpression
(
operandOperation
,
_semanticModel
,
boundParenthesized
.
Syntax
,
operandOperation
.
Type
,
ConvertToOptional
(
boundParenthesized
.
ConstantValueOpt
),
boundParenthesized
.
WasCompilerGenerated
)
Case
BoundKind
.
Conversion
,
BoundKind
.
DirectCast
,
BoundKind
.
TryCast
' This is the artificial conversion. Erase it from the tree.
Return
CreateConversionOperand
(
DirectCast
(
operand
,
BoundConversionOrCast
).
Operand
)
Case
BoundKind
.
DelegateCreationExpression
Return
CreateBoundDelegateCreationExpressionChildOperation
(
DirectCast
(
operand
,
BoundDelegateCreationExpression
))
Case
Else
Throw
ExceptionUtilities
.
UnexpectedValue
(
operand
.
Kind
)
End
Select
End
Function
Private
Function
CreateConversionOperand
(
operand
As
BoundExpression
)
As
IOperation
If
operand
.
Kind
=
BoundKind
.
DelegateCreationExpression
Then
' If the child is a BoundDelegateCreationExpression, we don't want to generate a nested IDelegateCreationExpression.
...
...
@@ -574,6 +523,48 @@ Namespace Microsoft.CodeAnalysis.Operations
End
If
End
Function
Private
Shared
Function
CreateConversion
(
expression
As
BoundExpression
)
As
Conversion
If
expression
.
Kind
=
BoundKind
.
Conversion
Then
Dim
conversion
=
DirectCast
(
expression
,
BoundConversion
)
Dim
conversionKind
=
conversion
.
ConversionKind
Dim
method
As
MethodSymbol
=
Nothing
If
conversionKind
.
HasFlag
(
VisualBasic
.
ConversionKind
.
UserDefined
)
AndAlso
conversion
.
Operand
.
Kind
=
BoundKind
.
UserDefinedConversion
Then
method
=
DirectCast
(
conversion
.
Operand
,
BoundUserDefinedConversion
).
Call
.
Method
End
If
Return
New
Conversion
(
KeyValuePair
.
Create
(
conversionKind
,
method
))
ElseIf
expression
.
Kind
=
BoundKind
.
TryCast
OrElse
expression
.
Kind
=
BoundKind
.
DirectCast
Then
Return
New
Conversion
(
KeyValuePair
.
Create
(
Of
ConversionKind
,
MethodSymbol
)(
DirectCast
(
expression
,
BoundConversionOrCast
).
ConversionKind
,
Nothing
))
End
If
Return
New
Conversion
(
Conversions
.
Identity
)
End
Function
Private
Shared
Function
IsDelegateCreation
(
conversionSyntax
As
SyntaxNode
,
operand
As
BoundNode
,
targetType
As
TypeSymbol
)
As
Boolean
If
Not
targetType
.
IsDelegateType
()
Then
Return
False
End
If
' 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)
' In the case of AddressOf, the operand can be a BoundDelegateCreationExpression, a BoundAddressOfOperator, or
' a BoundBadExpression. For simplicity, we just do a syntax check to make sure it's an AddressOfExpression so
' we don't have to compare against all 3 BoundKinds
Dim
validAddressOfConversionSyntax
=
operand
.
Syntax
.
Kind
()
=
SyntaxKind
.
AddressOfExpression
AndAlso
(
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
conversionSyntax
Is
operand
.
Syntax
))
Dim
validLambdaConversionNode
=
operand
.
Kind
=
BoundKind
.
Lambda
OrElse
operand
.
Kind
=
BoundKind
.
QueryLambda
OrElse
operand
.
Kind
=
BoundKind
.
UnboundLambda
Return
validAddressOfConversionSyntax
OrElse
validLambdaConversionNode
End
Function
#End Region
Friend
Class
Helper
Friend
Shared
Function
DeriveUnaryOperatorKind
(
operatorKind
As
VisualBasic
.
UnaryOperatorKind
)
As
UnaryOperatorKind
Select
Case
operatorKind
And
VisualBasic
.
UnaryOperatorKind
.
OpMask
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录