Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
2c3d73be
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,发现更多精彩内容 >>
未验证
提交
2c3d73be
编写于
2月 06, 2019
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address PR Feedback.
上级
d2523e59
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
265 addition
and
106 deletion
+265
-106
src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
...lers/CSharp/Portable/Operations/CSharpOperationFactory.cs
+6
-8
src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs
...pilers/CSharp/Portable/Operations/CSharpOperationNodes.cs
+6
-3
src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs
...ration/IOperation/IOperationTests_IIsPatternExpression.cs
+236
-71
src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
...ilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
+5
-12
src/Compilers/Core/Portable/Operations/OperationCloner.cs
src/Compilers/Core/Portable/Operations/OperationCloner.cs
+1
-1
src/Test/Utilities/Portable/Compilation/ControlFlowGraphVerifier.cs
...tilities/Portable/Compilation/ControlFlowGraphVerifier.cs
+10
-8
src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs
...st/Utilities/Portable/Compilation/TestOperationVisitor.cs
+1
-3
未找到文件。
src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
浏览文件 @
2c3d73be
...
...
@@ -2009,36 +2009,34 @@ private IOperation CreateUsingLocalDeclarationsOperation(BoundUsingLocalDeclarat
isImplicit
:
false
);
}
internal
IPropertySubpatternOperation
CreatePropertySubpattern
(
BoundSubpattern
subpattern
)
internal
IPropertySubpatternOperation
CreatePropertySubpattern
(
BoundSubpattern
subpattern
,
ITypeSymbol
matchedType
)
{
SyntaxNode
syntax
=
subpattern
.
Syntax
;
return
new
CSharpLazyPropertySubpatternOperation
(
this
,
subpattern
,
syntax
,
_semanticModel
);
return
new
CSharpLazyPropertySubpatternOperation
(
this
,
subpattern
,
matchedType
,
syntax
,
_semanticModel
);
}
internal
IOperation
CreatePropertySubpatternMember
(
Symbol
symbol
,
SyntaxNode
syntax
)
internal
IOperation
CreatePropertySubpatternMember
(
Symbol
symbol
,
ITypeSymbol
matchedType
,
SyntaxNode
syntax
)
{
var
nameSyntax
=
(
syntax
is
SubpatternSyntax
subpatSyntax
?
subpatSyntax
.
NameColon
?.
Name
:
null
)
??
syntax
;
bool
isImplicit
=
nameSyntax
!
=
syntax
;
bool
isImplicit
=
nameSyntax
=
=
syntax
;
switch
(
symbol
)
{
case
FieldSymbol
field
:
{
var
constantValue
=
field
.
ConstantValue
is
null
?
default
(
Optional
<
object
>)
:
new
Optional
<
object
>(
field
.
ConstantValue
);
var
receiver
=
new
InstanceReferenceOperation
(
InstanceReferenceKind
.
PatternInput
,
_semanticModel
,
nameSyntax
,
field
.
Containing
Type
,
constantValue
,
isImplicit
:
true
);
InstanceReferenceKind
.
PatternInput
,
_semanticModel
,
nameSyntax
,
matched
Type
,
constantValue
,
isImplicit
:
true
);
return
new
FieldReferenceOperation
(
field
,
isDeclaration
:
false
,
receiver
,
_semanticModel
,
nameSyntax
,
field
.
Type
.
TypeSymbol
,
constantValue
,
isImplicit
:
isImplicit
);
}
case
PropertySymbol
property
:
{
var
receiver
=
new
InstanceReferenceOperation
(
InstanceReferenceKind
.
PatternInput
,
_semanticModel
,
nameSyntax
,
property
.
Containing
Type
,
constantValue
:
default
,
isImplicit
:
true
);
InstanceReferenceKind
.
PatternInput
,
_semanticModel
,
nameSyntax
,
matched
Type
,
constantValue
:
default
,
isImplicit
:
true
);
return
new
PropertyReferenceOperation
(
property
,
receiver
,
ImmutableArray
<
IArgumentOperation
>.
Empty
,
_semanticModel
,
nameSyntax
,
property
.
Type
.
TypeSymbol
,
constantValue
:
default
,
isImplicit
:
isImplicit
);
}
case
null
:
return
null
;
default
:
// We should expose the symbol in this case somehow:
// https://github.com/dotnet/roslyn/issues/33175
...
...
src/Compilers/CSharp/Portable/Operations/CSharpOperationNodes.cs
浏览文件 @
2c3d73be
...
...
@@ -1516,7 +1516,7 @@ public override ImmutableArray<IPatternOperation> CreateDeconstructionSubpattern
public
override
ImmutableArray
<
IPropertySubpatternOperation
>
CreatePropertySubpatterns
()
{
return
_boundRecursivePattern
.
Properties
.
IsDefault
?
ImmutableArray
<
IPropertySubpatternOperation
>.
Empty
:
_boundRecursivePattern
.
Properties
.
SelectAsArray
((
p
,
fac
)
=>
fac
.
CreatePropertySubpattern
(
p
),
_operationFactory
);
_boundRecursivePattern
.
Properties
.
SelectAsArray
((
p
,
fac
)
=>
fac
.
CreatePropertySubpattern
(
p
,
MatchedType
),
_operationFactory
);
}
}
...
...
@@ -1524,20 +1524,23 @@ internal sealed partial class CSharpLazyPropertySubpatternOperation : LazyProper
{
private
readonly
BoundSubpattern
_subpattern
;
private
readonly
CSharpOperationFactory
_operationFactory
;
private
readonly
ITypeSymbol
_matchedType
;
public
CSharpLazyPropertySubpatternOperation
(
CSharpOperationFactory
operationFactory
,
BoundSubpattern
subpattern
,
ITypeSymbol
matchedType
,
SyntaxNode
syntax
,
SemanticModel
semanticModel
)
:
base
(
semanticModel
,
syntax
,
false
)
:
base
(
semanticModel
,
syntax
,
isImplicit
:
false
)
{
_subpattern
=
subpattern
;
_operationFactory
=
operationFactory
;
_matchedType
=
matchedType
;
}
public
override
IOperation
CreateMember
()
{
return
_operationFactory
.
CreatePropertySubpatternMember
(
_subpattern
.
Symbol
,
Syntax
);
return
_operationFactory
.
CreatePropertySubpatternMember
(
_subpattern
.
Symbol
,
_matchedType
,
Syntax
);
}
public
override
IPatternOperation
CreatePattern
()
...
...
src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IIsPatternExpression.cs
浏览文件 @
2c3d73be
...
...
@@ -650,69 +650,45 @@ void M(int? x, bool b, int x2, bool b2)
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
{R2}
Entering: {R1}
.locals {R1}
{
Locals: [System.Int32? y]
.locals {R2}
{
CaptureIds: [0] [1]
Block[B1] - Block
Predecessors: [B0]
Statements (3)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'b')
Value:
Block[B1] - Block
Predecessors: [B0]
Statements (2)
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b = x is var y;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b = x is var y')
Left:
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'x')
Value:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32?) (Syntax: 'x')
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b = x is var y;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b = x is var y')
Left:
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Boolean, IsImplicit) (Syntax: 'b')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x is var y')
Value:
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Int32?, IsImplicit) (Syntax: 'x')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var y') (InputType: System.Int32?, DeclaredSymbol: System.Int32? y, MatchesNull: True)
Next (Regular) Block[B2]
Leaving: {R2}
Entering: {R3}
}
.locals {R3}
{
CaptureIds: [2] [3]
Block[B2] - Block
Predecessors: [B1]
Statements (3)
IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'b2')
Value:
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x is var y')
Value:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32?) (Syntax: 'x')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var y') (InputType: System.Int32?, DeclaredSymbol: System.Int32? y, MatchesNull: True)
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b2 = x2 is 1;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b2 = x2 is 1')
Left:
IParameterReferenceOperation: b2 (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b2')
IFlowCaptureOperation: 3 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'x2')
Value:
IParameterReferenceOperation: x2 (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x2')
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b2 = x2 is 1;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b2 = x2 is 1')
Left:
IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.Boolean, IsImplicit) (Syntax: 'b2')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x2 is 1')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x2 is 1')
Value:
IParameterReferenceOperation: x2 (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x2')
Pattern:
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null) (Syntax: '1') (InputType: System.Int32)
Value:
IFlowCaptureReferenceOperation: 3 (OperationKind.FlowCaptureReference, Type: System.Int32, IsImplicit) (Syntax: 'x2')
Pattern:
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null) (Syntax: '1') (InputType: System.Int32)
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
Next (Regular) Block[B3]
Leaving: {R3} {R1}
}
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
Next (Regular) Block[B2]
Leaving: {R1}
}
Block[B3] - Exit
Predecessors: [B2]
Statements (0)"
;
Block[B2] - Exit
Predecessors: [B1]
Statements (0)
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
...
...
@@ -731,6 +707,42 @@ void M((int X, int Y)? x, bool b)
}/*</bind>*/
}
"
;
var
compilation
=
CreateCompilation
(
source
);
compilation
.
VerifyDiagnostics
();
string
expectedOperationTree
=
@"
IBlockOperation (1 statements, 2 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
Locals: Local_1: (System.Int32 X, System.Int32 Y) p
Local_2: System.Int32 z
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b = x is (1 ... var z } p;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b = x is (1 ... : var z } p')
Left:
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x is (1, _) ... : var z } p')
Value:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: (System.Int32 X, System.Int32 Y)?) (Syntax: 'x')
Pattern:
IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null) (Syntax: '(1, _) { It ... : var z } p') (InputType: (System.Int32 X, System.Int32 Y)?, DeclaredSymbol: (System.Int32 X, System.Int32 Y) p, MatchedType: (System.Int32 X, System.Int32 Y), DeconstructSymbol: null)
DeconstructionSubpatterns (2):
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null) (Syntax: '1') (InputType: System.Int32)
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IDiscardPatternOperation (OperationKind.DiscardPattern, Type: null) (Syntax: '_') (InputType: System.Int32)
PropertySubpatterns (1):
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Item1: var z')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 X, System.Int32 Y).Item1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Item1')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 X, System.Int32 Y), IsImplicit) (Syntax: 'Item1')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var z') (InputType: System.Int32, DeclaredSymbol: System.Int32 z, MatchesNull: True)
"
;
VerifyOperationTreeForTest
<
BlockSyntax
>(
compilation
,
expectedOperationTree
);
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
...
...
@@ -739,25 +751,18 @@ void M((int X, int Y)? x, bool b)
.locals {R1}
{
Locals: [(System.Int32 X, System.Int32 Y) p] [System.Int32 z]
CaptureIds: [0] [1]
Block[B1] - Block
Predecessors: [B0]
Statements (3)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'b')
Value:
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'x')
Value:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: (System.Int32 X, System.Int32 Y)?) (Syntax: 'x')
Statements (1)
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b = x is (1 ... var z } p;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b = x is (1 ... : var z } p')
Left:
I
FlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Boolean, IsImplicit
) (Syntax: 'b')
I
ParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean
) (Syntax: 'b')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'x is (1, _) ... : var z } p')
Value:
I
FlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: (System.Int32 X, System.Int32 Y)?, IsImplicit
) (Syntax: 'x')
I
ParameterReferenceOperation: x (OperationKind.ParameterReference, Type: (System.Int32 X, System.Int32 Y)?
) (Syntax: 'x')
Pattern:
IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null) (Syntax: '(1, _) { It ... : var z } p') (InputType: (System.Int32 X, System.Int32 Y)?, DeclaredSymbol: (System.Int32 X, System.Int32 Y) p, MatchedType: (System.Int32 X, System.Int32 Y), DeconstructSymbol: null)
DeconstructionSubpatterns (2):
...
...
@@ -768,9 +773,9 @@ void M((int X, int Y)? x, bool b)
PropertySubpatterns (1):
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Item1: var z')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 X, System.Int32 Y).Item1 (OperationKind.FieldReference, Type: System.Int32
, IsImplicit
) (Syntax: 'Item1')
IFieldReferenceOperation: System.Int32 (System.Int32 X, System.Int32 Y).Item1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Item1')
Instance Receiver:
I
FlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: (System.Int32 X, System.Int32 Y)?, IsImplicit) (Syntax: 'x
')
I
InstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 X, System.Int32 Y), IsImplicit) (Syntax: 'Item1
')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var z') (InputType: System.Int32, DeclaredSymbol: System.Int32 z, MatchesNull: True)
Next (Regular) Block[B2]
...
...
@@ -779,6 +784,92 @@ void M((int X, int Y)? x, bool b)
Block[B2] - Exit
Predecessors: [B1]
Statements (0)"
;
VerifyFlowGraphForTest
<
BlockSyntax
>(
compilation
,
expectedFlowGraph
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
,
CompilerFeature
.
Patterns
)]
[
Fact
]
public
void
IsPattern_NoControlFlow_03
()
{
string
source
=
@"
class C
{
void M((int X, (int Y, int Z))? tuple, bool b)
/*<bind>*/{
b = tuple is (1, _) { Item1: var x, Item2: { Y: 1, Z: var z } } p;
}/*</bind>*/
}
"
;
string
expectedFlowGraph
=
@"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Entering: {R1}
.locals {R1}
{
Locals: [(System.Int32 X, (System.Int32 Y, System.Int32 Z)) p] [System.Int32 x] [System.Int32 z]
Block[B1] - Block
Predecessors: [B0]
Statements (1)
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'b = tuple i ... ar z } } p;')
Expression:
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Boolean) (Syntax: 'b = tuple i ... var z } } p')
Left:
IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: System.Boolean) (Syntax: 'b')
Right:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'tuple is (1 ... var z } } p')
Value:
IParameterReferenceOperation: tuple (OperationKind.ParameterReference, Type: (System.Int32 X, (System.Int32 Y, System.Int32 Z))?) (Syntax: 'tuple')
Pattern:
IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null) (Syntax: '(1, _) { It ... var z } } p') (InputType: (System.Int32 X, (System.Int32 Y, System.Int32 Z))?, DeclaredSymbol: (System.Int32 X, (System.Int32 Y, System.Int32 Z)) p, MatchedType: (System.Int32 X, (System.Int32 Y, System.Int32 Z)), DeconstructSymbol: null)
DeconstructionSubpatterns (2):
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null) (Syntax: '1') (InputType: System.Int32)
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IDiscardPatternOperation (OperationKind.DiscardPattern, Type: null) (Syntax: '_') (InputType: (System.Int32 Y, System.Int32 Z))
PropertySubpatterns (2):
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Item1: var x')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 X, (System.Int32 Y, System.Int32 Z)).Item1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Item1')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 X, (System.Int32 Y, System.Int32 Z)), IsImplicit) (Syntax: 'Item1')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var x') (InputType: System.Int32, DeclaredSymbol: System.Int32 x, MatchesNull: True)
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Item2: { Y: ... Z: var z }')
Member:
IFieldReferenceOperation: (System.Int32 Y, System.Int32 Z) (System.Int32 X, (System.Int32 Y, System.Int32 Z)).Item2 (OperationKind.FieldReference, Type: (System.Int32 Y, System.Int32 Z)) (Syntax: 'Item2')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 X, (System.Int32 Y, System.Int32 Z)), IsImplicit) (Syntax: 'Item2')
Pattern:
IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null) (Syntax: '{ Y: 1, Z: var z }') (InputType: (System.Int32 Y, System.Int32 Z), DeclaredSymbol: null, MatchedType: (System.Int32 Y, System.Int32 Z), DeconstructSymbol: null)
DeconstructionSubpatterns (0)
PropertySubpatterns (2):
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Y: 1')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 Y, System.Int32 Z).Y (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Y')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 Y, System.Int32 Z), IsImplicit) (Syntax: 'Y')
Pattern:
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null) (Syntax: '1') (InputType: System.Int32)
Value:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Z: var z')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 Y, System.Int32 Z).Z (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Z')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 Y, System.Int32 Z), IsImplicit) (Syntax: 'Z')
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'var z') (InputType: System.Int32, DeclaredSymbol: System.Int32 z, MatchesNull: True)
Next (Regular) Block[B2]
Leaving: {R1}
}
Block[B2] - Exit
Predecessors: [B1]
Statements (0)
"
;
var
expectedDiagnostics
=
DiagnosticDescription
.
None
;
VerifyFlowGraphAndDiagnosticsForTest
<
BlockSyntax
>(
source
,
expectedFlowGraph
,
expectedDiagnostics
);
...
...
@@ -913,7 +1004,7 @@ void M((int X, int Y) tuple, bool b)
PropertySubpatterns (1):
IPropertySubpatternOperation (OperationKind.None, Type: null) (Syntax: 'Item1: int x')
Member:
IFieldReferenceOperation: System.Int32 (System.Int32 X, System.Int32 Y).Item1 (OperationKind.FieldReference, Type: System.Int32
, IsImplicit
) (Syntax: 'Item1')
IFieldReferenceOperation: System.Int32 (System.Int32 X, System.Int32 Y).Item1 (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'Item1')
Instance Receiver:
IInstanceReferenceOperation (ReferenceKind: PatternInput) (OperationKind.InstanceReference, Type: (System.Int32 X, System.Int32 Y), IsImplicit) (Syntax: 'Item1')
Pattern:
...
...
@@ -924,7 +1015,7 @@ void M((int X, int Y) tuple, bool b)
VerifyOperationTreeAndDiagnosticsForTest
<
IsPatternExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
,
CompilerFeature
.
Patterns
)]
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Patterns
)]
[
Fact
]
public
void
IsPattern_BadRecursivePattern_01
()
{
...
...
@@ -953,7 +1044,8 @@ void M((int X, int Y) tuple, bool b)
PropertySubpatterns (1):
IPropertySubpatternOperation (OperationKind.None, Type: null, IsInvalid) (Syntax: 'NotFound: int x')
Member:
null
IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'NotFound')
Children(0)
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null) (Syntax: 'int x') (InputType: ?, DeclaredSymbol: System.Int32 x, MatchesNull: False)
"
;
...
...
@@ -966,6 +1058,79 @@ void M((int X, int Y) tuple, bool b)
VerifyOperationTreeAndDiagnosticsForTest
<
IsPatternExpressionSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Patterns
)]
[
Fact
]
public
void
IsPattern_BadRecursivePattern_02
()
{
var
vbSource
=
@"
Public Class C1
Public Property Prop(index As Integer) As Integer
Get
Return 1
End Get
Set
End Set
End Property
End Class
"
;
var
vbCompilation
=
CreateVisualBasicCompilation
(
vbSource
);
var
source
=
@"
class C
{
void M1(object o, bool b)
{
b = /*<bind>*/o is C1 { Prop[1]: var x }/*</bind>*/;
}
}"
;
var
compilation
=
CreateCompilation
(
source
,
new
[]
{
vbCompilation
.
EmitToImageReference
()
});
compilation
.
VerifyDiagnostics
(
// (6,33): error CS8503: A property subpattern requires a reference to the property or field to be matched, e.g. '{ Name: Prop[1] }'
// b = /*<bind>*/o is C1 { Prop[1]: var x }/*</bind>*/;
Diagnostic
(
ErrorCode
.
ERR_PropertyPatternNameMissing
,
"Prop[1]"
).
WithArguments
(
"Prop[1]"
).
WithLocation
(
6
,
33
),
// (6,33): error CS0103: The name 'Prop' does not exist in the current context
// b = /*<bind>*/o is C1 { Prop[1]: var x }/*</bind>*/;
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"Prop"
).
WithArguments
(
"Prop"
).
WithLocation
(
6
,
33
),
// (6,40): error CS1003: Syntax error, ',' expected
// b = /*<bind>*/o is C1 { Prop[1]: var x }/*</bind>*/;
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
":"
).
WithArguments
(
","
,
":"
).
WithLocation
(
6
,
40
),
// (6,42): error CS1003: Syntax error, ',' expected
// b = /*<bind>*/o is C1 { Prop[1]: var x }/*</bind>*/;
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"var"
).
WithArguments
(
","
,
""
).
WithLocation
(
6
,
42
));
var
expectedOperationTree
=
@"
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean, IsInvalid) (Syntax: 'o is C1 { P ... 1]: var x }')
Value:
IParameterReferenceOperation: o (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'o')
Pattern:
IRecursivePatternOperation (OperationKind.RecursivePattern, Type: null, IsInvalid) (Syntax: 'C1 { Prop[1]: var x }') (InputType: System.Object, DeclaredSymbol: null, MatchedType: C1, DeconstructSymbol: null)
DeconstructionSubpatterns (0)
PropertySubpatterns (2):
IPropertySubpatternOperation (OperationKind.None, Type: null, IsInvalid) (Syntax: 'Prop[1]')
Member:
IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'Prop[1]')
Children(0)
Pattern:
IConstantPatternOperation (OperationKind.ConstantPattern, Type: null, IsInvalid) (Syntax: 'Prop[1]') (InputType: ?)
Value:
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'Prop[1]')
Children(2):
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: '1')
IInvalidOperation (OperationKind.Invalid, Type: ?, IsInvalid) (Syntax: 'Prop')
Children(0)
IPropertySubpatternOperation (OperationKind.None, Type: null, IsInvalid) (Syntax: 'var x')
Member:
IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'var x')
Children(0)
Pattern:
IDeclarationPatternOperation (OperationKind.DeclarationPattern, Type: null, IsInvalid) (Syntax: 'var x') (InputType: ?, DeclaredSymbol: ? x, MatchesNull: True)
"
;
VerifyOperationTreeForTest
<
IsPatternExpressionSyntax
>(
compilation
,
expectedOperationTree
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
,
CompilerFeature
.
Dataflow
,
CompilerFeature
.
Patterns
)]
[
Fact
]
public
void
IsPattern_ControlFlowInPattern
()
...
...
src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs
浏览文件 @
2c3d73be
...
...
@@ -5818,7 +5818,7 @@ IArrayInitializerOperation popAndAssembleArrayInitializerValues(IArrayInitialize
public
override
IOperation
VisitInstanceReference
(
IInstanceReferenceOperation
operation
,
int
?
captureIdForResult
)
{
if
(
operation
.
ReferenceKind
==
InstanceReferenceKind
.
ImplicitReceiver
||
operation
.
ReferenceKind
==
InstanceReferenceKind
.
PatternInput
)
if
(
operation
.
ReferenceKind
==
InstanceReferenceKind
.
ImplicitReceiver
)
{
// When we're in an object or collection initializer, we need to replace the instance reference with a reference to the object being initialized
Debug
.
Assert
(
operation
.
IsImplicit
);
...
...
@@ -6419,14 +6419,12 @@ public override IOperation VisitDefaultValue(IDefaultValueOperation operation, i
public
override
IOperation
VisitIsPattern
(
IIsPatternOperation
operation
,
int
?
captureIdForResult
)
{
EvalStackFrame
frame
=
PushStackFrame
();
var
capturedValue
=
VisitAndCapture
(
operation
.
Value
);
var
previousImplicitInstance
=
_currentImplicitInstance
;
_currentImplicitInstance
=
new
ImplicitInstanceInfo
(
capturedValue
);
PushOperand
(
Visit
(
operation
.
Value
));
var
visitedPattern
=
(
IPatternOperation
)
Visit
(
operation
.
Pattern
);
_currentImplicitInstance
=
previousImplicitInstance
;
IOperation
visitedValue
=
PopOperand
()
;
PopStackFrame
(
frame
);
return
new
IsPatternOperation
(
captur
edValue
,
visitedPattern
,
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
IsImplicit
(
operation
));
return
new
IsPatternOperation
(
visit
edValue
,
visitedPattern
,
semanticModel
:
null
,
operation
.
Syntax
,
operation
.
Type
,
operation
.
ConstantValue
,
IsImplicit
(
operation
));
}
public
override
IOperation
VisitInvalid
(
IInvalidOperation
operation
,
int
?
captureIdForResult
)
...
...
@@ -6630,14 +6628,11 @@ public override IOperation VisitSwitchExpression(ISwitchExpressionOperation oper
RegionBuilder
resultCaptureRegion
=
_currentRegion
;
int
captureOutput
=
captureIdForResult
??
GetNextCaptureId
(
resultCaptureRegion
);
var
capturedInput
=
VisitAndCapture
(
operation
.
Value
);
var
previousImplicitInstance
=
_currentImplicitInstance
;
var
switchImplicitInstance
=
new
ImplicitInstanceInfo
(
capturedInput
);
var
afterSwitch
=
new
BasicBlockBuilder
(
BasicBlockKind
.
Block
);
foreach
(
var
arm
in
operation
.
Arms
)
{
// START scope (arm locals)
_currentImplicitInstance
=
switchImplicitInstance
;
var
armScopeRegion
=
new
RegionBuilder
(
ControlFlowRegionKind
.
LocalLifetime
,
locals
:
arm
.
Locals
);
EnterRegion
(
armScopeRegion
);
var
afterArm
=
new
BasicBlockBuilder
(
BasicBlockKind
.
Block
);
...
...
@@ -6663,8 +6658,6 @@ public override IOperation VisitSwitchExpression(ISwitchExpressionOperation oper
PopStackFrameAndLeaveRegion
(
frame
);
}
_currentImplicitInstance
=
previousImplicitInstance
;
// captureOutput = e
VisitAndCapture
(
arm
.
Value
,
captureOutput
);
...
...
src/Compilers/Core/Portable/Operations/OperationCloner.cs
浏览文件 @
2c3d73be
...
...
@@ -552,7 +552,7 @@ internal override IOperation VisitRecursivePattern(IRecursivePatternOperation op
internal
override
IOperation
VisitPropertySubpattern
(
IPropertySubpatternOperation
operation
,
object
argument
)
{
return
new
PropertySubpatternOperation
(
semanticModel
:
nul
l
,
semanticModel
:
((
Operation
)
operation
).
OwningSemanticMode
l
,
operation
.
Syntax
,
operation
.
IsImplicit
,
Visit
(
operation
.
Member
),
...
...
src/Test/Utilities/Portable/Compilation/ControlFlowGraphVerifier.cs
浏览文件 @
2c3d73be
...
...
@@ -1728,14 +1728,16 @@ private static bool CanBeInControlFlowGraph(IOperation n)
case
OperationKind
.
InstanceReference
:
// Implicit instance receivers, except for anonymous type creations, are expected to have been removed when dealing with creations.
return
((
IInstanceReferenceOperation
)
n
).
ReferenceKind
==
InstanceReferenceKind
.
ContainingTypeInstance
||
((
IInstanceReferenceOperation
)
n
).
ReferenceKind
==
InstanceReferenceKind
.
ImplicitReceiver
&&
n
.
Type
.
IsAnonymousType
&&
n
.
Parent
is
IPropertyReferenceOperation
propertyReference
&&
propertyReference
.
Instance
==
n
&&
propertyReference
.
Parent
is
ISimpleAssignmentOperation
simpleAssignment
&&
simpleAssignment
.
Target
==
propertyReference
&&
simpleAssignment
.
Parent
.
Kind
==
OperationKind
.
AnonymousObjectCreation
;
var
instanceReference
=
(
IInstanceReferenceOperation
)
n
;
return
instanceReference
.
ReferenceKind
==
InstanceReferenceKind
.
ContainingTypeInstance
||
instanceReference
.
ReferenceKind
==
InstanceReferenceKind
.
PatternInput
||
(
instanceReference
.
ReferenceKind
==
InstanceReferenceKind
.
ImplicitReceiver
&&
n
.
Type
.
IsAnonymousType
&&
n
.
Parent
is
IPropertyReferenceOperation
propertyReference
&&
propertyReference
.
Instance
==
n
&&
propertyReference
.
Parent
is
ISimpleAssignmentOperation
simpleAssignment
&&
simpleAssignment
.
Target
==
propertyReference
&&
simpleAssignment
.
Parent
.
Kind
==
OperationKind
.
AnonymousObjectCreation
);
case
OperationKind
.
None
:
return
!(
n
is
IPlaceholderOperation
);
...
...
src/Test/Utilities/Portable/Compilation/TestOperationVisitor.cs
浏览文件 @
2c3d73be
...
...
@@ -1197,12 +1197,10 @@ internal override void VisitRecursivePattern(IRecursivePatternOperation operatio
internal
override
void
VisitPropertySubpattern
(
IPropertySubpatternOperation
operation
)
{
Assert
.
True
(
operation
.
Member
is
IMemberReferenceOperation
);
Assert
.
True
(
operation
.
Member
is
IMemberReferenceOperation
||
operation
.
Member
is
IInvalidOperation
);
var
member
=
(
IMemberReferenceOperation
)
operation
.
Member
;
switch
(
member
.
Member
)
{
case
null
:
// error case
break
;
case
IFieldSymbol
field
:
case
IPropertySymbol
prop
:
case
IErrorTypeSymbol
error
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录