Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
c26f4339
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,发现更多精彩内容 >>
提交
c26f4339
编写于
11月 04, 2019
作者:
G
Gen Lu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address review comments
上级
6b7e67f6
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
90 addition
and
97 deletion
+90
-97
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs
...ortCompletionProvider/AbstractImportCompletionProvider.cs
+1
-1
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletionHelper.cs
...mpletionProvider/ExtensionMethodImportCompletionHelper.cs
+84
-83
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/SerializableImportCompletionItem.cs
...ortCompletionProvider/SerializableImportCompletionItem.cs
+1
-1
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
...arp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
+0
-5
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
...Symbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
+2
-0
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs
...able/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs
+1
-1
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
...anguageServices/SyntaxFactsService/ISyntaxFactsService.cs
+0
-1
src/Workspaces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
...ces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
+1
-1
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
...ortable/LanguageServices/VisualBasicSyntaxFactsService.vb
+0
-4
未找到文件。
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs
浏览文件 @
c26f4339
...
...
@@ -189,7 +189,7 @@ private static async Task<bool> IsInImportsDirectiveAsync(Document document, int
var
syntaxFacts
=
document
.
GetRequiredLanguageService
<
ISyntaxFactsService
>();
var
syntaxTree
=
await
document
.
GetSyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
leftToken
=
syntaxTree
.
FindTokenOnLeftOfPosition
(
position
,
cancellationToken
,
includeDirectives
:
true
);
return
leftToken
.
GetAncestor
(
syntaxFacts
.
IsUsingOrImport
)
!=
null
;
return
leftToken
.
GetAncestor
(
syntaxFacts
.
IsUsingOr
ExternOr
Import
)
!=
null
;
}
protected
static
bool
IsAddingImportsSupported
(
Document
document
)
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletionHelper.cs
浏览文件 @
c26f4339
...
...
@@ -87,8 +87,7 @@ internal static partial class ExtensionMethodImportCompletionHelper
var
counter
=
new
StatisticCounter
();
var
ticks
=
Environment
.
TickCount
;
var
project
=
document
.
Project
;
var
assembly
=
(
await
project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
compilation
=
await
document
.
Project
.
GetRequiredCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
// Get the metadata name of all the base types and interfaces this type derived from.
using
var
_
=
PooledHashSet
<
string
>.
GetInstance
(
out
var
allTypeNamesBuilder
);
...
...
@@ -103,14 +102,11 @@ internal static partial class ExtensionMethodImportCompletionHelper
}
var
allTypeNames
=
allTypeNamesBuilder
.
ToImmutableArray
();
var
matchedMethods
=
await
GetPossibleExtensionMethodMatchesAsync
(
project
,
allTypeNames
,
forceIndexCreation
,
isPrecalculation
:
false
,
cancellationToken
).
ConfigureAwait
(
false
);
counter
.
GetFilterTicks
=
Environment
.
TickCount
-
ticks
;
counter
.
NoFilter
=
matchedMethods
==
null
;
var
indicesResult
=
await
TryGetIndicesAsync
(
document
.
Project
,
forceIndexCreation
,
cancellationToken
).
ConfigureAwait
(
false
);
// Don't show unimported extension methods if the index isn't ready.
if
(
matchedMethods
==
null
)
if
(
!
indicesResult
.
HasResult
)
{
// We use a very simple approach to build the cache in the background:
// queue a new task only if the previous task is completed, regardless of what
...
...
@@ -119,17 +115,22 @@ internal static partial class ExtensionMethodImportCompletionHelper
{
if
(
s_indexingTask
.
IsCompleted
)
{
s_indexingTask
=
Task
.
Run
(()
=>
GetPossibleExtensionMethodMatchesAsync
(
project
,
allTypeNames
,
forceIndexCreation
:
false
,
isPrecalcul
ation
:
true
,
CancellationToken
.
None
));
s_indexingTask
=
Task
.
Run
(()
=>
TryGetIndicesAsync
(
document
.
Project
,
forceIndexCre
ation
:
true
,
CancellationToken
.
None
));
}
}
return
(
ImmutableArray
<
SerializableImportCompletionItem
>.
Empty
,
counter
);
}
var
matchedMethods
=
CreateAggregatedFilter
(
allTypeNames
,
indicesResult
.
SyntaxIndices
,
indicesResult
.
SymbolInfos
);
counter
.
GetFilterTicks
=
Environment
.
TickCount
-
ticks
;
counter
.
NoFilter
=
!
indicesResult
.
HasResult
;
ticks
=
Environment
.
TickCount
;
var
semanticModel
=
await
document
.
GetSemanticModelAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
items
=
GetExtensionMethodItems
(
assembly
.
GlobalNamespace
,
receiverTypeSymbol
,
var
items
=
GetExtensionMethodItems
(
compilation
.
GlobalNamespace
,
receiverTypeSymbol
,
semanticModel
!,
position
,
namespaceInScope
,
matchedMethods
,
counter
,
cancellationToken
);
counter
.
GetSymbolTicks
=
Environment
.
TickCount
-
ticks
;
...
...
@@ -137,11 +138,9 @@ internal static partial class ExtensionMethodImportCompletionHelper
return
(
items
,
counter
);
}
private
static
async
Task
<
MultiDictionary
<
string
,
string
>?>
GetPossibleExtensionMethodMatch
esAsync
(
private
static
async
Task
<
GetIndicesResult
>
TryGetIndic
esAsync
(
Project
currentProject
,
ImmutableArray
<
string
>
targetTypeNames
,
bool
forceIndexCreation
,
bool
isPrecalculation
,
CancellationToken
cancellationToken
)
{
var
solution
=
currentProject
.
Solution
;
...
...
@@ -152,105 +151,92 @@ internal static partial class ExtensionMethodImportCompletionHelper
using
var
syntaxDisposer
=
ArrayBuilder
<
CacheEntry
>.
GetInstance
(
out
var
syntaxBuilder
);
using
var
symbolDisposer
=
ArrayBuilder
<
SymbolTreeInfo
>.
GetInstance
(
out
var
symbolBuilder
);
var
peReferences
=
PooledHashSet
<
PortableExecutableReference
>.
GetInstance
();
// We will only create missing indices in the following cases, neither would block completion.
// 1. We are asked explicitly to create missing indices (e.g. via expander)
// 2. We are trying to populate the data in background.
var
shouldCreateIndex
=
forceIndexCreation
||
isPrecalculation
;
try
foreach
(
var
projectId
in
relevantProjectIds
)
{
foreach
(
var
projectId
in
relevantProjectIds
)
var
project
=
solution
.
GetProject
(
projectId
);
if
(
project
==
null
||
!
project
.
SupportsCompilation
)
{
var
project
=
solution
.
GetProject
(
projectId
);
if
(
project
==
null
||
!
project
.
SupportsCompilation
)
{
continue
;
}
// Transitively get all the PE references
peReferences
.
AddRange
(
project
.
MetadataReferences
.
OfType
<
PortableExecutableReference
>());
continue
;
}
// By default, don't trigger index creation except for documents in current project.
var
loadOnly
=
!
shouldCreateIndex
&&
projectId
!=
currentProject
.
Id
;
var
cacheEntry
=
await
GetCacheEntryAsync
(
project
,
loadOnly
,
cacheService
,
cancellationToken
).
ConfigureAwait
(
false
);
// By default, don't trigger index creation except for documents in current project.
var
loadOnly
=
!
forceIndexCreation
&&
projectId
!=
currentProject
.
Id
;
var
cacheEntry
=
await
GetCacheEntryAsync
(
project
,
loadOnly
,
cacheService
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
cacheEntry
==
null
)
{
// Don't provide anything if we don't have all the required SyntaxTreeIndex created.
if
(
cacheEntry
==
null
)
{
return
null
;
}
syntaxBuilder
.
Add
(
cacheEntry
.
Value
);
return
GetIndicesResult
.
NoneResult
;
}
foreach
(
var
peReference
in
peReferences
)
{
var
info
=
await
SymbolTreeInfo
.
GetInfoForMetadataReferenceAsync
(
solution
,
peReference
,
loadOnly
:
!
shouldCreateIndex
,
cancellationToken
).
ConfigureAwait
(
false
);
syntaxBuilder
.
Add
(
cacheEntry
.
Value
);
}
// Don't provide anything if we don't have all the required SymbolTreeInfo created
.
if
(
info
==
null
)
{
return
null
;
}
// Search through all direct PE references
.
foreach
(
var
peReference
in
currentProject
.
MetadataReferences
.
OfType
<
PortableExecutableReference
>()
)
{
var
info
=
await
SymbolTreeInfo
.
GetInfoForMetadataReferenceAsync
(
solution
,
peReference
,
loadOnly
:
!
forceIndexCreation
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
info
.
ContainsExtensionMethod
)
{
symbolBuilder
.
Add
(
info
);
}
if
(
info
==
null
)
{
// Don't provide anything if we don't have all the required SymbolTreeInfo created.
return
GetIndicesResult
.
NoneResult
;
}
// We are just trying to populate the cache in background, no need to return any results.
if
(
isPrecalculation
)
if
(
info
.
ContainsExtensionMethod
)
{
return
null
;
symbolBuilder
.
Add
(
info
)
;
}
}
var
results
=
new
MultiDictionary
<
string
,
string
>();
var
syntaxIndices
=
syntaxBuilder
.
ToImmutable
();
var
symbolInfos
=
symbolBuilder
.
ToImmutable
();
return
new
GetIndicesResult
(
hasResult
:
true
,
syntaxIndices
,
symbolInfos
);
}
// Find matching extension methods from source.
foreach
(
var
info
in
syntaxBuilder
)
private
static
MultiDictionary
<
string
,
string
>
CreateAggregatedFilter
(
ImmutableArray
<
string
>
targetTypeNames
,
ImmutableArray
<
CacheEntry
>
syntaxIndices
,
ImmutableArray
<
SymbolTreeInfo
>
symbolInfos
)
{
var
results
=
new
MultiDictionary
<
string
,
string
>();
// Find matching extension methods from source.
foreach
(
var
index
in
syntaxIndices
)
{
// Add simple extension methods with matching target type name
foreach
(
var
targetTypeName
in
targetTypeNames
)
{
// Add simple extension methods with matching target type name
foreach
(
var
targetTypeName
in
targetTypeNames
)
var
methodInfos
=
index
.
SimpleExtensionMethodInfo
[
targetTypeName
];
if
(
methodInfos
.
Count
==
0
)
{
var
methodInfos
=
info
.
SimpleExtensionMethodInfo
[
targetTypeName
];
if
(
methodInfos
.
Count
==
0
)
{
continue
;
}
foreach
(
var
methodInfo
in
methodInfos
)
{
results
.
Add
(
methodInfo
.
FullyQualifiedContainerName
,
methodInfo
.
Name
);
}
continue
;
}
// Add all complex extension methods, we will need to completely rely on symbols to match them.
foreach
(
var
methodInfo
in
info
.
ComplexExtensionMethodInfo
)
foreach
(
var
methodInfo
in
methodInfos
)
{
results
.
Add
(
methodInfo
.
FullyQualifiedContainerName
,
methodInfo
.
Name
);
}
}
//
Find matching extension methods from metadata
foreach
(
var
info
in
symbolBuilder
)
//
Add all complex extension methods, we will need to completely rely on symbols to match them.
foreach
(
var
methodInfo
in
index
.
ComplexExtensionMethodInfo
)
{
var
methodInfos
=
info
.
GetMatchingExtensionMethodInfo
(
targetTypeNames
);
foreach
(
var
methodInfo
in
methodInfos
)
{
results
.
Add
(
methodInfo
.
FullyQualifiedContainerName
,
methodInfo
.
Name
);
}
results
.
Add
(
methodInfo
.
FullyQualifiedContainerName
,
methodInfo
.
Name
);
}
return
results
;
}
finally
// Find matching extension methods from metadata
foreach
(
var
info
in
symbolInfos
)
{
peReferences
.
Free
();
var
methodInfos
=
info
.
GetMatchingExtensionMethodInfo
(
targetTypeNames
);
foreach
(
var
methodInfo
in
methodInfos
)
{
results
.
Add
(
methodInfo
.
FullyQualifiedContainerName
,
methodInfo
.
Name
);
}
}
return
results
;
}
private
static
ImmutableArray
<
SerializableImportCompletionItem
>
GetExtensionMethodItems
(
...
...
@@ -334,7 +320,6 @@ internal static partial class ExtensionMethodImportCompletionHelper
IMethodSymbol
?
reducedMethodSymbol
=
null
;
if
(
methodSymbol
.
IsExtensionMethod
&&
(
methodNames
.
Count
==
0
||
methodNames
.
Contains
(
methodSymbol
.
Name
))
&&
IsSymbolAccessible
(
methodSymbol
,
position
,
semanticModel
))
{
reducedMethodSymbol
=
methodSymbol
.
ReduceExtensionMethod
(
receiverTypeSymbol
);
...
...
@@ -450,6 +435,22 @@ public void Dispose()
Children
.
Free
();
}
}
private
readonly
struct
GetIndicesResult
{
public
bool
HasResult
{
get
;
}
public
ImmutableArray
<
CacheEntry
>
SyntaxIndices
{
get
;
}
public
ImmutableArray
<
SymbolTreeInfo
>
SymbolInfos
{
get
;
}
public
GetIndicesResult
(
bool
hasResult
,
ImmutableArray
<
CacheEntry
>
syntaxIndices
=
default
,
ImmutableArray
<
SymbolTreeInfo
>
symbolInfos
=
default
)
{
HasResult
=
hasResult
;
SyntaxIndices
=
syntaxIndices
;
SymbolInfos
=
symbolInfos
;
}
public
static
GetIndicesResult
NoneResult
=>
new
GetIndicesResult
(
hasResult
:
false
);
}
}
internal
sealed
class
StatisticCounter
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/SerializableImportCompletionItem.cs
浏览文件 @
c26f4339
...
...
@@ -4,7 +4,7 @@
namespace
Microsoft.CodeAnalysis.Completion.Providers
{
internal
sealed
class
SerializableImportCompletionItem
internal
readonly
struct
SerializableImportCompletionItem
{
public
readonly
string
SymbolKeyData
;
public
readonly
int
Arity
;
...
...
src/Workspaces/CSharp/Portable/LanguageServices/CSharpSyntaxFactsService.cs
浏览文件 @
c26f4339
...
...
@@ -1371,11 +1371,6 @@ public bool IsUsingOrExternOrImport(SyntaxNode node)
node
.
IsKind
(
SyntaxKind
.
ExternAliasDirective
);
}
public
bool
IsUsingOrImport
(
SyntaxNode
node
)
{
return
node
.
IsKind
(
SyntaxKind
.
UsingDirective
);
}
public
bool
IsGlobalAttribute
(
SyntaxNode
node
)
{
return
node
.
IsKind
(
SyntaxKind
.
Attribute
)
&&
node
.
Parent
.
IsKind
(
SyntaxKind
.
AttributeList
)
&&
...
...
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
浏览文件 @
c26f4339
...
...
@@ -39,6 +39,8 @@ internal partial class SyntaxTreeIndex
/// </summary>
public
readonly
ImmutableArray
<
int
>
ComplexExtensionMethodInfo
{
get
;
}
public
bool
ContainsExtensionMethod
=>
SimpleExtensionMethodInfo
.
Count
>
0
||
ComplexExtensionMethodInfo
.
Length
>
0
;
public
ExtensionMethodInfo
(
ImmutableDictionary
<
string
,
ImmutableArray
<
int
>>
simpleExtensionMethodInfo
,
ImmutableArray
<
int
>
complexExtensionMethodInfo
)
...
...
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs
浏览文件 @
c26f4339
...
...
@@ -15,7 +15,7 @@ internal sealed partial class SyntaxTreeIndex
public
ImmutableArray
<
int
>
ComplexExtensionMethodInfo
=>
_extensionMethodInfo
.
ComplexExtensionMethodInfo
;
public
bool
ContainsExtensionMethod
=>
SimpleExtensionMethodInfo
.
Count
>
0
||
ComplexExtensionMethodInfo
.
Length
>
0
;
public
bool
ContainsExtensionMethod
=>
_extensionMethodInfo
.
ContainsExtensionMethod
;
public
bool
ProbablyContainsIdentifier
(
string
identifier
)
=>
_identifierInfo
.
ProbablyContainsIdentifier
(
identifier
);
public
bool
ProbablyContainsEscapedIdentifier
(
string
identifier
)
=>
_identifierInfo
.
ProbablyContainsEscapedIdentifier
(
identifier
);
...
...
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
浏览文件 @
c26f4339
...
...
@@ -89,7 +89,6 @@ internal interface ISyntaxFactsService : ILanguageService
bool
IsTypeNamedVarInVariableOrFieldDeclaration
(
SyntaxToken
token
,
SyntaxNode
parent
);
bool
IsTypeNamedDynamic
(
SyntaxToken
token
,
SyntaxNode
parent
);
bool
IsUsingOrExternOrImport
(
SyntaxNode
node
);
bool
IsUsingOrImport
(
SyntaxNode
node
);
bool
IsUsingAliasDirective
(
SyntaxNode
node
);
bool
IsGlobalAttribute
(
SyntaxNode
node
);
bool
IsDeclaration
(
SyntaxNode
node
);
...
...
src/Workspaces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
浏览文件 @
c26f4339
...
...
@@ -23,7 +23,7 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal
static
partial
class
DocumentExtensions
{
// ⚠ Verify IVTs do not use this method before removing it.
314104
// ⚠ Verify IVTs do not use this method before removing it.
public
static
TLanguageService
?
GetLanguageService
<
TLanguageService
>(
this
Document
?
document
)
where
TLanguageService
:
class
,
ILanguageService
=>
document
?.
Project
?.
LanguageServices
?.
GetService
<
TLanguageService
>();
...
...
src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicSyntaxFactsService.vb
浏览文件 @
c26f4339
...
...
@@ -1402,10 +1402,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End
Function
Public
Function
IsUsingOrExternOrImport
(
node
As
SyntaxNode
)
As
Boolean
Implements
ISyntaxFactsService
.
IsUsingOrExternOrImport
Return
IsUsingOrImport
(
node
)
End
Function
Public
Function
IsUsingOrImport
(
node
As
SyntaxNode
)
As
Boolean
Implements
ISyntaxFactsService
.
IsUsingOrImport
Return
node
.
IsKind
(
SyntaxKind
.
ImportsStatement
)
End
Function
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录