Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
32f09648
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,发现更多精彩内容 >>
未验证
提交
32f09648
编写于
3月 01, 2018
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for object creation.
上级
34e1379a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
766 addition
and
37 deletion
+766
-37
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IObjectCreationExpression.cs
...c/IOperation/IOperationTests_IObjectCreationExpression.cs
+360
-0
src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
...ilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
+72
-37
src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IObjectCreationExpression.vb
...c/IOperation/IOperationTests_IObjectCreationExpression.vb
+334
-0
未找到文件。
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IObjectCreationExpression.cs
浏览文件 @
32f09648
...
...
@@ -782,5 +782,365 @@ static void Main()
VerifyOperationTreeAndDiagnosticsForTest
<
ExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)]
[
Fact
]
public
void
ObjectCreationFlow_01
()
{
string
source
=
@"
public class MyClass
{
public MyClass(int i1, int i2, int i3) { }
static void M(bool b)
/*<bind>*/{
var c = new MyClass(1, 2, b ? 3 : 4);
}/*</bind>*/
}
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [MyClass c]
Block[B1] - Block
Predecessors: [B0]
Statements (2)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '1')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '2')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
Jump if False (Regular) to Block[B3]
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Next (Regular) Block[B2]
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '3')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 3) (Syntax: '3')
Next (Regular) Block[B4]
Block[B3] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '4')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 4) (Syntax: '4')
Next (Regular) Block[B4]
Block[B4] - Block
Predecessors: [B2] [B3]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 3 : 4)')
Left:
ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 3 : 4)')
Right:
IObjectCreationOperation (Constructor: MyClass..ctor(System.Int32 i1, System.Int32 i2, System.Int32 i3)) (OperationKind.ObjectCreation, Type: MyClass) (Syntax: 'new MyClass ... b ? 3 : 4)')
Arguments(3):
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i1) (OperationKind.Argument, Type: null) (Syntax: '1')
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 1, IsImplicit) (Syntax: '1')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i2) (OperationKind.Argument, Type: null) (Syntax: '2')
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 2, IsImplicit) (Syntax: '2')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i3) (OperationKind.Argument, Type: null) (Syntax: 'b ? 3 : 4')
IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.Int32, IsImplicit) (Syntax: 'b ? 3 : 4')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
Next (Regular) Block[B5]
Leaving: {R1}
}
Block[B5] - Exit
Predecessors: [B4]
Statements (0)
"
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)]
[
Fact
]
public
void
ObjectCreationFlow_02
()
{
string
source
=
@"
public class MyClass
{
public MyClass(int i1, int i2, int i3) { }
static void M(bool b)
/*<bind>*/{
var c = new MyClass(i1: 1, i2: 2, i3: b ? 3 : 4);
}/*</bind>*/
}
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [MyClass c]
Block[B1] - Block
Predecessors: [B0]
Statements (2)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '1')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '2')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
Jump if False (Regular) to Block[B3]
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Next (Regular) Block[B2]
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '3')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 3) (Syntax: '3')
Next (Regular) Block[B4]
Block[B3] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '4')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 4) (Syntax: '4')
Next (Regular) Block[B4]
Block[B4] - Block
Predecessors: [B2] [B3]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 3 : 4)')
Left:
ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 3 : 4)')
Right:
IObjectCreationOperation (Constructor: MyClass..ctor(System.Int32 i1, System.Int32 i2, System.Int32 i3)) (OperationKind.ObjectCreation, Type: MyClass) (Syntax: 'new MyClass ... b ? 3 : 4)')
Arguments(3):
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i1) (OperationKind.Argument, Type: null) (Syntax: 'i1: 1')
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 1, IsImplicit) (Syntax: '1')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i2) (OperationKind.Argument, Type: null) (Syntax: 'i2: 2')
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 2, IsImplicit) (Syntax: '2')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i3) (OperationKind.Argument, Type: null) (Syntax: 'i3: b ? 3 : 4')
IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.Int32, IsImplicit) (Syntax: 'b ? 3 : 4')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
Next (Regular) Block[B5]
Leaving: {R1}
}
Block[B5] - Exit
Predecessors: [B4]
Statements (0)
"
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)]
[
Fact
]
public
void
ObjectCreationFlow_03
()
{
string
source
=
@"
public class MyClass
{
public MyClass(int i1, int i2, int i3) { }
static void M(bool b)
/*<bind>*/{
var c = new MyClass(i3: 3, i2: 2, i1: b ? 1 : 4);
}/*</bind>*/
}
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [MyClass c]
Block[B1] - Block
Predecessors: [B0]
Statements (2)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '3')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 3) (Syntax: '3')
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '2')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
Jump if False (Regular) to Block[B3]
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Next (Regular) Block[B2]
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '1')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
Next (Regular) Block[B4]
Block[B3] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '4')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 4) (Syntax: '4')
Next (Regular) Block[B4]
Block[B4] - Block
Predecessors: [B2] [B3]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 1 : 4)')
Left:
ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 1 : 4)')
Right:
IObjectCreationOperation (Constructor: MyClass..ctor(System.Int32 i1, System.Int32 i2, System.Int32 i3)) (OperationKind.ObjectCreation, Type: MyClass) (Syntax: 'new MyClass ... b ? 1 : 4)')
Arguments(3):
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i3) (OperationKind.Argument, Type: null) (Syntax: 'i3: 3')
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 3, IsImplicit) (Syntax: '3')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i2) (OperationKind.Argument, Type: null) (Syntax: 'i2: 2')
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 2, IsImplicit) (Syntax: '2')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i1) (OperationKind.Argument, Type: null) (Syntax: 'i1: b ? 1 : 4')
IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.Int32, IsImplicit) (Syntax: 'b ? 1 : 4')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
Next (Regular) Block[B5]
Leaving: {R1}
}
Block[B5] - Exit
Predecessors: [B4]
Statements (0)
"
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)]
[
Fact
]
public
void
ObjectCreationFlow_04
()
{
string
source
=
@"
public class MyClass
{
public MyClass(int i1, int i2, int i3 = 0) { }
static void M(bool b)
/*<bind>*/{
var c = new MyClass(i1: 1, i2: b ? 2 : 3);
}/*</bind>*/
}
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [MyClass c]
Block[B1] - Block
Predecessors: [B0]
Statements (1)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '1')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
Jump if False (Regular) to Block[B3]
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Next (Regular) Block[B2]
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '2')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
Next (Regular) Block[B4]
Block[B3] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '3')
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 3) (Syntax: '3')
Next (Regular) Block[B4]
Block[B4] - Block
Predecessors: [B2] [B3]
Statements (1)
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 2 : 3)')
Left:
ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: MyClass, IsImplicit) (Syntax: 'c = new MyC ... b ? 2 : 3)')
Right:
IObjectCreationOperation (Constructor: MyClass..ctor(System.Int32 i1, System.Int32 i2, [System.Int32 i3 = 0])) (OperationKind.ObjectCreation, Type: MyClass) (Syntax: 'new MyClass ... b ? 2 : 3)')
Arguments(3):
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i1) (OperationKind.Argument, Type: null) (Syntax: 'i1: 1')
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Int32, Constant: 1, IsImplicit) (Syntax: '1')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: i2) (OperationKind.Argument, Type: null) (Syntax: 'i2: b ? 2 : 3')
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Int32, IsImplicit) (Syntax: 'b ? 2 : 3')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: i3) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'new MyClass ... b ? 2 : 3)')
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0, IsImplicit) (Syntax: 'new MyClass ... b ? 2 : 3)')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
Next (Regular) Block[B5]
Leaving: {R1}
}
Block[B5] - Exit
Predecessors: [B4]
Statements (0)
"
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
}
}
}
src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
浏览文件 @
32f09648
...
...
@@ -189,7 +189,7 @@ bool PackRegion(RegionBuilder region)
for
(
int
i
=
region
.
Regions
.
Count
-
1
;
i
>=
0
;
i
--)
{
RegionBuilder
subRegion
=
region
.
Regions
[
i
];
if
(
subRegion
.
Kind
==
ControlFlowGraph
.
RegionKind
.
Locals
&&
!
subRegion
.
HasRegions
&&
subRegion
.
FirstBlock
==
subRegion
.
LastBlock
)
{
BasicBlock
block
=
subRegion
.
FirstBlock
;
...
...
@@ -311,7 +311,7 @@ private static bool PackBlocks(ArrayBuilder<BasicBlock> blocks, PooledDictionary
ref
BasicBlock
.
Branch
next
=
ref
block
.
InternalNext
.
Branch
;
Debug
.
Assert
((
block
.
InternalNext
.
ReturnValue
==
null
)
==
((
next
.
Flags
&
BasicBlock
.
BranchFlags
.
Return
)
==
0
));
Debug
.
Assert
(
next
.
Destination
!=
null
||
Debug
.
Assert
(
next
.
Destination
!=
null
||
(
next
.
Flags
&
(
BasicBlock
.
BranchFlags
.
Error
|
BasicBlock
.
BranchFlags
.
ProgramTermination
|
BasicBlock
.
BranchFlags
.
Throw
|
BasicBlock
.
BranchFlags
.
ReThrow
|
...
...
@@ -536,10 +536,10 @@ private static bool PackBlocks(ArrayBuilder<BasicBlock> blocks, PooledDictionary
BasicBlock
predecessor
=
predecessors
.
Single
();
if
(
predecessor
.
Kind
!=
BasicBlockKind
.
Entry
&&
predecessor
.
InternalNext
.
Branch
.
Destination
==
block
&&
if
(
predecessor
.
Kind
!=
BasicBlockKind
.
Entry
&&
predecessor
.
InternalNext
.
Branch
.
Destination
==
block
&&
predecessor
.
InternalConditional
.
Condition
==
null
&&
regionMap
[
predecessor
]
==
currentRegion
)
regionMap
[
predecessor
]
==
currentRegion
)
{
Debug
.
Assert
(
predecessor
!=
block
);
Debug
.
Assert
(
predecessor
.
InternalNext
.
ReturnValue
==
null
);
...
...
@@ -1000,6 +1000,58 @@ private void SpillEvalStack()
}
}
// PROTOTYPE(dataflow): Revisit and determine if this is too much abstraction, or if it's fine as it is.
private
void
PushArray
<
T
>(
ImmutableArray
<
T
>
array
,
Func
<
T
,
IOperation
>
unwrapper
=
null
)
where
T
:
IOperation
{
Debug
.
Assert
(
unwrapper
!=
null
||
typeof
(
T
)
==
typeof
(
IOperation
));
foreach
(
var
element
in
array
)
{
_evalStack
.
Push
(
Visit
(
unwrapper
==
null
?
element
:
unwrapper
(
element
)));
}
}
private
ImmutableArray
<
T
>
PopArray
<
T
>(
ImmutableArray
<
T
>
originalArray
,
Func
<
IOperation
,
int
,
ImmutableArray
<
T
>,
T
>
wrapper
=
null
)
where
T
:
IOperation
{
Debug
.
Assert
(
wrapper
!=
null
||
typeof
(
T
)
==
typeof
(
IOperation
));
int
numElements
=
originalArray
.
Length
;
if
(
numElements
==
0
)
{
return
ImmutableArray
<
T
>.
Empty
;
}
else
{
var
builder
=
ArrayBuilder
<
T
>.
GetInstance
(
numElements
);
// Iterate in reverse order so the index corresponds to the original index when pushed onto the stack
for
(
int
i
=
numElements
-
1
;
i
>=
0
;
i
--)
{
IOperation
visitedElement
=
_evalStack
.
Pop
();
builder
.
Add
(
wrapper
!=
null
?
wrapper
(
visitedElement
,
i
,
originalArray
)
:
(
T
)
visitedElement
);
}
builder
.
ReverseContents
();
return
builder
.
ToImmutableAndFree
();
}
}
private
ImmutableArray
<
IArgumentOperation
>
VisitArguments
(
ImmutableArray
<
IArgumentOperation
>
arguments
)
{
PushArray
(
arguments
,
UnwrapArgument
);
return
PopArray
(
arguments
,
RewriteArgumentFromArray
);
IOperation
UnwrapArgument
(
IArgumentOperation
argument
)
{
return
argument
.
Value
;
}
IArgumentOperation
RewriteArgumentFromArray
(
IOperation
visitedArgument
,
int
index
,
ImmutableArray
<
IArgumentOperation
>
args
)
{
Debug
.
Assert
(
index
>=
0
&&
index
<
args
.
Length
);
var
originalArgument
=
(
BaseArgument
)
args
[
index
];
return
new
ArgumentOperation
(
visitedArgument
,
originalArgument
.
ArgumentKind
,
originalArgument
.
Parameter
,
originalArgument
.
InConversionConvertibleOpt
,
originalArgument
.
OutConversionConvertibleOpt
,
semanticModel
:
null
,
originalArgument
.
Syntax
,
originalArgument
.
ConstantValue
,
originalArgument
.
IsImplicit
);
}
}
public
override
IOperation
VisitSimpleAssignment
(
ISimpleAssignmentOperation
operation
,
int
?
captureIdForResult
)
{
_evalStack
.
Push
(
Visit
(
operation
.
Target
));
...
...
@@ -1414,7 +1466,7 @@ public override IOperation VisitConditionalAccess(IConditionalAccessOperation op
LinkBlocks
(
CurrentBasicBlock
,
(
Operation
.
SetParentOperation
(
MakeIsNullOperation
(((
Operation
)
operation
).
SemanticModel
,
new
FlowCaptureReference
(
testExpressionCaptureId
,
testExpressionSyntax
,
testExpressionType
,
constantValue
)),
new
FlowCaptureReference
(
testExpressionCaptureId
,
testExpressionSyntax
,
testExpressionType
,
constantValue
)),
null
),
true
,
RegularBranch
(
whenNull
)));
...
...
@@ -1940,37 +1992,25 @@ public override IOperation VisitInvocation(IInvocationOperation operation, int?
_evalStack
.
Push
(
Visit
(
operation
.
Instance
));
}
ImmutableArray
<
IArgumentOperation
>
arguments
=
operation
.
Arguments
;
foreach
(
IArgumentOperation
argument
in
arguments
)
{
_evalStack
.
Push
(
Visit
(
argument
.
Value
));
}
ImmutableArray
<
IArgumentOperation
>
visitedArguments
;
if
(!
arguments
.
IsEmpty
)
{
var
builder
=
ArrayBuilder
<
IArgumentOperation
>.
GetInstance
();
for
(
int
i
=
arguments
.
Length
-
1
;
i
>=
0
;
i
--)
{
IOperation
visitedValue
=
_evalStack
.
Pop
();
var
originalArgument
=
(
BaseArgument
)
arguments
[
i
];
builder
.
Add
(
new
ArgumentOperation
(
visitedValue
,
originalArgument
.
ArgumentKind
,
originalArgument
.
Parameter
,
originalArgument
.
InConversionConvertibleOpt
,
originalArgument
.
OutConversionConvertibleOpt
,
semanticModel
:
null
,
originalArgument
.
Syntax
,
originalArgument
.
ConstantValue
,
originalArgument
.
IsImplicit
));
}
builder
.
ReverseContents
();
visitedArguments
=
builder
.
ToImmutableAndFree
();
}
else
{
visitedArguments
=
ImmutableArray
<
IArgumentOperation
>.
Empty
;
}
ImmutableArray
<
IArgumentOperation
>
visitedArguments
=
VisitArguments
(
operation
.
Arguments
);
IOperation
visitedInstance
=
operation
.
Instance
==
null
?
null
:
_evalStack
.
Pop
();
return
new
InvocationExpression
(
operation
.
TargetMethod
,
visitedInstance
,
operation
.
IsVirtual
,
visitedArguments
,
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
operation
.
IsImplicit
);
}
public
override
IOperation
VisitObjectCreation
(
IObjectCreationOperation
operation
,
int
?
captureIdForResult
)
{
ImmutableArray
<
IArgumentOperation
>
visitedArgs
=
VisitArguments
(
operation
.
Arguments
);
// Initializer is removed from the tree and turned into a series of statements that assign to the created instance
var
objectCreation
=
new
ObjectCreationExpression
(
operation
.
Constructor
,
initializer
:
null
,
visitedArgs
,
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
operation
.
IsImplicit
);
// PROTOTYPE(dataflow): For a non-null initializer, we'll need to assign the created object to a flow reference and rewrite all initializers to assign to/call functions on it, then return return the flow reference
return
objectCreation
;
}
internal
override
IOperation
VisitNoneOperation
(
IOperation
operation
,
int
?
captureIdForResult
)
{
if
(
_currentStatement
==
operation
)
...
...
@@ -2247,11 +2287,6 @@ public override IOperation VisitAddressOf(IAddressOfOperation operation, int? ca
return
new
AddressOfExpression
(
Visit
(
operation
.
Reference
),
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
operation
.
IsImplicit
);
}
public
override
IOperation
VisitObjectCreation
(
IObjectCreationOperation
operation
,
int
?
captureIdForResult
)
{
return
new
ObjectCreationExpression
(
operation
.
Constructor
,
Visit
(
operation
.
Initializer
),
VisitArray
(
operation
.
Arguments
),
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
operation
.
IsImplicit
);
}
public
override
IOperation
VisitAnonymousObjectCreation
(
IAnonymousObjectCreationOperation
operation
,
int
?
captureIdForResult
)
{
return
new
AnonymousObjectCreationExpression
(
VisitArray
(
operation
.
Initializers
),
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
operation
.
IsImplicit
);
...
...
src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IObjectCreationExpression.vb
浏览文件 @
32f09648
...
...
@@ -539,5 +539,339 @@ BC30456: 'MissingField' is not a member of 'C'.
VerifyOperationTreeAndDiagnosticsForTest
(
Of
ObjectCreationExpressionSyntax
)(
source
,
expectedOperationTree
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)
>
<
Fact
()
>
Public
Sub
ObjectCreationFlow_01
()
Dim
source
=
<
!
[
CDATA
[
Class
C
Public
Sub
New
(
i1
As
Integer
,
i2
As
Integer
)
End
Sub
Public
Sub
M
(
b
As
Boolean
)
'BIND:"Public Sub M(b As Boolean)"
Dim
c
=
New
C
(
1
,
If
(
b
,
1
,
2
))
End
Sub
End
Class
]]
>
.
Value
Dim
expectedDiagnostics
=
String
.
Empty
Dim
expectedFlowGraph
=
<
!
[
CDATA
[
Block
[
B0
]
-
Entry
Statements
(
0
)
Next
(
Regular
)
Block
[
B1
]
Entering
:
{
R1
}
.
locals
{
R1
}
{
Locals
:
[
c
As
C
]
Block
[
B1
]
-
Block
Predecessors
:
[
B0
]
Statements
(
1
)
IFlowCaptureOperation
:
0
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'1')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
1
)
(
Syntax
:
'1')
Jump
if
False
(
Regular
)
to
Block
[
B3
]
IParameterReferenceOperation
:
b
(
OperationKind
.
ParameterReference
,
Type
:
System
.
Boolean
)
(
Syntax
:
'b')
Next
(
Regular
)
Block
[
B2
]
Block
[
B2
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'1')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
1
)
(
Syntax
:
'1')
Next
(
Regular
)
Block
[
B4
]
Block
[
B3
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'2')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
2
)
(
Syntax
:
'2')
Next
(
Regular
)
Block
[
B4
]
Block
[
B4
]
-
Block
Predecessors
:
[
B2
]
[
B3
]
Statements
(
1
)
ISimpleAssignmentOperation
(
OperationKind
.
SimpleAssignment
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c = New C(1 ... f(b, 1, 2))')
Left
:
ILocalReferenceOperation
:
c
(
IsDeclaration
:
True
)
(
OperationKind
.
LocalReference
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c')
Right
:
IObjectCreationOperation
(
Constructor
:
Sub
C
.
.
ctor
(
i1
As
System
.
Int32
,
i2
As
System
.
Int32
))
(
OperationKind
.
ObjectCreation
,
Type
:
C
)
(
Syntax
:
'New C(1, If(b, 1, 2))')
Arguments
(
2
):
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i1
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'1')
IFlowCaptureReferenceOperation
:
0
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
Constant
:
1
,
IsImplicit
)
(
Syntax
:
'1')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i2
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'If(b, 1, 2)')
IFlowCaptureReferenceOperation
:
1
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
IsImplicit
)
(
Syntax
:
'If(b, 1, 2)')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
Initializer
:
null
Next
(
Regular
)
Block
[
B5
]
Leaving
:
{
R1
}
}
Block
[
B5
]
-
Exit
Predecessors
:
[
B4
]
Statements
(
0
)
]]
>
.
Value
VerifyFlowGraphAndDiagnosticsForTest
(
Of
MethodBlockSyntax
)(
source
,
expectedFlowGraph
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)
>
<
Fact
()
>
Public
Sub
ObjectCreationFlow_02
()
Dim
source
=
<
!
[
CDATA
[
Class
C
Public
Sub
New
(
i1
As
Integer
,
i2
As
Integer
)
End
Sub
Public
Sub
M
(
b
As
Boolean
)
'BIND:"Public Sub M(b As Boolean)"
Dim
c
=
New
C
(
i2
:
=
2
,
i1
:
=
If
(
b
,
2
,
3
))
End
Sub
End
Class
]]
>
.
Value
Dim
expectedDiagnostics
=
String
.
Empty
Dim
expectedFlowGraph
=
<
!
[
CDATA
[
Block
[
B0
]
-
Entry
Statements
(
0
)
Next
(
Regular
)
Block
[
B1
]
Entering
:
{
R1
}
.
locals
{
R1
}
{
Locals
:
[
c
As
C
]
Block
[
B1
]
-
Block
Predecessors
:
[
B0
]
Statements
(
0
)
Jump
if
False
(
Regular
)
to
Block
[
B3
]
IParameterReferenceOperation
:
b
(
OperationKind
.
ParameterReference
,
Type
:
System
.
Boolean
)
(
Syntax
:
'b')
Next
(
Regular
)
Block
[
B2
]
Block
[
B2
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
0
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'2')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
2
)
(
Syntax
:
'2')
Next
(
Regular
)
Block
[
B4
]
Block
[
B3
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
0
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'3')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
3
)
(
Syntax
:
'3')
Next
(
Regular
)
Block
[
B4
]
Block
[
B4
]
-
Block
Predecessors
:
[
B2
]
[
B3
]
Statements
(
1
)
ISimpleAssignmentOperation
(
OperationKind
.
SimpleAssignment
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c = New C(i ... f(b, 2, 3))')
Left
:
ILocalReferenceOperation
:
c
(
IsDeclaration
:
True
)
(
OperationKind
.
LocalReference
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c')
Right
:
IObjectCreationOperation
(
Constructor
:
Sub
C
.
.
ctor
(
i1
As
System
.
Int32
,
i2
As
System
.
Int32
))
(
OperationKind
.
ObjectCreation
,
Type
:
C
)
(
Syntax
:
'New C(i2:=2 ... f(b, 2, 3))')
Arguments
(
2
):
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i1
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'i1:=If(b, 2, 3)')
IFlowCaptureReferenceOperation
:
0
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
IsImplicit
)
(
Syntax
:
'If(b, 2, 3)')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i2
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'i2:=2')
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
2
)
(
Syntax
:
'2')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
Initializer
:
null
Next
(
Regular
)
Block
[
B5
]
Leaving
:
{
R1
}
}
Block
[
B5
]
-
Exit
Predecessors
:
[
B4
]
Statements
(
0
)
]]
>
.
Value
VerifyFlowGraphAndDiagnosticsForTest
(
Of
MethodBlockSyntax
)(
source
,
expectedFlowGraph
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)
>
<
Fact
()
>
Public
Sub
ObjectCreationFlow_03
()
Dim
source
=
<
!
[
CDATA
[
Class
C
Public
Sub
New
(
i1
As
Integer
,
i2
As
Integer
)
End
Sub
Public
Sub
M
(
b
As
Boolean
)
'BIND:"Public Sub M(b As Boolean)"
Dim
c
=
New
C
(
i2
:
=
If
(
b
,
2
,
3
),
i1
:
=
1
)
End
Sub
End
Class
]]
>
.
Value
Dim
expectedDiagnostics
=
String
.
Empty
Dim
expectedFlowGraph
=
<
!
[
CDATA
[
Block
[
B0
]
-
Entry
Statements
(
0
)
Next
(
Regular
)
Block
[
B1
]
Entering
:
{
R1
}
.
locals
{
R1
}
{
Locals
:
[
c
As
C
]
Block
[
B1
]
-
Block
Predecessors
:
[
B0
]
Statements
(
1
)
IFlowCaptureOperation
:
0
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'1')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
1
)
(
Syntax
:
'1')
Jump
if
False
(
Regular
)
to
Block
[
B3
]
IParameterReferenceOperation
:
b
(
OperationKind
.
ParameterReference
,
Type
:
System
.
Boolean
)
(
Syntax
:
'b')
Next
(
Regular
)
Block
[
B2
]
Block
[
B2
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'2')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
2
)
(
Syntax
:
'2')
Next
(
Regular
)
Block
[
B4
]
Block
[
B3
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'3')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
3
)
(
Syntax
:
'3')
Next
(
Regular
)
Block
[
B4
]
Block
[
B4
]
-
Block
Predecessors
:
[
B2
]
[
B3
]
Statements
(
1
)
ISimpleAssignmentOperation
(
OperationKind
.
SimpleAssignment
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c = New C(i ... 3), i1:=1)')
Left
:
ILocalReferenceOperation
:
c
(
IsDeclaration
:
True
)
(
OperationKind
.
LocalReference
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c')
Right
:
IObjectCreationOperation
(
Constructor
:
Sub
C
.
.
ctor
(
i1
As
System
.
Int32
,
i2
As
System
.
Int32
))
(
OperationKind
.
ObjectCreation
,
Type
:
C
)
(
Syntax
:
'New C(i2:=I ... 3), i1:=1)')
Arguments
(
2
):
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i1
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'i1:=1')
IFlowCaptureReferenceOperation
:
0
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
Constant
:
1
,
IsImplicit
)
(
Syntax
:
'1')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i2
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'i2:=If(b, 2, 3)')
IFlowCaptureReferenceOperation
:
1
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
IsImplicit
)
(
Syntax
:
'If(b, 2, 3)')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
Initializer
:
null
Next
(
Regular
)
Block
[
B5
]
Leaving
:
{
R1
}
}
Block
[
B5
]
-
Exit
Predecessors
:
[
B4
]
Statements
(
0
)
]]
>
.
Value
VerifyFlowGraphAndDiagnosticsForTest
(
Of
MethodBlockSyntax
)(
source
,
expectedFlowGraph
,
expectedDiagnostics
)
End
Sub
<
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
)
>
<
Fact
()
>
Public
Sub
ObjectCreationFlow_04
()
Dim
source
=
<
!
[
CDATA
[
Class
C
Public
Sub
New
(
i1
As
Integer
,
i2
As
Integer
,
Optional
i3
As
Integer
=
3
)
End
Sub
Public
Sub
M
(
b
As
Boolean
)
'BIND:"Public Sub M(b As Boolean)"
Dim
c
=
New
C
(
1
,
If
(
b
,
2
,
3
))
End
Sub
End
Class
]]
>
.
Value
Dim
expectedDiagnostics
=
String
.
Empty
Dim
expectedFlowGraph
=
<
!
[
CDATA
[
Block
[
B0
]
-
Entry
Statements
(
0
)
Next
(
Regular
)
Block
[
B1
]
Entering
:
{
R1
}
.
locals
{
R1
}
{
Locals
:
[
c
As
C
]
Block
[
B1
]
-
Block
Predecessors
:
[
B0
]
Statements
(
1
)
IFlowCaptureOperation
:
0
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'1')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
1
)
(
Syntax
:
'1')
Jump
if
False
(
Regular
)
to
Block
[
B3
]
IParameterReferenceOperation
:
b
(
OperationKind
.
ParameterReference
,
Type
:
System
.
Boolean
)
(
Syntax
:
'b')
Next
(
Regular
)
Block
[
B2
]
Block
[
B2
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'2')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
2
)
(
Syntax
:
'2')
Next
(
Regular
)
Block
[
B4
]
Block
[
B3
]
-
Block
Predecessors
:
[
B1
]
Statements
(
1
)
IFlowCaptureOperation
:
1
(
OperationKind
.
FlowCapture
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'3')
Value
:
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
3
)
(
Syntax
:
'3')
Next
(
Regular
)
Block
[
B4
]
Block
[
B4
]
-
Block
Predecessors
:
[
B2
]
[
B3
]
Statements
(
1
)
ISimpleAssignmentOperation
(
OperationKind
.
SimpleAssignment
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c = New C(1 ... f(b, 2, 3))')
Left
:
ILocalReferenceOperation
:
c
(
IsDeclaration
:
True
)
(
OperationKind
.
LocalReference
,
Type
:
C
,
IsImplicit
)
(
Syntax
:
'c')
Right
:
IObjectCreationOperation
(
Constructor
:
Sub
C
.
.
ctor
(
i1
As
System
.
Int32
,
i2
As
System
.
Int32
,
[
i3
As
System
.
Int32
=
3
]
))
(
OperationKind
.
ObjectCreation
,
Type
:
C
)
(
Syntax
:
'New C(1, If(b, 2, 3))')
Arguments
(
3
):
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i1
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'1')
IFlowCaptureReferenceOperation
:
0
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
Constant
:
1
,
IsImplicit
)
(
Syntax
:
'1')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
IArgumentOperation
(
ArgumentKind
.
Explicit
,
Matching
Parameter
:
i2
)
(
OperationKind
.
Argument
,
Type
:
null
)
(
Syntax
:
'If(b, 2, 3)')
IFlowCaptureReferenceOperation
:
1
(
OperationKind
.
FlowCaptureReference
,
Type
:
System
.
Int32
,
IsImplicit
)
(
Syntax
:
'If(b, 2, 3)')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
IArgumentOperation
(
ArgumentKind
.
DefaultValue
,
Matching
Parameter
:
i3
)
(
OperationKind
.
Argument
,
Type
:
null
,
IsImplicit
)
(
Syntax
:
'C')
ILiteralOperation
(
OperationKind
.
Literal
,
Type
:
System
.
Int32
,
Constant
:
3
,
IsImplicit
)
(
Syntax
:
'C')
InConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
OutConversion
:
CommonConversion
(
Exists
:
True
,
IsIdentity
:
True
,
IsNumeric
:
False
,
IsReference
:
False
,
IsUserDefined
:
False
)
(
MethodSymbol
:
null
)
Initializer
:
null
Next
(
Regular
)
Block
[
B5
]
Leaving
:
{
R1
}
}
Block
[
B5
]
-
Exit
Predecessors
:
[
B4
]
Statements
(
0
)
]]
>
.
Value
VerifyFlowGraphAndDiagnosticsForTest
(
Of
MethodBlockSyntax
)(
source
,
expectedFlowGraph
,
expectedDiagnostics
)
End
Sub
End
Class
End
Namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录