Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
699eed6a
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,发现更多精彩内容 >>
提交
699eed6a
编写于
5月 14, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
restore file
上级
d7d64d39
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
154 addition
and
0 deletion
+154
-0
src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
...s/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
+154
-0
未找到文件。
src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs
0 → 100644
浏览文件 @
699eed6a
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Collections.Generic
;
using
System.Threading
;
namespace
Microsoft.CodeAnalysis
{
internal
partial
struct
SymbolKey
{
private
static
class
BodyLevelSymbolKey
{
public
static
void
Create
(
ISymbol
symbol
,
SymbolKeyWriter
visitor
)
{
var
containingSymbol
=
symbol
.
ContainingSymbol
;
while
(
containingSymbol
.
DeclaringSyntaxReferences
.
IsDefaultOrEmpty
)
{
containingSymbol
=
containingSymbol
.
ContainingSymbol
;
}
var
compilation
=
((
ISourceAssemblySymbol
)
symbol
.
ContainingAssembly
).
Compilation
;
var
kind
=
symbol
.
Kind
;
var
localName
=
symbol
.
Name
;
// Use two mechanisms to try to find the symbol across compilations. First, we use a whitespace
// insensitive system where we keep track of the list of all locals in the container and we just store
// our index in it.
//
// The above works for cases where the symbol has a real declaration and can be found by walking the
// declarations of the container. However, not all symbols can be found that way. For example, error
// locals in VB can't be found using GetDeclaredSymbol. For those, we store the actual local span and
// use GetSymbolInfo to find it.
var
ordinal
=
GetOrdinal
();
visitor
.
WriteString
(
localName
);
visitor
.
WriteSymbolKey
(
containingSymbol
);
visitor
.
WriteInteger
(
ordinal
);
visitor
.
WriteLocation
(
symbol
.
Locations
[
0
]);
visitor
.
WriteInteger
((
int
)
kind
);
return
;
int
GetOrdinal
()
{
foreach
(
var
possibleSymbol
in
EnumerateSymbols
(
compilation
,
containingSymbol
,
kind
,
localName
,
visitor
.
CancellationToken
))
{
if
(
possibleSymbol
.
symbol
.
Equals
(
symbol
))
return
possibleSymbol
.
ordinal
;
}
return
int
.
MaxValue
;
}
}
public
static
SymbolKeyResolution
Resolve
(
SymbolKeyReader
reader
)
{
var
cancellationToken
=
reader
.
CancellationToken
;
var
localName
=
reader
.
ReadString
();
var
containingSymbolResolution
=
reader
.
ReadSymbolKey
();
var
ordinal
=
reader
.
ReadInteger
();
var
location
=
reader
.
ReadLocation
();
var
kind
=
(
SymbolKind
)
reader
.
ReadInteger
();
var
containingSymbol
=
containingSymbolResolution
.
Symbol
;
if
(
containingSymbol
!=
null
)
{
if
(
ordinal
!=
int
.
MaxValue
)
{
foreach
(
var
symbol
in
EnumerateSymbols
(
reader
.
Compilation
,
containingSymbol
,
kind
,
localName
,
cancellationToken
))
{
if
(
symbol
.
ordinal
==
ordinal
)
return
new
SymbolKeyResolution
(
symbol
.
symbol
);
}
}
else
{
var
resolution
=
reader
.
ResolveLocation
(
location
);
if
(
resolution
!=
null
)
return
resolution
.
Value
;
}
}
return
new
SymbolKeyResolution
();
}
private
static
IEnumerable
<(
ISymbol
symbol
,
int
ordinal
)>
EnumerateSymbols
(
Compilation
compilation
,
ISymbol
containingSymbol
,
SymbolKind
kind
,
string
localName
,
CancellationToken
cancellationToken
)
{
var
ordinal
=
0
;
foreach
(
var
declaringLocation
in
containingSymbol
.
DeclaringSyntaxReferences
)
{
// This operation can potentially fail. If containingSymbol came from
// a SpeculativeSemanticModel, containingSymbol.ContainingAssembly.Compilation
// may not have been rebuilt to reflect the trees used by the
// SpeculativeSemanticModel to produce containingSymbol. In that case,
// asking the ContainingAssembly's compilation for a SemanticModel based
// on trees for containingSymbol with throw an ArgumentException.
// Unfortunately, the best way to avoid this (currently) is to see if
// we're asking for a model for a tree that's part of the compilation.
// (There's no way to get back to a SemanticModel from a symbol).
// TODO (rchande): It might be better to call compilation.GetSemanticModel
// and catch the ArgumentException. The compilation internally has a
// Dictionary<SyntaxTree, ...> that it uses to check if the SyntaxTree
// is applicable wheras the public interface requires us to enumerate
// the entire IEnumerable of trees in the Compilation.
if
(!
Contains
(
compilation
.
SyntaxTrees
,
declaringLocation
.
SyntaxTree
))
{
continue
;
}
var
node
=
declaringLocation
.
GetSyntax
(
cancellationToken
);
if
(
node
.
Language
==
LanguageNames
.
VisualBasic
)
{
node
=
node
.
Parent
;
}
var
semanticModel
=
compilation
.
GetSemanticModel
(
node
.
SyntaxTree
);
foreach
(
var
token
in
node
.
DescendantNodes
())
{
var
symbol
=
semanticModel
.
GetDeclaredSymbol
(
token
,
cancellationToken
);
if
(
symbol
!=
null
&&
symbol
.
Kind
==
kind
&&
SymbolKey
.
Equals
(
compilation
,
symbol
.
Name
,
localName
))
{
yield
return
(
symbol
,
ordinal
++);
}
}
}
}
private
static
bool
Contains
(
IEnumerable
<
SyntaxTree
>
trees
,
SyntaxTree
tree
)
{
foreach
(
var
current
in
trees
)
{
if
(
current
==
tree
)
{
return
true
;
}
}
return
false
;
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录