Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
612f5c3c
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,发现更多精彩内容 >>
提交
612f5c3c
编写于
10月 28, 2019
作者:
G
Gen Lu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Address review comments
上级
d5d152d8
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
157 addition
and
109 deletion
+157
-109
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractExtensionMethodImportCompletionProvider.cs
...ovider/AbstractExtensionMethodImportCompletionProvider.cs
+13
-22
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionCacheServiceFactory.cs
...onProvider/AbstractImportCompletionCacheServiceFactory.cs
+10
-10
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs
...ortCompletionProvider/AbstractImportCompletionProvider.cs
+43
-45
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionService.CacheEntry.cs
...rovider/AbstractTypeImportCompletionService.CacheEntry.cs
+5
-0
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletionHelper.CacheEntry.cs
...vider/ExtensionMethodImportCompletionHelper.CacheEntry.cs
+4
-1
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletionHelper.cs
...mpletionProvider/ExtensionMethodImportCompletionHelper.cs
+1
-19
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ImportCompletionItem.cs
...roviders/ImportCompletionProvider/ImportCompletionItem.cs
+4
-1
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/SerializableImportCompletionItem.cs
...ortCompletionProvider/SerializableImportCompletionItem.cs
+25
-0
src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb
...letionProvider/ExtensionMethodImportCompletionProvider.vb
+1
-1
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.Node.cs
...re/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.Node.cs
+1
-1
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs
...ortable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs
+2
-0
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
...Symbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
+1
-1
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs
...Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs
+1
-1
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
...anguageServices/SyntaxFactsService/ISyntaxFactsService.cs
+13
-0
src/Workspaces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
...ces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
+3
-0
src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
...aces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
+12
-1
src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
+9
-0
src/Workspaces/Core/Portable/WorkspacesResources.resx
src/Workspaces/Core/Portable/WorkspacesResources.resx
+3
-0
src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_ExtensionMethodFiltering.cs
.../Services/CodeAnalysisService_ExtensionMethodFiltering.cs
+6
-6
未找到文件。
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractExtensionMethodImportCompletionProvider.cs
浏览文件 @
612f5c3c
...
...
@@ -8,6 +8,7 @@
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery
;
namespace
Microsoft.CodeAnalysis.Completion.Providers
...
...
@@ -26,10 +27,10 @@ protected override bool ShouldProvideCompletion(Document document, SyntaxContext
bool
isExpandedCompletion
,
CancellationToken
cancellationToken
)
{
var
syntaxFacts
=
completionContext
.
Document
.
Project
.
LanguageServices
.
GetRequired
Service
<
ISyntaxFactsService
>();
var
syntaxFacts
=
completionContext
.
Document
.
GetRequiredLanguage
Service
<
ISyntaxFactsService
>();
if
(
TryGetReceiverTypeSymbol
(
syntaxContext
,
syntaxFacts
,
out
var
receiverTypeSymbol
))
{
var
items
=
await
ExtensionMethodImportCompletion
Service
.
GetUnimportExtensionMethodsAsync
(
var
items
=
await
ExtensionMethodImportCompletion
Helper
.
GetUnimportExtensionMethodsAsync
(
completionContext
.
Document
,
completionContext
.
Position
,
receiverTypeSymbol
,
...
...
@@ -63,27 +64,18 @@ private static bool TryGetReceiverTypeSymbol(SyntaxContext syntaxContext, ISynta
}
private
static
ITypeSymbol
?
GetSymbolType
(
ISymbol
symbol
)
{
switch
(
symbol
)
=>
symbol
switch
{
case
ILocalSymbol
localSymbol
:
return
localSymbol
.
Type
;
case
IFieldSymbol
fieldSymbol
:
return
fieldSymbol
.
Type
;
case
IPropertySymbol
propertySymbol
:
return
propertySymbol
.
Type
;
case
IParameterSymbol
parameterSymbol
:
return
parameterSymbol
.
Type
;
case
IAliasSymbol
aliasSymbol
:
return
aliasSymbol
.
Target
as
ITypeSymbol
;
}
return
symbol
as
ITypeSymbol
;
}
ILocalSymbol
localSymbol
=>
localSymbol
.
Type
,
IFieldSymbol
fieldSymbol
=>
fieldSymbol
.
Type
,
IPropertySymbol
propertySymbol
=>
propertySymbol
.
Type
,
IParameterSymbol
parameterSymbol
=>
parameterSymbol
.
Type
,
IAliasSymbol
aliasSymbol
=>
aliasSymbol
.
Target
as
ITypeSymbol
,
_
=>
symbol
as
ITypeSymbol
,
};
private
CompletionItem
Convert
(
SerializableImportCompletionItem
serializableItem
)
{
return
ImportCompletionItem
.
Create
(
private
CompletionItem
Convert
(
SerializableImportCompletionItem
serializableItem
)
=>
ImportCompletionItem
.
Create
(
serializableItem
.
Name
,
serializableItem
.
Arity
,
serializableItem
.
ContainingNamespace
,
...
...
@@ -91,6 +83,5 @@ private CompletionItem Convert(SerializableImportCompletionItem serializableItem
GenericSuffix
,
CompletionItemFlags
.
Expanded
,
serializableItem
.
SymbolKeyData
);
}
}
}
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionCacheServiceFactory.cs
浏览文件 @
612f5c3c
...
...
@@ -10,13 +10,13 @@
namespace
Microsoft.CodeAnalysis.Completion.Providers.ImportCompletion
{
internal
abstract
class
AbstractImportCompletionCacheServiceFactory
<
TProject
,
TPortableExecutable
>
:
IWorkspaceServiceFactory
internal
abstract
class
AbstractImportCompletionCacheServiceFactory
<
TProject
CacheEntry
,
TMetadataCacheEntry
>
:
IWorkspaceServiceFactory
{
private
readonly
ConcurrentDictionary
<
string
,
T
PortableExecutable
>
_peItemsCache
=
new
ConcurrentDictionary
<
string
,
T
PortableExecutable
>();
private
readonly
ConcurrentDictionary
<
string
,
T
MetadataCacheEntry
>
_peItemsCache
=
new
ConcurrentDictionary
<
string
,
T
MetadataCacheEntry
>();
private
readonly
ConcurrentDictionary
<
ProjectId
,
TProject
>
_projectItemsCache
=
new
ConcurrentDictionary
<
ProjectId
,
TProject
>();
private
readonly
ConcurrentDictionary
<
ProjectId
,
TProject
CacheEntry
>
_projectItemsCache
=
new
ConcurrentDictionary
<
ProjectId
,
TProject
CacheEntry
>();
public
IWorkspaceService
CreateService
(
HostWorkspaceServices
workspaceServices
)
{
...
...
@@ -39,15 +39,15 @@ private void OnCacheFlushRequested(object sender, EventArgs e)
_projectItemsCache
.
Clear
();
}
private
class
ImportCompletionCacheService
:
IImportCompletionCacheService
<
TProject
,
TPortableExecutable
>
private
class
ImportCompletionCacheService
:
IImportCompletionCacheService
<
TProject
CacheEntry
,
TMetadataCacheEntry
>
{
public
IDictionary
<
string
,
T
PortableExecutable
>
PEItemsCache
{
get
;
}
public
IDictionary
<
string
,
T
MetadataCacheEntry
>
PEItemsCache
{
get
;
}
public
IDictionary
<
ProjectId
,
TProject
>
ProjectItemsCache
{
get
;
}
public
IDictionary
<
ProjectId
,
TProject
CacheEntry
>
ProjectItemsCache
{
get
;
}
public
ImportCompletionCacheService
(
ConcurrentDictionary
<
string
,
T
PortableExecutable
>
peCache
,
ConcurrentDictionary
<
ProjectId
,
TProject
>
projectCache
)
ConcurrentDictionary
<
string
,
T
MetadataCacheEntry
>
peCache
,
ConcurrentDictionary
<
ProjectId
,
TProject
CacheEntry
>
projectCache
)
{
PEItemsCache
=
peCache
;
ProjectItemsCache
=
projectCache
;
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractImportCompletionProvider.cs
浏览文件 @
612f5c3c
...
...
@@ -113,51 +113,49 @@ internal override async Task<CompletionChange> GetChangeAsync(Document document,
return
CompletionChange
.
Create
(
change
);
}
else
{
// Find context node so we can use it to decide where to insert using/imports.
var
tree
=
(
await
document
.
GetSyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
root
=
await
tree
.
GetRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
addImportContextNode
=
root
.
FindToken
(
completionListSpan
.
Start
,
findInsideTrivia
:
true
).
Parent
;
// Add required using/imports directive.
var
addImportService
=
document
.
GetLanguageService
<
IAddImportsService
>()!;
var
optionSet
=
await
document
.
GetOptionsAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
placeSystemNamespaceFirst
=
optionSet
.
GetOption
(
GenerationOptions
.
PlaceSystemNamespaceFirst
,
document
.
Project
.
Language
);
var
compilation
=
(
await
document
.
Project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
importNode
=
CreateImport
(
document
,
containingNamespace
);
var
rootWithImport
=
addImportService
.
AddImport
(
compilation
,
root
,
addImportContextNode
,
importNode
,
placeSystemNamespaceFirst
,
cancellationToken
);
var
documentWithImport
=
document
.
WithSyntaxRoot
(
rootWithImport
);
// This only formats the annotated import we just added, not the entire document.
var
formattedDocumentWithImport
=
await
Formatter
.
FormatAsync
(
documentWithImport
,
Formatter
.
Annotation
,
cancellationToken
:
cancellationToken
).
ConfigureAwait
(
false
);
var
builder
=
ArrayBuilder
<
TextChange
>.
GetInstance
();
// Get text change for add import
var
importChanges
=
await
formattedDocumentWithImport
.
GetTextChangesAsync
(
document
,
cancellationToken
).
ConfigureAwait
(
false
);
builder
.
AddRange
(
importChanges
);
// Create text change for complete type name.
//
// Note: Don't try to obtain TextChange for completed type name by replacing the text directly,
// then use Document.GetTextChangesAsync on document created from the changed text. This is
// because it will do a diff and return TextChanges with minimum span instead of actual
// replacement span.
//
// For example: If I'm typing "asd", the completion provider could be triggered after "a"
// is typed. Then if I selected type "AsnEncodedData" to commit, by using the approach described
// above, we will get a TextChange of "AsnEncodedDat" with 0 length span, instead of a change of
// the full display text with a span of length 1. This will later mess up span-tracking and end up
// with "AsnEncodedDatasd" in the code.
builder
.
Add
(
new
TextChange
(
completionListSpan
,
completionItem
.
DisplayText
));
// Then get the combined change
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
newText
=
text
.
WithChanges
(
builder
);
return
CompletionChange
.
Create
(
Utilities
.
Collapse
(
newText
,
builder
.
ToImmutableAndFree
()));
}
// Find context node so we can use it to decide where to insert using/imports.
var
tree
=
(
await
document
.
GetSyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
root
=
await
tree
.
GetRootAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
addImportContextNode
=
root
.
FindToken
(
completionListSpan
.
Start
,
findInsideTrivia
:
true
).
Parent
;
// Add required using/imports directive.
var
addImportService
=
document
.
GetLanguageService
<
IAddImportsService
>()!;
var
optionSet
=
await
document
.
GetOptionsAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
placeSystemNamespaceFirst
=
optionSet
.
GetOption
(
GenerationOptions
.
PlaceSystemNamespaceFirst
,
document
.
Project
.
Language
);
var
compilation
=
(
await
document
.
Project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!;
var
importNode
=
CreateImport
(
document
,
containingNamespace
);
var
rootWithImport
=
addImportService
.
AddImport
(
compilation
,
root
,
addImportContextNode
,
importNode
,
placeSystemNamespaceFirst
,
cancellationToken
);
var
documentWithImport
=
document
.
WithSyntaxRoot
(
rootWithImport
);
// This only formats the annotated import we just added, not the entire document.
var
formattedDocumentWithImport
=
await
Formatter
.
FormatAsync
(
documentWithImport
,
Formatter
.
Annotation
,
cancellationToken
:
cancellationToken
).
ConfigureAwait
(
false
);
var
builder
=
ArrayBuilder
<
TextChange
>.
GetInstance
();
// Get text change for add import
var
importChanges
=
await
formattedDocumentWithImport
.
GetTextChangesAsync
(
document
,
cancellationToken
).
ConfigureAwait
(
false
);
builder
.
AddRange
(
importChanges
);
// Create text change for complete type name.
//
// Note: Don't try to obtain TextChange for completed type name by replacing the text directly,
// then use Document.GetTextChangesAsync on document created from the changed text. This is
// because it will do a diff and return TextChanges with minimum span instead of actual
// replacement span.
//
// For example: If I'm typing "asd", the completion provider could be triggered after "a"
// is typed. Then if I selected type "AsnEncodedData" to commit, by using the approach described
// above, we will get a TextChange of "AsnEncodedDat" with 0 length span, instead of a change of
// the full display text with a span of length 1. This will later mess up span-tracking and end up
// with "AsnEncodedDatasd" in the code.
builder
.
Add
(
new
TextChange
(
completionListSpan
,
completionItem
.
DisplayText
));
// Then get the combined change
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
newText
=
text
.
WithChanges
(
builder
);
return
CompletionChange
.
Create
(
Utilities
.
Collapse
(
newText
,
builder
.
ToImmutableAndFree
()));
async
Task
<
bool
>
ShouldCompleteWithFullyQualifyTypeName
()
{
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/AbstractTypeImportCompletionService.CacheEntry.cs
浏览文件 @
612f5c3c
...
...
@@ -41,6 +41,11 @@ internal abstract partial class AbstractTypeImportCompletionService
bool
isAttributeContext
,
bool
isCaseSensitive
)
{
// We will need to adjust some items if the request is made in:
// 1. attribute context, then we will not show or complete with "Attribute" suffix.
// 2. a project with different langauge than when the cache entry was created,
// then we will change the generic suffix accordingly.
// Otherwise, we can simply return cached items.
var
isSameLanguage
=
Language
==
language
;
if
(
isSameLanguage
&&
!
isAttributeContext
)
{
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletion
Service
.CacheEntry.cs
→
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletion
Helper
.CacheEntry.cs
浏览文件 @
612f5c3c
...
...
@@ -18,13 +18,16 @@
namespace
Microsoft.CodeAnalysis.Completion.Providers
{
internal
static
partial
class
ExtensionMethodImportCompletion
Service
internal
static
partial
class
ExtensionMethodImportCompletion
Helper
{
private
readonly
struct
CacheEntry
{
public
Checksum
Checksum
{
get
;
}
public
string
Language
{
get
;
}
/// <summary>
/// Mapping from the name of target type to extension method symbol infos.
/// </summary>
public
readonly
MultiDictionary
<
string
,
DeclaredSymbolInfo
>
SimpleExtensionMethodInfo
{
get
;
}
public
readonly
ImmutableArray
<
DeclaredSymbolInfo
>
ComplexExtensionMethodInfo
{
get
;
}
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletion
Service
.cs
→
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ExtensionMethodImportCompletion
Helper
.cs
浏览文件 @
612f5c3c
...
...
@@ -19,29 +19,11 @@
namespace
Microsoft.CodeAnalysis.Completion.Providers
{
internal
sealed
class
SerializableImportCompletionItem
{
public
readonly
string
SymbolKeyData
;
public
readonly
int
Arity
;
public
readonly
string
Name
;
public
readonly
Glyph
Glyph
;
public
readonly
string
ContainingNamespace
;
public
SerializableImportCompletionItem
(
string
symbolKeyData
,
string
name
,
int
arity
,
Glyph
glyph
,
string
containingNamespace
)
{
SymbolKeyData
=
symbolKeyData
;
Arity
=
arity
;
Name
=
name
;
Glyph
=
glyph
;
ContainingNamespace
=
containingNamespace
;
}
}
/// <summary>
/// Provides completion items for extension methods from unimported namespace.
/// </summary>
/// <remarks>It runs out-of-proc if it's enabled</remarks>
internal
static
partial
class
ExtensionMethodImportCompletion
Service
internal
static
partial
class
ExtensionMethodImportCompletion
Helper
{
private
static
readonly
char
[]
s_dotSeparator
=
new
char
[]
{
'.'
};
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/ImportCompletionItem.cs
浏览文件 @
612f5c3c
...
...
@@ -39,6 +39,7 @@ public static CompletionItem Create(string name, int arity, string containingNam
}
else
{
// We don't need arity to recover symbol if we have SymbolKeyData.
builder
.
Add
(
TypeAritySuffixName
,
AbstractDeclaredSymbolInfoFactoryService
.
GetMetadataAritySuffix
(
arity
));
}
...
...
@@ -97,7 +98,7 @@ public static string GetContainingNamespace(CompletionItem item)
public
static
async
Task
<
CompletionDescription
>
GetCompletionDescriptionAsync
(
Document
document
,
CompletionItem
item
,
CancellationToken
cancellationToken
)
{
var
compilation
=
(
await
document
.
Project
.
Get
CompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!
;
var
compilation
=
(
await
document
.
Project
.
Get
RequiredCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))
;
var
symbol
=
GetSymbol
(
item
,
compilation
);
if
(
symbol
!=
null
)
...
...
@@ -125,11 +126,13 @@ private static string GetFullyQualifiedName(string namespaceName, string typeNam
private
static
ISymbol
?
GetSymbol
(
CompletionItem
item
,
Compilation
compilation
)
{
// If we have SymbolKey data (i.e. this is an extension method item), use it to recover symbol
if
(
item
.
Properties
.
TryGetValue
(
SymbolKeyData
,
out
var
symbolId
))
{
return
SymbolKey
.
ResolveString
(
symbolId
,
compilation
).
GetAnySymbol
();
}
// Otherwise, this is a type item, so we should have all the data to constrcut its metadata name
var
containingNamespace
=
GetContainingNamespace
(
item
);
var
typeName
=
item
.
Properties
.
TryGetValue
(
AttributeFullName
,
out
var
attributeFullName
)
?
attributeFullName
:
item
.
DisplayText
;
var
fullyQualifiedName
=
GetFullyQualifiedName
(
containingNamespace
,
typeName
);
...
...
src/Features/Core/Portable/Completion/Providers/ImportCompletionProvider/SerializableImportCompletionItem.cs
0 → 100644
浏览文件 @
612f5c3c
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#
nullable
enable
namespace
Microsoft.CodeAnalysis.Completion.Providers
{
internal
sealed
class
SerializableImportCompletionItem
{
public
readonly
string
SymbolKeyData
;
public
readonly
int
Arity
;
public
readonly
string
Name
;
public
readonly
Glyph
Glyph
;
public
readonly
string
ContainingNamespace
;
public
SerializableImportCompletionItem
(
string
symbolKeyData
,
string
name
,
int
arity
,
Glyph
glyph
,
string
containingNamespace
)
{
SymbolKeyData
=
symbolKeyData
;
Arity
=
arity
;
Name
=
name
;
Glyph
=
glyph
;
ContainingNamespace
=
containingNamespace
;
}
}
}
src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb
浏览文件 @
612f5c3c
...
...
@@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Protected
Overrides
ReadOnly
Property
GenericSuffix
As
String
Get
Return
"(Of )"
Return
"(Of
...
)"
End
Get
End
Property
...
...
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.Node.cs
浏览文件 @
612f5c3c
...
...
@@ -82,7 +82,7 @@ private string GetDebuggerDisplay()
private
readonly
struct
ParameterTypeInfo
{
/// <summary>
/// This is the type name of the parameter when <see cref="IsComplexType"/> is
tru
e.
/// This is the type name of the parameter when <see cref="IsComplexType"/> is
fals
e.
/// </summary>
public
readonly
string
Name
;
...
...
src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Metadata.cs
浏览文件 @
612f5c3c
...
...
@@ -430,6 +430,8 @@ private void GenerateMetadataNodes()
var
decoder
=
new
SignatureDecoder
<
ParameterTypeInfo
,
object
>(
ParameterTypeInfoProvider
.
Instance
,
_metadataReader
,
genericContext
:
null
);
var
signature
=
decoder
.
DecodeMethodSignature
(
ref
blob
);
// It'd be good if we don't need to go through all parameters and make unnecessary allocations.
// However, this is not possible with meatadata reader API right now (although it's possible by copying code from meatadata reader implementaion)
if
(
signature
.
ParameterTypes
.
Length
>
0
)
{
_containsExtensionsMethod
=
true
;
...
...
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ExtensionMethodInfo.cs
浏览文件 @
612f5c3c
...
...
@@ -20,7 +20,7 @@ internal partial class SyntaxTreeIndex
//
// Complex methods include:
// - Method declared in the document which includes using alias directive
// - Generic method where the target type is
generic
// - Generic method where the target type is
a type-paramter (e.g. List<T> would be considered simple, not complex)
// - If the target type name is one of the following (i.e. name of the type for the first parameter)
// 1. Array type
// 2. ValueTuple type
...
...
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs
浏览文件 @
612f5c3c
...
...
@@ -131,7 +131,7 @@ internal sealed partial class SyntaxTreeIndex
// }
//
// If we detect this, we will simply treat extension methods whose
// target type is this al
ai
s as complex method.
// target type is this al
ia
s as complex method.
if
(
usingAliases
.
ContainsKey
(
aliasName
))
{
usingAliases
[
aliasName
]
=
null
;
...
...
src/Workspaces/Core/Portable/LanguageServices/SyntaxFactsService/ISyntaxFactsService.cs
浏览文件 @
612f5c3c
...
...
@@ -174,6 +174,19 @@ internal interface ISyntaxFactsService : ILanguageService
bool
IsLeftSideOfDot
(
SyntaxNode
node
);
SyntaxNode
GetRightSideOfDot
(
SyntaxNode
node
);
/// <summary>
/// Get the node on the left side of the dot if given a dotted expression.
/// </summary>
/// <param name="allowImplicitTarget">
/// In VB, we have a member access expression with a null expression, this may be one of the
/// following forms:
/// 1) new With { .a = 1, .b = .a <-- .a refers to the anonymous type
/// 2) With obj : .m <-- .m refers to the obj type
/// 3) new T() With { .a = 1, .b = .a <-- 'a refers to the T type
/// If `allowImplicitTarget` is set to true, the returned node will be set to approperiate node, otherwise, it will return null.
/// This parameter has no affect on C# node.
/// </param>
SyntaxNode
GetLeftSideOfDot
(
SyntaxNode
node
,
bool
allowImplicitTarget
=
false
);
bool
IsRightSideOfQualifiedName
(
SyntaxNode
node
);
...
...
src/Workspaces/Core/Portable/Shared/Extensions/DocumentExtensions.cs
浏览文件 @
612f5c3c
...
...
@@ -27,6 +27,9 @@ internal static partial class DocumentExtensions
public
static
TLanguageService
?
GetLanguageService
<
TLanguageService
>(
this
Document
?
document
)
where
TLanguageService
:
class
,
ILanguageService
=>
document
?.
Project
?.
LanguageServices
?.
GetService
<
TLanguageService
>();
public
static
TLanguageService
GetRequiredLanguageService
<
TLanguageService
>(
this
Document
document
)
where
TLanguageService
:
class
,
ILanguageService
=>
document
.
Project
.
LanguageServices
.
GetRequiredService
<
TLanguageService
>();
public
static
bool
IsOpen
(
this
Document
document
)
{
var
workspace
=
document
.
Project
.
Solution
.
Workspace
as
Workspace
;
...
...
src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
浏览文件 @
612f5c3c
...
...
@@ -2,12 +2,12 @@
#
nullable
enable
using
System
;
using
System.Collections.Immutable
;
using
System.Diagnostics
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Text
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Shared.Extensions
...
...
@@ -122,5 +122,16 @@ public static async Task<VersionStamp> GetVersionAsync(this Project project, Can
var
newSolution
=
project
.
Solution
.
AddAnalyzerConfigDocuments
(
ImmutableArray
.
Create
(
documentInfo
));
return
newSolution
.
GetProject
(
project
.
Id
)?.
GetAnalyzerConfigDocument
(
id
);
}
public
static
async
Task
<
Compilation
>
GetRequiredCompilationAsync
(
this
Project
project
,
CancellationToken
cancellationToken
)
{
var
compilation
=
await
project
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
if
(
compilation
==
null
)
{
throw
new
InvalidOperationException
(
string
.
Format
(
WorkspacesResources
.
Project_0_does_not_support_compilation
,
project
.
Name
));
}
return
compilation
;
}
}
}
src/Workspaces/Core/Portable/WorkspacesResources.Designer.cs
浏览文件 @
612f5c3c
...
...
@@ -1366,6 +1366,15 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Project {0} does not support compilation..
/// </summary>
internal
static
string
Project_0_does_not_support_compilation
{
get
{
return
ResourceManager
.
GetString
(
"Project_0_does_not_support_compilation"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Project file not found: '{0}'.
/// </summary>
...
...
src/Workspaces/Core/Portable/WorkspacesResources.resx
浏览文件 @
612f5c3c
...
...
@@ -1479,4 +1479,7 @@ Zero-width positive lookbehind assertions are typically used at the beginning of
<data
name=
"Document_does_not_support_syntax_trees"
xml:space=
"preserve"
>
<value>
Document does not support syntax trees
</value>
</data>
<data
name=
"Project_0_does_not_support_compilation"
xml:space=
"preserve"
>
<value>
Project {0} does not support compilation.
</value>
</data>
</root>
\ No newline at end of file
src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_ExtensionMethodFiltering.cs
浏览文件 @
612f5c3c
...
...
@@ -2,18 +2,18 @@
#
nullable
enable
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Completion.Providers
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
namespace
Microsoft.CodeAnalysis.Remote
{
internal
partial
class
CodeAnalysisService
:
IRemoteExtensionMethodImportCompletionService
{
public
Task
<(
IList
<
SerializableImportCompletionItem
>,
StatisticCounter
)>
GetUnimportedExtensionMethodsAsync
(
DocumentId
documentId
,
int
position
,
...
...
@@ -28,20 +28,20 @@ internal partial class CodeAnalysisService : IRemoteExtensionMethodImportComplet
{
var
solution
=
await
GetSolutionAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
document
=
solution
.
GetDocument
(
documentId
)!;
var
compilation
=
(
await
document
.
Project
.
Get
CompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))!
;
var
compilation
=
(
await
document
.
Project
.
Get
RequiredCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
))
;
var
symbol
=
SymbolKey
.
ResolveString
(
receiverTypeSymbolKeyData
,
compilation
,
cancellationToken
:
cancellationToken
).
GetAnySymbol
();
if
(
symbol
is
ITypeSymbol
receiverTypeSymbol
)
{
var
syntaxFacts
=
document
.
Project
.
LanguageServices
.
GetRequired
Service
<
ISyntaxFactsService
>();
var
syntaxFacts
=
document
.
GetRequiredLanguage
Service
<
ISyntaxFactsService
>();
var
namespaceInScopeSet
=
new
HashSet
<
string
>(
namespaceInScope
,
syntaxFacts
.
StringComparer
);
var
(
items
,
counter
)
=
await
ExtensionMethodImportCompletion
Service
.
GetUnimportExtensionMethodsInCurrentProcessAsync
(
var
(
items
,
counter
)
=
await
ExtensionMethodImportCompletion
Helper
.
GetUnimportExtensionMethodsInCurrentProcessAsync
(
document
,
position
,
receiverTypeSymbol
,
namespaceInScopeSet
,
isExpandedCompletion
,
cancellationToken
).
ConfigureAwait
(
false
);
return
((
IList
<
SerializableImportCompletionItem
>)
items
,
counter
);
}
return
(
new
SerializableImportCompletionItem
[
0
]
,
new
StatisticCounter
());
return
(
Array
.
Empty
<
SerializableImportCompletionItem
>()
,
new
StatisticCounter
());
}
},
cancellationToken
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录