Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
a4672177
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,发现更多精彩内容 >>
未验证
提交
a4672177
编写于
2月 21, 2019
作者:
A
Andrew Hall
提交者:
GitHub
2月 21, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #33227 from ryzngard/issue/28827_gotoimplementation_broken
Update the FindImplementationsForInterfaceMember
上级
893d30fc
9c9990e9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
91 addition
and
13 deletion
+91
-13
src/Test/Utilities/Portable/TestBase.cs
src/Test/Utilities/Portable/TestBase.cs
+12
-0
src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
...paces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
+6
-5
src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs
.../Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs
+31
-8
src/Workspaces/CoreTest/FindReferencesTests.cs
src/Workspaces/CoreTest/FindReferencesTests.cs
+42
-0
未找到文件。
src/Test/Utilities/Portable/TestBase.cs
浏览文件 @
a4672177
...
...
@@ -246,6 +246,18 @@ private static MetadataReference GetOrCreateMetadataReference(ref MetadataRefere
LazyThreadSafetyMode
.
PublicationOnly
);
public
static
MetadataReference
CSharpNetStandard10Ref
=>
s_stdCSharpRef
.
Value
;
private
static
readonly
Lazy
<
MetadataReference
>
s_std20Ref
=
new
Lazy
<
MetadataReference
>(
()
=>
AssemblyMetadata
.
CreateFromImage
(
TestResources
.
NetFX
.
netstandard20
.
netstandard
).
GetReference
(
display
:
"netstandard20.netstandard.dll"
),
LazyThreadSafetyMode
.
PublicationOnly
);
public
static
MetadataReference
NetStandard20Ref
=>
s_std20Ref
.
Value
;
private
static
readonly
Lazy
<
MetadataReference
>
s_46NetStandardFacade
=
new
Lazy
<
MetadataReference
>(
()
=>
AssemblyMetadata
.
CreateFromImage
(
TestResources
.
NetFX
.
net461
.
netstandard
).
GetReference
(
display
:
"net461.netstandard.dll"
),
LazyThreadSafetyMode
.
PublicationOnly
);
public
static
MetadataReference
Net46StandardFacade
=>
s_46NetStandardFacade
.
Value
;
private
static
readonly
Lazy
<
MetadataReference
>
s_systemDynamicRuntimeRef
=
new
Lazy
<
MetadataReference
>(
()
=>
AssemblyMetadata
.
CreateFromImage
(
TestResources
.
NetFX
.
netstandard13
.
System_Dynamic_Runtime
).
GetReference
(
display
:
"System.Dynamic.Runtime.dll (netstandard 1.3 ref)"
),
LazyThreadSafetyMode
.
PublicationOnly
);
...
...
src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs
浏览文件 @
a4672177
...
...
@@ -144,8 +144,8 @@ public static partial class SymbolFinder
var
sourceMethod
=
await
FindSourceDefinitionAsync
(
m
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
var
bestMethod
=
sourceMethod
.
Symbol
!=
null
?
sourceMethod
:
m
;
var
implementations
=
type
.
FindImplementationsForInterfaceMember
(
bestMethod
.
Symbol
,
solution
.
Workspace
,
cancellationToken
);
var
implementations
=
await
type
.
FindImplementationsForInterfaceMemberAsync
(
bestMethod
.
Symbol
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
foreach
(
var
implementation
in
implementations
)
{
if
(
implementation
.
Symbol
!=
null
&&
...
...
@@ -249,10 +249,11 @@ public static partial class SymbolFinder
ImmutableArray
<
SymbolAndProjectId
>.
Builder
results
=
null
;
foreach
(
var
t
in
allTypes
.
Convert
<
INamedTypeSymbol
,
ITypeSymbol
>())
{
foreach
(
var
m
in
t
.
FindImplementationsForInterfaceMember
(
symbol
,
solution
.
Workspace
,
cancellationToken
))
var
implementations
=
await
t
.
FindImplementationsForInterfaceMemberAsync
(
symbolAndProjectId
.
Symbol
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
foreach
(
var
implementation
in
implementations
)
{
var
sourceDef
=
await
FindSourceDefinitionAsync
(
m
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
var
bestDef
=
sourceDef
.
Symbol
!=
null
?
sourceDef
:
m
;
var
sourceDef
=
await
FindSourceDefinitionAsync
(
implementation
,
solution
,
cancellationToken
).
ConfigureAwait
(
false
);
var
bestDef
=
sourceDef
.
Symbol
!=
null
?
sourceDef
:
implementation
;
if
(
IsAccessible
(
bestDef
))
{
results
=
results
??
ImmutableArray
.
CreateBuilder
<
SymbolAndProjectId
>();
...
...
src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs
浏览文件 @
a4672177
...
...
@@ -6,9 +6,11 @@
using
System.Diagnostics
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.FindSymbols
;
using
Microsoft.CodeAnalysis.LanguageServices
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Roslyn.Utilities
;
...
...
@@ -91,10 +93,10 @@ public static ITypeSymbol RemoveNullableIfPresent(this ITypeSymbol symbol)
/// interfaceMember, or this type doesn't supply a member that successfully implements
/// interfaceMember).
/// </summary>
public
static
IEnumerable
<
SymbolAndProjectId
>
FindImplementationsForInterfaceMember
(
public
static
async
Task
<
ImmutableArray
<
SymbolAndProjectId
>>
FindImplementationsForInterfaceMemberAsync
(
this
SymbolAndProjectId
<
ITypeSymbol
>
typeSymbolAndProjectId
,
ISymbol
interfaceMember
,
Workspace
workspace
,
Solution
solution
,
CancellationToken
cancellationToken
)
{
// This method can return multiple results. Consider the case of:
...
...
@@ -106,19 +108,21 @@ public static ITypeSymbol RemoveNullableIfPresent(this ITypeSymbol symbol)
// If you're looking for the implementations of IGoo<X>.Goo then you want to find both
// results in C.
var
arrBuilder
=
ArrayBuilder
<
SymbolAndProjectId
>.
GetInstance
();
// TODO(cyrusn): Implement this using the actual code for
// TypeSymbol.FindImplementationForInterfaceMember
var
typeSymbol
=
typeSymbolAndProjectId
.
Symbol
;
if
(
typeSymbol
==
null
||
interfaceMember
==
null
)
{
yield
break
;
return
arrBuilder
.
ToImmutableAndFree
()
;
}
if
(
interfaceMember
.
Kind
!=
SymbolKind
.
Event
&&
interfaceMember
.
Kind
!=
SymbolKind
.
Method
&&
interfaceMember
.
Kind
!=
SymbolKind
.
Property
)
{
yield
break
;
return
arrBuilder
.
ToImmutableAndFree
()
;
}
// WorkItem(4843)
...
...
@@ -143,7 +147,7 @@ public static ITypeSymbol RemoveNullableIfPresent(this ITypeSymbol symbol)
var
interfaceType
=
interfaceMember
.
ContainingType
;
if
(!
typeSymbol
.
ImplementsIgnoringConstruction
(
interfaceType
))
{
yield
break
;
return
arrBuilder
.
ToImmutableAndFree
()
;
}
// We've ascertained that the type T implements some constructed type of the form I<X>.
...
...
@@ -153,14 +157,31 @@ public static ITypeSymbol RemoveNullableIfPresent(this ITypeSymbol symbol)
// instantiations of that method.
var
originalInterfaceType
=
interfaceMember
.
ContainingType
.
OriginalDefinition
;
var
originalInterfaceMember
=
interfaceMember
.
OriginalDefinition
;
var
constructedInterfaces
=
typeSymbol
.
AllInterfaces
.
Where
(
i
=>
SymbolEquivalenceComparer
.
Instance
.
Equals
(
i
.
OriginalDefinition
,
originalInterfaceType
));
// Try to get the compilation for the symbol we're searching for,
// which can help identify matches with the call to SymbolFinder.OriginalSymbolsMatch.
// OriginalSymbolMatch allows types to be matched across different assemblies
// if they are considered to be the same type, which provides a more accurate
// implementations list for interfaces.
var
typeSymbolProject
=
solution
.
GetProject
(
typeSymbolAndProjectId
.
ProjectId
);
var
typeSymbolCompilation
=
typeSymbolProject
==
null
?
null
:
await
typeSymbolProject
.
GetCompilationAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
foreach
(
var
constructedInterface
in
constructedInterfaces
)
{
cancellationToken
.
ThrowIfCancellationRequested
();
var
constructedInterfaceMember
=
constructedInterface
.
GetMembers
().
FirstOrDefault
(
m
=>
SymbolEquivalenceComparer
.
Instance
.
Equals
(
m
.
OriginalDefinition
,
originalInterfaceMember
));
SymbolFinder
.
OriginalSymbolsMatch
(
m
,
interfaceMember
,
solution
,
typeSymbolCompilation
,
symbolToMatchCompilation
:
null
,
cancellationToken
));
if
(
constructedInterfaceMember
==
null
)
{
...
...
@@ -177,16 +198,18 @@ public static ITypeSymbol RemoveNullableIfPresent(this ITypeSymbol symbol)
if
(
seenTypeDeclaringInterface
)
{
var
result
=
FindImplementations
(
w
orkspace
,
constructedInterfaceMember
,
currentType
);
var
result
=
FindImplementations
(
solution
.
W
orkspace
,
constructedInterfaceMember
,
currentType
);
if
(
result
!=
null
)
{
yield
return
typeSymbolAndProjectId
.
WithSymbol
(
result
);
arrBuilder
.
Add
(
typeSymbolAndProjectId
.
WithSymbol
(
result
)
);
break
;
}
}
}
}
return
arrBuilder
.
ToImmutableAndFree
();
}
private
static
ISymbol
FindImplementations
(
Workspace
workspace
,
ISymbol
constructedInterfaceMember
,
ITypeSymbol
currentType
)
...
...
src/Workspaces/CoreTest/FindReferencesTests.cs
浏览文件 @
a4672177
...
...
@@ -8,6 +8,7 @@
using
Microsoft.CodeAnalysis.CSharp.Symbols
;
using
Microsoft.CodeAnalysis.CSharp.Syntax
;
using
Microsoft.CodeAnalysis.FindSymbols
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Microsoft.CodeAnalysis.Text
;
using
Roslyn.Test.Utilities
;
using
Xunit
;
...
...
@@ -268,6 +269,47 @@ class B : C, A
Assert
.
Empty
(
expectedMatchedLines
);
}
[
Fact
,
WorkItem
(
28827
,
"https://github.com/dotnet/roslyn/issues/28827"
)]
public
async
Task
FindReferences_DifferingAssemblies
()
{
var
solution
=
new
AdhocWorkspace
().
CurrentSolution
;
solution
=
AddProjectWithMetadataReferences
(
solution
,
"NetStandardProject"
,
LanguageNames
.
CSharp
,
@"
namespace N
{
public interface I
{
System.Uri Get();
}
}"
,
NetStandard20Ref
);
solution
=
AddProjectWithMetadataReferences
(
solution
,
"DesktopProject"
,
LanguageNames
.
CSharp
,
@"
using N;
namespace N2
{
public class Impl : I
{
public System.Uri Get()
{
return null;
}
}
}"
,
SystemRef_v46
,
solution
.
Projects
.
Single
(
pid
=>
pid
.
Name
==
"NetStandardProject"
).
Id
);
var
desktopProject
=
solution
.
Projects
.
First
(
p
=>
p
.
Name
==
"DesktopProject"
);
solution
=
solution
.
AddMetadataReferences
(
desktopProject
.
Id
,
new
[]
{
MscorlibRef_v46
,
Net46StandardFacade
});
desktopProject
=
solution
.
GetProject
(
desktopProject
.
Id
);
var
netStandardProject
=
solution
.
Projects
.
First
(
p
=>
p
.
Name
==
"NetStandardProject"
);
var
interfaceMethod
=
(
IMethodSymbol
)(
await
netStandardProject
.
GetCompilationAsync
()).
GetTypeByMetadataName
(
"N.I"
).
GetMembers
(
"Get"
).
First
();
var
references
=
(
await
SymbolFinder
.
FindReferencesAsync
(
interfaceMethod
,
solution
)).
ToList
();
Assert
.
Equal
(
2
,
references
.
Count
);
Assert
.
True
(
references
.
Any
(
r
=>
r
.
DefinitionAndProjectId
.
ProjectId
==
desktopProject
.
Id
));
}
[
WorkItem
(
4936
,
"https://github.com/dotnet/roslyn/issues/4936"
)]
[
Fact
]
public
async
Task
OverriddenMethodsFromPortableToDesktop
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录