Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
14ec71b1
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,发现更多精彩内容 >>
未验证
提交
14ec71b1
编写于
2月 08, 2018
作者:
J
Julien Couvreur
提交者:
GitHub
2月 08, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Create missing binder for local function with both block and expression bodies (#24651)
上级
76853730
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
76 addition
and
45 deletion
+76
-45
src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs
src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs
+50
-45
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs
...ers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs
+26
-0
未找到文件。
src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs
浏览文件 @
14ec71b1
...
...
@@ -52,9 +52,9 @@ private void Visit(CSharpSyntaxNode syntax, Binder enclosing)
// This may change if the language is extended to allow iterator lambdas, in which case the lambda would also be returned.
// (lambdas currently throw a diagnostic in WithLambdaParametersBinder.GetIteratorElementType when a yield is used within them)
public
static
SmallDictionary
<
SyntaxNode
,
Binder
>
BuildMap
(
Symbol
containingMemberOrLambda
,
SyntaxNode
syntax
,
Binder
enclosing
,
Symbol
containingMemberOrLambda
,
SyntaxNode
syntax
,
Binder
enclosing
,
ArrayBuilder
<
SyntaxNode
>
methodsWithYields
,
Action
<
Binder
,
SyntaxNode
>
binderUpdatedHandler
=
null
)
{
...
...
@@ -195,12 +195,54 @@ public override void VisitParenthesizedLambdaExpression(ParenthesizedLambdaExpre
public
override
void
VisitLocalFunctionStatement
(
LocalFunctionStatementSyntax
node
)
{
var
body
=
(
CSharpSyntaxNode
)
node
.
Body
??
node
.
ExpressionBody
;
bool
oldSawYield
=
_sawYield
;
Symbol
oldMethod
=
_containingMemberOrLambda
;
Binder
binder
=
_enclosing
;
LocalFunctionSymbol
match
=
FindLocalFunction
(
node
,
_enclosing
);
if
((
object
)
match
!=
null
)
{
_containingMemberOrLambda
=
match
;
binder
=
match
.
IsGenericMethod
?
new
WithMethodTypeParametersBinder
(
match
,
_enclosing
)
:
_enclosing
;
binder
=
binder
.
WithUnsafeRegionIfNecessary
(
node
.
Modifiers
);
binder
=
new
InMethodBinder
(
match
,
binder
);
}
BlockSyntax
blockBody
=
node
.
Body
;
if
(
blockBody
!=
null
)
{
_sawYield
=
false
;
Visit
(
blockBody
,
binder
);
if
(
_sawYield
)
{
_methodsWithYields
.
Add
(
blockBody
);
}
}
ArrowExpressionClauseSyntax
arrowBody
=
node
.
ExpressionBody
;
if
(
arrowBody
!=
null
)
{
_sawYield
=
false
;
Visit
(
arrowBody
,
binder
);
Debug
.
Assert
(!
_sawYield
);
}
_containingMemberOrLambda
=
oldMethod
;
_sawYield
=
oldSawYield
;
}
private
static
LocalFunctionSymbol
FindLocalFunction
(
LocalFunctionStatementSyntax
node
,
Binder
enclosing
)
{
LocalFunctionSymbol
match
=
null
;
// Don't use LookupLocalFunction because it recurses up the tree, as it
// should be defined in the directly enclosing block (see note below)
Binder
possibleScopeBinder
=
_
enclosing
;
Binder
possibleScopeBinder
=
enclosing
;
while
(
possibleScopeBinder
!=
null
&&
!
possibleScopeBinder
.
IsLocalFunctionsScopeBinder
)
{
possibleScopeBinder
=
possibleScopeBinder
.
Next
;
...
...
@@ -217,44 +259,7 @@ public override void VisitLocalFunctionStatement(LocalFunctionStatementSyntax no
}
}
bool
oldSawYield
=
_sawYield
;
_sawYield
=
false
;
if
(
match
!=
null
)
{
var
oldMethod
=
_containingMemberOrLambda
;
_containingMemberOrLambda
=
match
;
if
(
body
!=
null
)
{
Binder
binder
=
match
.
IsGenericMethod
?
new
WithMethodTypeParametersBinder
(
match
,
_enclosing
)
:
_enclosing
;
binder
=
binder
.
WithUnsafeRegionIfNecessary
(
node
.
Modifiers
);
Visit
(
body
,
new
InMethodBinder
(
match
,
binder
));
}
_containingMemberOrLambda
=
oldMethod
;
}
else
{
// The enclosing block should have found this node and created a LocalFunctionMethodSymbol
// The code that does so is in LocalScopeBinder.BuildLocalFunctions
if
(
body
!=
null
)
{
// do our best to attempt to bind
Visit
(
body
);
}
}
if
(
_sawYield
)
{
_methodsWithYields
.
Add
(
body
);
}
_sawYield
=
oldSawYield
;
return
match
;
}
public
override
void
VisitArrowExpressionClause
(
ArrowExpressionClauseSyntax
node
)
...
...
@@ -402,7 +407,7 @@ public override void VisitForStatement(ForStatementSyntax node)
foreach
(
var
initializer
in
node
.
Initializers
)
{
Visit
(
initializer
,
binder
);
}
}
}
ExpressionSyntax
condition
=
node
.
Condition
;
...
...
@@ -717,7 +722,7 @@ private void AddToMap(SyntaxNode node, Binder binder)
{
// If this ever breaks, make sure that all callers of
// CanHaveAssociatedLocalBinder are in sync.
Debug
.
Assert
(
node
.
CanHaveAssociatedLocalBinder
()
||
Debug
.
Assert
(
node
.
CanHaveAssociatedLocalBinder
()
||
(
node
==
_root
&&
node
is
ExpressionSyntax
));
// Cleverness: for some nodes (e.g. lock), we want to specify a binder flag that
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs
浏览文件 @
14ec71b1
using
Microsoft.CodeAnalysis.CSharp.Symbols
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.CSharp.Test.Utilities
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Roslyn.Test.Utilities
;
using
System
;
using
System.Linq
;
using
Xunit
;
namespace
Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
...
...
@@ -73,6 +75,30 @@ public class E
0"
);
}
[
Fact
]
[
WorkItem
(
24647
,
"https://github.com/dotnet/roslyn/issues/24647"
)]
public
void
Repro24647
()
{
var
comp
=
CreateStandardCompilation
(
@"
class Program
{
static void Main(string[] args)
{
void local() { } => new object();
}
}"
);
var
tree
=
comp
.
SyntaxTrees
.
Single
();
var
model
=
comp
.
GetSemanticModel
(
tree
,
ignoreAccessibility
:
false
);
var
creation
=
tree
.
GetRoot
().
DescendantNodes
().
OfType
<
ObjectCreationExpressionSyntax
>().
Single
();
var
operation
=
model
.
GetOperation
(
creation
);
Assert
.
Null
(
operation
);
// we didn't bind the expression body, but should. See issue https://github.com/dotnet/roslyn/issues/24650
var
info
=
model
.
GetTypeInfo
(
creation
);
Assert
.
Equal
(
"System.Object"
,
info
.
Type
.
ToTestDisplayString
());
Assert
.
Equal
(
"System.Object"
,
info
.
ConvertedType
.
ToTestDisplayString
());
}
[
Fact
]
[
WorkItem
(
22027
,
"https://github.com/dotnet/roslyn/issues/22027"
)]
public
void
Repro22027
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录