Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
9a777fff
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,发现更多精彩内容 >>
提交
9a777fff
编写于
7月 10, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add parameter should respect multi-line paraemters.
上级
4902a12a
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
355 addition
and
44 deletion
+355
-44
src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
...itorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
+111
-0
src/EditorFeatures/VisualBasicTest/AddParameter/AddParameterTests.vb
...eatures/VisualBasicTest/AddParameter/AddParameterTests.vb
+84
-0
src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs
...table/AddParameter/AbstractAddParameterCodeFixProvider.cs
+152
-44
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
...s/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
+1
-0
src/Workspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
...orkspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
+5
-0
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
+1
-0
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb
...sic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb
+1
-0
未找到文件。
src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
浏览文件 @
9a777fff
...
...
@@ -230,5 +230,116 @@ void M()
}
}"
);
}
[
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)]
public
async
Task
TestMultiLineParameters1
()
{
await
TestInRegularAndScriptAsync
(
@"
class C
{
public C(int i,
/* foo */ int j)
{
}
private void Foo()
{
new [|C|](true, 0, 0);
}
}"
,
@"
class C
{
public C(bool v,
int i,
/* foo */ int j)
{
}
private void Foo()
{
new C(true, 0, 0);
}
}"
,
ignoreTrivia
:
false
);
}
[
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)]
public
async
Task
TestMultiLineParameters2
()
{
await
TestInRegularAndScriptAsync
(
@"
class C
{
public C(int i,
/* foo */ int j)
{
}
private void Foo()
{
new [|C|](0, true, 0);
}
}"
,
@"
class C
{
public C(int i,
bool v,
/* foo */ int j)
{
}
private void Foo()
{
new C(0, true, 0);
}
}"
,
ignoreTrivia
:
false
);
}
[
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)]
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)]
public
async
Task
TestMultiLineParameters3
()
{
await
TestInRegularAndScriptAsync
(
@"
class C
{
public C(int i,
/* foo */ int j)
{
}
private void Foo()
{
new [|C|](0, 0, true);
}
}"
,
@"
class C
{
public C(int i,
/* foo */ int j,
bool v)
{
}
private void Foo()
{
new C(0, 0, true);
}
}"
,
ignoreTrivia
:
false
);
}
}
}
src/EditorFeatures/VisualBasicTest/AddParameter/AddParameterTests.vb
浏览文件 @
9a777fff
...
...
@@ -200,5 +200,89 @@ class D
end class
"
)
End
Function
<
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)
>
Public
Async
Function
TestMultiLineParameters1
()
As
Task
Await
TestInRegularAndScriptAsync
(
"
class C
public sub new(i as integer,
j as integer)
end sub
private sub Foo()
dim x = new C(true, 0, [|0|])
end sub
end class"
,
"
class C
public sub new(v As Boolean,
i as integer,
j as integer)
end sub
private sub Foo()
dim x = new C(true, 0, 0)
end sub
end class"
,
ignoreTrivia
:
=
False
)
End
Function
<
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)
>
Public
Async
Function
TestMultiLineParameters2
()
As
Task
Await
TestInRegularAndScriptAsync
(
"
class C
public sub new(i as integer,
j as integer)
end sub
private sub Foo()
dim x = new C(0, true, [|0|])
end sub
end class"
,
"
class C
public sub new(i as integer,
v As Boolean,
j as integer)
end sub
private sub Foo()
dim x = new C(0, true, 0)
end sub
end class"
,
ignoreTrivia
:
=
False
)
End
Function
<
WorkItem
(
20708
,
"https://github.com/dotnet/roslyn/issues/20708"
)
>
<
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsAddParameter
)
>
Public
Async
Function
TestMultiLineParameters3
()
As
Task
Await
TestInRegularAndScriptAsync
(
"
class C
public sub new(i as integer,
j as integer)
end sub
private sub Foo()
dim x = new C(0, 0, [|true|])
end sub
end class"
,
"
class C
public sub new(i as integer,
j as integer,
v As Boolean)
end sub
private sub Foo()
dim x = new C(0, 0, true)
end sub
end class"
,
ignoreTrivia
:
=
False
)
End
Function
End
Class
End
Namespace
src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs
浏览文件 @
9a777fff
...
...
@@ -10,6 +10,7 @@
using
Microsoft.CodeAnalysis.CodeFixes
;
using
Microsoft.CodeAnalysis.CodeGeneration
;
using
Microsoft.CodeAnalysis.Editing
;
using
Microsoft.CodeAnalysis.Formatting
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
...
...
@@ -169,56 +170,49 @@ private int NonParamsParameterCount(IMethodSymbol method)
SeparatedSyntaxList
<
TArgumentSyntax
>
argumentList
,
CancellationToken
cancellationToken
)
{
var
generator
=
SyntaxGenerator
.
GetGenerator
(
invocationDocument
.
Project
.
Solution
.
Workspace
,
method
.
Language
);
var
methodDeclaration
=
await
method
.
DeclaringSyntaxReferences
[
0
].
GetSyntaxAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
syntaxFacts
=
invocationDocument
.
GetLanguageService
<
ISyntaxFactsService
>();
var
semanticFacts
=
invocationDocument
.
GetLanguageService
<
ISemanticFactsService
>();
var
argumentName
=
syntaxFacts
.
GetNameForArgument
(
argument
);
var
expression
=
syntaxFacts
.
GetExpressionOfArgument
(
argument
);
var
semanticModel
=
await
invocationDocument
.
GetSemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
parameterType
=
semanticModel
.
GetTypeInfo
(
expression
).
Type
??
semanticModel
.
Compilation
.
ObjectType
;
var
newMethodDeclaration
=
GetNewMethodDeclaration
(
method
,
argument
,
argumentList
,
generator
,
methodDeclaration
,
semanticFacts
,
argumentName
,
expression
,
semanticModel
,
parameterType
,
cancellationToken
);
var
root
=
methodDeclaration
.
SyntaxTree
.
GetRoot
(
cancellationToken
);
var
newRoot
=
root
.
ReplaceNode
(
methodDeclaration
,
newMethodDeclaration
);
var
(
parameterSymbol
,
isNamedArgument
)
=
await
CreateParameterSymbolAsync
(
invocationDocument
,
method
,
argument
,
cancellationToken
).
ConfigureAwait
(
false
);
var
methodDocument
=
invocationDocument
.
Project
.
Solution
.
GetDocument
(
methodDeclaration
.
SyntaxTree
);
var
syntaxFacts
=
methodDocument
.
GetLanguageService
<
ISyntaxFactsService
>();
var
methodDeclarationRoot
=
methodDeclaration
.
SyntaxTree
.
GetRoot
(
cancellationToken
);
var
editor
=
new
SyntaxEditor
(
methodDeclarationRoot
,
methodDocument
.
Project
.
Solution
.
Workspace
);
var
parameterDeclaration
=
editor
.
Generator
.
ParameterDeclaration
(
parameterSymbol
)
.
WithAdditionalAnnotations
(
Formatter
.
Annotation
);
AddParameter
(
syntaxFacts
,
editor
,
methodDeclaration
,
isNamedArgument
,
argument
,
argumentList
,
parameterDeclaration
,
cancellationToken
);
var
newRoot
=
editor
.
GetChangedRoot
();
var
newDocument
=
methodDocument
.
WithSyntaxRoot
(
newRoot
);
return
newDocument
;
}
private
static
SyntaxNode
GetNewMethodDeclaration
(
private
async
Task
<(
IParameterSymbol
,
bool
isNamedArgument
)>
CreateParameterSymbolAsync
(
Document
invocationDocument
,
IMethodSymbol
method
,
TArgumentSyntax
argument
,
SeparatedSyntaxList
<
TArgumentSyntax
>
argumentList
,
SyntaxGenerator
generator
,
SyntaxNode
declaration
,
ISemanticFactsService
semanticFacts
,
string
argumentName
,
SyntaxNode
expression
,
SemanticModel
semanticModel
,
ITypeSymbol
parameterType
,
CancellationToken
cancellationToken
)
{
var
syntaxFacts
=
invocationDocument
.
GetLanguageService
<
ISyntaxFactsService
>();
var
semanticFacts
=
invocationDocument
.
GetLanguageService
<
ISemanticFactsService
>();
var
argumentName
=
syntaxFacts
.
GetNameForArgument
(
argument
);
var
expression
=
syntaxFacts
.
GetExpressionOfArgument
(
argument
);
var
semanticModel
=
await
invocationDocument
.
GetSemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
parameterType
=
semanticModel
.
GetTypeInfo
(
expression
).
Type
??
semanticModel
.
Compilation
.
ObjectType
;
if
(!
string
.
IsNullOrWhiteSpace
(
argumentName
))
{
var
newParameterSymbol
=
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
attributes
:
default
(
ImmutableArray
<
AttributeData
>),
refKind
:
RefKind
.
None
,
isParams
:
false
,
type
:
parameterType
,
name
:
argumentName
);
var
newParameterDeclaration
=
generator
.
ParameterDeclaration
(
newParameterSymbol
);
return
generator
.
AddParameters
(
declaration
,
new
[]
{
newParameterDeclaration
});
attributes
:
default
,
refKind
:
RefKind
.
None
,
isParams
:
false
,
type
:
parameterType
,
name
:
argumentName
);
return
(
newParameterSymbol
,
isNamedArgument
:
true
);
}
else
{
...
...
@@ -227,19 +221,133 @@ private int NonParamsParameterCount(IMethodSymbol method)
var
uniqueName
=
NameGenerator
.
EnsureUniqueness
(
name
,
method
.
Parameters
.
Select
(
p
=>
p
.
Name
));
var
newParameterSymbol
=
CodeGenerationSymbolFactory
.
CreateParameterSymbol
(
attributes
:
default
(
ImmutableArray
<
AttributeData
>),
refKind
:
RefKind
.
None
,
isParams
:
false
,
type
:
parameterType
,
name
:
uniqueName
);
var
argumentIndex
=
argumentList
.
IndexOf
(
argument
);
var
newParameterDeclaration
=
generator
.
ParameterDeclaration
(
newParameterSymbol
);
return
generator
.
InsertParameters
(
declaration
,
argumentIndex
,
new
[]
{
newParameterDeclaration
});
attributes
:
default
,
refKind
:
RefKind
.
None
,
isParams
:
false
,
type
:
parameterType
,
name
:
uniqueName
);
return
(
newParameterSymbol
,
isNamedArgument
:
false
);
}
}
private
static
void
AddParameter
(
ISyntaxFactsService
syntaxFacts
,
SyntaxEditor
editor
,
SyntaxNode
declaration
,
bool
isNamedArgument
,
TArgumentSyntax
argument
,
SeparatedSyntaxList
<
TArgumentSyntax
>
argumentList
,
SyntaxNode
parameterDeclaration
,
CancellationToken
cancellationToken
)
{
var
generator
=
editor
.
Generator
;
var
existingParameters
=
generator
.
GetParameters
(
declaration
);
var
placeOnNewLine
=
ShouldPlaceParametersOnNewLine
(
existingParameters
,
cancellationToken
);
var
argumentIndex
=
argumentList
.
IndexOf
(
argument
);
if
(
isNamedArgument
||
argumentIndex
==
existingParameters
.
Count
)
{
if
(
placeOnNewLine
)
{
var
leadingIndentation
=
GetDesiredLeadingIndentation
(
generator
,
syntaxFacts
,
existingParameters
.
Last
(),
includeLeadingNewLine
:
true
);
parameterDeclaration
=
parameterDeclaration
.
WithPrependedLeadingTrivia
(
leadingIndentation
)
.
WithAdditionalAnnotations
(
Formatter
.
Annotation
);
}
editor
.
AddParameter
(
declaration
,
parameterDeclaration
);
}
else
{
if
(
placeOnNewLine
)
{
if
(
argumentIndex
==
0
)
{
// Have to move the next parameter to the next line.
editor
.
InsertParameter
(
declaration
,
argumentIndex
,
parameterDeclaration
);
var
nextParameter
=
existingParameters
[
argumentIndex
];
var
leadingIndentation
=
GetDesiredLeadingIndentation
(
generator
,
syntaxFacts
,
existingParameters
[
argumentIndex
+
1
],
includeLeadingNewLine
:
true
);
editor
.
ReplaceNode
(
nextParameter
,
nextParameter
.
WithPrependedLeadingTrivia
(
leadingIndentation
)
.
WithAdditionalAnnotations
(
Formatter
.
Annotation
));
}
else
{
var
nextParameter
=
existingParameters
[
argumentIndex
];
var
leadingIndentation
=
GetDesiredLeadingIndentation
(
generator
,
syntaxFacts
,
existingParameters
[
argumentIndex
],
includeLeadingNewLine
:
false
);
parameterDeclaration
=
parameterDeclaration
.
WithPrependedLeadingTrivia
(
leadingIndentation
);
editor
.
InsertParameter
(
declaration
,
argumentIndex
,
parameterDeclaration
);
editor
.
ReplaceNode
(
nextParameter
,
nextParameter
.
WithPrependedLeadingTrivia
(
generator
.
ElasticCarriageReturnLineFeed
)
.
WithAdditionalAnnotations
(
Formatter
.
Annotation
));
}
}
else
{
editor
.
InsertParameter
(
declaration
,
argumentIndex
,
parameterDeclaration
);
}
}
}
private
static
List
<
SyntaxTrivia
>
GetDesiredLeadingIndentation
(
SyntaxGenerator
generator
,
ISyntaxFactsService
syntaxFacts
,
SyntaxNode
node
,
bool
includeLeadingNewLine
)
{
var
triviaList
=
new
List
<
SyntaxTrivia
>();
if
(
includeLeadingNewLine
)
{
triviaList
.
Add
(
generator
.
ElasticCarriageReturnLineFeed
);
}
var
lastWhitespace
=
default
(
SyntaxTrivia
);
foreach
(
var
trivia
in
node
.
GetLeadingTrivia
().
Reverse
())
{
if
(
syntaxFacts
.
IsWhitespaceTrivia
(
trivia
))
{
lastWhitespace
=
trivia
;
}
else
if
(
syntaxFacts
.
IsEndOfLineTrivia
(
trivia
))
{
break
;
}
}
if
(
lastWhitespace
.
RawKind
!=
0
)
{
triviaList
.
Add
(
lastWhitespace
);
}
return
triviaList
;
}
private
static
bool
ShouldPlaceParametersOnNewLine
(
IReadOnlyList
<
SyntaxNode
>
parameters
,
CancellationToken
cancellationToken
)
{
if
(
parameters
.
Count
<=
1
)
{
return
false
;
}
var
text
=
parameters
[
0
].
SyntaxTree
.
GetText
(
cancellationToken
);
for
(
int
i
=
1
,
n
=
parameters
.
Count
;
i
<
n
;
i
++)
{
var
lastParameter
=
parameters
[
i
-
1
];
var
thisParameter
=
parameters
[
i
];
if
(
text
.
AreOnSameLine
(
lastParameter
.
GetLastToken
(),
thisParameter
.
GetFirstToken
()))
{
return
false
;
}
}
// All parameters are on different lines. Place the new parameter on a new line as well.
return
true
;
}
private
static
readonly
SymbolDisplayFormat
SimpleFormat
=
new
SymbolDisplayFormat
(
typeQualificationStyle
:
SymbolDisplayTypeQualificationStyle
.
NameOnly
,
...
...
src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs
浏览文件 @
9a777fff
...
...
@@ -19,6 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration
[
ExportLanguageService
(
typeof
(
SyntaxGenerator
),
LanguageNames
.
CSharp
),
Shared
]
internal
class
CSharpSyntaxGenerator
:
SyntaxGenerator
{
internal
override
SyntaxTrivia
ElasticCarriageReturnLineFeed
=>
SyntaxFactory
.
ElasticCarriageReturnLineFeed
;
internal
override
SyntaxTrivia
CarriageReturnLineFeed
=>
SyntaxFactory
.
CarriageReturnLineFeed
;
internal
override
bool
RequiresExplicitImplementationForInterfaceMembers
=>
false
;
...
...
src/Workspaces/Core/Portable/Editing/SyntaxEditorExtensions.cs
浏览文件 @
9a777fff
...
...
@@ -64,6 +64,11 @@ public static void AddParameter(this SyntaxEditor editor, SyntaxNode declaration
editor
.
ReplaceNode
(
declaration
,
(
d
,
g
)
=>
g
.
AddParameters
(
d
,
new
[]
{
parameter
}));
}
public
static
void
InsertParameter
(
this
SyntaxEditor
editor
,
SyntaxNode
declaration
,
int
index
,
SyntaxNode
parameter
)
{
editor
.
ReplaceNode
(
declaration
,
(
d
,
g
)
=>
g
.
InsertParameters
(
d
,
index
,
new
[]
{
parameter
}));
}
public
static
void
AddAttribute
(
this
SyntaxEditor
editor
,
SyntaxNode
declaration
,
SyntaxNode
attribute
)
{
editor
.
ReplaceNode
(
declaration
,
(
d
,
g
)
=>
g
.
AddAttributes
(
d
,
new
[]
{
attribute
}));
...
...
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
浏览文件 @
9a777fff
...
...
@@ -31,6 +31,7 @@ public abstract class SyntaxGenerator : ILanguageService
public
static
SyntaxRemoveOptions
DefaultRemoveOptions
=
SyntaxRemoveOptions
.
KeepUnbalancedDirectives
|
SyntaxRemoveOptions
.
AddElasticMarker
;
internal
abstract
SyntaxTrivia
CarriageReturnLineFeed
{
get
;
}
internal
abstract
SyntaxTrivia
ElasticCarriageReturnLineFeed
{
get
;
}
internal
abstract
bool
RequiresExplicitImplementationForInterfaceMembers
{
get
;
}
internal
abstract
SyntaxTrivia
EndOfLine
(
string
text
);
...
...
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb
浏览文件 @
9a777fff
...
...
@@ -16,6 +16,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Public
Shared
ReadOnly
Instance
As
SyntaxGenerator
=
New
VisualBasicSyntaxGenerator
()
Friend
Overrides
ReadOnly
Property
ElasticCarriageReturnLineFeed
As
SyntaxTrivia
=
SyntaxFactory
.
ElasticCarriageReturnLineFeed
Friend
Overrides
ReadOnly
Property
CarriageReturnLineFeed
As
SyntaxTrivia
=
SyntaxFactory
.
CarriageReturnLineFeed
Friend
Overrides
ReadOnly
Property
RequiresExplicitImplementationForInterfaceMembers
As
Boolean
=
True
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录