Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
fc3724ba
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,发现更多精彩内容 >>
提交
fc3724ba
编写于
3月 22, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix genarate-equals failing in partial types.
上级
423c52f2
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
189 addition
and
15 deletion
+189
-15
src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
...omMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
+172
-0
src/EditorFeatures/VisualBasicTest/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.vb
...omMembers/GenerateEqualsAndGetHashCodeFromMembersTests.vb
+0
-2
src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs
...HashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs
+17
-13
未找到文件。
src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
浏览文件 @
fc3724ba
...
@@ -2695,5 +2695,177 @@ public override bool Equals(object? obj)
...
@@ -2695,5 +2695,177 @@ public override bool Equals(object? obj)
optionsCallback
:
options
=>
EnableOption
(
options
,
GenerateOperatorsId
),
optionsCallback
:
options
=>
EnableOption
(
options
,
GenerateOperatorsId
),
parameters
:
CSharpLatestImplicit
);
parameters
:
CSharpLatestImplicit
);
}
}
[
WorkItem
(
42574
,
"https://github.com/dotnet/roslyn/issues/42574"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateEqualsAndGetHashCode
)]
public
async
Task
TestPartialTypes1
()
{
await
TestWithPickMembersDialogAsync
(
@"<Workspace>
<Project Language=""C#"" CommonReferences=""true"">
<Document>
partial class Goo
{
int bar;
[||]
}
</Document>
<Document>
partial class Goo
{
}
</Document>
</Project>
</Workspace>"
,
@"
partial class Goo
{
int bar;
public override bool Equals(object obj)
{
return obj is Goo goo &&
bar == goo.bar;
}
public override int GetHashCode()
{
return 999205674 + bar.GetHashCode();
}
}
"
,
chosenSymbols
:
new
[]
{
"bar"
},
index
:
1
);
}
[
WorkItem
(
42574
,
"https://github.com/dotnet/roslyn/issues/42574"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateEqualsAndGetHashCode
)]
public
async
Task
TestPartialTypes2
()
{
await
TestWithPickMembersDialogAsync
(
@"<Workspace>
<Project Language=""C#"" CommonReferences=""true"">
<Document>
partial class Goo
{
int bar;
}
</Document>
<Document>
partial class Goo
{
[||]
}
</Document>
</Project>
</Workspace>"
,
@"
partial class Goo
{
public override bool Equals(object obj)
{
return obj is Goo goo &&
bar == goo.bar;
}
public override int GetHashCode()
{
return 999205674 + bar.GetHashCode();
}
}
"
,
chosenSymbols
:
new
[]
{
"bar"
},
index
:
1
);
}
[
WorkItem
(
42574
,
"https://github.com/dotnet/roslyn/issues/42574"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateEqualsAndGetHashCode
)]
public
async
Task
TestPartialTypes3
()
{
await
TestWithPickMembersDialogAsync
(
@"<Workspace>
<Project Language=""C#"" CommonReferences=""true"">
<Document>
partial class Goo
{
[||]
}
</Document>
<Document>
partial class Goo
{
int bar;
}
</Document>
</Project>
</Workspace>"
,
@"
partial class Goo
{
public override bool Equals(object obj)
{
return obj is Goo goo &&
bar == goo.bar;
}
public override int GetHashCode()
{
return 999205674 + bar.GetHashCode();
}
}
"
,
chosenSymbols
:
new
[]
{
"bar"
},
index
:
1
);
}
[
WorkItem
(
42574
,
"https://github.com/dotnet/roslyn/issues/42574"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateEqualsAndGetHashCode
)]
public
async
Task
TestPartialTypes4
()
{
await
TestWithPickMembersDialogAsync
(
@"<Workspace>
<Project Language=""C#"" CommonReferences=""true"">
<Document>
partial class Goo
{
}
</Document>
<Document>
partial class Goo
{
int bar;
[||]
}
</Document>
</Project>
</Workspace>"
,
@"
partial class Goo
{
int bar;
public override bool Equals(object obj)
{
return obj is Goo goo &&
bar == goo.bar;
}
public override int GetHashCode()
{
return 999205674 + bar.GetHashCode();
}
}
"
,
chosenSymbols
:
new
[]
{
"bar"
},
index
:
1
);
}
}
}
}
}
src/EditorFeatures/VisualBasicTest/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.vb
浏览文件 @
fc3724ba
...
@@ -2,12 +2,10 @@
...
@@ -2,12 +2,10 @@
' The .NET Foundation licenses this file to you under the MIT license.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
' See the LICENSE file in the project root for more information.
Imports
System.Collections.Immutable
Imports
Microsoft.CodeAnalysis.CodeRefactorings
Imports
Microsoft.CodeAnalysis.CodeRefactorings
Imports
Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings
Imports
Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings
Imports
Microsoft.CodeAnalysis.GenerateEqualsAndGetHashCodeFromMembers
Imports
Microsoft.CodeAnalysis.GenerateEqualsAndGetHashCodeFromMembers
Imports
Microsoft.CodeAnalysis.PickMembers
Imports
Microsoft.CodeAnalysis.PickMembers
Imports
Microsoft.CodeAnalysis.Text
Namespace
Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.GenerateConstructorFromMembers
Namespace
Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.GenerateConstructorFromMembers
Public
Class
GenerateEqualsAndGetHashCodeFromMembersTests
Public
Class
GenerateEqualsAndGetHashCodeFromMembersTests
...
...
src/Features/Core/Portable/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeAction.cs
浏览文件 @
fc3724ba
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// See the LICENSE file in the project root for more information.
#
nullable
enable
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Collections.Immutable
;
...
@@ -88,7 +90,7 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
...
@@ -88,7 +90,7 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
if
(
constructedTypeToImplement
is
object
)
if
(
constructedTypeToImplement
is
object
)
{
{
var
generator
=
_document
.
GetLanguageService
<
SyntaxGenerator
>();
var
generator
=
_document
.
Get
Required
LanguageService
<
SyntaxGenerator
>();
newType
=
generator
.
AddInterfaceType
(
newType
,
newType
=
generator
.
AddInterfaceType
(
newType
,
generator
.
TypeExpression
(
constructedTypeToImplement
));
generator
.
TypeExpression
(
constructedTypeToImplement
));
...
@@ -97,20 +99,22 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
...
@@ -97,20 +99,22 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
var
newDocument
=
await
UpdateDocumentAndAddImportsAsync
(
var
newDocument
=
await
UpdateDocumentAndAddImportsAsync
(
oldType
,
newType
,
cancellationToken
).
ConfigureAwait
(
false
);
oldType
,
newType
,
cancellationToken
).
ConfigureAwait
(
false
);
var
service
=
_document
.
GetLanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
var
service
=
_document
.
Get
Required
LanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
var
formattedDocument
=
await
service
.
FormatDocumentAsync
(
var
formattedDocument
=
await
service
.
FormatDocumentAsync
(
newDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
newDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
return
formattedDocument
;
return
formattedDocument
;
}
}
private
async
Task
<
INamedTypeSymbol
>
GetConstructedTypeToImplementAsync
(
CancellationToken
cancellationToken
)
private
async
Task
<
INamedTypeSymbol
?
>
GetConstructedTypeToImplementAsync
(
CancellationToken
cancellationToken
)
{
{
if
(!
_implementIEquatable
)
if
(!
_implementIEquatable
)
return
null
;
return
null
;
var
semanticModel
=
await
_document
.
GetSemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
semanticModel
=
await
_document
.
Get
Required
SemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
equatableType
=
semanticModel
.
Compilation
.
GetTypeByMetadataName
(
typeof
(
IEquatable
<>).
FullName
);
var
equatableType
=
semanticModel
.
Compilation
.
GetTypeByMetadataName
(
typeof
(
IEquatable
<>).
FullName
);
if
(
equatableType
==
null
)
return
null
;
var
useNullableTypeArgument
=
var
useNullableTypeArgument
=
!
_containingType
.
IsValueType
!
_containingType
.
IsValueType
...
@@ -123,7 +127,7 @@ private async Task<INamedTypeSymbol> GetConstructedTypeToImplementAsync(Cancella
...
@@ -123,7 +127,7 @@ private async Task<INamedTypeSymbol> GetConstructedTypeToImplementAsync(Cancella
private
async
Task
<
Document
>
UpdateDocumentAndAddImportsAsync
(
SyntaxNode
oldType
,
SyntaxNode
newType
,
CancellationToken
cancellationToken
)
private
async
Task
<
Document
>
UpdateDocumentAndAddImportsAsync
(
SyntaxNode
oldType
,
SyntaxNode
newType
,
CancellationToken
cancellationToken
)
{
{
var
oldRoot
=
await
_document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
oldRoot
=
await
_document
.
Get
Required
SyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
newDocument
=
_document
.
WithSyntaxRoot
(
var
newDocument
=
_document
.
WithSyntaxRoot
(
oldRoot
.
ReplaceNode
(
oldType
,
newType
));
oldRoot
.
ReplaceNode
(
oldType
,
newType
));
newDocument
=
await
ImportAdder
.
AddImportsFromSymbolAnnotationAsync
(
newDocument
=
await
ImportAdder
.
AddImportsFromSymbolAnnotationAsync
(
...
@@ -137,12 +141,12 @@ private async Task<Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType
...
@@ -137,12 +141,12 @@ private async Task<Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType
CancellationToken
cancellationToken
)
CancellationToken
cancellationToken
)
{
{
var
workspace
=
_document
.
Project
.
Solution
.
Workspace
;
var
workspace
=
_document
.
Project
.
Solution
.
Workspace
;
var
syntaxTree
=
await
_document
.
GetSyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
syntaxTree
=
await
_document
.
Get
Required
SyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
declarationService
=
_document
.
GetLanguageService
<
ISymbolDeclarationService
>();
var
declarationService
=
_document
.
Get
Required
LanguageService
<
ISymbolDeclarationService
>();
var
typeDeclaration
=
declarationService
.
GetDeclarations
(
_containingType
)
var
typeDeclaration
=
declarationService
.
GetDeclarations
(
_containingType
)
.
Select
(
r
=>
r
.
GetSyntax
(
cancellationToken
))
.
Select
(
r
=>
r
.
GetSyntax
(
cancellationToken
))
.
First
(
s
=>
s
.
FullSpan
.
IntersectsWith
(
_textSpan
.
Start
));
.
First
(
s
=>
s
.
SyntaxTree
==
syntaxTree
&&
s
.
FullSpan
.
IntersectsWith
(
_textSpan
.
Start
));
var
newTypeDeclaration
=
CodeGenerator
.
AddMemberDeclarations
(
var
newTypeDeclaration
=
CodeGenerator
.
AddMemberDeclarations
(
typeDeclaration
,
methods
,
workspace
,
typeDeclaration
,
methods
,
workspace
,
...
@@ -153,9 +157,9 @@ private async Task<Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType
...
@@ -153,9 +157,9 @@ private async Task<Document> UpdateDocumentAndAddImportsAsync(SyntaxNode oldType
private
async
Task
AddOperatorsAsync
(
List
<
IMethodSymbol
>
members
,
CancellationToken
cancellationToken
)
private
async
Task
AddOperatorsAsync
(
List
<
IMethodSymbol
>
members
,
CancellationToken
cancellationToken
)
{
{
var
compilation
=
await
_document
.
Project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
compilation
=
await
_document
.
Project
.
Get
Required
CompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
generator
=
_document
.
GetLanguageService
<
SyntaxGenerator
>();
var
generator
=
_document
.
Get
Required
LanguageService
<
SyntaxGenerator
>();
// add nullable annotation to the parameter reference type, so that (in)equality operator implementations allow comparison against null
// add nullable annotation to the parameter reference type, so that (in)equality operator implementations allow comparison against null
var
parameters
=
ImmutableArray
.
Create
(
var
parameters
=
ImmutableArray
.
Create
(
...
@@ -210,13 +214,13 @@ private IMethodSymbol CreateInequalityOperator(Compilation compilation, SyntaxGe
...
@@ -210,13 +214,13 @@ private IMethodSymbol CreateInequalityOperator(Compilation compilation, SyntaxGe
private
Task
<
IMethodSymbol
>
CreateGetHashCodeMethodAsync
(
CancellationToken
cancellationToken
)
private
Task
<
IMethodSymbol
>
CreateGetHashCodeMethodAsync
(
CancellationToken
cancellationToken
)
{
{
var
service
=
_document
.
GetLanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
var
service
=
_document
.
Get
Required
LanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
return
service
.
GenerateGetHashCodeMethodAsync
(
_document
,
_containingType
,
_selectedMembers
,
cancellationToken
);
return
service
.
GenerateGetHashCodeMethodAsync
(
_document
,
_containingType
,
_selectedMembers
,
cancellationToken
);
}
}
private
Task
<
IMethodSymbol
>
CreateEqualsMethodAsync
(
CancellationToken
cancellationToken
)
private
Task
<
IMethodSymbol
>
CreateEqualsMethodAsync
(
CancellationToken
cancellationToken
)
{
{
var
service
=
_document
.
GetLanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
var
service
=
_document
.
Get
Required
LanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
return
_implementIEquatable
return
_implementIEquatable
?
service
.
GenerateEqualsMethodThroughIEquatableEqualsAsync
(
_document
,
_containingType
,
cancellationToken
)
?
service
.
GenerateEqualsMethodThroughIEquatableEqualsAsync
(
_document
,
_containingType
,
cancellationToken
)
:
service
.
GenerateEqualsMethodAsync
(
_document
,
_containingType
,
_selectedMembers
,
cancellationToken
);
:
service
.
GenerateEqualsMethodAsync
(
_document
,
_containingType
,
_selectedMembers
,
cancellationToken
);
...
@@ -224,7 +228,7 @@ private Task<IMethodSymbol> CreateEqualsMethodAsync(CancellationToken cancellati
...
@@ -224,7 +228,7 @@ private Task<IMethodSymbol> CreateEqualsMethodAsync(CancellationToken cancellati
private
async
Task
<
IMethodSymbol
>
CreateIEquatableEqualsMethodAsync
(
INamedTypeSymbol
constructedEquatableType
,
CancellationToken
cancellationToken
)
private
async
Task
<
IMethodSymbol
>
CreateIEquatableEqualsMethodAsync
(
INamedTypeSymbol
constructedEquatableType
,
CancellationToken
cancellationToken
)
{
{
var
service
=
_document
.
GetLanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
var
service
=
_document
.
Get
Required
LanguageService
<
IGenerateEqualsAndGetHashCodeService
>();
return
await
service
.
GenerateIEquatableEqualsMethodAsync
(
return
await
service
.
GenerateIEquatableEqualsMethodAsync
(
_document
,
_containingType
,
_selectedMembers
,
constructedEquatableType
,
cancellationToken
).
ConfigureAwait
(
false
);
_document
,
_containingType
,
_selectedMembers
,
constructedEquatableType
,
cancellationToken
).
ConfigureAwait
(
false
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录