Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
414fa9d7
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,发现更多精彩内容 >>
提交
414fa9d7
编写于
3月 13, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Preserve file banner when generating a type in a new file.
上级
897028e9
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
209 addition
and
19 deletion
+209
-19
src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs
.../CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs
+77
-0
src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateType/GenerateTypeTests.vb
...alBasicTest/Diagnostics/GenerateType/GenerateTypeTests.vb
+69
-0
src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs
...rtable/GenerateType/AbstractGenerateTypeService.Editor.cs
+30
-19
src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
...spaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
+12
-0
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
...arp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
+3
-0
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
...anguageServices/SyntaxFactsService/ISyntaxFactsService.cs
+2
-0
src/Workspaces/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
...s/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
+12
-0
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
...ortable/LanguageServices/VisualBasicSyntaxFactsService.vb
+4
-0
未找到文件。
src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs
浏览文件 @
414fa9d7
...
...
@@ -4782,6 +4782,83 @@ public B()
}"
,
index
:
2
);
}
[
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)]
[
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)]
public
async
Task
TestPreserveFileBanner1
()
{
await
TestAddDocumentInRegularAndScriptAsync
(
@"// I am a banner
class Program
{
void Main ( )
{
[|Foo|] f ;
}
} "
,
@"// I am a banner
internal class Foo
{
}"
,
expectedContainers
:
ImmutableArray
<
string
>.
Empty
,
expectedDocumentName
:
"Foo.cs"
,
ignoreTrivia
:
false
);
}
[
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)]
[
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)]
public
async
Task
TestPreserveFileBanner2
()
{
await
TestAddDocumentInRegularAndScriptAsync
(
@"/// I am a doc comment
class Program
{
void Main ( )
{
[|Foo|] f ;
}
} "
,
@"internal class Foo
{
}"
,
expectedContainers
:
ImmutableArray
<
string
>.
Empty
,
expectedDocumentName
:
"Foo.cs"
,
ignoreTrivia
:
false
);
}
[
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)]
[
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)]
public
async
Task
TestPreserveFileBanner3
()
{
await
TestAddDocumentInRegularAndScriptAsync
(
@"// I am a banner
using System;
class Program
{
void Main (StackOverflowException e)
{
var f = new [|Foo|](e);
}
}"
,
@"// I am a banner
using System;
internal class Foo
{
private StackOverflowException e;
public Foo(StackOverflowException e)
{
this.e = e;
}
}"
,
expectedContainers
:
ImmutableArray
<
string
>.
Empty
,
expectedDocumentName
:
"Foo.cs"
,
ignoreTrivia
:
false
);
}
}
public
partial
class
GenerateTypeWithUnboundAnalyzerTests
:
AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
...
...
src/EditorFeatures/VisualBasicTest/Diagnostics/GenerateType/GenerateTypeTests.vb
浏览文件 @
414fa9d7
...
...
@@ -465,6 +465,75 @@ expectedContainers:=ImmutableArray.Create("Foo"),
expectedDocumentName
:
=
"Bar.vb"
)
End
Function
<
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)
>
<
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)
>
Public
Async
Function
TestPreserveBanner1
()
As
Task
Await
TestAddDocumentInRegularAndScriptAsync
(
"' I am a banner!
Class Program
Sub Main()
Call New [|Bar|]()
End Sub
End Class"
,
"' I am a banner!
Friend Class Bar
Public Sub New()
End Sub
End Class
"
,
expectedContainers
:
=
ImmutableArray
(
Of
String
).
Empty
,
expectedDocumentName
:
=
"Bar.vb"
,
ignoreTrivia
:
=
False
)
End
Function
<
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)
>
<
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)
>
Public
Async
Function
TestPreserveBanner2
()
As
Task
Await
TestAddDocumentInRegularAndScriptAsync
(
"''' I am a doc comment!
Class Program
Sub Main()
Call New [|Bar|]()
End Sub
End Class"
,
"Friend Class Bar
Public Sub New()
End Sub
End Class
"
,
expectedContainers
:
=
ImmutableArray
(
Of
String
).
Empty
,
expectedDocumentName
:
=
"Bar.vb"
,
ignoreTrivia
:
=
False
)
End
Function
<
WorkItem
(
17361
,
"https://github.com/dotnet/roslyn/issues/17361"
)
>
<
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)
>
Public
Async
Function
TestPreserveBanner3
()
As
Task
Await
TestAddDocumentInRegularAndScriptAsync
(
"' I am a banner!
Imports System
Class Program
Sub Main(e As StackOverflowException)
Call New [|Bar|](e)
End Sub
End Class"
,
"' I am a banner!
Imports System
Friend Class Bar
Private e As StackOverflowException
Public Sub New(e As StackOverflowException)
Me.e = e
End Sub
End Class
"
,
expectedContainers
:
=
ImmutableArray
(
Of
String
).
Empty
,
expectedDocumentName
:
=
"Bar.vb"
,
ignoreTrivia
:
=
False
)
End
Function
<
WpfFact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsGenerateType
)
>
Public
Async
Function
TestGenerateIntoGlobalNamespaceNewFile
()
As
Task
Await
TestAddDocumentInRegularAndScriptAsync
(
...
...
src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs
浏览文件 @
414fa9d7
...
...
@@ -9,6 +9,7 @@
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.CodeGeneration
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.ProjectManagement
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Text
;
...
...
@@ -272,10 +273,11 @@ private void AddFoldersToNamespaceContainers(List<string> container, IList<strin
var
newSemanticModel
=
await
newDocument
.
GetSemanticModelAsync
(
_cancellationToken
).
ConfigureAwait
(
false
);
var
enclosingNamespace
=
newSemanticModel
.
GetEnclosingNamespace
(
0
,
_cancellationToken
);
var
namespaceContainersAndUsings
=
GetNamespaceContainersAndAddUsingsOrImport
(
isDialog
,
folders
,
areFoldersValidIdentifiers
,
projectToBeUpdated
,
triggeringProject
);
var
namespaceContainersAndUsings
=
GetNamespaceContainersAndAddUsingsOrImport
(
isDialog
,
folders
,
areFoldersValidIdentifiers
,
projectToBeUpdated
,
triggeringProject
);
var
containers
=
namespaceContainersAndUsings
.
Item1
;
var
includeUsingsOrImports
=
namespaceContainersAndUsings
.
Item2
;
var
containers
=
namespaceContainersAndUsings
.
containers
;
var
includeUsingsOrImports
=
namespaceContainersAndUsings
.
usingOrImport
;
var
rootNamespaceOrType
=
namedType
.
GenerateRootNamespaceOrType
(
containers
);
...
...
@@ -293,17 +295,32 @@ private void AddFoldersToNamespaceContainers(List<string> container, IList<strin
// 1: folders -> if triggered from Dialog
// 2: containers -> if triggered not from a Dialog but from QualifiedName
// 3: triggering document folder structure -> if triggered not from a Dialog and a SimpleName
var
adjustedContainer
=
isDialog
?
folders
:
_state
.
SimpleName
!=
_state
.
NameOrMemberAccessExpression
?
containers
.
ToList
()
:
_document
.
Document
.
Folders
.
ToList
();
var
adjustedContainer
=
isDialog
?
folders
:
_state
.
SimpleName
!=
_state
.
NameOrMemberAccessExpression
?
containers
.
ToList
()
:
_document
.
Document
.
Folders
.
ToList
();
// Now, take the code that would be generated and actually create an edit that would
// produce a document with that code in it.
var
newRoot
=
await
codeGenResult
.
GetSyntaxRootAsync
(
_cancellationToken
).
ConfigureAwait
(
false
);
if
(
newDocument
.
Project
.
Language
==
_document
.
Document
.
Project
.
Language
)
{
var
syntaxFacts
=
_document
.
Document
.
GetLanguageService
<
ISyntaxFactsService
>();
var
fileBanner
=
syntaxFacts
.
GetFileBanner
(
_document
.
Root
);
if
(
fileBanner
.
Any
(
syntaxFacts
.
IsRegularComment
))
{
newRoot
=
newRoot
.
WithPrependedLeadingTrivia
(
fileBanner
);
}
}
return
await
CreateAddDocumentAndUpdateUsingsOrImportsOperationsAsync
(
projectToBeUpdated
,
triggeringProject
,
documentName
,
await
codeGenResult
.
GetSyntaxRootAsync
(
_cancellationToken
).
ConfigureAwait
(
false
)
,
newRoot
,
_document
.
Document
,
includeUsingsOrImports
,
adjustedContainer
,
...
...
@@ -437,7 +454,7 @@ private async Task<IEnumerable<CodeActionOperation>> GetGenerateIntoContainingNa
return
new
CodeActionOperation
[]
{
new
ApplyChangesOperation
(
updatedSolution
)
};
}
private
Tuple
<
string
[],
string
>
GetNamespaceContainersAndAddUsingsOrImport
(
private
(
string
[]
containers
,
string
usingOrImport
)
GetNamespaceContainersAndAddUsingsOrImport
(
bool
isDialog
,
IList
<
string
>
folders
,
bool
areFoldersValidIdentifiers
,
...
...
@@ -467,18 +484,12 @@ private async Task<IEnumerable<CodeActionOperation>> GetGenerateIntoContainingNa
else
{
// Generated from the Dialog
List
<
string
>
containerList
=
new
List
<
string
>();
string
rootNamespaceOfTheProjectGeneratedInto
;
var
containerList
=
new
List
<
string
>();
if
(
_targetProjectChangeInLanguage
==
TargetProjectChangeInLanguage
.
NoChange
)
{
rootNamespaceOfTheProjectGeneratedInto
=
_service
.
GetRootNamespace
(
_generateTypeOptionsResult
.
Project
.
CompilationOptions
).
Trim
();
}
else
{
rootNamespaceOfTheProjectGeneratedInto
=
_targetLanguageService
.
GetRootNamespace
(
_generateTypeOptionsResult
.
Project
.
CompilationOptions
).
Trim
();
}
var
rootNamespaceOfTheProjectGeneratedInto
=
_targetProjectChangeInLanguage
==
TargetProjectChangeInLanguage
.
NoChange
?
_service
.
GetRootNamespace
(
_generateTypeOptionsResult
.
Project
.
CompilationOptions
).
Trim
()
:
_targetLanguageService
.
GetRootNamespace
(
_generateTypeOptionsResult
.
Project
.
CompilationOptions
).
Trim
();
var
projectManagementService
=
_document
.
Project
.
Solution
.
Workspace
.
Services
.
GetService
<
IProjectManagementService
>();
var
defaultNamespace
=
_generateTypeOptionsResult
.
DefaultNamespace
;
...
...
@@ -526,7 +537,7 @@ private async Task<IEnumerable<CodeActionOperation>> GetGenerateIntoContainingNa
Contract
.
Assert
(
includeUsingsOrImports
!=
null
);
}
return
Tuple
.
Create
(
containers
,
includeUsingsOrImports
);
return
(
containers
,
includeUsingsOrImports
);
}
private
async
Task
<
IEnumerable
<
CodeActionOperation
>>
GetGenerateIntoTypeOperationsAsync
(
INamedTypeSymbol
namedType
)
...
...
src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs
浏览文件 @
414fa9d7
...
...
@@ -2,6 +2,7 @@
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Threading
;
...
...
@@ -657,6 +658,17 @@ public static bool IsAnyLambdaOrAnonymousMethod(this SyntaxNode node)
return
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
));
}
public
static
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
this
SyntaxNode
root
)
{
Debug
.
Assert
(
root
.
FullSpan
.
Start
==
0
);
var
leadingTrivia
=
root
.
GetLeadingTrivia
();
var
index
=
0
;
s_fileBannerMatcher
.
TryMatch
(
leadingTrivia
.
ToList
(),
ref
index
);
return
ImmutableArray
.
CreateRange
(
leadingTrivia
.
Take
(
index
));
}
public
static
bool
IsAnyAssignExpression
(
this
SyntaxNode
node
)
{
return
SyntaxFacts
.
IsAssignmentExpression
(
node
.
Kind
());
...
...
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
浏览文件 @
414fa9d7
...
...
@@ -1979,5 +1979,8 @@ public bool IsBetweenTypeMembers(SourceText sourceText, SyntaxNode root, int pos
public
ImmutableArray
<
SyntaxNode
>
GetSelectedMembers
(
SyntaxNode
root
,
TextSpan
textSpan
)
=>
ImmutableArray
<
SyntaxNode
>.
CastUp
(
root
.
GetMembersInSpan
(
textSpan
));
public
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
SyntaxNode
root
)
=>
root
.
GetFileBanner
();
}
}
\ No newline at end of file
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
浏览文件 @
414fa9d7
...
...
@@ -279,6 +279,8 @@ internal interface ISyntaxFactsService : ILanguageService
out
SyntaxNode
newRoot
,
out
SyntaxNode
newContextNode
);
SyntaxNode
GetNextExecutableStatement
(
SyntaxNode
statement
);
ImmutableArray
<
SyntaxTrivia
>
GetFileBanner
(
SyntaxNode
root
);
}
[
Flags
]
...
...
src/Workspaces/VisualBasic/Portable/Extensions/SyntaxNodeExtensions.vb
浏览文件 @
414fa9d7
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports
System.Collections.Immutable
Imports
System.Runtime.CompilerServices
Imports
System.Threading
Imports
Microsoft.CodeAnalysis
...
...
@@ -538,6 +539,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Return
DirectCast
(
node
.
WithLeadingTrivia
(
leadingTriviaToKeep
.
Skip
(
index
)),
TSyntaxNode
)
End
Function
<
Extension
>
Public
Function
GetFileBanner
(
root
As
SyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Debug
.
Assert
(
root
.
FullSpan
.
Start
=
0
)
Dim
leadingTrivia
=
root
.
GetLeadingTrivia
()
Dim
index
=
0
s_fileBannerMatcher
.
TryMatch
(
leadingTrivia
.
ToList
(),
index
)
Return
ImmutableArray
.
CreateRange
(
leadingTrivia
.
Take
(
index
))
End
Function
''' <summary>
''' Returns true if this is a block that can contain multiple executable statements. i.e.
''' this node is the VB equivalent of a BlockSyntax in C#.
...
...
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
浏览文件 @
414fa9d7
...
...
@@ -1733,5 +1733,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public
Function
GetSelectedMembers
(
root
As
SyntaxNode
,
textSpan
As
TextSpan
)
As
ImmutableArray
(
Of
SyntaxNode
)
Implements
ISyntaxFactsService
.
GetSelectedMembers
Return
ImmutableArray
(
Of
SyntaxNode
).
CastUp
(
root
.
GetMembersInSpan
(
textSpan
))
End
Function
Public
Function
GetFileBanner
(
root
As
SyntaxNode
)
As
ImmutableArray
(
Of
SyntaxTrivia
)
Implements
ISyntaxFactsService
.
GetFileBanner
Return
root
.
GetFileBanner
()
End
Function
End
Class
End
Namespace
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录