Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
95a24448
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,发现更多精彩内容 >>
提交
95a24448
编写于
6月 12, 2017
作者:
C
CyrusNajmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Cache symbol finding results to help callers who are making many calls into it.
上级
b663584e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
68 addition
and
17 deletion
+68
-17
src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs
...ortable/FindSymbols/FindReferences/DependentTypeFinder.cs
+68
-17
未找到文件。
src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs
浏览文件 @
95a24448
// 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.Concurrent
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Runtime.CompilerServices
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Roslyn.Utilities
;
...
...
@@ -15,6 +18,8 @@ namespace Microsoft.CodeAnalysis.FindSymbols
{
using
SymbolAndProjectIdSet
=
HashSet
<
SymbolAndProjectId
<
INamedTypeSymbol
>>;
using
RelatedTypeCache
=
ConditionalWeakTable
<
Solution
,
ConcurrentDictionary
<
INamedTypeSymbol
,
AsyncLazy
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>>>;
/// <summary>
/// Provides helper methods for finding dependent types (derivations, implementations,
/// etc.) across a solution. The results found are returned in pairs of <see cref="ISymbol"/>s
...
...
@@ -38,17 +43,44 @@ internal static class DependentTypeFinder
private
static
readonly
ObjectPool
<
SymbolAndProjectIdSet
>
s_setPool
=
new
ObjectPool
<
SymbolAndProjectIdSet
>(
()
=>
new
SymbolAndProjectIdSet
(
SymbolAndProjectIdComparer
<
INamedTypeSymbol
>.
SymbolEquivalenceInstance
));
// Caches from a types to their related types (in the context of a specific solution).
// Kept as a cache so that clients who make many calls into us won't end up computing
// the same data over and over again. Will be let go the moment the solution they're
// based off of is no longer alive.
private
static
readonly
RelatedTypeCache
s_typeToImmediatelyDerivedClassesMap
=
new
RelatedTypeCache
();
private
static
readonly
RelatedTypeCache
s_typeToTransitivelyDerivedClassesMap
=
new
RelatedTypeCache
();
private
static
readonly
RelatedTypeCache
s_typeToTransitivelyImplementingTypesMap
=
new
RelatedTypeCache
();
private
static
readonly
RelatedTypeCache
s_typeToImmediatelyDerivedAndImplementingTypesMap
=
new
RelatedTypeCache
();
public
static
async
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindTypesFromCacheOrComputeAsync
(
INamedTypeSymbol
type
,
Solution
solution
,
RelatedTypeCache
cache
,
Func
<
CancellationToken
,
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>>
findAsync
,
CancellationToken
cancellationToken
)
{
var
dictionary
=
cache
.
GetOrCreateValue
(
solution
);
var
lazy
=
dictionary
.
GetOrAdd
(
type
,
new
AsyncLazy
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>(
asynchronousComputeFunction
:
findAsync
,
cacheResult
:
true
));
return
await
lazy
.
GetValueAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
}
/// <summary>
/// Used for implementing the Inherited-By relation for progression.
/// </summary>
internal
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindImmediatelyDerivedClassesAsync
(
public
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindImmediatelyDerivedClassesAsync
(
INamedTypeSymbol
type
,
Solution
solution
,
CancellationToken
cancellationToken
)
{
return
FindDerivedClassesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
:
null
,
transitive
:
false
,
cancellationToken
:
cancellationToken
);
return
FindTypesFromCacheOrComputeAsync
(
type
,
solution
,
s_typeToImmediatelyDerivedClassesMap
,
c
=>
FindDerivedClassesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
:
null
,
transitive
:
false
,
cancellationToken
:
c
),
cancellationToken
);
}
/// <summary>
...
...
@@ -60,9 +92,12 @@ internal static class DependentTypeFinder
IImmutableSet
<
Project
>
projects
,
CancellationToken
cancellationToken
)
{
return
FindDerivedClassesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
,
transitive
:
true
,
cancellationToken
:
cancellationToken
);
return
FindTypesFromCacheOrComputeAsync
(
type
,
solution
,
s_typeToTransitivelyDerivedClassesMap
,
c
=>
FindDerivedClassesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
,
transitive
:
true
,
cancellationToken
:
c
),
cancellationToken
);
}
private
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindDerivedClassesAsync
(
...
...
@@ -95,7 +130,19 @@ internal static class DependentTypeFinder
/// Implementation of <see cref="SymbolFinder.FindImplementationsAsync(SymbolAndProjectId, Solution, IImmutableSet{Project}, CancellationToken)"/> for
/// <see cref="INamedTypeSymbol"/>s
/// </summary>
public
static
async
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindTransitivelyImplementingTypesAsync
(
public
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindTransitivelyImplementingTypesAsync
(
INamedTypeSymbol
type
,
Solution
solution
,
IImmutableSet
<
Project
>
projects
,
CancellationToken
cancellationToken
)
{
return
FindTypesFromCacheOrComputeAsync
(
type
,
solution
,
s_typeToTransitivelyImplementingTypesMap
,
c
=>
FindTransitivelyImplementingTypesWorkerAsync
(
type
,
solution
,
projects
,
c
),
cancellationToken
);
}
private
static
async
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindTransitivelyImplementingTypesWorkerAsync
(
INamedTypeSymbol
type
,
Solution
solution
,
IImmutableSet
<
Project
>
projects
,
...
...
@@ -113,14 +160,17 @@ internal static class DependentTypeFinder
/// <summary>
/// Used for implementing the Inherited-By relation for progression.
/// </summary>
internal
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindImmediatelyDerivedAndImplementingTypesAsync
(
public
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindImmediatelyDerivedAndImplementingTypesAsync
(
INamedTypeSymbol
type
,
Solution
solution
,
CancellationToken
cancellationToken
)
{
return
FindDerivedAndImplementingTypesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
:
null
,
transitive
:
false
,
cancellationToken
:
cancellationToken
);
return
FindTypesFromCacheOrComputeAsync
(
type
,
solution
,
s_typeToImmediatelyDerivedAndImplementingTypesMap
,
c
=>
FindDerivedAndImplementingTypesAsync
(
SymbolAndProjectId
.
Create
(
type
,
projectId
:
null
),
solution
,
projects
:
null
,
transitive
:
false
,
cancellationToken
:
c
),
cancellationToken
);
}
private
static
Task
<
ImmutableArray
<
SymbolAndProjectId
<
INamedTypeSymbol
>>>
FindDerivedAndImplementingTypesAsync
(
...
...
@@ -553,7 +603,8 @@ internal static class DependentTypeFinder
var
typesToSearchFor
=
CreateSymbolAndProjectIdSet
();
typesToSearchFor
.
AddAll
(
sourceAndMetadataTypes
);
var
inheritanceQuery
=
new
InheritanceQuery
(
sourceAndMetadataTypes
);
var
caseSensitive
=
project
.
LanguageServices
.
GetService
<
ISyntaxFactsService
>().
IsCaseSensitive
;
var
inheritanceQuery
=
new
InheritanceQuery
(
sourceAndMetadataTypes
,
caseSensitive
);
// As long as there are new types to search for, keep looping.
while
(
typesToSearchFor
.
Count
>
0
)
...
...
@@ -562,10 +613,10 @@ internal static class DependentTypeFinder
inheritanceQuery
.
TypeNames
.
AddRange
(
typesToSearchFor
.
Select
(
c
=>
c
.
Symbol
.
Name
));
// Search all the documents of this project in parallel.
var
tasks
=
project
.
Documents
.
Select
(
d
=>
FindImmediatelyInheritingTypesInDocumentAsync
(
var
tasks
=
project
.
Documents
.
Select
(
d
=>
Task
.
Run
(()
=>
FindImmediatelyInheritingTypesInDocumentAsync
(
d
,
typesToSearchFor
,
inheritanceQuery
,
cachedModels
,
cachedInfos
,
sourceTypeImmediatelyMatches
,
cancellationToken
)).
ToArray
();
sourceTypeImmediatelyMatches
,
cancellationToken
)
,
cancellationToken
)
).
ToArray
();
await
Task
.
WhenAll
(
tasks
).
ConfigureAwait
(
false
);
...
...
@@ -720,13 +771,13 @@ private class InheritanceQuery
public
readonly
HashSet
<
string
>
TypeNames
;
public
InheritanceQuery
(
SymbolAndProjectIdSet
sourceAndMetadataTypes
)
public
InheritanceQuery
(
SymbolAndProjectIdSet
sourceAndMetadataTypes
,
bool
caseSensitive
)
{
DerivesFromSystemObject
=
sourceAndMetadataTypes
.
Any
(
t
=>
t
.
Symbol
.
SpecialType
==
SpecialType
.
System_Object
);
DerivesFromSystemValueType
=
sourceAndMetadataTypes
.
Any
(
t
=>
t
.
Symbol
.
SpecialType
==
SpecialType
.
System_ValueType
);
DerivesFromSystemEnum
=
sourceAndMetadataTypes
.
Any
(
t
=>
t
.
Symbol
.
SpecialType
==
SpecialType
.
System_Enum
);
DerivesFromSystemMulticastDelegate
=
sourceAndMetadataTypes
.
Any
(
t
=>
t
.
Symbol
.
SpecialType
==
SpecialType
.
System_MulticastDelegate
);
TypeNames
=
new
HashSet
<
string
>(
StringComparer
.
OrdinalIgnoreCase
);
TypeNames
=
caseSensitive
?
new
HashSet
<
string
>()
:
new
HashSet
<
string
>(
StringComparer
.
OrdinalIgnoreCase
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录