Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET
Roslyn
提交
4b85e651
R
Roslyn
项目概览
dotNET
/
Roslyn
通知
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,发现更多精彩内容 >>
未验证
提交
4b85e651
编写于
4月 02, 2018
作者:
F
Fredric Silberberg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Addressed pr feedback.
上级
ba3c9b5e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
108 addition
and
21 deletion
+108
-21
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
+6
-7
src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
...lers/CSharp/Portable/Operations/CSharpOperationFactory.cs
+5
-8
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IForEachLoopStatement.cs
...antic/IOperation/IOperationTests_IForEachLoopStatement.cs
+97
-6
未找到文件。
src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs
浏览文件 @
4b85e651
...
...
@@ -298,17 +298,16 @@ private BoundForEachStatement BindForEachPartsWorker(DiagnosticBag diagnostics,
deconstructStep
=
new
BoundForEachDeconstructStep
(
variables
,
deconstruction
,
valuePlaceholder
).
MakeCompilerGenerated
();
}
else
if
(!
node
.
HasErrors
)
{
// error: must declare foreach loop iteration variables.
Error
(
diagnostics
,
ErrorCode
.
ERR_MustDeclareForeachIteration
,
variables
);
hasErrors
=
true
;
}
else
{
// Bind the expression for error recovery, but discard all new diagnostics
iterationErrorExpression
=
originalBinder
.
BindExpression
(
node
.
Variable
,
new
DiagnosticBag
());
iterationErrorExpression
=
BindExpression
(
node
.
Variable
,
new
DiagnosticBag
());
hasErrors
=
true
;
if
(!
node
.
HasErrors
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_MustDeclareForeachIteration
,
variables
);
}
}
boundIterationVariableType
=
new
BoundTypeExpression
(
variables
,
aliasOpt
:
null
,
type
:
iterationVariableType
).
MakeCompilerGenerated
();
...
...
src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
浏览文件 @
4b85e651
...
...
@@ -1450,20 +1450,17 @@ private IForEachLoopOperation CreateBoundForEachStatementOperation(BoundForEachS
{
loopControlVariable
=
new
Lazy
<
IOperation
>(()
=>
Create
(
boundForEachStatement
.
DeconstructionOpt
.
DeconstructionAssignment
.
Left
));
}
else
if
(
locals
.
Length
==
1
)
{
var
local
=
(
LocalSymbol
)
locals
.
Single
();
// We use iteration variable type syntax as the underlying syntax node as there is no variable declarator syntax in the syntax tree.
var
declaratorSyntax
=
boundForEachStatement
.
IterationVariableType
.
Syntax
;
loopControlVariable
=
new
Lazy
<
IOperation
>(()
=>
new
VariableDeclarator
(
local
,
initializer
:
null
,
ignoredArguments
:
ImmutableArray
<
IOperation
>.
Empty
,
semanticModel
:
_semanticModel
,
syntax
:
declaratorSyntax
,
type
:
null
,
constantValue
:
default
,
isImplicit
:
false
));
}
else
if
(
boundForEachStatement
.
IterationErrorExpressionOpt
!=
null
)
{
loopControlVariable
=
new
Lazy
<
IOperation
>(()
=>
Create
(
boundForEachStatement
.
IterationErrorExpressionOpt
));
}
else
{
loopControlVariable
=
OperationFactory
.
NullOperation
;
Debug
.
Assert
(
locals
.
Length
==
1
);
var
local
=
(
LocalSymbol
)
locals
[
0
];
// We use iteration variable type syntax as the underlying syntax node as there is no variable declarator syntax in the syntax tree.
var
declaratorSyntax
=
boundForEachStatement
.
IterationVariableType
.
Syntax
;
loopControlVariable
=
new
Lazy
<
IOperation
>(()
=>
new
VariableDeclarator
(
local
,
initializer
:
null
,
ignoredArguments
:
ImmutableArray
<
IOperation
>.
Empty
,
semanticModel
:
_semanticModel
,
syntax
:
declaratorSyntax
,
type
:
null
,
constantValue
:
default
,
isImplicit
:
false
));
}
Lazy
<
IOperation
>
collection
=
new
Lazy
<
IOperation
>(()
=>
Create
(
boundForEachStatement
.
Expression
));
...
...
src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IForEachLoopStatement.cs
浏览文件 @
4b85e651
...
...
@@ -1220,12 +1220,13 @@ public static void M(int[] x)
IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }')
IForEachLoopOperation (LoopKind.ForEach) (OperationKind.Loop, Type: null, IsInvalid) (Syntax: 'foreach (x[ ... }')
LoopControlVariable:
null
Collection:
IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Collections.IEnumerable, IsImplicit) (Syntax: 'x')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand:
IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Int32) (Syntax: 'x[0]')
Array reference:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32[]) (Syntax: 'x')
Indices(1):
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
Collection:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32[]) (Syntax: 'x')
Body:
IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
NextVariables(0)
...
...
@@ -1283,7 +1284,7 @@ public static void M(int[] x)
[
CompilerTrait
(
CompilerFeature
.
IOperation
)]
[
Fact
,
WorkItem
(
19996
,
"https://github.com/dotnet/roslyn/issues/19996"
)]
public
void
IForEachLoopStatement_InvalidLoopControlVariableExpression
()
public
void
IForEachLoopStatement_InvalidLoopControlVariableExpression
_01
()
{
string
source
=
@"
class C
...
...
@@ -1326,5 +1327,95 @@ void M(int a, int b)
VerifyOperationTreeAndDiagnosticsForTest
<
ForEachVariableStatementSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
)]
[
Fact
,
WorkItem
(
17602
,
"https://github.com/dotnet/roslyn/issues/17602"
)]
public
void
IForEachLoopStatement_InvalidLoopControlVariableExpression_02
()
{
string
source
=
@"
class C
{
void M(int a, int b)
{
int[] arr = new int[10];
/*<bind>*/foreach (M2(out var x) in arr)
{
}/*</bind>*/
}
void M2(out int x)
{
x = 0;
}
}
"
;
string
expectedOperationTree
=
@"
IForEachLoopOperation (LoopKind.ForEach) (OperationKind.Loop, Type: null, IsInvalid) (Syntax: 'foreach (M2 ... }')
Locals: Local_1: System.Int32 x
LoopControlVariable:
IInvocationOperation ( void C.M2(out System.Int32 x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'M2(out var x)')
Instance Receiver:
IInstanceReferenceOperation (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'M2')
Arguments(1):
IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: 'out var x')
IDeclarationExpressionOperation (OperationKind.DeclarationExpression, Type: System.Int32) (Syntax: 'var x')
ILocalReferenceOperation: x (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'x')
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)
Collection:
ILocalReferenceOperation: arr (OperationKind.LocalReference, Type: System.Int32[]) (Syntax: 'arr')
Body:
IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
NextVariables(0)
"
;
var
expectedDiagnostics
=
new
DiagnosticDescription
[]
{
// file.cs(7,42): error CS0230: Type and identifier are both required in a foreach statement
// /*<bind>*/foreach (M2(out var x) in arr)
Diagnostic
(
ErrorCode
.
ERR_BadForeachDecl
,
"in"
).
WithLocation
(
7
,
42
)
};
VerifyOperationTreeAndDiagnosticsForTest
<
ForEachVariableStatementSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
[
CompilerTrait
(
CompilerFeature
.
IOperation
)]
[
Fact
,
WorkItem
(
17602
,
"https://github.com/dotnet/roslyn/issues/17602"
)]
public
void
IForEachLoopStatement_InvalidLoopControlVariableExpression_03
()
{
string
source
=
@"
class C
{
void M(object o)
{
int[] arr = new int[10];
/*<bind>*/foreach (o is int x in arr)
{
}/*</bind>*/
}
}
"
;
string
expectedOperationTree
=
@"
IForEachLoopOperation (LoopKind.ForEach) (OperationKind.Loop, Type: null, IsInvalid) (Syntax: 'foreach (o ... }')
Locals: Local_1: System.Int32 x
LoopControlVariable:
IIsPatternOperation (OperationKind.IsPattern, Type: System.Boolean) (Syntax: 'o is int x')
Expression:
IParameterReferenceOperation: o (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'o')
Pattern:
IDeclarationPatternOperation (Declared Symbol: System.Int32 x) (OperationKind.DeclarationPattern, Type: null) (Syntax: 'int x')
Collection:
ILocalReferenceOperation: arr (OperationKind.LocalReference, Type: System.Int32[]) (Syntax: 'arr')
Body:
IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
NextVariables(0)
"
;
var
expectedDiagnostics
=
new
DiagnosticDescription
[]
{
// file.cs(7,39): error CS0230: Type and identifier are both required in a foreach statement
// /*<bind>*/foreach (o is int x in arr)
Diagnostic
(
ErrorCode
.
ERR_BadForeachDecl
,
"in"
).
WithLocation
(
7
,
39
)
};
VerifyOperationTreeAndDiagnosticsForTest
<
ForEachVariableStatementSyntax
>(
source
,
expectedOperationTree
,
expectedDiagnostics
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录