Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
0178773e
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,发现更多精彩内容 >>
提交
0178773e
编写于
12月 05, 2014
作者:
J
jmarolf
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
GFU in dictionary initializers (changeset 1381842)
上级
11e6790c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
103 addition
and
78 deletion
+103
-78
Src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs
.../CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs
+48
-56
Src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
...nguageServices/CSharpTypeInferenceService.TypeInferrer.cs
+55
-22
未找到文件。
Src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs
浏览文件 @
0178773e
...
...
@@ -461,60 +461,57 @@ private static bool CanReplace(ISymbol symbol)
}
}
// Technically, you could introduce an LValue for "Foo" in "Foo()" even if "Foo" binds
// to a method. (i.e. by assigning to a Func<...> type). However, this is so contrived
// and none of the features that use this extension consider this replaceable.
if
(
expression
.
Parent
is
InvocationExpressionSyntax
)
switch
(
expression
.
Parent
.
CSharpKind
())
{
if
(
expression
.
IsKind
(
SyntaxKind
.
IdentifierName
)
||
expression
is
MemberAccessExpressionSyntax
)
{
// If it looks like a method then we don't allow it to be replaced if it is a
// method (or if it doesn't bind).
case
SyntaxKind
.
InvocationExpression
:
// Technically, you could introduce an LValue for "Foo" in "Foo()" even if "Foo" binds
// to a method. (i.e. by assigning to a Func<...> type). However, this is so contrived
// and none of the features that use this extension consider this replaceable.
if
(
expression
.
IsKind
(
SyntaxKind
.
IdentifierName
)
||
expression
is
MemberAccessExpressionSyntax
)
{
// If it looks like a method then we don't allow it to be replaced if it is a
// method (or if it doesn't bind).
var
symbolInfo
=
semanticModel
.
GetSymbolInfo
(
expression
,
cancellationToken
);
return
symbolInfo
.
GetBestOrAllSymbols
().
Any
()
&&
!
symbolInfo
.
GetBestOrAllSymbols
().
Any
(
s
=>
s
is
IMethodSymbol
);
}
else
{
// It doesn't look like a method, we allow this to be replaced.
var
symbolInfo
=
semanticModel
.
GetSymbolInfo
(
expression
,
cancellationToken
);
return
symbolInfo
.
GetBestOrAllSymbols
().
Any
()
&&
!
symbolInfo
.
GetBestOrAllSymbols
().
Any
(
s
=>
s
is
IMethodSymbol
);
}
else
{
// It doesn't look like a method, we allow this to be replaced.
return
true
;
}
case
SyntaxKind
.
IsExpression
:
case
SyntaxKind
.
AsExpression
:
// Can't introduce a variable for the type portion of an is/as check.
var
isOrAsExpression
=
(
BinaryExpressionSyntax
)
expression
.
Parent
;
return
expression
==
isOrAsExpression
.
Left
;
case
SyntaxKind
.
EqualsValueClause
:
case
SyntaxKind
.
ExpressionStatement
:
case
SyntaxKind
.
ArrayInitializerExpression
:
case
SyntaxKind
.
CollectionInitializerExpression
:
case
SyntaxKind
.
ConditionalAccessExpression
:
case
SyntaxKind
.
Argument
:
case
SyntaxKind
.
AttributeArgument
:
case
SyntaxKind
.
AnonymousObjectMemberDeclarator
:
case
SyntaxKind
.
ArrowExpressionClause
:
case
SyntaxKind
.
AwaitExpression
:
case
SyntaxKind
.
ReturnStatement
:
case
SyntaxKind
.
YieldReturnStatement
:
case
SyntaxKind
.
ParenthesizedLambdaExpression
:
case
SyntaxKind
.
SimpleLambdaExpression
:
case
SyntaxKind
.
ParenthesizedExpression
:
case
SyntaxKind
.
ArrayRankSpecifier
:
case
SyntaxKind
.
ConditionalExpression
:
case
SyntaxKind
.
IfStatement
:
case
SyntaxKind
.
CatchFilterClause
:
case
SyntaxKind
.
WhileStatement
:
case
SyntaxKind
.
DoStatement
:
case
SyntaxKind
.
ThrowStatement
:
case
SyntaxKind
.
SwitchStatement
:
case
SyntaxKind
.
InterpolatedStringInsert
:
case
SyntaxKind
.
ComplexElementInitializerExpression
:
// Direct parent kind checks.
return
true
;
}
}
// Direct parent kind checks.
if
(
expression
.
IsParentKind
(
SyntaxKind
.
ExpressionStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
EqualsValueClause
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ArrayInitializerExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
CollectionInitializerExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ConditionalAccessExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
Argument
)
||
expression
.
IsParentKind
(
SyntaxKind
.
AttributeArgument
)
||
expression
.
IsParentKind
(
SyntaxKind
.
AnonymousObjectMemberDeclarator
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ArrowExpressionClause
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ReturnStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
YieldReturnStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ParenthesizedLambdaExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
SimpleLambdaExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ParenthesizedExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ArrayRankSpecifier
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ConditionalExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
IfStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
CatchFilterClause
)
||
expression
.
IsParentKind
(
SyntaxKind
.
WhileStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
DoStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
ThrowStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
SwitchStatement
)
||
expression
.
IsParentKind
(
SyntaxKind
.
InterpolatedStringInsert
))
{
return
true
;
}
if
(
expression
.
IsParentKind
(
SyntaxKind
.
IsExpression
)
||
expression
.
IsParentKind
(
SyntaxKind
.
AsExpression
))
{
// Can't introduce a variable for the type portion of an is/as check.
var
isOrAsExpression
=
(
BinaryExpressionSyntax
)
expression
.
Parent
;
return
expression
==
isOrAsExpression
.
Left
;
}
if
(
expression
.
Parent
is
PrefixUnaryExpressionSyntax
)
...
...
@@ -525,11 +522,6 @@ private static bool CanReplace(ISymbol symbol)
}
}
if
(
expression
.
Parent
is
AwaitExpressionSyntax
)
{
return
true
;
}
var
parentNonExpression
=
expression
.
GetAncestors
().
SkipWhile
(
n
=>
n
is
ExpressionSyntax
).
FirstOrDefault
();
var
topExpression
=
expression
;
while
(
topExpression
.
Parent
is
TypeSyntax
)
...
...
Src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs
浏览文件 @
0178773e
...
...
@@ -354,6 +354,22 @@ private IEnumerable<ITypeSymbol> InferTypeInArgument(ArgumentSyntax argument, Sy
}
}
if
(
argument
.
Parent
.
IsParentKind
(
SyntaxKind
.
ImplicitElementAccess
)
&&
argument
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
)
&&
argument
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectInitializerExpression
)
&&
argument
.
Parent
.
Parent
.
Parent
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
{
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
argument
.
Parent
.
Parent
.
Parent
.
Parent
.
Parent
;
var
types
=
GetTypes
(
objectCreation
);
if
(
types
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
return
types
.
OfType
<
INamedTypeSymbol
>().
SelectMany
(
t
=>
GetCollectionElementType
(
t
,
parameterIndex
:
0
));
}
}
return
SpecializedCollections
.
EmptyEnumerable
<
ITypeSymbol
>();
}
...
...
@@ -978,8 +994,8 @@ private IEnumerable<ITypeSymbol> InferTypeInPropertyDeclaration(PropertyDeclarat
Contract
.
Assert
(
propertyDeclaration
?.
Type
!=
null
,
"Property type should never be null"
);
var
typeInfo
=
this
.
semanticModel
.
GetTypeInfo
(
propertyDeclaration
.
Type
);
return
typeInfo
.
Type
!=
null
?
SpecializedCollections
.
SingletonEnumerable
(
typeInfo
.
Type
)
return
typeInfo
.
Type
!=
null
?
SpecializedCollections
.
SingletonEnumerable
(
typeInfo
.
Type
)
:
SpecializedCollections
.
EmptyEnumerable
<
ITypeSymbol
>();
}
...
...
@@ -1116,6 +1132,13 @@ private IEnumerable<ITypeSymbol> InferTypeInIfStatement(IfStatementSyntax ifStat
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ArrayCreationExpression
))
{
// new int[] { Foo() }
var
symbols
=
this
.
semanticModel
.
GetCollectionInitializerSymbolInfo
(
initializerExpression
).
GetAllSymbols
();
if
(
symbols
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
return
symbols
.
OfType
<
INamedTypeSymbol
>();
}
var
arrayCreation
=
(
ArrayCreationExpressionSyntax
)
initializerExpression
.
Parent
;
IEnumerable
<
ITypeSymbol
>
types
=
GetTypes
(
arrayCreation
);
...
...
@@ -1127,21 +1150,30 @@ private IEnumerable<ITypeSymbol> InferTypeInIfStatement(IfStatementSyntax ifStat
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
{
// new List<T> { Foo() }
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
initializerExpression
.
Parent
;
IEnumerable
<
ITypeSymbol
>
types
=
GetTypes
(
objectCreation
);
if
(
types
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
return
types
.
OfType
<
INamedTypeSymbol
>().
SelectMany
(
t
=>
GetCollectionElementType
(
t
,
parameterIndex
:
0
,
parameterCount
:
1
));
GetCollectionElementType
(
t
,
parameterIndex
:
0
));
}
}
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ComplexElementInitializerExpression
)
&&
initializerExpression
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
else
if
((
initializerExpression
.
IsParentKind
(
SyntaxKind
.
ComplexElementInitializerExpression
)
&&
initializerExpression
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
))
||
(
initializerExpression
.
IsKind
(
SyntaxKind
.
ComplexElementInitializerExpression
)
&&
initializerExpression
.
IsParentKind
(
SyntaxKind
.
CollectionInitializerExpression
)
&&
initializerExpression
.
Parent
.
IsParentKind
(
SyntaxKind
.
ObjectCreationExpression
)))
{
// new Dictionary<K,V> { { Foo(), ... } }
var
objectCreation
=
(
ObjectCreationExpressionSyntax
)
initializerExpression
.
Parent
.
Parent
;
var
symbols
=
this
.
semanticModel
.
GetCollectionInitializerSymbolInfo
(
initializerExpression
).
GetAllSymbols
();
if
(
symbols
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
return
symbols
.
OfType
<
INamedTypeSymbol
>();
}
IEnumerable
<
ITypeSymbol
>
types
=
GetTypes
(
objectCreation
);
...
...
@@ -1153,13 +1185,19 @@ private IEnumerable<ITypeSymbol> InferTypeInIfStatement(IfStatementSyntax ifStat
return
types
.
OfType
<
INamedTypeSymbol
>().
SelectMany
(
t
=>
GetCollectionElementType
(
t
,
parameterIndex
:
parameterIndex
,
parameterCount
:
initializerExpression
.
Expressions
.
Count
));
parameterIndex
:
parameterIndex
));
}
}
else
if
(
initializerExpression
.
IsParentKind
(
SyntaxKind
.
SimpleAssignmentExpression
))
{
// new Foo { a = { Foo() } }
var
symbols
=
this
.
semanticModel
.
GetCollectionInitializerSymbolInfo
(
initializerExpression
).
GetAllSymbols
();
if
(
symbols
.
Any
(
t
=>
t
is
INamedTypeSymbol
))
{
return
symbols
.
OfType
<
INamedTypeSymbol
>();
}
var
assignExpression
=
(
AssignmentExpressionSyntax
)
initializerExpression
.
Parent
;
IEnumerable
<
ITypeSymbol
>
types
=
GetTypes
(
assignExpression
.
Left
);
...
...
@@ -1171,8 +1209,7 @@ private IEnumerable<ITypeSymbol> InferTypeInIfStatement(IfStatementSyntax ifStat
return
types
.
OfType
<
INamedTypeSymbol
>().
SelectMany
(
t
=>
GetCollectionElementType
(
t
,
parameterIndex
:
parameterIndex
,
parameterCount
:
initializerExpression
.
Expressions
.
Count
));
parameterIndex
:
parameterIndex
));
}
}
...
...
@@ -1570,21 +1607,17 @@ private IEnumerable<ITypeSymbol> InferTypeInWhileStatement(WhileStatementSyntax
return
SpecializedCollections
.
SingletonEnumerable
(
this
.
Compilation
.
GetSpecialType
(
SpecialType
.
System_Boolean
));
}
private
IEnumerable
<
ITypeSymbol
>
GetCollectionElementType
(
INamedTypeSymbol
type
,
int
parameterIndex
,
int
parameterCount
)
private
IEnumerable
<
ITypeSymbol
>
GetCollectionElementType
(
INamedTypeSymbol
type
,
int
parameterIndex
)
{
if
(
type
!=
null
)
{
// TODO(cyrusn): Move to use matt's Lookup method once he's checked in.
#if false
var
addMethods
=
this
.
Binding
.
Lookup
(
leftType
,
"Add"
).
OfType
<
MethodSymbol
>();
var
method
=
addMethods
.
Where
(
m
=>
!
m
.
IsStatic
)
.
Where
(
m
=>
m
.
Arity
==
0
)
.
Where
(
m
=>
m
.
Parameters
.
Count
==
parameterCount
).
FirstOrDefault
();
if
(
method
!=
null
)
{
return
method
.
Parameters
[
parameterIndex
].
Type
;
}
#endif
var
parameters
=
type
.
GetAllTypeArguments
();
var
elementType
=
parameters
.
ElementAtOrDefault
(
parameterIndex
);
if
(
elementType
!=
null
)
{
return
SpecializedCollections
.
SingletonCollection
(
elementType
);
}
}
return
SpecializedCollections
.
EmptyEnumerable
<
ITypeSymbol
>();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录