Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
d1a672eb
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,发现更多精彩内容 >>
提交
d1a672eb
编写于
6月 30, 2018
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Find-Refs on an accessor should only produce results for that accessor.
上级
96f0c6d8
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
157 addition
and
23 deletion
+157
-23
src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs
...itorFeatures/Core/FindUsages/AbstractFindUsagesService.cs
+1
-1
src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs
...DocumentHighlighting/AbstractDocumentHighlightsService.cs
+1
-1
src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs
.../FindSymbols/FindReferences/FindReferencesSearchEngine.cs
+34
-2
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs
...s/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs
+22
-0
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs
...ferences/Finders/PropertyAccessorSymbolReferenceFinder.cs
+52
-12
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs
...s/FindReferences/Finders/PropertySymbolReferenceFinder.cs
+17
-0
src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
...paces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
+2
-1
src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
+4
-1
src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs
...able/Shared/Extensions/IFindReferencesResultExtensions.cs
+16
-3
src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs
...aces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs
+8
-2
未找到文件。
src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs
浏览文件 @
d1a672eb
...
...
@@ -134,7 +134,7 @@ internal abstract partial class AbstractFindUsagesService : IFindUsagesService
await
context
.
SetSearchTitleAsync
(
string
.
Format
(
EditorFeaturesResources
.
_0_references
,
FindUsagesHelpers
.
GetDisplayName
(
symbol
))).
ConfigureAwait
(
false
);
var
options
=
FindReferencesSearchOptions
.
Default
;
var
options
=
FindReferencesSearchOptions
.
GetFeatureOptionsForStartingSymbol
(
symbol
)
;
var
progressAdapter
=
new
FindReferencesProgressAdapter
(
project
.
Solution
,
context
,
options
);
// Now call into the underlying FAR engine to find reference. The FAR
...
...
src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs
浏览文件 @
d1a672eb
...
...
@@ -111,7 +111,7 @@ private static async Task<ISymbol> GetSymbolToSearchAsync(Document document, int
var
progress
=
new
StreamingProgressCollector
(
StreamingFindReferencesProgress
.
Instance
);
var
options
=
FindReferencesSearchOptions
.
Default
;
var
options
=
FindReferencesSearchOptions
.
GetFeatureOptionsForStartingSymbol
(
symbol
)
;
await
SymbolFinder
.
FindReferencesAsync
(
symbolAndProjectId
,
document
.
Project
.
Solution
,
progress
,
documentsToSearch
,
options
,
cancellationToken
).
ConfigureAwait
(
false
);
...
...
src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs
浏览文件 @
d1a672eb
...
...
@@ -21,11 +21,43 @@ namespace Microsoft.CodeAnalysis.FindSymbols
internal
class
FindReferencesSearchOptions
{
public
static
readonly
FindReferencesSearchOptions
Default
=
new
FindReferencesSearchOptions
();
new
FindReferencesSearchOptions
(
associatePropertyReferencesWithSpecificAccessor
:
false
);
public
FindReferencesSearchOptions
()
/// <summary>
/// When searching for property, associate specific references we find to the relevant
/// accessor symbol (if there is one). For example, in C#, this would result in:
///
/// P = 0; // A reference to the P.set accessor
/// var v = P; // A reference to the P.get accessor
/// P++; // A reference to P.get and P.set accessors
/// nameof(P); // A reference only to P. Not associated with a particular accessor.
///
/// The default for this is false. With that default, all of the above references
/// are associated with the property P and not the accessors.
/// </summary>
public
bool
AssociatePropertyReferencesWithSpecificAccessor
{
get
;
}
public
FindReferencesSearchOptions
(
bool
associatePropertyReferencesWithSpecificAccessor
)
{
AssociatePropertyReferencesWithSpecificAccessor
=
associatePropertyReferencesWithSpecificAccessor
;
}
public
FindReferencesSearchOptions
WithAssociatePropertyReferencesWithSpecificAccessor
(
bool
associatePropertyReferencesWithSpecificAccessor
)
{
return
new
FindReferencesSearchOptions
(
associatePropertyReferencesWithSpecificAccessor
);
}
/// <summary>
/// For IDE features, if the user starts searching on an accessor, then we want to give
/// results associated with the specific accessor. Otherwise, if they search on a property,
/// then associate everything with the property.
/// </summary>
public
static
FindReferencesSearchOptions
GetFeatureOptionsForStartingSymbol
(
ISymbol
symbol
)
=>
symbol
.
IsPropertyAccessor
()
?
new
FindReferencesSearchOptions
(
associatePropertyReferencesWithSpecificAccessor
:
true
)
:
FindReferencesSearchOptions
.
Default
;
}
internal
partial
class
FindReferencesSearchEngine
...
...
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs
浏览文件 @
d1a672eb
...
...
@@ -57,5 +57,27 @@ protected AbstractMethodOrPropertyOrEventSymbolReferenceFinder()
return
ImmutableArray
<
SymbolAndProjectId
>.
Empty
;
}
protected
ImmutableArray
<
IMethodSymbol
>
GetReferencedAccessorSymbols
(
ISemanticFactsService
semanticFacts
,
SemanticModel
model
,
IPropertySymbol
property
,
SyntaxNode
node
,
CancellationToken
cancellationToken
)
{
if
(
semanticFacts
.
IsWrittenTo
(
model
,
node
,
cancellationToken
))
{
// if it was only written to, then only the setter was referenced.
// if it was written *and* read, then both accessors were referenced.
return
semanticFacts
.
IsOnlyWrittenTo
(
model
,
node
,
cancellationToken
)
?
ImmutableArray
.
Create
(
property
.
SetMethod
)
:
ImmutableArray
.
Create
(
property
.
GetMethod
,
property
.
SetMethod
);
}
else
{
// Wasn't written. This could be a normal read, or used through something
// like nameof().
return
semanticFacts
.
IsNameOfContext
(
model
,
node
.
SpanStart
,
cancellationToken
)
?
ImmutableArray
<
IMethodSymbol
>.
Empty
:
ImmutableArray
.
Create
(
property
.
GetMethod
);
}
}
}
}
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs
浏览文件 @
d1a672eb
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.FindSymbols.Finders
{
internal
class
PropertyAccessorSymbolReferenceFinder
:
AbstractMethodOrPropertyOrEventSymbolReferenceFinder
<
IMethodSymbol
>
{
protected
override
bool
CanFind
(
IMethodSymbol
symbol
)
{
return
symbol
.
MethodKind
.
IsPropertyAccessor
();
}
=>
symbol
.
MethodKind
.
IsPropertyAccessor
();
protected
override
async
Task
<
ImmutableArray
<
SymbolAndProjectId
>>
DetermineCascadedSymbolsAsync
(
SymbolAndProjectId
<
IMethodSymbol
>
symbolAndProjectId
,
...
...
@@ -26,27 +23,70 @@ protected override bool CanFind(IMethodSymbol symbol)
var
result
=
await
base
.
DetermineCascadedSymbolsAsync
(
symbolAndProjectId
,
solution
,
projects
,
options
,
cancellationToken
).
ConfigureAwait
(
false
);
var
symbol
=
symbolAndProjectId
.
Symbol
;
if
(
symbol
.
AssociatedSymbol
!=
null
)
// If we've been asked to search for specific accessors, then do not cascade.
// We don't want to produce results for the associated property.
if
(!
options
.
AssociatePropertyReferencesWithSpecificAccessor
)
{
result
=
result
.
Add
(
symbolAndProjectId
.
WithSymbol
(
symbol
.
AssociatedSymbol
));
var
symbol
=
symbolAndProjectId
.
Symbol
;
if
(
symbol
.
AssociatedSymbol
!=
null
)
{
result
=
result
.
Add
(
symbolAndProjectId
.
WithSymbol
(
symbol
.
AssociatedSymbol
));
}
}
return
result
;
}
protected
override
Task
<
ImmutableArray
<
Document
>>
DetermineDocumentsToSearchAsync
(
protected
override
async
Task
<
ImmutableArray
<
Document
>>
DetermineDocumentsToSearchAsync
(
IMethodSymbol
symbol
,
Project
project
,
IImmutableSet
<
Document
>
documents
,
FindReferencesSearchOptions
options
,
CancellationToken
cancellationToken
)
{
return
FindDocumentsAsync
(
project
,
documents
,
cancellationToken
,
symbol
.
Name
);
var
result
=
await
FindDocumentsAsync
(
project
,
documents
,
cancellationToken
,
symbol
.
Name
).
ConfigureAwait
(
false
);
if
(
options
.
AssociatePropertyReferencesWithSpecificAccessor
)
{
// we want to associate normal property references with the specific
// accessor being referenced. So we also need to include documents
// with our property's name.
var
propDocuments
=
await
FindDocumentsAsync
(
project
,
documents
,
cancellationToken
,
symbol
.
AssociatedSymbol
.
Name
).
ConfigureAwait
(
false
);
result
=
result
.
AddRange
(
propDocuments
);
}
return
result
;
}
protected
override
Task
<
ImmutableArray
<
ReferenceLocation
>>
FindReferencesInDocumentAsync
(
protected
override
async
Task
<
ImmutableArray
<
ReferenceLocation
>>
FindReferencesInDocumentAsync
(
IMethodSymbol
symbol
,
Document
document
,
SemanticModel
semanticModel
,
FindReferencesSearchOptions
options
,
CancellationToken
cancellationToken
)
{
return
FindReferencesInDocumentUsingSymbolNameAsync
(
symbol
,
document
,
semanticModel
,
cancellationToken
);
var
references
=
await
FindReferencesInDocumentUsingSymbolNameAsync
(
symbol
,
document
,
semanticModel
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
symbol
.
AssociatedSymbol
is
IPropertySymbol
property
&&
options
.
AssociatePropertyReferencesWithSpecificAccessor
)
{
var
propertyReferences
=
await
ReferenceFinders
.
Property
.
FindReferencesInDocumentAsync
(
SymbolAndProjectId
.
Create
(
property
,
document
.
Project
.
Id
),
document
,
semanticModel
,
options
.
WithAssociatePropertyReferencesWithSpecificAccessor
(
false
),
cancellationToken
).
ConfigureAwait
(
false
);
var
semanticFacts
=
document
.
GetLanguageService
<
ISemanticFactsService
>();
var
accessorReferences
=
propertyReferences
.
WhereAsArray
(
loc
=>
{
var
accessors
=
GetReferencedAccessorSymbols
(
semanticFacts
,
semanticModel
,
property
,
loc
.
Location
.
FindNode
(
getInnermostNodeForTie
:
true
,
cancellationToken
),
cancellationToken
);
return
accessors
.
Contains
(
symbol
);
});
references
=
references
.
AddRange
(
accessorReferences
);
}
return
references
;
}
}
}
src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs
浏览文件 @
d1a672eb
...
...
@@ -93,6 +93,23 @@ private static bool IsForEachProperty(IPropertySymbol symbol)
var
nameReferences
=
await
FindReferencesInDocumentUsingSymbolNameAsync
(
symbol
,
document
,
semanticModel
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
options
.
AssociatePropertyReferencesWithSpecificAccessor
)
{
// We want to associate property references to a specific accessor (if an accessor
// is being referenced). Check if this reference would match an accessor. if so, do
// not add it. It will be added by PropertyAccessorSymbolReferenceFinder.
var
semanticFacts
=
document
.
GetLanguageService
<
ISemanticFactsService
>();
nameReferences
=
nameReferences
.
WhereAsArray
(
loc
=>
{
var
accessors
=
GetReferencedAccessorSymbols
(
semanticFacts
,
semanticModel
,
symbol
,
loc
.
Location
.
FindNode
(
getInnermostNodeForTie
:
true
,
cancellationToken
),
cancellationToken
);
return
accessors
.
Length
==
0
;
});
}
var
forEachReferences
=
IsForEachProperty
(
symbol
)
?
await
FindReferencesInForEachStatementsAsync
(
symbol
,
document
,
semanticModel
,
cancellationToken
).
ConfigureAwait
(
false
)
:
ImmutableArray
<
ReferenceLocation
>.
Empty
;
...
...
src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
浏览文件 @
d1a672eb
...
...
@@ -130,7 +130,8 @@ public static partial class SymbolFinder
{
foreach
(
var
interfaceType
in
GetAllInterfaces
(
type
))
{
if
(
interfaceType
.
Symbol
.
MemberNames
.
Contains
(
symbol
.
Name
))
if
(
interfaceType
.
Symbol
.
MemberNames
.
Contains
(
symbol
.
Name
)
||
symbol
.
IsPropertyAccessor
())
{
foreach
(
var
m
in
GetMembers
(
interfaceType
,
symbol
.
Name
))
{
...
...
src/Workspaces/Core/Portable/Remote/RemoteArguments.cs
浏览文件 @
d1a672eb
...
...
@@ -14,16 +14,19 @@ namespace Microsoft.CodeAnalysis.Remote
internal
class
SerializableFindReferencesSearchOptions
{
public
bool
AssociatePropertyReferencesWithSpecificAccessor
;
public
static
SerializableFindReferencesSearchOptions
Dehydrate
(
FindReferencesSearchOptions
options
)
{
return
new
SerializableFindReferencesSearchOptions
{
AssociatePropertyReferencesWithSpecificAccessor
=
options
.
AssociatePropertyReferencesWithSpecificAccessor
};
}
public
FindReferencesSearchOptions
Rehydrate
()
{
return
new
FindReferencesSearchOptions
();
return
new
FindReferencesSearchOptions
(
AssociatePropertyReferencesWithSpecificAccessor
);
}
}
...
...
src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs
浏览文件 @
d1a672eb
...
...
@@ -50,10 +50,23 @@ internal static partial class IFindReferencesResultExtensions
return
false
;
}
// We don't want to clutter the UI with property accessors if there are no direct
if
(
definition
.
IsPropertyAccessor
())
// If we're associating property references with an accessor, then we don't want to show
// a property if it is has no references. Similarly, if we're associated associating
// everything with the property, then we don't want to include accessors if there are no
// references to them.
if
(
options
.
AssociatePropertyReferencesWithSpecificAccessor
)
{
return
false
;
if
(
definition
.
Kind
==
SymbolKind
.
Property
)
{
return
false
;
}
}
else
{
if
(
definition
.
IsPropertyAccessor
())
{
return
false
;
}
}
// Otherwise we still show the item even if there are no references to it.
...
...
src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs
浏览文件 @
d1a672eb
...
...
@@ -135,9 +135,15 @@ public static bool IsImplementableMember(this ISymbol symbol)
return
true
;
}
if
(
symbol
.
Kind
==
SymbolKind
.
Method
&&
((
IMethodSymbol
)
symbol
).
MethodKind
==
MethodKind
.
Ordinary
)
if
(
symbol
.
Kind
==
SymbolKind
.
Method
)
{
return
true
;
var
methodSymbol
=
(
IMethodSymbol
)
symbol
;
if
(
methodSymbol
.
MethodKind
==
MethodKind
.
Ordinary
||
methodSymbol
.
MethodKind
==
MethodKind
.
PropertyGet
||
methodSymbol
.
MethodKind
==
MethodKind
.
PropertySet
)
{
return
true
;
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录