Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
9d0b3a86
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,发现更多精彩内容 >>
提交
9d0b3a86
编写于
3月 02, 2016
作者:
A
AlekseyTs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Test/fix scoping rules for pattern locals in constructor initializers.
上级
df84adde
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
275 addition
and
8 deletion
+275
-8
src/Compilers/CSharp/Portable/Binder/Binder.cs
src/Compilers/CSharp/Portable/Binder/Binder.cs
+12
-0
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
+2
-6
src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
...rs/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
+3
-1
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
+3
-1
src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
...rs/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
+255
-0
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder.cs
浏览文件 @
9d0b3a86
...
@@ -761,6 +761,18 @@ internal Binder WithPatternVariablesIfAny(ExpressionSyntax scopeOpt)
...
@@ -761,6 +761,18 @@ internal Binder WithPatternVariablesIfAny(ExpressionSyntax scopeOpt)
return
new
PatternVariableBinder
(
scopeOpt
,
scopeOpt
,
this
);
return
new
PatternVariableBinder
(
scopeOpt
,
scopeOpt
,
this
);
}
}
internal
Binder
WithPatternVariablesIfAny
(
ArgumentListSyntax
initializerArgumentListOpt
)
{
Debug
.
Assert
(
Locals
.
Length
==
0
);
if
(
initializerArgumentListOpt
==
null
||
initializerArgumentListOpt
.
Arguments
.
Count
==
0
)
{
return
this
;
}
return
new
PatternVariableBinder
(
initializerArgumentListOpt
,
initializerArgumentListOpt
.
Arguments
,
this
);
}
internal
BoundExpression
WrapWithVariablesIfAny
(
BoundExpression
expression
)
internal
BoundExpression
WrapWithVariablesIfAny
(
BoundExpression
expression
)
{
{
return
(
Locals
.
Length
==
0
)
return
(
Locals
.
Length
==
0
)
...
...
src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs
浏览文件 @
9d0b3a86
...
@@ -2645,12 +2645,8 @@ private static bool IsNegativeConstantForArraySize(BoundExpression expression)
...
@@ -2645,12 +2645,8 @@ private static bool IsNegativeConstantForArraySize(BoundExpression expression)
MethodSymbol
constructor
,
MethodSymbol
constructor
,
DiagnosticBag
diagnostics
)
DiagnosticBag
diagnostics
)
{
{
// Handle scoping for possible pattern variables declared in the initializer
var
result
=
BindConstructorInitializerCore
(
initializerArgumentListOpt
,
constructor
,
diagnostics
);
PatternVariableBinder
patBinder
=
(
initializerArgumentListOpt
!=
null
)
return
WrapWithVariablesIfAny
(
result
);
?
new
PatternVariableBinder
(
initializerArgumentListOpt
,
initializerArgumentListOpt
.
Arguments
,
this
)
:
null
;
var
result
=
(
patBinder
??
this
).
BindConstructorInitializerCore
(
initializerArgumentListOpt
,
constructor
,
diagnostics
);
return
patBinder
?.
WrapWithVariablesIfAny
(
result
)
??
result
;
}
}
private
BoundExpression
BindConstructorInitializerCore
(
private
BoundExpression
BindConstructorInitializerCore
(
...
...
src/Compilers/CSharp/Portable/Compilation/SyntaxTreeSemanticModel.cs
浏览文件 @
9d0b3a86
...
@@ -1042,7 +1042,9 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
...
@@ -1042,7 +1042,9 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
(
ConstructorInitializerSyntax
)
node
,
(
ConstructorInitializerSyntax
)
node
,
constructorSymbol
,
constructorSymbol
,
//insert an extra binder to perform constructor initialization checks
//insert an extra binder to perform constructor initialization checks
outer
.
WithAdditionalFlagsAndContainingMemberOrLambda
(
BinderFlags
.
ConstructorInitializer
,
constructorSymbol
));
// Handle scoping for possible pattern variables declared in the initializer
outer
.
WithAdditionalFlagsAndContainingMemberOrLambda
(
BinderFlags
.
ConstructorInitializer
,
constructorSymbol
).
WithPatternVariablesIfAny
(((
ConstructorInitializerSyntax
)
node
).
ArgumentList
));
}
}
case
SyntaxKind
.
Attribute
:
case
SyntaxKind
.
Attribute
:
...
...
src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
浏览文件 @
9d0b3a86
...
@@ -1726,7 +1726,9 @@ internal static BoundExpression BindConstructorInitializer(MethodSymbol construc
...
@@ -1726,7 +1726,9 @@ internal static BoundExpression BindConstructorInitializer(MethodSymbol construc
}
}
// wrap in ConstructorInitializerBinder for appropriate errors
// wrap in ConstructorInitializerBinder for appropriate errors
Binder
initializerBinder
=
outerBinder
.
WithAdditionalFlagsAndContainingMemberOrLambda
(
BinderFlags
.
ConstructorInitializer
,
constructor
);
// Handle scoping for possible pattern variables declared in the initializer
Binder
initializerBinder
=
outerBinder
.
WithAdditionalFlagsAndContainingMemberOrLambda
(
BinderFlags
.
ConstructorInitializer
,
constructor
).
WithPatternVariablesIfAny
(
initializerArgumentListOpt
);
return
initializerBinder
.
BindConstructorInitializer
(
initializerArgumentListOpt
,
constructor
,
diagnostics
);
return
initializerBinder
.
BindConstructorInitializer
(
initializerArgumentListOpt
,
constructor
,
diagnostics
);
}
}
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs
浏览文件 @
9d0b3a86
...
@@ -4556,5 +4556,260 @@ class Test : System.Attribute
...
@@ -4556,5 +4556,260 @@ class Test : System.Attribute
VerifyNotInScope
(
model
,
x7Ref
[
1
]);
VerifyNotInScope
(
model
,
x7Ref
[
1
]);
VerifyNotInScope
(
model
,
x7Ref
[
2
]);
VerifyNotInScope
(
model
,
x7Ref
[
2
]);
}
}
[
Fact
]
public
void
ScopeOfPatternVariables_ConstructorInitializers_01
()
{
var
source
=
@"
public class X
{
public static void Main()
{
}
X(byte x)
: this(3 is int x3 && x3 > 0)
{}
X(sbyte x)
: this(x4 && 4 is int x4)
{}
X(short x)
: this(51 is int x5 &&
52 is int x5 &&
x5 > 0)
{}
X(ushort x)
: this(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
{}
X(int x)
: this(7 is int x7 && x7 > 0)
{}
X(uint x)
: this(x7, 2)
{}
void Test73() { Dummy(x7, 3); }
X(params object[] x) {}
bool Dummy(params object[] x) {return true;}
}
"
;
var
compilation
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
DebugExe
,
parseOptions
:
patternParseOptions
);
compilation
.
VerifyDiagnostics
(
// (13,16): error CS0841: Cannot use local variable 'x4' before it is declared
// : this(x4 && 4 is int x4)
Diagnostic
(
ErrorCode
.
ERR_VariableUsedBeforeDeclaration
,
"x4"
).
WithArguments
(
"x4"
).
WithLocation
(
13
,
16
),
// (18,26): error CS0128: A local variable named 'x5' is already defined in this scope
// 52 is int x5 &&
Diagnostic
(
ErrorCode
.
ERR_LocalDuplicate
,
"x5"
).
WithArguments
(
"x5"
).
WithLocation
(
18
,
26
),
// (23,48): error CS0128: A local variable named 'x6' is already defined in this scope
// : this(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
Diagnostic
(
ErrorCode
.
ERR_LocalDuplicate
,
"x6"
).
WithArguments
(
"x6"
).
WithLocation
(
23
,
48
),
// (30,16): error CS0103: The name 'x7' does not exist in the current context
// : this(x7, 2)
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x7"
).
WithArguments
(
"x7"
).
WithLocation
(
30
,
16
),
// (32,27): error CS0103: The name 'x7' does not exist in the current context
// void Test73() { Dummy(x7, 3); }
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x7"
).
WithArguments
(
"x7"
).
WithLocation
(
32
,
27
)
);
var
tree
=
compilation
.
SyntaxTrees
.
Single
();
var
model
=
compilation
.
GetSemanticModel
(
tree
);
var
x3Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x3"
).
Single
();
var
x3Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x3"
).
Single
();
VerifyModelForDeclarationPattern
(
model
,
x3Decl
,
x3Ref
);
var
x4Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x4"
).
Single
();
var
x4Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x4"
).
Single
();
VerifyModelForDeclarationPattern
(
model
,
x4Decl
,
x4Ref
);
var
x5Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x5"
).
ToArray
();
var
x5Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x5"
).
Single
();
Assert
.
Equal
(
2
,
x5Decl
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x5Decl
[
0
],
x5Ref
);
VerifyModelForDeclarationPatternDuplicateInSameScope
(
model
,
x5Decl
[
1
]);
var
x6Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x6"
).
ToArray
();
var
x6Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x6"
).
ToArray
();
Assert
.
Equal
(
2
,
x6Decl
.
Length
);
Assert
.
Equal
(
2
,
x6Ref
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x6Decl
[
0
],
x6Ref
);
VerifyModelForDeclarationPatternDuplicateInSameScope
(
model
,
x6Decl
[
1
]);
var
x7Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x7"
).
Single
();
var
x7Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x7"
).
ToArray
();
Assert
.
Equal
(
3
,
x7Ref
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x7Decl
,
x7Ref
[
0
]);
VerifyNotInScope
(
model
,
x7Ref
[
1
]);
VerifyNotInScope
(
model
,
x7Ref
[
2
]);
}
[
Fact
]
public
void
ScopeOfPatternVariables_ConstructorInitializers_02
()
{
var
source
=
@"
public class X : Y
{
public static void Main()
{
}
X(byte x)
: base(3 is int x3 && x3 > 0)
{}
X(sbyte x)
: base(x4 && 4 is int x4)
{}
X(short x)
: base(51 is int x5 &&
52 is int x5 &&
x5 > 0)
{}
X(ushort x)
: base(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
{}
X(int x)
: base(7 is int x7 && x7 > 0)
{}
X(uint x)
: base(x7, 2)
{}
void Test73() { Dummy(x7, 3); }
bool Dummy(params object[] x) {return true;}
}
public class Y
{
public Y(params object[] x) {}
}
"
;
var
compilation
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
DebugExe
,
parseOptions
:
patternParseOptions
);
compilation
.
VerifyDiagnostics
(
// (13,16): error CS0841: Cannot use local variable 'x4' before it is declared
// : base(x4 && 4 is int x4)
Diagnostic
(
ErrorCode
.
ERR_VariableUsedBeforeDeclaration
,
"x4"
).
WithArguments
(
"x4"
).
WithLocation
(
13
,
16
),
// (18,26): error CS0128: A local variable named 'x5' is already defined in this scope
// 52 is int x5 &&
Diagnostic
(
ErrorCode
.
ERR_LocalDuplicate
,
"x5"
).
WithArguments
(
"x5"
).
WithLocation
(
18
,
26
),
// (23,48): error CS0128: A local variable named 'x6' is already defined in this scope
// : base(6 is int x6 && x6 > 0, 6 is int x6 && x6 > 0)
Diagnostic
(
ErrorCode
.
ERR_LocalDuplicate
,
"x6"
).
WithArguments
(
"x6"
).
WithLocation
(
23
,
48
),
// (30,16): error CS0103: The name 'x7' does not exist in the current context
// : base(x7, 2)
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x7"
).
WithArguments
(
"x7"
).
WithLocation
(
30
,
16
),
// (32,27): error CS0103: The name 'x7' does not exist in the current context
// void Test73() { Dummy(x7, 3); }
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x7"
).
WithArguments
(
"x7"
).
WithLocation
(
32
,
27
)
);
var
tree
=
compilation
.
SyntaxTrees
.
Single
();
var
model
=
compilation
.
GetSemanticModel
(
tree
);
var
x3Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x3"
).
Single
();
var
x3Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x3"
).
Single
();
VerifyModelForDeclarationPattern
(
model
,
x3Decl
,
x3Ref
);
var
x4Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x4"
).
Single
();
var
x4Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x4"
).
Single
();
VerifyModelForDeclarationPattern
(
model
,
x4Decl
,
x4Ref
);
var
x5Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x5"
).
ToArray
();
var
x5Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x5"
).
Single
();
Assert
.
Equal
(
2
,
x5Decl
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x5Decl
[
0
],
x5Ref
);
VerifyModelForDeclarationPatternDuplicateInSameScope
(
model
,
x5Decl
[
1
]);
var
x6Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x6"
).
ToArray
();
var
x6Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x6"
).
ToArray
();
Assert
.
Equal
(
2
,
x6Decl
.
Length
);
Assert
.
Equal
(
2
,
x6Ref
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x6Decl
[
0
],
x6Ref
);
VerifyModelForDeclarationPatternDuplicateInSameScope
(
model
,
x6Decl
[
1
]);
var
x7Decl
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
DeclarationPatternSyntax
>().
Where
(
p
=>
p
.
Identifier
.
ValueText
==
"x7"
).
Single
();
var
x7Ref
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
IdentifierNameSyntax
>().
Where
(
id
=>
id
.
Identifier
.
ValueText
==
"x7"
).
ToArray
();
Assert
.
Equal
(
3
,
x7Ref
.
Length
);
VerifyModelForDeclarationPattern
(
model
,
x7Decl
,
x7Ref
[
0
]);
VerifyNotInScope
(
model
,
x7Ref
[
1
]);
VerifyNotInScope
(
model
,
x7Ref
[
2
]);
}
[
Fact
]
public
void
ScopeOfPatternVariables_ConstructorInitializers_03
()
{
var
source
=
@"using System;
public class X
{
public static void Main()
{
new D(1);
new D(10);
new D(1.2);
}
}
class D
{
public D(object o) : this(o is int x && x >= 5)
{
Console.WriteLine(x);
}
public D(bool b) { Console.WriteLine(b); }
}
"
;
var
compilation
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
DebugExe
,
parseOptions
:
patternParseOptions
);
compilation
.
VerifyDiagnostics
(
// (15,27): error CS0103: The name 'x' does not exist in the current context
// Console.WriteLine(x);
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x"
).
WithArguments
(
"x"
).
WithLocation
(
15
,
27
)
);
}
[
Fact
]
public
void
ScopeOfPatternVariables_ConstructorInitializers_04
()
{
var
source
=
@"using System;
public class X
{
public static void Main()
{
new D(1);
new D(10);
new D(1.2);
}
}
class D : C
{
public D(object o) : base(o is int x && x >= 5)
{
Console.WriteLine(x);
}
}
class C
{
public C(bool b) { Console.WriteLine(b); }
}
"
;
var
compilation
=
CreateCompilationWithMscorlib45
(
source
,
options
:
TestOptions
.
DebugExe
,
parseOptions
:
patternParseOptions
);
compilation
.
VerifyDiagnostics
(
// (15,27): error CS0103: The name 'x' does not exist in the current context
// Console.WriteLine(x);
Diagnostic
(
ErrorCode
.
ERR_NameNotInContext
,
"x"
).
WithArguments
(
"x"
).
WithLocation
(
15
,
27
)
);
}
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录