Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
41ff5758
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,发现更多精彩内容 >>
未验证
提交
41ff5758
编写于
7月 06, 2020
作者:
M
msftbot[bot]
提交者:
GitHub
7月 06, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #45667 from davidwengier/TupleToStructFixArgumentNameCase
Fix "Tuple to Struct" named parameters being cased incorrectly
上级
a8583d1e
11c26899
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
205 addition
and
39 deletion
+205
-39
src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
...arpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
+71
-4
src/EditorFeatures/VisualBasicTest/ConvertTupleToStruct/ConvertTupleToStructTests.vb
...sicTest/ConvertTupleToStruct/ConvertTupleToStructTests.vb
+70
-17
src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs
...ruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs
+16
-0
src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs
...ct/AbstractConvertTupleToStructCodeRefactoringProvider.cs
+27
-18
src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb
...VisualBasicConvertTupleToStructCodeRefactoringProvider.vb
+21
-0
未找到文件。
src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
浏览文件 @
41ff5758
...
...
@@ -106,6 +106,73 @@ public static implicit operator (int a, int b)(NewStruct value)
await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
GetPreferImplicitTypeOptions
(
host
));
}
[
WorkItem
(
45451
,
"https://github.com/dotnet/roslyn/issues/45451"
)]
[
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)]
public
async
Task
ConvertSingleTupleType_ChangeArgumentNameCase
(
TestHost
host
)
{
var
text
=
@"
class Test
{
void Method()
{
var t1 = [||](A: 1, B: 2);
}
}
"
;
var
expected
=
@"
class Test
{
void Method()
{
var t1 = new {|Rename:NewStruct|}(a: 1, b: 2);
}
}
internal struct NewStruct
{
public int A;
public int B;
public NewStruct(int a, int b)
{
A = a;
B = b;
}
public override bool Equals(object obj)
{
return obj is NewStruct other &&
A == other.A &&
B == other.B;
}
public override int GetHashCode()
{
var hashCode = -1817952719;
hashCode = hashCode * -1521134295 + A.GetHashCode();
hashCode = hashCode * -1521134295 + B.GetHashCode();
return hashCode;
}
public void Deconstruct(out int a, out int b)
{
a = A;
b = B;
}
public static implicit operator (int A, int B)(NewStruct value)
{
return (value.A, value.B);
}
public static implicit operator NewStruct((int A, int B) value)
{
return new NewStruct(value.A, value.B);
}
}"
;
await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
GetPreferImplicitTypeOptions
(
host
));
}
[
WorkItem
(
39916
,
"https://github.com/dotnet/roslyn/issues/39916"
)]
[
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)]
public
async
Task
ConvertSingleTupleType_Explicit
(
TestHost
host
)
...
...
@@ -1991,8 +2058,8 @@ void Method()
var t1 = new {|Rename:NewStruct|}(1, 2);
var t2 = new NewStruct(1, 2);
var t3 = (a: 1, b: 2);
var t4 = new NewStruct(
Item1: 1, I
tem2: 2);
var t5 = new NewStruct(
Item1: 1, I
tem2: 2);
var t4 = new NewStruct(
item1: 1, i
tem2: 2);
var t5 = new NewStruct(
item1: 1, i
tem2: 2);
}
}
...
...
@@ -2069,8 +2136,8 @@ void Method()
var t1 = new NewStruct(1, 2);
var t2 = new NewStruct(1, 2);
var t3 = (a: 1, b: 2);
var t4 = new {|Rename:NewStruct|}(
Item1: 1, I
tem2: 2);
var t5 = new NewStruct(
Item1: 1, I
tem2: 2);
var t4 = new {|Rename:NewStruct|}(
item1: 1, i
tem2: 2);
var t5 = new NewStruct(
item1: 1, i
tem2: 2);
}
}
...
...
src/EditorFeatures/VisualBasicTest/ConvertTupleToStruct/ConvertTupleToStructTests.vb
浏览文件 @
41ff5758
...
...
@@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ConvertTupleToStru
Public
Class
ConvertTupleToStructTests
Inherits
AbstractVisualBasicCodeActionTest
Protected
Overrides
Function
CreateCodeRefactoringProvider
(
W
orkspace
As
Workspace
,
parameters
As
TestParameters
)
As
CodeRefactoringProvider
Protected
Overrides
Function
CreateCodeRefactoringProvider
(
w
orkspace
As
Workspace
,
parameters
As
TestParameters
)
As
CodeRefactoringProvider
Return
New
VisualBasicConvertTupleToStructCodeRefactoringProvider
()
End
Function
...
...
@@ -89,6 +89,63 @@ End Structure
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
=
GetTestOptions
(
host
))
End
Function
<
WorkItem
(
45451
,
"https://github.com/dotnet/roslyn/issues/45451"
)
>
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
Public
Async
Function
ConvertSingleTupleType_ChangeArgumentNameCase
(
host
As
TestHost
)
As
Task
Dim
text
=
"
class Test
sub Method()
dim t1 = [||](A:=1, B:=2)
end sub
end class
"
Dim
expected
=
"
class Test
sub Method()
dim t1 = New {|Rename:NewStruct|}(a:=1, b:=2)
end sub
end class
Friend Structure NewStruct
Public A As Integer
Public B As Integer
Public Sub New(a As Integer, b As Integer)
Me.A = a
Me.B = b
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
If Not (TypeOf obj Is NewStruct) Then
Return False
End If
Dim other = DirectCast(obj, NewStruct)
Return A = other.A AndAlso
B = other.B
End Function
Public Overrides Function GetHashCode() As Integer
Return (A, B).GetHashCode()
End Function
Public Sub Deconstruct(ByRef a As Integer, ByRef b As Integer)
a = Me.A
b = Me.B
End Sub
Public Shared Widening Operator CType(value As NewStruct) As (A As Integer, B As Integer)
Return (value.A, value.B)
End Operator
Public Shared Widening Operator CType(value As (A As Integer, B As Integer)) As NewStruct
Return New NewStruct(value.A, value.B)
End Operator
End Structure
"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
=
GetTestOptions
(
host
))
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
Public
Async
Function
ConvertSingleTupleTypeNoNames
(
host
As
TestHost
)
As
Task
Dim
text
=
"
...
...
@@ -671,7 +728,7 @@ end class"
class Test
sub Method()
dim t1 = New {|Rename:NewStruct|}(a:=1, b:=2)
dim t2 = New NewStruct(
A:=3, B
:=4)
dim t2 = New NewStruct(
a:=3, b
:=4)
end sub
end class
...
...
@@ -843,10 +900,6 @@ End Structure
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
=
GetTestOptions
(
host
))
End
Function
Sub
foo
(
a
As
Integer
,
b
As
Integer
)
End
Sub
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
Public
Async
Function
TestFixAllMatchesInSingleMethod
(
host
As
TestHost
)
As
Task
Dim
text
=
"
...
...
@@ -975,8 +1028,8 @@ End Structure
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
options
:
=
GetTestOptions
(
host
))
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
Public
Async
Function
NotIfReferencesAnonymousTypeInternally
(
host
As
TestHost
)
As
Task
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
Public
Async
Function
NotIfReferencesAnonymousTypeInternally
()
As
Task
Dim
text
=
"
class Test
sub Method()
...
...
@@ -1547,7 +1600,7 @@ class Test
dim t1 = New {|Rename:NewStruct|}(1, 2)
dim t2 = New NewStruct(1, 2)
dim t3 = (a:=1, b:=2)
dim t4 = New NewStruct(
Item1:=1, I
tem2:=2)
dim t4 = New NewStruct(
item1:=1, i
tem2:=2)
dim t5 = New NewStruct(item1:=1, item2:=2)
end sub
end class
...
...
@@ -1616,7 +1669,7 @@ class Test
dim t1 = New NewStruct(1, 2)
dim t2 = New NewStruct(1, 2)
dim t3 = (a:=1, b:=2)
dim t4 = New {|Rename:NewStruct|}(
Item1:=1, I
tem2:=2)
dim t4 = New {|Rename:NewStruct|}(
item1:=1, i
tem2:=2)
dim t5 = New NewStruct(item1:=1, item2:=2)
end sub
end class
...
...
@@ -1829,7 +1882,7 @@ End Structure
FeaturesResources
.
updating_usages_in_containing_member
,
FeaturesResources
.
updating_usages_in_containing_type
})
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
...
...
@@ -1906,7 +1959,7 @@ Friend Structure NewStruct
End Operator
End Structure
"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
...
...
@@ -1985,7 +2038,7 @@ Friend Structure NewStruct
End Operator
End Structure
"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
...
...
@@ -2101,7 +2154,7 @@ end class
</Document>
</Project>
</Workspace>"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
1
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
#End Region
...
...
@@ -2225,7 +2278,7 @@ end class
</Document>
</Project>
</Workspace>"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
2
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
2
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
#End Region
...
...
@@ -2338,7 +2391,7 @@ end class
</Document>
</Project>
</Workspace>"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
3
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
3
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
<
Theory
,
CombinatorialData
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsConvertTupleToStruct
)
>
...
...
@@ -2445,7 +2498,7 @@ end class
</Document>
</Project>
</Workspace>"
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
3
)
Await
TestInRegularAndScriptAsync
(
text
,
expected
,
index
:
=
3
,
options
:
=
GetTestOptions
(
host
)
)
End
Function
#End Region
...
...
src/Features/CSharp/Portable/ConvertTupleToStruct/CSharpConvertTupleToStructCodeRefactoringProvider.cs
浏览文件 @
41ff5758
...
...
@@ -9,6 +9,8 @@
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.Host.Mef
;
#
nullable
enable
namespace
Microsoft.CodeAnalysis.CSharp.ConvertTupleToStruct
{
[
ExtensionOrder
(
Before
=
PredefinedCodeRefactoringProviderNames
.
IntroduceVariable
)]
...
...
@@ -32,5 +34,19 @@ internal class CSharpConvertTupleToStructCodeRefactoringProvider :
public
CSharpConvertTupleToStructCodeRefactoringProvider
()
{
}
protected
override
ArgumentSyntax
GetArgumentWithChangedName
(
ArgumentSyntax
argument
,
string
name
)
=>
argument
.
WithNameColon
(
ChangeName
(
argument
.
NameColon
,
name
));
private
static
NameColonSyntax
?
ChangeName
(
NameColonSyntax
?
nameColon
,
string
name
)
{
if
(
nameColon
==
null
)
{
return
null
;
}
var
newName
=
SyntaxFactory
.
IdentifierName
(
name
).
WithTriviaFrom
(
nameColon
.
Name
);
return
nameColon
.
WithName
(
newName
);
}
}
}
src/Features/Core/Portable/ConvertTupleToStruct/AbstractConvertTupleToStructCodeRefactoringProvider.cs
浏览文件 @
41ff5758
...
...
@@ -53,6 +53,8 @@ internal abstract partial class AbstractConvertTupleToStructCodeRefactoringProvi
where
TTypeBlockSyntax
:
SyntaxNode
where
TNamespaceDeclarationSyntax
:
SyntaxNode
{
protected
abstract
TArgumentSyntax
GetArgumentWithChangedName
(
TArgumentSyntax
argument
,
string
name
);
public
override
async
Task
ComputeRefactoringsAsync
(
CodeRefactoringContext
context
)
{
var
(
document
,
textSpan
,
cancellationToken
)
=
context
;
...
...
@@ -203,7 +205,7 @@ private static string GetTitle(Scope scope)
return
document
.
WithSyntaxRoot
(
newRoot
).
Project
.
Solution
;
}
private
static
async
Task
<
Solution
>
ConvertToStructInCurrentProcessAsync
(
private
async
Task
<
Solution
>
ConvertToStructInCurrentProcessAsync
(
Document
document
,
TextSpan
span
,
Scope
scope
,
CancellationToken
cancellationToken
)
{
var
(
tupleExprOrTypeNode
,
tupleType
)
=
await
TryGetTupleInfoAsync
(
...
...
@@ -259,7 +261,7 @@ private static string GetTitle(Scope scope)
return
updatedSolution
;
}
private
static
async
Task
ReplaceExpressionAndTypesInScopeAsync
(
private
async
Task
ReplaceExpressionAndTypesInScopeAsync
(
Dictionary
<
Document
,
SyntaxEditor
>
documentToEditorMap
,
ImmutableArray
<
DocumentToUpdate
>
documentsToUpdate
,
SyntaxNode
tupleExprOrTypeNode
,
INamedTypeSymbol
tupleType
,
...
...
@@ -305,7 +307,7 @@ private static string GetTitle(Scope scope)
// We should only ever get a default array (meaning, update the root), or a
// non-empty array. We should never be asked to update exactly '0' nodes.
Debug
.
Assert
(
documentToUpdate
.
NodesToUpdate
.
IsDefault
||
documentToUpdate
.
NodesToUpdate
.
Length
>=
1
);
!
documentToUpdate
.
NodesToUpdate
.
IsEmpty
);
// If we were given specific nodes to update, only update those. Otherwise
// updated everything from the root down.
...
...
@@ -347,7 +349,7 @@ private static string GetTitle(Scope scope)
structNameToken
=
structNameToken
.
WithAdditionalAnnotations
(
RenameAnnotation
.
Create
());
}
return
typeParameters
.
Length
==
0
return
typeParameters
.
IsEmpty
?
(
TNameSyntax
)
generator
.
IdentifierName
(
structNameToken
)
:
(
TNameSyntax
)
generator
.
GenericName
(
structNameToken
,
typeParameters
.
Select
(
tp
=>
generator
.
IdentifierName
(
tp
.
Name
)));
}
...
...
@@ -546,7 +548,7 @@ private static bool InfoProbablyContainsTupleFieldNames(SyntaxTreeIndex info, Im
return
currentSolution
;
}
private
static
async
Task
<
bool
>
ReplaceTupleExpressionsAndTypesInDocumentAsync
(
private
async
Task
<
bool
>
ReplaceTupleExpressionsAndTypesInDocumentAsync
(
Document
document
,
SyntaxEditor
editor
,
SyntaxNode
startingNode
,
INamedTypeSymbol
tupleType
,
TNameSyntax
fullyQualifiedStructName
,
string
structName
,
ImmutableArray
<
ITypeParameterSymbol
>
typeParameters
,
...
...
@@ -566,7 +568,7 @@ private static bool InfoProbablyContainsTupleFieldNames(SyntaxTreeIndex info, Im
return
changed
;
}
private
static
async
Task
<
bool
>
ReplaceMatchingTupleExpressionsAsync
(
private
async
Task
<
bool
>
ReplaceMatchingTupleExpressionsAsync
(
Document
document
,
SyntaxEditor
editor
,
SyntaxNode
startingNode
,
INamedTypeSymbol
tupleType
,
TNameSyntax
qualifiedTypeName
,
string
typeName
,
ImmutableArray
<
ITypeParameterSymbol
>
typeParameters
,
...
...
@@ -622,7 +624,7 @@ private static bool AreEquivalent(StringComparer comparer, INamedTypeSymbol tupl
return
true
;
}
private
static
void
ReplaceWithObjectCreation
(
private
void
ReplaceWithObjectCreation
(
SyntaxEditor
editor
,
string
typeName
,
ImmutableArray
<
ITypeParameterSymbol
>
typeParameters
,
TNameSyntax
qualifiedTypeName
,
SyntaxNode
startingCreationNode
,
TTupleExpressionSyntax
childCreation
)
{
...
...
@@ -649,27 +651,31 @@ private static bool AreEquivalent(StringComparer comparer, INamedTypeSymbol tupl
});
}
private
static
SeparatedSyntaxList
<
TArgumentSyntax
>
ConvertArguments
(
SyntaxGenerator
generator
,
SeparatedSyntaxList
<
TArgumentSyntax
>
arguments
)
private
SeparatedSyntaxList
<
TArgumentSyntax
>
ConvertArguments
(
SyntaxGenerator
generator
,
SeparatedSyntaxList
<
TArgumentSyntax
>
arguments
)
=>
generator
.
SeparatedList
<
TArgumentSyntax
>(
ConvertArguments
(
generator
,
arguments
.
GetWithSeparators
()));
private
static
SyntaxNodeOrTokenList
ConvertArguments
(
SyntaxGenerator
generator
,
SyntaxNodeOrTokenList
list
)
private
SyntaxNodeOrTokenList
ConvertArguments
(
SyntaxGenerator
generator
,
SyntaxNodeOrTokenList
list
)
=>
new
SyntaxNodeOrTokenList
(
list
.
Select
(
v
=>
ConvertArgumentOrToken
(
generator
,
v
)));
private
static
SyntaxNodeOrToken
ConvertArgumentOrToken
(
SyntaxGenerator
generator
,
SyntaxNodeOrToken
arg
)
private
SyntaxNodeOrToken
ConvertArgumentOrToken
(
SyntaxGenerator
generator
,
SyntaxNodeOrToken
arg
)
=>
arg
.
IsToken
?
arg
:
ConvertArgument
(
generator
,
(
TArgumentSyntax
)
arg
.
AsNode
());
private
static
TArgumentSyntax
ConvertArgument
(
private
TArgumentSyntax
ConvertArgument
(
SyntaxGenerator
generator
,
TArgumentSyntax
argument
)
{
// Keep named arguments for literal args. It helps keep the code self-documenting.
// If the original arguments had names then we keep them, but convert the case to match the
// the constructor parameters they now refer to. It helps keep the code self-documenting.
// Remove for complex args as it's most likely just clutter a person doesn't need
// when instantiating their new type.
var
expr
=
generator
.
SyntaxFacts
.
GetExpressionOfArgument
(
argument
);
if
(
expr
is
TLiteralExpressionSyntax
)
{
return
argument
;
var
argumentName
=
generator
.
SyntaxFacts
.
GetNameForArgument
(
argument
);
var
newArgumentName
=
GetConstructorParameterName
(
argumentName
);
return
GetArgumentWithChangedName
(
argument
,
newArgumentName
);
}
return
(
TArgumentSyntax
)
generator
.
Argument
(
expr
).
WithTriviaFrom
(
argument
);
...
...
@@ -800,9 +806,9 @@ private static SyntaxNodeOrToken ConvertArgumentOrToken(SyntaxGenerator generato
SyntaxGenerator
generator
,
ArrayBuilder
<
ISymbol
>
members
,
INamedTypeSymbol
tupleType
,
INamedTypeSymbol
structType
)
{
const
string
v
alueName
=
"value"
;
const
string
V
alueName
=
"value"
;
var
valueNode
=
generator
.
IdentifierName
(
v
alueName
);
var
valueNode
=
generator
.
IdentifierName
(
V
alueName
);
var
arguments
=
tupleType
.
TupleElements
.
SelectAsArray
<
IFieldSymbol
,
SyntaxNode
>(
field
=>
generator
.
Argument
(
generator
.
MemberAccessExpression
(
valueNode
,
field
.
Name
)));
...
...
@@ -818,7 +824,7 @@ private static SyntaxNodeOrToken ConvertArgumentOrToken(SyntaxGenerator generato
Accessibility
.
Public
,
DeclarationModifiers
.
Static
,
tupleType
,
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
structType
,
v
alueName
),
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
structType
,
V
alueName
),
isImplicit
:
true
,
ImmutableArray
.
Create
(
convertToTupleStatement
)));
members
.
Add
(
CodeGenerationSymbolFactory
.
CreateConversionSymbol
(
...
...
@@ -826,7 +832,7 @@ private static SyntaxNodeOrToken ConvertArgumentOrToken(SyntaxGenerator generato
Accessibility
.
Public
,
DeclarationModifiers
.
Static
,
structType
,
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
tupleType
,
v
alueName
),
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
tupleType
,
V
alueName
),
isImplicit
:
true
,
ImmutableArray
.
Create
(
convertToStructStatement
)));
}
...
...
@@ -854,7 +860,7 @@ private static SyntaxNodeOrToken ConvertArgumentOrToken(SyntaxGenerator generato
var
parameters
=
fields
.
SelectAsArray
<
IFieldSymbol
,
IParameterSymbol
>(
field
=>
{
var
parameter
=
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
field
.
Type
,
field
.
Name
.
ToCamelCase
(
trimLeadingTypePrefix
:
fals
e
));
field
.
Type
,
GetConstructorParameterName
(
field
.
Nam
e
));
parameterToPropMap
[
parameter
.
Name
]
=
field
;
...
...
@@ -872,6 +878,9 @@ private static SyntaxNodeOrToken ConvertArgumentOrToken(SyntaxGenerator generato
return
constructor
;
}
private
static
string
GetConstructorParameterName
(
string
name
)
=>
name
.
ToCamelCase
(
trimLeadingTypePrefix
:
false
);
// TODO: This is the common case, but should ideally match the users style preference
private
class
MyCodeAction
:
CodeAction
.
SolutionChangeAction
{
public
MyCodeAction
(
string
title
,
Func
<
CancellationToken
,
Task
<
Solution
>>
createChangedSolution
)
...
...
src/Features/VisualBasic/Portable/ConvertTupleToStruct/VisualBasicConvertTupleToStructCodeRefactoringProvider.vb
浏览文件 @
41ff5758
...
...
@@ -30,5 +30,26 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertTupleToStruct
<
SuppressMessage
(
"RoslynDiagnosticsReliability"
,
"RS0033:Importing constructor should be [Obsolete]"
,
Justification
:
=
"Used in test code: https://github.com/dotnet/roslyn/issues/42814"
)
>
Public
Sub
New
()
End
Sub
Protected
Overrides
Function
GetArgumentWithChangedName
(
argument
As
ArgumentSyntax
,
name
As
String
)
As
ArgumentSyntax
Dim
simpleArgument
=
TryCast
(
argument
,
SimpleArgumentSyntax
)
If
simpleArgument
Is
Nothing
Then
Return
argument
End
If
Dim
nameColonEquals
=
simpleArgument
.
NameColonEquals
Return
simpleArgument
.
WithNameColonEquals
(
ChangeName
(
nameColonEquals
,
name
))
End
Function
Private
Shared
Function
ChangeName
(
nameColonEquals
As
NameColonEqualsSyntax
,
name
As
String
)
As
NameColonEqualsSyntax
If
nameColonEquals
Is
Nothing
Then
Return
Nothing
End
If
Dim
newName
=
SyntaxFactory
.
IdentifierName
(
name
).
WithTriviaFrom
(
nameColonEquals
.
Name
)
Return
nameColonEquals
.
WithName
(
newName
)
End
Function
End
Class
End
Namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录