Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
cd10095f
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,发现更多精彩内容 >>
提交
cd10095f
编写于
4月 16, 2018
作者:
N
Neme12
提交者:
Julien Couvreur
4月 16, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix for UseDeconstruction with default literal (#26140)
Merged on behalf of @Neme12. Thanks
上级
5e1c3344
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
43 addition
and
8 deletion
+43
-8
src/EditorFeatures/CSharpTest/UseDeconstruction/UseDeconstructionTests.cs
...es/CSharpTest/UseDeconstruction/UseDeconstructionTests.cs
+24
-1
src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs
...construction/CSharpUseDeconstructionDiagnosticAnalyzer.cs
+19
-7
未找到文件。
src/EditorFeatures/CSharpTest/UseDeconstruction/UseDeconstructionTests.cs
浏览文件 @
cd10095f
...
...
@@ -2,6 +2,7 @@
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.CSharp
;
using
Microsoft.CodeAnalysis.CSharp.UseDeconstruction
;
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics
;
...
...
@@ -481,7 +482,7 @@ void M()
(string name, int age) [|person|] = default;
Console.WriteLine(person.name + "" "" + person.age);
}
}"
);
}"
,
new
TestParameters
(
parseOptions
:
CSharpParseOptions
.
Default
.
WithLanguageVersion
(
LanguageVersion
.
CSharp7_1
))
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseDeconstruction
)]
...
...
@@ -610,6 +611,28 @@ void M()
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseDeconstruction
)]
public
async
Task
TestWithTupleLiteralConversion
()
{
await
TestInRegularAndScriptAsync
(
@"class C
{
void M()
{
(object name, double age) [|person|] = (null, 0);
Console.WriteLine(person.name + "" "" + person.age);
}
}"
,
@"class C
{
void M()
{
(object name, double age) = (null, 0);
Console.WriteLine(name + "" "" + age);
}
}"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseDeconstruction
)]
public
async
Task
TestWithImplicitTupleConversion
()
{
...
...
src/Features/CSharp/Portable/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs
浏览文件 @
cd10095f
...
...
@@ -125,10 +125,10 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
var
local
=
(
ILocalSymbol
)
semanticModel
.
GetDeclaredSymbol
(
declarator
,
cancellationToken
);
var
expressionType
=
semanticModel
.
GetTypeInfo
(
declarator
.
Initializer
.
Value
,
cancellationToken
).
Type
;
var
initializerConversion
=
semanticModel
.
GetConversion
(
declarator
.
Initializer
.
Value
,
cancellationToken
)
;
return
TryAnalyze
(
semanticModel
,
local
,
variableDeclaration
.
Type
,
declarator
.
Identifier
,
expressionType
,
semanticModel
,
local
,
variableDeclaration
.
Type
,
declarator
.
Identifier
,
initializerConversion
,
variableDeclaration
.
Parent
.
Parent
,
out
tupleType
,
out
memberAccessExpressions
,
cancellationToken
);
}
...
...
@@ -140,10 +140,10 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
CancellationToken
cancellationToken
)
{
var
local
=
semanticModel
.
GetDeclaredSymbol
(
forEachStatement
,
cancellationToken
);
var
element
Type
=
semanticModel
.
GetForEachStatementInfo
(
forEachStatement
).
ElementType
;
var
element
Conversion
=
semanticModel
.
GetForEachStatementInfo
(
forEachStatement
).
ElementConversion
;
return
TryAnalyze
(
semanticModel
,
local
,
forEachStatement
.
Type
,
forEachStatement
.
Identifier
,
element
Type
,
semanticModel
,
local
,
forEachStatement
.
Type
,
forEachStatement
.
Identifier
,
element
Conversion
,
forEachStatement
,
out
tupleType
,
out
memberAccessExpressions
,
cancellationToken
);
}
...
...
@@ -152,7 +152,7 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
ILocalSymbol
local
,
TypeSyntax
typeNode
,
SyntaxToken
identifier
,
ITypeSymbol
initializerType
,
Conversion
conversion
,
SyntaxNode
searchScope
,
out
INamedTypeSymbol
tupleType
,
out
ImmutableArray
<
MemberAccessExpressionSyntax
>
memberAccessExpressions
,
...
...
@@ -171,9 +171,21 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
return
false
;
}
if
(
conversion
.
Exists
&&
!
conversion
.
IsIdentity
&&
!
conversion
.
IsTupleConversion
&&
!
conversion
.
IsTupleLiteralConversion
)
{
// If there is any other conversion, we bail out because the source type might not be a tuple
// or it is a tuple but only thanks to target type inference, which won't occur in a deconstruction.
// Interesting case that illustrates this is initialization with a default literal:
// (int a, int b) t = default;
// This is classified as conversion.IsNullLiteral.
return
false
;
}
var
type
=
semanticModel
.
GetTypeInfo
(
typeNode
,
cancellationToken
).
Type
;
if
(
type
==
null
||
!
type
.
IsTupleType
||
initializerType
==
null
||
!
initializerType
.
IsTupleType
)
if
(
type
==
null
||
!
type
.
IsTupleType
)
{
return
false
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录