Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
54d3f8a4
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,发现更多精彩内容 >>
提交
54d3f8a4
编写于
9月 09, 2015
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add a setter to the auto-prop if the field is written to outside of a constructor.
上级
5323f402
变更
17
显示空白变更内容
内联
并排
Showing
17 changed file
with
226 addition
and
78 deletion
+226
-78
src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs
.../CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs
+89
-9
src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs
...pTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs
+24
-0
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs
...tractEditorInlineRenameService.InlineRenameLocationSet.cs
+2
-2
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs
...ame/AbstractEditorInlineRenameService.SymbolRenameInfo.cs
+5
-5
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.cs
...ntation/InlineRename/AbstractEditorInlineRenameService.cs
+1
-1
src/EditorFeatures/Test2/Rename/RenameEngineResult.vb
src/EditorFeatures/Test2/Rename/RenameEngineResult.vb
+2
-2
src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
...rp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
+3
-3
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
+9
-1
src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt
src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt
+1
-0
src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs
...ortable/Rename/ConflictEngine/ConflictResolver.Session.cs
+2
-2
src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs
...s/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs
+1
-1
src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs
...ore/Portable/Rename/RenameLocation.ReferenceProcessing.cs
+4
-2
src/Workspaces/Core/Portable/Rename/RenameLocation.cs
src/Workspaces/Core/Portable/Rename/RenameLocation.cs
+14
-14
src/Workspaces/Core/Portable/Rename/RenameLocations.cs
src/Workspaces/Core/Portable/Rename/RenameLocations.cs
+17
-16
src/Workspaces/Core/Portable/Rename/Renamer.cs
src/Workspaces/Core/Portable/Rename/Renamer.cs
+49
-17
src/Workspaces/Core/Portable/Workspaces.csproj
src/Workspaces/Core/Portable/Workspaces.csproj
+1
-1
src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb
...rtable/Rename/VisualBasicRenameRewriterLanguageService.vb
+2
-2
未找到文件。
src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs
浏览文件 @
54d3f8a4
...
...
@@ -60,13 +60,18 @@ private async Task<Solution> ProcessResult(CodeFixContext context, Diagnostic di
var
propertySymbol
=
(
IPropertySymbol
)
propertySemanticModel
.
GetDeclaredSymbol
(
property
);
Debug
.
Assert
(
fieldDocument
.
Project
==
propertyDocument
.
Project
);
var
compilation
=
await
fieldDocument
.
Project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
project
=
fieldDocument
.
Project
;
var
compilation
=
await
project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
// First, rename all usages of the field to point at the property. Except don't actually
// rename the field itself. We want to be able to find it again post rename.
var
solution
=
context
.
Document
.
Project
.
Solution
;
var
updatedSolution
=
await
Renamer
.
RenameSymbolAsync
(
solution
,
fieldSymbol
,
propertySymbol
.
Name
,
solution
.
Workspace
.
Options
,
var
fieldLocations
=
await
Renamer
.
GetRenameLocationsAsync
(
solution
,
fieldSymbol
,
solution
.
Workspace
.
Options
,
cancellationToken
).
ConfigureAwait
(
false
);
// First, create the updated property we want to replace the old property with
var
updatedProperty
=
UpdateProperty
(
project
,
fieldSymbol
,
propertySymbol
,
property
,
fieldLocations
,
cancellationToken
);
// Now, rename all usages of the field to point at the property. Except don't actually
// rename the field itself. We want to be able to find it again post rename.
var
updatedSolution
=
await
Renamer
.
RenameAsync
(
fieldLocations
,
propertySymbol
.
Name
,
location
=>
!
location
.
SourceSpan
.
IntersectsWith
(
declaratorLocation
.
SourceSpan
),
symbols
=>
HasConflict
(
symbols
,
propertySymbol
,
compilation
,
cancellationToken
),
cancellationToken
).
ConfigureAwait
(
false
);
...
...
@@ -90,8 +95,6 @@ private async Task<Solution> ProcessResult(CodeFixContext context, Diagnostic di
var
fieldDeclaration
=
(
FieldDeclarationSyntax
)
declarator
.
Parent
.
Parent
;
var
nodeToRemove
=
fieldDeclaration
.
Declaration
.
Variables
.
Count
>
1
?
declarator
:
(
SyntaxNode
)
fieldDeclaration
;
var
updatedProperty
=
UpdateProperty
(
property
);
const
SyntaxRemoveOptions
options
=
SyntaxRemoveOptions
.
KeepUnbalancedDirectives
|
SyntaxRemoveOptions
.
AddElasticMarker
;
if
(
fieldDocument
==
propertyDocument
)
{
...
...
@@ -149,9 +152,86 @@ private async Task<Solution> ProcessResult(CodeFixContext context, Diagnostic di
return
null
;
}
private
PropertyDeclarationSyntax
UpdateProperty
(
PropertyDeclarationSyntax
propertyDeclaration
)
private
PropertyDeclarationSyntax
UpdateProperty
(
Project
project
,
IFieldSymbol
fieldSymbol
,
IPropertySymbol
propertySymbol
,
PropertyDeclarationSyntax
propertyDeclaration
,
RenameLocations
fieldRenameLocations
,
CancellationToken
cancellationToken
)
{
return
propertyDeclaration
.
WithAccessorList
(
UpdateAccessorList
(
propertyDeclaration
.
AccessorList
));
var
updatedProperty
=
propertyDeclaration
.
WithAccessorList
(
UpdateAccessorList
(
propertyDeclaration
.
AccessorList
));
// We may need to add a setter if the field is written to outside of the constructor
// of it's class.
if
(
AddSetterIfNecessary
(
fieldSymbol
,
propertyDeclaration
,
fieldRenameLocations
,
cancellationToken
))
{
var
accessor
=
SyntaxFactory
.
AccessorDeclaration
(
SyntaxKind
.
SetAccessorDeclaration
)
.
WithSemicolonToken
(
SyntaxFactory
.
Token
(
SyntaxKind
.
SemicolonToken
));
var
generator
=
SyntaxGenerator
.
GetGenerator
(
project
);
if
(
fieldSymbol
.
DeclaredAccessibility
!=
propertySymbol
.
DeclaredAccessibility
)
{
accessor
=
(
AccessorDeclarationSyntax
)
generator
.
WithAccessibility
(
accessor
,
fieldSymbol
.
DeclaredAccessibility
);
}
updatedProperty
=
updatedProperty
.
AddAccessorListAccessors
(
accessor
);
}
return
updatedProperty
;
}
private
bool
AddSetterIfNecessary
(
IFieldSymbol
fieldSymbol
,
PropertyDeclarationSyntax
propertyDeclaration
,
RenameLocations
fieldRenameLocations
,
CancellationToken
cancellationToken
)
{
if
(
propertyDeclaration
.
AccessorList
.
Accessors
.
Any
(
SyntaxKind
.
SetAccessorDeclaration
))
{
// No need to add an setter if we already have one.
return
false
;
}
// If the original field was written to outside of a constructor (or the property
// we're converting), then we'll need to add a setter to the property we're creating.
var
containingTypeNodes
=
fieldSymbol
.
ContainingType
.
DeclaringSyntaxReferences
.
Select
(
s
=>
s
.
GetSyntax
(
cancellationToken
)).
ToImmutableArray
();
return
fieldRenameLocations
.
Locations
.
Any
(
loc
=>
NeedsSetter
(
loc
,
containingTypeNodes
,
propertyDeclaration
,
cancellationToken
));
}
private
bool
NeedsSetter
(
RenameLocation
location
,
ImmutableArray
<
SyntaxNode
>
containingTypeNodes
,
PropertyDeclarationSyntax
propertyDeclaration
,
CancellationToken
cancellationToken
)
{
if
(!
location
.
IsWrittenTo
)
{
// We don't need a setter if we're not writing to this field.
return
false
;
}
var
node
=
location
.
Location
.
FindToken
(
cancellationToken
).
Parent
;
while
(
node
!=
null
)
{
if
(
node
==
propertyDeclaration
)
{
// We don't need a setter if we're a reference in the property we're replacing.
return
false
;
}
if
(
node
.
IsKind
(
SyntaxKind
.
ConstructorDeclaration
))
{
// If we're written to in a constructor in the field's class, we don't need
// a setter.
if
(
containingTypeNodes
.
Contains
(
node
.
Parent
))
{
return
false
;
}
}
node
=
node
.
Parent
;
}
// We do need a setter
return
true
;
}
private
AccessorListSyntax
UpdateAccessorList
(
AccessorListSyntax
accessorList
)
...
...
src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs
浏览文件 @
54d3f8a4
...
...
@@ -191,5 +191,29 @@ public void TestUpdateReferencesConflictResolution()
@"class Class { [|int i|]; int P { get { return i; } } public Class(int P) { i = 1; } }"
,
@"class Class { int P { get; } public Class(int P) { this.P = 1; } }"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseAutoProperty
)]
public
void
TestWriteInConstructor
()
{
Test
(
@"class Class { [|int i|]; int P { get { return i; } } public Class() { i = 1; } }"
,
@"class Class { int P { get; } public Class() { P = 1; } }"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseAutoProperty
)]
public
void
TestWriteInNotInConstructor1
()
{
Test
(
@"class Class { [|int i|]; int P { get { return i; } } public Foo() { i = 1; } }"
,
@"class Class { int P { get; set; } public Foo() { P = 1; } }"
);
}
[
Fact
,
Trait
(
Traits
.
Feature
,
Traits
.
Features
.
CodeActionsUseAutoProperty
)]
public
void
TestWriteInNotInConstructor2
()
{
Test
(
@"class Class { [|int i|]; public int P { get { return i; } } public Foo() { i = 1; } }"
,
@"class Class { public int P { get; private set; } public Foo() { P = 1; } }"
);
}
}
}
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.InlineRenameLocationSet.cs
浏览文件 @
54d3f8a4
...
...
@@ -14,12 +14,12 @@ internal abstract partial class AbstractEditorInlineRenameService
{
private
class
InlineRenameLocationSet
:
IInlineRenameLocationSet
{
private
readonly
RenameLocation
Set
_renameLocationSet
;
private
readonly
RenameLocation
s
_renameLocationSet
;
private
readonly
SymbolInlineRenameInfo
_renameInfo
;
public
IList
<
InlineRenameLocation
>
Locations
{
get
;
}
public
InlineRenameLocationSet
(
SymbolInlineRenameInfo
renameInfo
,
RenameLocation
Set
renameLocationSet
)
public
InlineRenameLocationSet
(
SymbolInlineRenameInfo
renameInfo
,
RenameLocation
s
renameLocationSet
)
{
_renameInfo
=
renameInfo
;
_renameLocationSet
=
renameLocationSet
;
...
...
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs
浏览文件 @
54d3f8a4
...
...
@@ -31,7 +31,7 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfo
private
readonly
Document
_document
;
private
readonly
IEnumerable
<
IRefactorNotifyService
>
_refactorNotifyServices
;
private
Task
<
RenameLocation
Set
>
_underlyingFindRenameLocationsTask
;
private
Task
<
RenameLocation
s
>
_underlyingFindRenameLocationsTask
;
/// <summary>
/// Whether or not we shortened the trigger span (say because we were renaming an attribute,
...
...
@@ -61,7 +61,7 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfo
_document
=
document
;
this
.
RenameSymbol
=
renameSymbol
;
this
.
HasOverloads
=
RenameLocation
Set
.
GetOverloadedSymbols
(
this
.
RenameSymbol
).
Any
();
this
.
HasOverloads
=
RenameLocation
s
.
GetOverloadedSymbols
(
this
.
RenameSymbol
).
Any
();
this
.
ForceRenameOverloads
=
forceRenameOverloads
;
_isRenamingAttributePrefix
=
CanRenameAttributePrefix
(
document
,
triggerSpan
,
cancellationToken
);
...
...
@@ -208,14 +208,14 @@ public string GetFinalSymbolName(string replacementText)
public
Task
<
IInlineRenameLocationSet
>
FindRenameLocationsAsync
(
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
{
Task
<
RenameLocation
Set
>
renameTask
;
Task
<
RenameLocation
s
>
renameTask
;
lock
(
_gate
)
{
if
(
_underlyingFindRenameLocationsTask
==
null
)
{
// If this is the first call, then just start finding the initial set of rename
// locations.
_underlyingFindRenameLocationsTask
=
RenameLocation
Set
.
FindAsync
(
_underlyingFindRenameLocationsTask
=
RenameLocation
s
.
FindAsync
(
this
.
RenameSymbol
,
_document
.
Project
.
Solution
,
optionSet
,
cancellationToken
);
renameTask
=
_underlyingFindRenameLocationsTask
;
...
...
@@ -234,7 +234,7 @@ public Task<IInlineRenameLocationSet> FindRenameLocationsAsync(OptionSet optionS
return
GetLocationSet
(
renameTask
,
optionSet
,
cancellationToken
);
}
private
async
Task
<
IInlineRenameLocationSet
>
GetLocationSet
(
Task
<
RenameLocation
Set
>
renameTask
,
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
private
async
Task
<
IInlineRenameLocationSet
>
GetLocationSet
(
Task
<
RenameLocation
s
>
renameTask
,
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
{
var
locationSet
=
await
renameTask
.
ConfigureAwait
(
false
);
if
(
optionSet
!=
null
)
...
...
src/EditorFeatures/Core/Implementation/InlineRename/AbstractEditorInlineRenameService.cs
浏览文件 @
54d3f8a4
...
...
@@ -97,7 +97,7 @@ private IInlineRenameInfo GetRenameInfo(Document document, int position, Cancell
}
}
var
symbol
=
RenameLocation
Set
.
ReferenceProcessing
.
GetRenamableSymbolAsync
(
document
,
triggerToken
.
SpanStart
,
cancellationToken
:
cancellationToken
).
WaitAndGetResult
(
cancellationToken
);
var
symbol
=
RenameLocation
s
.
ReferenceProcessing
.
GetRenamableSymbolAsync
(
document
,
triggerToken
.
SpanStart
,
cancellationToken
:
cancellationToken
).
WaitAndGetResult
(
cancellationToken
);
if
(
symbol
==
null
)
{
return
new
FailureInlineRenameInfo
(
EditorFeaturesResources
.
YouCannotRenameThisElement
);
...
...
src/EditorFeatures/Test2/Rename/RenameEngineResult.vb
浏览文件 @
54d3f8a4
...
...
@@ -68,7 +68,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename
Dim
document
=
workspace
.
CurrentSolution
.
GetDocument
(
cursorDocument
.
Id
)
Dim
symbol
=
RenameLocation
Set
.
ReferenceProcessing
.
GetRenamableSymbolAsync
(
document
,
cursorPosition
,
CancellationToken
.
None
).
Result
Dim
symbol
=
RenameLocation
s
.
ReferenceProcessing
.
GetRenamableSymbolAsync
(
document
,
cursorPosition
,
CancellationToken
.
None
).
Result
If
symbol
Is
Nothing
Then
AssertEx
.
Fail
(
"The symbol touching the $$ could not be found."
)
...
...
@@ -82,7 +82,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename
Next
End
If
Dim
locations
=
RenameLocation
Set
.
FindAsync
(
symbol
,
workspace
.
CurrentSolution
,
optionSet
,
CancellationToken
.
None
).
Result
Dim
locations
=
RenameLocation
s
.
FindAsync
(
symbol
,
workspace
.
CurrentSolution
,
optionSet
,
CancellationToken
.
None
).
Result
Dim
originalName
=
symbol
.
Name
.
Split
(
"."
c
).
Last
()
Dim
result
=
ConflictResolver
.
ResolveConflictsAsync
(
locations
,
originalName
,
renameTo
,
optionSet
,
CancellationToken
.
None
).
Result
...
...
src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs
浏览文件 @
54d3f8a4
...
...
@@ -614,7 +614,7 @@ private SyntaxToken RenameToken(SyntaxToken oldToken, SyntaxToken newToken, stri
private
SyntaxToken
RenameInStringLiteral
(
SyntaxToken
oldToken
,
SyntaxToken
newToken
,
Func
<
SyntaxTriviaList
,
string
,
string
,
SyntaxTriviaList
,
SyntaxToken
>
createNewStringLiteral
)
{
var
originalString
=
newToken
.
ToString
();
string
replacedString
=
RenameLocation
Set
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
);
string
replacedString
=
RenameLocation
s
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
);
if
(
replacedString
!=
originalString
)
{
var
oldSpan
=
oldToken
.
Span
;
...
...
@@ -642,7 +642,7 @@ private SyntaxToken RenameInTrivia(SyntaxToken token, IEnumerable<SyntaxTrivia>
private
SyntaxTrivia
RenameInCommentTrivia
(
SyntaxTrivia
trivia
)
{
var
originalString
=
trivia
.
ToString
();
string
replacedString
=
RenameLocation
Set
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
);
string
replacedString
=
RenameLocation
s
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
);
if
(
replacedString
!=
originalString
)
{
var
oldSpan
=
trivia
.
Span
;
...
...
@@ -819,7 +819,7 @@ private SyntaxToken RenameWithinToken(SyntaxToken oldToken, SyntaxToken newToken
var
properties
=
new
List
<
ISymbol
>();
foreach
(
var
referencedSymbol
in
referencedSymbols
)
{
var
property
=
await
RenameLocation
Set
.
ReferenceProcessing
.
GetPropertyFromAccessorOrAnOverride
(
var
property
=
await
RenameLocation
s
.
ReferenceProcessing
.
GetPropertyFromAccessorOrAnOverride
(
referencedSymbol
,
baseSolution
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
property
!=
null
)
{
...
...
src/Workspaces/Core/Portable/Editing/SyntaxGenerator.cs
浏览文件 @
54d3f8a4
...
...
@@ -36,7 +36,15 @@ public static SyntaxGenerator GetGenerator(Workspace workspace, string language)
/// </summary>
public
static
SyntaxGenerator
GetGenerator
(
Document
document
)
{
return
document
.
Project
.
LanguageServices
.
GetService
<
SyntaxGenerator
>();
return
GetGenerator
(
document
.
Project
);
}
/// <summary>
/// Gets the <see cref="SyntaxGenerator"/> for the language corresponding to the project.
/// </summary>
public
static
SyntaxGenerator
GetGenerator
(
Project
project
)
{
return
project
.
LanguageServices
.
GetService
<
SyntaxGenerator
>();
}
#
region
Declarations
...
...
src/Workspaces/Core/Portable/PublicAPI.Unshipped.txt
浏览文件 @
54d3f8a4
Microsoft.CodeAnalysis.Editing.SyntaxEditor.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> void
Microsoft.CodeAnalysis.Project.IsSubmission.get -> bool
Microsoft.CodeAnalysis.Workspace.UpdateReferencesAfterAdd() -> void
static Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetGenerator(Microsoft.CodeAnalysis.Project project) -> Microsoft.CodeAnalysis.Editing.SyntaxGenerator
virtual Microsoft.CodeAnalysis.Editing.SyntaxGenerator.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode root, Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> Microsoft.CodeAnalysis.SyntaxNode
\ No newline at end of file
src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs
浏览文件 @
54d3f8a4
...
...
@@ -28,7 +28,7 @@ internal static partial class ConflictResolver
private
class
Session
{
// Set of All Locations that will be renamed (does not include non-reference locations that need to be checked for conflicts)
private
readonly
RenameLocation
Set
_renameLocationSet
;
private
readonly
RenameLocation
s
_renameLocationSet
;
// Rename Symbol's Source Location
private
readonly
Location
_renameSymbolDeclarationLocation
;
...
...
@@ -52,7 +52,7 @@ private class Session
private
bool
_documentOfRenameSymbolHasBeenRenamed
;
public
Session
(
RenameLocation
Set
renameLocationSet
,
RenameLocation
s
renameLocationSet
,
Location
renameSymbolDeclarationLocation
,
string
originalText
,
string
replacementText
,
...
...
src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs
浏览文件 @
54d3f8a4
...
...
@@ -45,7 +45,7 @@ internal static partial class ConflictResolver
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A conflict resolution containing the new solution.</returns>
public
static
Task
<
ConflictResolution
>
ResolveConflictsAsync
(
RenameLocation
Set
renameLocationSet
,
RenameLocation
s
renameLocationSet
,
string
originalText
,
string
replacementText
,
OptionSet
optionSet
,
...
...
src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs
浏览文件 @
54d3f8a4
...
...
@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis.Rename
/// A helper class that contains some of the methods and filters that must be used when
/// processing the raw results from the FindReferences API.
/// </summary>
internal
sealed
partial
class
RenameLocation
Set
internal
sealed
partial
class
RenameLocation
s
{
internal
static
class
ReferenceProcessing
{
...
...
@@ -354,7 +354,8 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
{
if
(
location
.
Alias
.
Name
==
referencedSymbol
.
Name
)
{
results
.
Add
(
new
RenameLocation
(
location
.
Location
,
location
.
Document
.
Id
,
isCandidateLocation
:
location
.
IsCandidateLocation
,
isRenamableAliasUsage
:
true
));
results
.
Add
(
new
RenameLocation
(
location
.
Location
,
location
.
Document
.
Id
,
isCandidateLocation
:
location
.
IsCandidateLocation
,
isRenamableAliasUsage
:
true
,
isWrittenTo
:
location
.
IsWrittenTo
));
// We also need to add the location of the alias itself
var
aliasLocation
=
location
.
Alias
.
Locations
.
Single
();
...
...
@@ -367,6 +368,7 @@ internal static async Task<IEnumerable<RenameLocation>> GetRenamableReferenceLoc
results
.
Add
(
new
RenameLocation
(
location
.
Location
,
location
.
Document
.
Id
,
isWrittenTo
:
location
.
IsWrittenTo
,
isCandidateLocation
:
location
.
IsCandidateLocation
,
isMethodGroupReference
:
location
.
IsCandidateLocation
&&
location
.
CandidateReason
==
CandidateReason
.
MemberGroup
,
isRenamableAccessor
:
await
IsPropertyAccessorOrAnOverride
(
referencedSymbol
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
)));
...
...
src/Workspaces/Core/Portable/Rename/RenameLocation.cs
浏览文件 @
54d3f8a4
...
...
@@ -14,6 +14,7 @@ internal struct RenameLocation : IEquatable<RenameLocation>
public
readonly
bool
IsRenamableAliasUsage
;
public
readonly
bool
IsRenamableAccessor
;
public
readonly
TextSpan
ContainingLocationForStringOrComment
;
public
readonly
bool
IsWrittenTo
;
public
bool
IsRenameInStringOrComment
{
get
{
return
ContainingLocationForStringOrComment
!=
default
(
TextSpan
);
}
}
...
...
@@ -26,26 +27,25 @@ internal struct RenameLocation : IEquatable<RenameLocation>
bool
isMethodGroupReference
=
false
,
bool
isRenamableAliasUsage
=
false
,
bool
isRenamableAccessor
=
false
,
bool
isWrittenTo
=
false
,
TextSpan
containingLocationForStringOrComment
=
default
(
TextSpan
))
{
this
.
Location
=
location
;
this
.
DocumentId
=
documentId
;
this
.
IsCandidateLocation
=
isCandidateLocation
;
this
.
IsMethodGroupReference
=
isMethodGroupReference
;
this
.
IsRenamableAliasUsage
=
isRenamableAliasUsage
;
this
.
IsRenamableAccessor
=
isRenamableAccessor
;
this
.
ContainingLocationForStringOrComment
=
containingLocationForStringOrComment
;
Location
=
location
;
DocumentId
=
documentId
;
IsCandidateLocation
=
isCandidateLocation
;
IsMethodGroupReference
=
isMethodGroupReference
;
IsRenamableAliasUsage
=
isRenamableAliasUsage
;
IsRenamableAccessor
=
isRenamableAccessor
;
IsWrittenTo
=
isWrittenTo
;
ContainingLocationForStringOrComment
=
containingLocationForStringOrComment
;
}
public
RenameLocation
(
ReferenceLocation
referenceLocation
,
DocumentId
documentId
)
:
this
(
referenceLocation
.
Location
,
documentId
,
isCandidateLocation
:
referenceLocation
.
IsCandidateLocation
&&
referenceLocation
.
CandidateReason
!=
CandidateReason
.
LateBound
,
isMethodGroupReference
:
referenceLocation
.
IsCandidateLocation
&&
referenceLocation
.
CandidateReason
==
CandidateReason
.
MemberGroup
,
isWrittenTo
:
referenceLocation
.
IsWrittenTo
)
{
this
.
Location
=
referenceLocation
.
Location
;
this
.
DocumentId
=
documentId
;
this
.
IsCandidateLocation
=
referenceLocation
.
IsCandidateLocation
&&
referenceLocation
.
CandidateReason
!=
CandidateReason
.
LateBound
;
this
.
IsMethodGroupReference
=
referenceLocation
.
IsCandidateLocation
&&
referenceLocation
.
CandidateReason
==
CandidateReason
.
MemberGroup
;
this
.
IsRenamableAliasUsage
=
false
;
this
.
IsRenamableAccessor
=
false
;
this
.
ContainingLocationForStringOrComment
=
default
(
TextSpan
);
}
public
bool
Equals
(
RenameLocation
other
)
...
...
src/Workspaces/Core/Portable/Rename/RenameLocation
Set
.cs
→
src/Workspaces/Core/Portable/Rename/RenameLocation
s
.cs
浏览文件 @
54d3f8a4
...
...
@@ -14,10 +14,10 @@
namespace
Microsoft.CodeAnalysis.Rename
{
/// <summary>
/// Holds the
I
Locations of a symbol that should be renamed, along with the symbol and Solution
/// Holds the Locations of a symbol that should be renamed, along with the symbol and Solution
/// for the set.
/// </summary>
internal
sealed
partial
class
RenameLocation
Set
internal
sealed
partial
class
RenameLocation
s
{
private
class
SearchResult
{
...
...
@@ -37,26 +37,27 @@ public SearchResult(ISet<RenameLocation> locations, IEnumerable<ReferenceLocatio
private
readonly
ISymbol
_symbol
;
private
readonly
Solution
_solution
;
private
readonly
SearchResult
_mergedResult
;
internal
OptionSet
Options
{
get
;
}
// possibly null fields
private
readonly
OptionSet
_optionSet
;
private
readonly
SearchResult
_originalSymbolResult
;
private
readonly
List
<
SearchResult
>
_overloadsResult
;
private
readonly
IEnumerable
<
RenameLocation
>
_stringsResult
;
private
readonly
IEnumerable
<
RenameLocation
>
_commentsResult
;
public
RenameLocationSet
(
ISet
<
RenameLocation
>
locations
,
ISymbol
symbol
,
Solution
solution
,
IEnumerable
<
ISymbol
>
referencedSymbols
,
IEnumerable
<
ReferenceLocation
>
implicitLoca
tions
)
internal
RenameLocations
(
ISet
<
RenameLocation
>
locations
,
ISymbol
symbol
,
Solution
solution
,
IEnumerable
<
ISymbol
>
referencedSymbols
,
IEnumerable
<
ReferenceLocation
>
implicitLocations
,
OptionSet
op
tions
)
{
_symbol
=
symbol
;
_solution
=
solution
;
_mergedResult
=
new
SearchResult
(
locations
,
implicitLocations
,
referencedSymbols
);
Options
=
options
;
}
private
RenameLocation
Set
(
ISymbol
symbol
,
Solution
solution
,
OptionSet
optionSet
,
SearchResult
originalSymbolResult
,
List
<
SearchResult
>
overloadsResult
,
IEnumerable
<
RenameLocation
>
stringsResult
,
IEnumerable
<
RenameLocation
>
commentsResult
)
private
RenameLocation
s
(
ISymbol
symbol
,
Solution
solution
,
OptionSet
options
,
SearchResult
originalSymbolResult
,
List
<
SearchResult
>
overloadsResult
,
IEnumerable
<
RenameLocation
>
stringsResult
,
IEnumerable
<
RenameLocation
>
commentsResult
)
{
_symbol
=
symbol
;
_solution
=
solution
;
_optionSet
=
optionSet
;
Options
=
options
;
_originalSymbolResult
=
originalSymbolResult
;
_overloadsResult
=
overloadsResult
;
_stringsResult
=
stringsResult
;
...
...
@@ -66,18 +67,18 @@ private RenameLocationSet(ISymbol symbol, Solution solution, OptionSet optionSet
var
mergedReferencedSymbols
=
new
List
<
ISymbol
>();
var
mergedImplicitLocations
=
new
List
<
ReferenceLocation
>();
if
(
option
Set
.
GetOption
(
RenameOptions
.
RenameInStrings
))
if
(
option
s
.
GetOption
(
RenameOptions
.
RenameInStrings
))
{
mergedLocations
.
AddRange
(
stringsResult
);
}
if
(
option
Set
.
GetOption
(
RenameOptions
.
RenameInComments
))
if
(
option
s
.
GetOption
(
RenameOptions
.
RenameInComments
))
{
mergedLocations
.
AddRange
(
commentsResult
);
}
var
renameMethodGroupReferences
=
option
Set
.
GetOption
(
RenameOptions
.
RenameOverloads
)
||
!
GetOverloadedSymbols
(
symbol
).
Any
();
var
overloadsToMerge
=
(
option
Set
.
GetOption
(
RenameOptions
.
RenameOverloads
)
?
overloadsResult
:
null
)
??
SpecializedCollections
.
EmptyEnumerable
<
SearchResult
>();
var
renameMethodGroupReferences
=
option
s
.
GetOption
(
RenameOptions
.
RenameOverloads
)
||
!
GetOverloadedSymbols
(
symbol
).
Any
();
var
overloadsToMerge
=
(
option
s
.
GetOption
(
RenameOptions
.
RenameOverloads
)
?
overloadsResult
:
null
)
??
SpecializedCollections
.
EmptyEnumerable
<
SearchResult
>();
foreach
(
var
result
in
overloadsToMerge
.
Concat
(
originalSymbolResult
))
{
mergedLocations
.
AddRange
(
renameMethodGroupReferences
...
...
@@ -100,22 +101,22 @@ private RenameLocationSet(ISymbol symbol, Solution solution, OptionSet optionSet
/// <summary>
/// Find the locations that need to be renamed.
/// </summary>
public
static
async
Task
<
RenameLocationSet
>
FindAsync
(
ISymbol
symbol
,
Solution
solution
,
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
internal
static
async
Task
<
RenameLocations
>
FindAsync
(
ISymbol
symbol
,
Solution
solution
,
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
{
Contract
.
ThrowIfNull
(
symbol
);
using
(
Logger
.
LogBlock
(
FunctionId
.
Rename_AllRenameLocations
,
cancellationToken
))
{
symbol
=
await
ReferenceProcessing
.
FindDefinitionSymbolAsync
(
symbol
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
var
originalSymbolResult
=
await
AddLocationsReferenceSymbolsAsync
(
symbol
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
var
intermediateResult
=
new
RenameLocation
Set
(
symbol
,
solution
,
optionSet
,
originalSymbolResult
,
overloadsResult
:
null
,
stringsResult
:
null
,
commentsResult
:
null
);
var
intermediateResult
=
new
RenameLocation
s
(
symbol
,
solution
,
optionSet
,
originalSymbolResult
,
overloadsResult
:
null
,
stringsResult
:
null
,
commentsResult
:
null
);
return
await
intermediateResult
.
FindWithUpdatedOptionsAsync
(
optionSet
,
cancellationToken
).
ConfigureAwait
(
false
);
}
}
public
async
Task
<
RenameLocationSet
>
FindWithUpdatedOptionsAsync
(
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
internal
async
Task
<
RenameLocations
>
FindWithUpdatedOptionsAsync
(
OptionSet
optionSet
,
CancellationToken
cancellationToken
)
{
Contract
.
ThrowIfNull
(
_optionSet
,
"FindWithUpdatedOptionsAsync can only be called on a result of FindAsync"
);
Contract
.
ThrowIfNull
(
Options
,
"FindWithUpdatedOptionsAsync can only be called on a result of FindAsync"
);
using
(
Logger
.
LogBlock
(
FunctionId
.
Rename_AllRenameLocations
,
cancellationToken
))
{
var
overloadsResult
=
_overloadsResult
??
(
optionSet
.
GetOption
(
RenameOptions
.
RenameOverloads
)
...
...
@@ -130,7 +131,7 @@ public async Task<RenameLocationSet> FindWithUpdatedOptionsAsync(OptionSet optio
optionSet
.
GetOption
(
RenameOptions
.
RenameInComments
)
&&
_commentsResult
==
null
,
cancellationToken
).
ConfigureAwait
(
false
);
return
new
RenameLocation
Set
(
_symbol
,
_solution
,
optionSet
,
_originalSymbolResult
,
return
new
RenameLocation
s
(
_symbol
,
_solution
,
optionSet
,
_originalSymbolResult
,
_overloadsResult
??
overloadsResult
,
_stringsResult
??
stringsAndComments
.
Item1
,
_commentsResult
??
stringsAndComments
.
Item2
);
...
...
src/Workspaces/Core/Portable/Rename/Renamer.cs
浏览文件 @
54d3f8a4
...
...
@@ -18,14 +18,7 @@ public static Task<Solution> RenameSymbolAsync(Solution solution, ISymbol symbol
return
RenameSymbolAsync
(
solution
,
symbol
,
newName
,
optionSet
,
filter
:
null
,
cancellationToken
:
cancellationToken
);
}
internal
static
async
Task
<
Solution
>
RenameSymbolAsync
(
Solution
solution
,
ISymbol
symbol
,
string
newName
,
OptionSet
optionSet
,
Func
<
Location
,
bool
>
filter
,
Func
<
IEnumerable
<
ISymbol
>,
bool
?>
hasConflict
=
null
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
))
internal
static
Task
<
RenameLocations
>
GetRenameLocationsAsync
(
Solution
solution
,
ISymbol
symbol
,
OptionSet
options
,
CancellationToken
cancellationToken
)
{
if
(
solution
==
null
)
{
...
...
@@ -37,27 +30,66 @@ public static Task<Solution> RenameSymbolAsync(Solution solution, ISymbol symbol
throw
new
ArgumentNullException
(
nameof
(
symbol
));
}
cancellationToken
.
ThrowIfCancellationRequested
();
options
=
options
??
solution
.
Workspace
.
Options
;
return
RenameLocations
.
FindAsync
(
symbol
,
solution
,
options
,
cancellationToken
);
}
internal
static
async
Task
<
Solution
>
RenameAsync
(
RenameLocations
locations
,
string
newName
,
Func
<
Location
,
bool
>
filter
=
null
,
Func
<
IEnumerable
<
ISymbol
>,
bool
?>
hasConflict
=
null
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
))
{
if
(
string
.
IsNullOrEmpty
(
newName
))
{
throw
new
ArgumentException
(
"newName"
);
throw
new
ArgumentException
(
nameof
(
newName
)
);
}
cancellationToken
.
ThrowIfCancellationRequested
();
optionSet
=
optionSet
??
solution
.
Workspace
.
Options
;
var
renameLocationSet
=
await
RenameLocationSet
.
FindAsync
(
symbol
,
solution
,
optionSet
,
cancellationToken
).
ConfigureAwait
(
false
);
var
symbol
=
locations
.
Symbol
;
if
(
filter
!=
null
)
{
renameLocationSet
=
new
RenameLocationSet
(
renameLocationSet
.
Locations
.
Where
(
loc
=>
filter
(
loc
.
Location
)).
ToSet
(),
renameLocationSet
.
Symbol
,
renameLocationSet
.
Solution
,
renameLocationSet
.
ReferencedSymbols
,
renameLocationSet
.
ImplicitLocations
);
locations
=
new
RenameLocations
(
locations
.
Locations
.
Where
(
loc
=>
filter
(
loc
.
Location
)).
ToSet
(),
symbol
,
locations
.
Solution
,
locations
.
ReferencedSymbols
,
locations
.
ImplicitLocations
,
locations
.
Options
);
}
var
conflictResolution
=
await
ConflictResolver
.
ResolveConflictsAsync
(
renameLocationSet
,
symbol
.
Name
,
newName
,
optionSet
,
hasConflict
,
cancellationToken
).
ConfigureAwait
(
false
);
locations
,
symbol
.
Name
,
newName
,
locations
.
Options
,
hasConflict
,
cancellationToken
).
ConfigureAwait
(
false
);
return
conflictResolution
.
NewSolution
;
}
internal
static
async
Task
<
Solution
>
RenameSymbolAsync
(
Solution
solution
,
ISymbol
symbol
,
string
newName
,
OptionSet
options
,
Func
<
Location
,
bool
>
filter
,
Func
<
IEnumerable
<
ISymbol
>,
bool
?>
hasConflict
=
null
,
CancellationToken
cancellationToken
=
default
(
CancellationToken
))
{
if
(
solution
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
solution
));
}
if
(
symbol
==
null
)
{
throw
new
ArgumentNullException
(
nameof
(
symbol
));
}
cancellationToken
.
ThrowIfCancellationRequested
();
options
=
options
??
solution
.
Workspace
.
Options
;
var
renameLocations
=
await
GetRenameLocationsAsync
(
solution
,
symbol
,
options
,
cancellationToken
).
ConfigureAwait
(
false
);
return
await
RenameAsync
(
renameLocations
,
newName
,
filter
,
hasConflict
,
cancellationToken
).
ConfigureAwait
(
false
);
}
}
}
\ No newline at end of file
src/Workspaces/Core/Portable/Workspaces.csproj
浏览文件 @
54d3f8a4
...
...
@@ -649,7 +649,7 @@
<Compile
Include=
"Rename\RenameEntityKind.cs"
/>
<Compile
Include=
"Rename\RenameLocation.cs"
/>
<Compile
Include=
"Rename\RenameLocation.ReferenceProcessing.cs"
/>
<Compile
Include=
"Rename\RenameLocation
Set
.cs"
/>
<Compile
Include=
"Rename\RenameLocation
s
.cs"
/>
<Compile
Include=
"Rename\RenameOptions.cs"
/>
<Compile
Include=
"Rename\Renamer.cs"
/>
<Compile
Include=
"Rename\RenameRewriterParameters.cs"
/>
...
...
src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb
浏览文件 @
54d3f8a4
...
...
@@ -545,7 +545,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename
Private
Function
RenameInStringLiteral
(
oldToken
As
SyntaxToken
,
newToken
As
SyntaxToken
,
createNewStringLiteral
As
Func
(
Of
SyntaxTriviaList
,
String
,
String
,
SyntaxTriviaList
,
SyntaxToken
))
As
SyntaxToken
Dim
originalString
=
newToken
.
ToString
()
Dim
replacedString
As
String
=
RenameLocation
Set
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
)
Dim
replacedString
As
String
=
RenameLocation
s
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
)
If
replacedString
<>
originalString
Then
Dim
oldSpan
=
oldToken
.
Span
newToken
=
createNewStringLiteral
(
newToken
.
LeadingTrivia
,
replacedString
,
replacedString
,
newToken
.
TrailingTrivia
)
...
...
@@ -558,7 +558,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename
Private
Function
RenameInCommentTrivia
(
trivia
As
SyntaxTrivia
)
As
SyntaxTrivia
Dim
originalString
=
trivia
.
ToString
()
Dim
replacedString
As
String
=
RenameLocation
Set
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
)
Dim
replacedString
As
String
=
RenameLocation
s
.
ReferenceProcessing
.
ReplaceMatchingSubStrings
(
originalString
,
_originalText
,
_replacementText
)
If
replacedString
<>
originalString
Then
Dim
oldSpan
=
trivia
.
Span
Dim
newTrivia
=
SyntaxFactory
.
CommentTrivia
(
replacedString
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录