Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
47b80b58
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,发现更多精彩内容 >>
提交
47b80b58
编写于
7月 01, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Cache previous results of NavigateTo so we can filter quickly as the user types.
上级
458c526a
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
117 addition
and
24 deletion
+117
-24
src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs
...e/NavigateTo/AbstractNavigateToSearchService.InProcess.cs
+111
-19
src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.SearchResult.cs
...avigateTo/AbstractNavigateToSearchService.SearchResult.cs
+6
-5
未找到文件。
src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs
浏览文件 @
47b80b58
// 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
;
using
System.Collections.Immutable
;
using
System.Linq
;
using
System.Runtime.CompilerServices
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.FindSymbols
;
...
...
@@ -15,21 +17,24 @@ namespace Microsoft.CodeAnalysis.NavigateTo
{
internal
abstract
partial
class
AbstractNavigateToSearchService
{
private
static
ConditionalWeakTable
<
Project
,
Tuple
<
string
,
ImmutableArray
<
SearchResult
>>>
s_lastProjectSearchCache
=
new
ConditionalWeakTable
<
Project
,
Tuple
<
string
,
ImmutableArray
<
SearchResult
>>>();
public
static
Task
<
ImmutableArray
<
INavigateToSearchResult
>>
SearchProjectInCurrentProcessAsync
(
Project
project
,
string
searchPattern
,
CancellationToken
cancellationToken
)
{
return
Find
NavigableDeclaredSymbolInfo
sAsync
(
return
Find
SearchResult
sAsync
(
project
,
searchDocument
:
null
,
pattern
:
searchPattern
,
cancellationToken
:
cancellationToken
);
}
public
static
Task
<
ImmutableArray
<
INavigateToSearchResult
>>
SearchDocumentInCurrentProcessAsync
(
Document
document
,
string
searchPattern
,
CancellationToken
cancellationToken
)
{
return
Find
NavigableDeclaredSymbolInfo
sAsync
(
return
Find
SearchResult
sAsync
(
document
.
Project
,
document
,
searchPattern
,
cancellationToken
);
}
private
static
async
Task
<
ImmutableArray
<
INavigateToSearchResult
>>
Find
NavigableDeclaredSymbolInfo
sAsync
(
private
static
async
Task
<
ImmutableArray
<
INavigateToSearchResult
>>
Find
SearchResult
sAsync
(
Project
project
,
Document
searchDocument
,
string
pattern
,
CancellationToken
cancellationToken
)
{
// If the user created a dotted pattern then we'll grab the last part of the name
...
...
@@ -48,9 +53,19 @@ internal abstract partial class AbstractNavigateToSearchService
try
{
return
await
FindNavigableDeclaredSymbolInfosAsync
(
project
,
searchDocument
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
cancellationToken
).
ConfigureAwait
(
false
);
// If we're searching a single document, then just do a full search of
// that document (we're fast enough to not need to optimize that case).
//
// If, however, we are searching a project, then see if we could potentially
// use the last computed results we have for that project. If so, it can
// be much faster to reuse and filter that result than to compute it from
// scratch.
var
task
=
searchDocument
!=
null
?
ComputeSearchResultsAsync
(
project
,
searchDocument
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
cancellationToken
)
:
TryFilterPreviousSearchResultsAsync
(
project
,
searchDocument
,
pattern
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
cancellationToken
);
var
searchResults
=
await
task
.
ConfigureAwait
(
false
);
return
ImmutableArray
<
INavigateToSearchResult
>.
CastUp
(
searchResults
);
}
finally
{
...
...
@@ -60,13 +75,77 @@ internal abstract partial class AbstractNavigateToSearchService
}
}
private
static
async
Task
<
ImmutableArray
<
INavigateToSearchResult
>>
FindNavigableDeclaredSymbolInfosAsync
(
private
static
async
Task
<
ImmutableArray
<
SearchResult
>>
TryFilterPreviousSearchResultsAsync
(
Project
project
,
Document
searchDocument
,
string
pattern
,
PatternMatcher
nameMatcher
,
PatternMatcher
containerMatcherOpt
,
ArrayBuilder
<
PatternMatch
>
nameMatches
,
ArrayBuilder
<
PatternMatch
>
containerMatches
,
CancellationToken
cancellationToken
)
{
// Searching an entire project. See if we already performed that same
// search with a substring of the current pattern. if so, we can use
// the previous result and just filter that down. This is useful for
// the common case where a user types some pattern, then keeps adding
// to it.
ImmutableArray
<
SearchResult
>
searchResults
;
if
(
s_lastProjectSearchCache
.
TryGetValue
(
project
,
out
var
previousResult
)
&&
pattern
.
StartsWith
(
previousResult
.
Item1
))
{
// We can reuse the previous results and just filter them.
searchResults
=
FilterPreviousResults
(
previousResult
.
Item2
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
cancellationToken
);
}
else
{
// Didn't have previous results. Or it was a very different pattern.
// Can't reuse.
searchResults
=
await
ComputeSearchResultsAsync
(
project
,
searchDocument
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
cancellationToken
).
ConfigureAwait
(
false
);
}
// Would like to use CWT.AddOrUpdate. But that is not available on the
// version of .Net that we're using. So we need to take lock as we're
// making multiple mutations.
lock
(
s_lastProjectSearchCache
)
{
s_lastProjectSearchCache
.
Remove
(
project
);
s_lastProjectSearchCache
.
Add
(
project
,
Tuple
.
Create
(
pattern
,
searchResults
));
}
return
searchResults
;
}
private
static
ImmutableArray
<
SearchResult
>
FilterPreviousResults
(
ImmutableArray
<
SearchResult
>
previousResults
,
PatternMatcher
nameMatcher
,
PatternMatcher
containerMatcherOpt
,
ArrayBuilder
<
PatternMatch
>
nameMatches
,
ArrayBuilder
<
PatternMatch
>
containerMatches
,
CancellationToken
cancellationToken
)
{
var
result
=
ArrayBuilder
<
SearchResult
>.
GetInstance
();
foreach
(
var
previousResult
in
previousResults
)
{
var
document
=
previousResult
.
Document
;
var
info
=
previousResult
.
DeclaredSymbolInfo
;
ExamineInfo
(
document
,
info
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
result
,
cancellationToken
);
}
return
result
.
ToImmutableAndFree
();
}
private
static
async
Task
<
ImmutableArray
<
SearchResult
>>
ComputeSearchResultsAsync
(
Project
project
,
Document
searchDocument
,
PatternMatcher
nameMatcher
,
PatternMatcher
containerMatcherOpt
,
ArrayBuilder
<
PatternMatch
>
nameMatches
,
ArrayBuilder
<
PatternMatch
>
containerMatches
,
CancellationToken
cancellationToken
)
{
var
result
=
ArrayBuilder
<
INavigateTo
SearchResult
>.
GetInstance
();
var
result
=
ArrayBuilder
<
SearchResult
>.
GetInstance
();
foreach
(
var
document
in
project
.
Documents
)
{
if
(
searchDocument
!=
null
&&
document
!=
searchDocument
)
...
...
@@ -79,23 +158,36 @@ internal abstract partial class AbstractNavigateToSearchService
foreach
(
var
declaredSymbolInfo
in
declarationInfo
.
DeclaredSymbolInfos
)
{
nameMatches
.
Clear
();
containerMatches
.
Clear
();
cancellationToken
.
ThrowIfCancellationRequested
();
if
(
nameMatcher
.
AddMatches
(
declaredSymbolInfo
.
Name
,
nameMatches
)
&&
containerMatcherOpt
?.
AddMatches
(
declaredSymbolInfo
.
FullyQualifiedContainerName
,
containerMatches
)
!=
false
)
{
result
.
Add
(
ConvertResult
(
declaredSymbolInfo
,
document
,
nameMatches
,
containerMatches
));
}
ExamineInfo
(
document
,
declaredSymbolInfo
,
nameMatcher
,
containerMatcherOpt
,
nameMatches
,
containerMatches
,
result
,
cancellationToken
);
}
}
return
result
.
ToImmutableAndFree
();
}
private
static
INavigateToSearchResult
ConvertResult
(
private
static
void
ExamineInfo
(
Document
document
,
DeclaredSymbolInfo
declaredSymbolInfo
,
PatternMatcher
nameMatcher
,
PatternMatcher
containerMatcherOpt
,
ArrayBuilder
<
PatternMatch
>
nameMatches
,
ArrayBuilder
<
PatternMatch
>
containerMatches
,
ArrayBuilder
<
SearchResult
>
result
,
CancellationToken
cancellationToken
)
{
nameMatches
.
Clear
();
containerMatches
.
Clear
();
cancellationToken
.
ThrowIfCancellationRequested
();
if
(
nameMatcher
.
AddMatches
(
declaredSymbolInfo
.
Name
,
nameMatches
)
&&
containerMatcherOpt
?.
AddMatches
(
declaredSymbolInfo
.
FullyQualifiedContainerName
,
containerMatches
)
!=
false
)
{
result
.
Add
(
ConvertResult
(
declaredSymbolInfo
,
document
,
nameMatches
,
containerMatches
));
}
}
private
static
SearchResult
ConvertResult
(
DeclaredSymbolInfo
declaredSymbolInfo
,
Document
document
,
ArrayBuilder
<
PatternMatch
>
nameMatches
,
ArrayBuilder
<
PatternMatch
>
containerMatches
)
{
...
...
src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.SearchResult.cs
浏览文件 @
47b80b58
...
...
@@ -16,7 +16,7 @@ internal abstract partial class AbstractNavigateToSearchService
private
class
SearchResult
:
INavigateToSearchResult
{
public
string
AdditionalInformation
=>
_lazyAdditionalInfo
.
Value
;
public
string
Name
=>
_d
eclaredSymbolInfo
.
Name
;
public
string
Name
=>
D
eclaredSymbolInfo
.
Name
;
public
string
Summary
{
get
;
}
public
string
Kind
{
get
;
}
...
...
@@ -26,8 +26,9 @@ private class SearchResult : INavigateToSearchResult
public
bool
IsCaseSensitive
{
get
;
}
public
ImmutableArray
<
TextSpan
>
NameMatchSpans
{
get
;
}
private
readonly
Document
_document
;
private
readonly
DeclaredSymbolInfo
_declaredSymbolInfo
;
public
readonly
Document
Document
;
public
readonly
DeclaredSymbolInfo
DeclaredSymbolInfo
;
private
readonly
Lazy
<
string
>
_lazyAdditionalInfo
;
public
SearchResult
(
...
...
@@ -35,8 +36,8 @@ private class SearchResult : INavigateToSearchResult
NavigateToMatchKind
matchKind
,
bool
isCaseSensitive
,
INavigableItem
navigableItem
,
ImmutableArray
<
TextSpan
>
nameMatchSpans
)
{
_d
ocument
=
document
;
_d
eclaredSymbolInfo
=
declaredSymbolInfo
;
D
ocument
=
document
;
D
eclaredSymbolInfo
=
declaredSymbolInfo
;
Kind
=
kind
;
MatchKind
=
matchKind
;
IsCaseSensitive
=
isCaseSensitive
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录