Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
949d1137
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,发现更多精彩内容 >>
提交
949d1137
编写于
7月 20, 2016
作者:
B
Balaji Krishnan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Minor code cleanups and added..
.. checks identifier checks for rename type.
上级
aacc93a8
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
60 addition
and
45 deletion
+60
-45
src/EditorFeatures/Test/MoveType/AbstractMoveTypeTest.cs
src/EditorFeatures/Test/MoveType/AbstractMoveTypeTest.cs
+2
-2
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeCodeAction.cs
...gs/MoveType/AbstractMoveTypeService.MoveTypeCodeAction.cs
+3
-3
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs
...orings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs
+25
-20
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.RenameTypeEditor.cs
...ings/MoveType/AbstractMoveTypeService.RenameTypeEditor.cs
+2
-1
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs
...odeRefactorings/MoveType/AbstractMoveTypeService.State.cs
+9
-7
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.cs
...able/CodeRefactorings/MoveType/AbstractMoveTypeService.cs
+9
-3
src/Features/Core/Portable/FeaturesResources.resx
src/Features/Core/Portable/FeaturesResources.resx
+3
-3
src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb
...e/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb
+2
-2
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSemanticFactsService.cs
...p/Portable/LanguageServices/CSharpSemanticFactsService.cs
+1
-2
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSemanticFactsService.vb
...table/LanguageServices/VisualBasicSemanticFactsService.vb
+4
-2
未找到文件。
src/EditorFeatures/Test/MoveType/AbstractMoveTypeTest.cs
浏览文件 @
949d1137
...
...
@@ -17,8 +17,8 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.MoveType
{
public
abstract
class
AbstractMoveTypeTest
:
AbstractCodeActionTest
{
private
string
RenameFileCodeActionTitle
=
FeaturesResources
.
Rename
file
to_0
;
private
string
RenameTypeCodeActionTitle
=
FeaturesResources
.
Rename
type
to_0
;
private
string
RenameFileCodeActionTitle
=
FeaturesResources
.
Rename
_file_
to_0
;
private
string
RenameTypeCodeActionTitle
=
FeaturesResources
.
Rename
_type_
to_0
;
protected
override
CodeRefactoringProvider
CreateCodeRefactoringProvider
(
Workspace
workspace
)
{
...
...
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeCodeAction.cs
浏览文件 @
949d1137
...
...
@@ -34,11 +34,11 @@ private string CreateDisplayText()
switch
(
_operationKind
)
{
case
OperationKind
.
MoveType
:
return
string
.
Format
(
FeaturesResources
.
Move
type
to_0
,
_state
.
TargetFileNameCandidate
);
return
string
.
Format
(
FeaturesResources
.
Move
_type_
to_0
,
_state
.
TargetFileNameCandidate
);
case
OperationKind
.
RenameType
:
return
string
.
Format
(
FeaturesResources
.
Rename
type
to_0
,
_state
.
DocumentName
);
return
string
.
Format
(
FeaturesResources
.
Rename
_type_
to_0
,
_state
.
DocumentName
);
case
OperationKind
.
RenameFile
:
return
string
.
Format
(
FeaturesResources
.
Rename
file
to_0
,
_state
.
TargetFileNameCandidate
);
return
string
.
Format
(
FeaturesResources
.
Rename
_file_
to_0
,
_state
.
TargetFileNameCandidate
);
}
throw
ExceptionUtilities
.
Unreachable
;
...
...
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.MoveTypeEditor.cs
浏览文件 @
949d1137
...
...
@@ -2,6 +2,7 @@
using
System
;
using
System.Collections.Generic
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
...
...
@@ -41,8 +42,8 @@ internal override async Task<IEnumerable<CodeActionOperation>> GetOperationsAsyn
/// <remarks>
/// The algorithm for this, is as follows:
/// 1. Fork the original document that contains the type to be moved.
/// 2. Keep the type
and required namespace containers, using statements
///
and
remove everything else from the forked document.
/// 2. Keep the type
, required namespace containers and using statements.
/// remove everything else from the forked document.
/// 3. Add this forked document to the solution.
/// 4. Finally, update the original document and remove the type from it.
/// </remarks>
...
...
@@ -52,7 +53,7 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
var
projectToBeUpdated
=
SemanticDocument
.
Document
.
Project
;
var
newDocumentId
=
DocumentId
.
CreateNewId
(
projectToBeUpdated
.
Id
,
documentName
);
var
solutionWithNewDocument
=
await
AddNewDocumentWith
TypeDeclaration
Async
(
var
solutionWithNewDocument
=
await
AddNewDocumentWith
SingleTypeDeclarationAndImports
Async
(
SemanticDocument
,
documentName
,
newDocumentId
,
State
.
TypeNode
,
CancellationToken
).
ConfigureAwait
(
false
);
// Get the original source document again, from the latest forked solution.
...
...
@@ -60,10 +61,10 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
// update source document to add partial modifiers to type chain
// and/or remove type declaration from original source document.
var
solutionWithBothDocumentsUpdated
=
await
Update
SourceDocumentAsync
(
var
solutionWithBothDocumentsUpdated
=
await
RemoveTypeFrom
SourceDocumentAsync
(
sourceDocument
,
State
.
TypeNode
,
CancellationToken
).
ConfigureAwait
(
false
);
return
new
CodeActionOperation
[]
{
new
ApplyChangesOperation
(
solutionWithBothDocumentsUpdated
)
}
;
return
SpecializedCollections
.
SingletonEnumerable
(
new
ApplyChangesOperation
(
solutionWithBothDocumentsUpdated
))
;
}
/// <summary>
...
...
@@ -76,13 +77,16 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
/// <param name="typeNode">type to move from original document to new document</param>
/// <param name="cancellationToken">a cancellation token</param>
/// <returns>the new solution which contains a new document with the type being moved</returns>
private
async
Task
<
Solution
>
AddNewDocumentWith
TypeDeclaration
Async
(
private
async
Task
<
Solution
>
AddNewDocumentWith
SingleTypeDeclarationAndImports
Async
(
SemanticDocument
sourceDocument
,
string
newDocumentName
,
DocumentId
newDocumentId
,
TTypeDeclarationSyntax
typeNode
,
CancellationToken
cancellationToken
)
{
Debug
.
Assert
(
sourceDocument
.
Document
.
Name
!=
newDocumentName
,
$"New document name is same as old document name:
{
newDocumentName
}
"
);
var
root
=
sourceDocument
.
Root
;
var
projectToBeUpdated
=
sourceDocument
.
Document
.
Project
;
var
documentEditor
=
await
DocumentEditor
.
CreateAsync
(
sourceDocument
.
Document
,
cancellationToken
).
ConfigureAwait
(
false
);
...
...
@@ -106,7 +110,9 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
// get the updated document, perform clean up like remove unused usings.
var
newDocument
=
solutionWithNewDocument
.
GetDocument
(
newDocumentId
);
return
await
CleanUpDocumentAsync
(
newDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
newDocument
=
await
CleanUpDocumentAsync
(
newDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
return
newDocument
.
Project
.
Solution
;
}
/// <summary>
...
...
@@ -117,7 +123,7 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
/// <param name="typeNode">type that was moved to new document</param>
/// <param name="cancellationToken">a cancellation token</param>
/// <returns>an updated solution with the original document fixed up as appropriate.</returns>
private
async
Task
<
Solution
>
Update
SourceDocumentAsync
(
private
async
Task
<
Solution
>
RemoveTypeFrom
SourceDocumentAsync
(
Document
sourceDocument
,
TTypeDeclarationSyntax
typeNode
,
CancellationToken
cancellationToken
)
{
var
documentEditor
=
await
DocumentEditor
.
CreateAsync
(
sourceDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
...
...
@@ -126,7 +132,10 @@ private async Task<IEnumerable<CodeActionOperation>> MoveTypeToNewFileAsync(stri
documentEditor
.
RemoveNode
(
typeNode
,
SyntaxRemoveOptions
.
KeepNoTrivia
);
var
updatedDocument
=
documentEditor
.
GetChangedDocument
();
return
await
CleanUpDocumentAsync
(
updatedDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
updatedDocument
=
await
CleanUpDocumentAsync
(
updatedDocument
,
cancellationToken
).
ConfigureAwait
(
false
);
return
updatedDocument
.
Project
.
Solution
;
}
/// <summary>
...
...
@@ -187,18 +196,14 @@ private static bool FilterToTopLevelMembers(SyntaxNode node, SyntaxNode typeNode
private
void
AddPartialModifiersToTypeChain
(
DocumentEditor
documentEditor
,
TTypeDeclarationSyntax
typeNode
)
{
var
semanticFacts
=
State
.
SemanticDocument
.
Document
.
GetLanguageService
<
ISemanticFactsService
>();
var
typeChain
=
typeNode
.
Ancestors
().
OfType
<
TTypeDeclarationSyntax
>();
if
(
typeNode
.
Parent
is
TTypeDeclarationSyntax
)
foreach
(
var
node
in
typeChain
)
{
var
typeChain
=
typeNode
.
Ancestors
().
OfType
<
TTypeDeclarationSyntax
>();
foreach
(
var
node
in
typeChain
)
var
symbol
=
(
ITypeSymbol
)
State
.
SemanticDocument
.
SemanticModel
.
GetDeclaredSymbol
(
node
,
CancellationToken
);
if
(!
semanticFacts
.
IsPartial
(
symbol
))
{
var
symbol
=
(
ITypeSymbol
)
State
.
SemanticDocument
.
SemanticModel
.
GetDeclaredSymbol
(
node
,
CancellationToken
);
if
(!
semanticFacts
.
IsPartial
(
symbol
))
{
documentEditor
.
SetModifiers
(
node
,
DeclarationModifiers
.
Partial
);
}
documentEditor
.
SetModifiers
(
node
,
DeclarationModifiers
.
Partial
);
}
}
}
...
...
@@ -206,7 +211,7 @@ private void AddPartialModifiersToTypeChain(DocumentEditor documentEditor, TType
/// <summary>
/// Perform clean ups on a given document.
/// </summary>
private
async
Task
<
Solution
>
CleanUpDocumentAsync
(
Document
document
,
CancellationToken
cancellationToken
)
private
async
Task
<
Document
>
CleanUpDocumentAsync
(
Document
document
,
CancellationToken
cancellationToken
)
{
document
=
await
document
.
GetLanguageService
<
IRemoveUnnecessaryImportsService
>()
...
...
@@ -214,7 +219,7 @@ private async Task<Solution> CleanUpDocumentAsync(Document document, Cancellatio
.
ConfigureAwait
(
false
);
var
root
=
await
document
.
GetSyntaxRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
return
document
.
Project
.
Solution
.
WithDocumentSyntaxRoot
(
document
.
Id
,
root
,
PreservationMode
.
PreserveIdentity
);
return
document
.
WithSyntaxRoot
(
root
);
}
}
}
...
...
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.RenameTypeEditor.cs
浏览文件 @
949d1137
...
...
@@ -5,6 +5,7 @@
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.Rename
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.CodeRefactorings.MoveType
{
...
...
@@ -33,7 +34,7 @@ private async Task<IEnumerable<CodeActionOperation>> RenameTypeToMatchFileAsync(
// if no such conflicts exist, proceed with RenameSymbolAsync.
var
symbol
=
State
.
SemanticDocument
.
SemanticModel
.
GetDeclaredSymbol
(
State
.
TypeNode
,
CancellationToken
);
var
newSolution
=
await
Renamer
.
RenameSymbolAsync
(
solution
,
symbol
,
State
.
DocumentName
,
SemanticDocument
.
Document
.
Options
,
CancellationToken
).
ConfigureAwait
(
false
);
return
new
CodeActionOperation
[]
{
new
ApplyChangesOperation
(
newSolution
)
}
;
return
SpecializedCollections
.
SingletonEnumerable
(
new
ApplyChangesOperation
(
newSolution
))
;
}
}
}
...
...
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.State.cs
浏览文件 @
949d1137
...
...
@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.CodeRefactorings.MoveType
{
internal
abstract
partial
class
AbstractMoveTypeService
<
TService
,
TTypeDeclarationSyntax
,
TNamespaceDeclarationSyntax
,
TMemberDeclarationSyntax
,
TCompilationUnitSyntax
>
{
pr
otected
class
State
pr
ivate
class
State
{
private
readonly
TService
_service
;
public
SemanticDocument
SemanticDocument
{
get
;
}
...
...
@@ -20,8 +20,9 @@ protected class State
public
string
TypeName
{
get
;
set
;
}
public
string
DocumentName
{
get
;
set
;
}
public
string
TargetFileNameCandidate
{
get
;
set
;
}
public
bool
IsDocumentNameAValidIdentifier
{
get
;
set
;
}
private
State
(
TService
service
,
SemanticDocument
document
)
private
State
(
TService
service
,
SemanticDocument
document
)
{
this
.
_service
=
service
;
this
.
SemanticDocument
=
document
;
...
...
@@ -51,7 +52,7 @@ internal static State Generate(TService service, SemanticDocument document, Text
var
root
=
this
.
SemanticDocument
.
Root
;
var
syntaxFacts
=
this
.
SemanticDocument
.
Project
.
LanguageServices
.
GetService
<
ISyntaxFactsService
>();
var
typeDeclaration
=
_service
.
GetNode
t
oAnalyze
(
root
,
textSpan
)
as
TTypeDeclarationSyntax
;
var
typeDeclaration
=
_service
.
GetNode
T
oAnalyze
(
root
,
textSpan
)
as
TTypeDeclarationSyntax
;
if
(
typeDeclaration
==
null
)
{
return
false
;
...
...
@@ -71,15 +72,16 @@ internal static State Generate(TService service, SemanticDocument document, Text
TypeNode
=
typeDeclaration
;
TypeName
=
typeSymbol
.
Name
;
DocumentName
=
Path
.
GetFileNameWithoutExtension
(
this
.
SemanticDocument
.
Document
.
Name
);
IsDocumentNameAValidIdentifier
=
syntaxFacts
.
IsValidIdentifier
(
DocumentName
);
if
(
string
.
Equals
(
DocumentName
,
TypeName
,
StringComparison
.
CurrentCultureIgnoreCase
))
// TODO: Make this check better, it won't detect Outer.Inner.cs cases.
if
(
string
.
Equals
(
DocumentName
,
TypeName
,
StringComparison
.
CurrentCulture
))
{
// if type name matches document name, we have nothing more to do.
// if type name matches document name
in a case sensitive manner
, we have nothing more to do.
return
false
;
}
TargetFileNameCandidate
=
typeSymbol
.
Name
+
(
SemanticDocument
.
Document
.
Project
.
Language
==
LanguageNames
.
CSharp
?
".cs"
:
".vb"
);
TargetFileNameCandidate
=
Path
.
Combine
(
typeSymbol
.
Name
+
Path
.
GetExtension
(
this
.
SemanticDocument
.
Document
.
Name
));
return
true
;
}
...
...
src/Features/Core/Portable/CodeRefactorings/MoveType/AbstractMoveTypeService.cs
浏览文件 @
949d1137
...
...
@@ -27,10 +27,10 @@ internal enum OperationKind
public
bool
ShouldAnalyze
(
SyntaxNode
root
,
TextSpan
span
)
{
return
GetNode
t
oAnalyze
(
root
,
span
)
is
TTypeDeclarationSyntax
;
return
GetNode
T
oAnalyze
(
root
,
span
)
is
TTypeDeclarationSyntax
;
}
protected
virtual
SyntaxNode
GetNode
t
oAnalyze
(
SyntaxNode
root
,
TextSpan
span
)
protected
virtual
SyntaxNode
GetNode
T
oAnalyze
(
SyntaxNode
root
,
TextSpan
span
)
{
return
root
.
FindNode
(
span
);
}
...
...
@@ -74,7 +74,13 @@ private List<CodeAction> CreateActions(State state, CancellationToken cancellati
// one type declaration in current document. No moving around required, just sync
// document name and type name by offering rename in both directions between type and document.
actions
.
Add
(
GetCodeAction
(
state
,
operationKind
:
OperationKind
.
RenameFile
));
actions
.
Add
(
GetCodeAction
(
state
,
operationKind
:
OperationKind
.
RenameType
));
// only if the document name can be legal identifier in the language,
// offer to rename type with document name
if
(
state
.
IsDocumentNameAValidIdentifier
)
{
actions
.
Add
(
GetCodeAction
(
state
,
operationKind
:
OperationKind
.
RenameType
));
}
}
else
{
...
...
src/Features/Core/Portable/FeaturesResources.resx
浏览文件 @
949d1137
...
...
@@ -1035,13 +1035,13 @@ This version used in: {2}</value>
<data
name=
"Convert_to_interpolated_string"
xml:space=
"preserve"
>
<value>
Convert to interpolated string
</value>
</data>
<data
name=
"Move
type
to_0"
xml:space=
"preserve"
>
<data
name=
"Move
_type_
to_0"
xml:space=
"preserve"
>
<value>
Move type to {0}
</value>
</data>
<data
name=
"Rename
file
to_0"
xml:space=
"preserve"
>
<data
name=
"Rename
_file_
to_0"
xml:space=
"preserve"
>
<value>
Rename file to {0}
</value>
</data>
<data
name=
"Rename
type
to_0"
xml:space=
"preserve"
>
<data
name=
"Rename
_type_
to_0"
xml:space=
"preserve"
>
<value>
Rename type to {0}
</value>
</data>
</root>
\ No newline at end of file
src/Features/VisualBasic/Portable/CodeRefactorings/MoveType/VisualBasicMoveTypeService.vb
浏览文件 @
949d1137
...
...
@@ -13,8 +13,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.MoveType
''' <summary>
''' Gets the TypeBlock node to analyze
''' </summary>
Protected
Overrides
Function
GetNode
t
oAnalyze
(
root
As
SyntaxNode
,
span
As
TextSpan
)
As
SyntaxNode
Dim
node
=
MyBase
.
GetNode
t
oAnalyze
(
root
,
span
)
Protected
Overrides
Function
GetNode
T
oAnalyze
(
root
As
SyntaxNode
,
span
As
TextSpan
)
As
SyntaxNode
Dim
node
=
MyBase
.
GetNode
T
oAnalyze
(
root
,
span
)
If
node
.
IsKind
(
SyntaxKind
.
ModuleStatement
,
SyntaxKind
.
ClassStatement
,
SyntaxKind
.
StructureStatement
,
...
...
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSemanticFactsService.cs
浏览文件 @
949d1137
...
...
@@ -266,8 +266,7 @@ public bool IsNameOfContext(SemanticModel semanticModel, int position, Cancellat
public
bool
IsPartial
(
ITypeSymbol
typeSymbol
)
{
var
syntaxRefs
=
typeSymbol
.
DeclaringSyntaxReferences
;
return
syntaxRefs
.
Length
>
1
||
((
BaseTypeDeclarationSyntax
)
syntaxRefs
.
Single
().
GetSyntax
()).
Modifiers
.
Any
(
SyntaxKind
.
PartialKeyword
);
return
syntaxRefs
.
Any
(
n
=>
((
BaseTypeDeclarationSyntax
)
n
.
GetSyntax
()).
Modifiers
.
Any
(
SyntaxKind
.
PartialKeyword
));
}
}
}
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSemanticFactsService.vb
浏览文件 @
949d1137
...
...
@@ -250,8 +250,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public
Function
IsPartial
(
typeSymbol
As
ITypeSymbol
)
As
Boolean
Implements
ISemanticFactsService
.
IsPartial
Dim
syntaxRefs
=
typeSymbol
.
DeclaringSyntaxReferences
Return
syntaxRefs
.
Length
>
1
OrElse
DirectCast
(
syntaxRefs
.
Single
().
GetSyntax
(),
TypeStatementSyntax
).
Modifiers
.
Any
(
SyntaxKind
.
PartialKeyword
)
Return
syntaxRefs
.
Any
(
Function
(
n
As
SyntaxReference
)
Return
DirectCast
(
n
.
GetSyntax
(),
TypeStatementSyntax
).
Modifiers
.
Any
(
SyntaxKind
.
PartialKeyword
)
End
Function
)
End
Function
End
Class
End
Namespace
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录