Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
8a2857e6
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8a2857e6
编写于
6月 08, 2017
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove intermediate forms and some other refactoring
上级
9a471606
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
843 addition
and
2828 deletion
+843
-2828
src/librustc_save_analysis/data.rs
src/librustc_save_analysis/data.rs
+0
-421
src/librustc_save_analysis/dump.rs
src/librustc_save_analysis/dump.rs
+0
-40
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/dump_visitor.rs
+440
-558
src/librustc_save_analysis/external_data.rs
src/librustc_save_analysis/external_data.rs
+0
-748
src/librustc_save_analysis/json_api_dumper.rs
src/librustc_save_analysis/json_api_dumper.rs
+11
-297
src/librustc_save_analysis/json_dumper.rs
src/librustc_save_analysis/json_dumper.rs
+21
-380
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/lib.rs
+333
-293
src/librustc_save_analysis/span_utils.rs
src/librustc_save_analysis/span_utils.rs
+38
-91
未找到文件。
src/librustc_save_analysis/data.rs
已删除
100644 → 0
浏览文件 @
9a471606
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Structs representing the analysis data from a crate.
//!
//! The `Dump` trait can be used together with `DumpVisitor` in order to
//! retrieve the data from a crate.
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::{
CrateNum
,
DefId
};
use
syntax
::
ast
::{
self
,
Attribute
,
NodeId
};
use
syntax_pos
::
Span
;
use
rls_data
::{
ExternalCrateData
,
Signature
};
pub
struct
CrateData
{
pub
name
:
String
,
pub
number
:
u32
,
pub
span
:
Span
,
}
/// Data for any entity in the Rust language. The actual data contained varies
/// with the kind of entity being queried. See the nested structs for details.
#[derive(Debug)]
pub
enum
Data
{
/// Data for Enums.
EnumData
(
EnumData
),
/// Data for extern crates.
ExternCrateData
(
ExternCrateData
),
/// Data about a function call.
FunctionCallData
(
FunctionCallData
),
/// Data for all kinds of functions and methods.
FunctionData
(
FunctionData
),
/// Data about a function ref.
FunctionRefData
(
FunctionRefData
),
/// Data for impls.
ImplData
(
ImplData2
),
/// Data for trait inheritance.
InheritanceData
(
InheritanceData
),
/// Data about a macro declaration.
MacroData
(
MacroData
),
/// Data about a macro use.
MacroUseData
(
MacroUseData
),
/// Data about a method call.
MethodCallData
(
MethodCallData
),
/// Data for method declarations (methods with a body are treated as functions).
MethodData
(
MethodData
),
/// Data for modules.
ModData
(
ModData
),
/// Data for a reference to a module.
ModRefData
(
ModRefData
),
/// Data for a struct declaration.
StructData
(
StructData
),
/// Data for a struct variant.
StructVariantDat
(
StructVariantData
),
/// Data for a trait declaration.
TraitData
(
TraitData
),
/// Data for a tuple variant.
TupleVariantData
(
TupleVariantData
),
/// Data for a typedef.
TypeDefData
(
TypeDefData
),
/// Data for a reference to a type or trait.
TypeRefData
(
TypeRefData
),
/// Data for a use statement.
UseData
(
UseData
),
/// Data for a global use statement.
UseGlobData
(
UseGlobData
),
/// Data for local and global variables (consts and statics), and fields.
VariableData
(
VariableData
),
/// Data for the use of some variable (e.g., the use of a local variable, which
/// will refere to that variables declaration).
VariableRefData
(
VariableRefData
),
}
#[derive(Eq,
PartialEq,
Clone,
Copy,
Debug)]
pub
enum
Visibility
{
Public
,
Restricted
,
Inherited
,
}
impl
<
'a
>
From
<&
'a
ast
::
Visibility
>
for
Visibility
{
fn
from
(
v
:
&
'a
ast
::
Visibility
)
->
Visibility
{
match
*
v
{
ast
::
Visibility
::
Public
=>
Visibility
::
Public
,
ast
::
Visibility
::
Crate
(
_
)
=>
Visibility
::
Restricted
,
ast
::
Visibility
::
Restricted
{
..
}
=>
Visibility
::
Restricted
,
ast
::
Visibility
::
Inherited
=>
Visibility
::
Inherited
,
}
}
}
impl
<
'a
>
From
<&
'a
hir
::
Visibility
>
for
Visibility
{
fn
from
(
v
:
&
'a
hir
::
Visibility
)
->
Visibility
{
match
*
v
{
hir
::
Visibility
::
Public
=>
Visibility
::
Public
,
hir
::
Visibility
::
Crate
=>
Visibility
::
Restricted
,
hir
::
Visibility
::
Restricted
{
..
}
=>
Visibility
::
Restricted
,
hir
::
Visibility
::
Inherited
=>
Visibility
::
Inherited
,
}
}
}
/// Data for the prelude of a crate.
#[derive(Debug)]
pub
struct
CratePreludeData
{
pub
crate_name
:
String
,
pub
crate_root
:
String
,
pub
external_crates
:
Vec
<
ExternalCrateData
>
,
pub
span
:
Span
,
}
/// Data for enum declarations.
#[derive(Clone,
Debug)]
pub
struct
EnumData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
value
:
String
,
pub
qualname
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
variants
:
Vec
<
NodeId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data for extern crates.
#[derive(Debug)]
pub
struct
ExternCrateData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
crate_num
:
CrateNum
,
pub
location
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
}
/// Data about a function call.
#[derive(Debug)]
pub
struct
FunctionCallData
{
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
DefId
,
}
/// Data for all kinds of functions and methods.
#[derive(Clone,
Debug)]
pub
struct
FunctionData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
declaration
:
Option
<
DefId
>
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
value
:
String
,
pub
visibility
:
Visibility
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data about a function call.
#[derive(Debug)]
pub
struct
FunctionRefData
{
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
DefId
,
}
#[derive(Debug)]
pub
struct
ImplData
{
pub
id
:
NodeId
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
trait_ref
:
Option
<
DefId
>
,
pub
self_ref
:
Option
<
DefId
>
,
}
#[derive(Debug)]
// FIXME: this struct should not exist. However, removing it requires heavy
// refactoring of dump_visitor.rs. See PR 31838 for more info.
pub
struct
ImplData2
{
pub
id
:
NodeId
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
// FIXME: I'm not really sure inline data is the best way to do this. Seems
// OK in this case, but generalising leads to returning chunks of AST, which
// feels wrong.
pub
trait_ref
:
Option
<
TypeRefData
>
,
pub
self_ref
:
Option
<
TypeRefData
>
,
}
#[derive(Debug)]
pub
struct
InheritanceData
{
pub
span
:
Span
,
pub
base_id
:
DefId
,
pub
deriv_id
:
NodeId
}
/// Data about a macro declaration.
#[derive(Debug)]
pub
struct
MacroData
{
pub
span
:
Span
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
docs
:
String
,
}
/// Data about a macro use.
#[derive(Debug)]
pub
struct
MacroUseData
{
pub
span
:
Span
,
pub
name
:
String
,
pub
qualname
:
String
,
// Because macro expansion happens before ref-ids are determined,
// we use the callee span to reference the associated macro definition.
pub
callee_span
:
Span
,
pub
scope
:
NodeId
,
pub
imported
:
bool
,
}
/// Data about a method call.
#[derive(Debug)]
pub
struct
MethodCallData
{
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
decl_id
:
Option
<
DefId
>
,
}
/// Data for method declarations (methods with a body are treated as functions).
#[derive(Clone,
Debug)]
pub
struct
MethodData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
value
:
String
,
pub
decl_id
:
Option
<
DefId
>
,
pub
parent
:
Option
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data for modules.
#[derive(Debug)]
pub
struct
ModData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
filename
:
String
,
pub
items
:
Vec
<
NodeId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data for a reference to a module.
#[derive(Debug)]
pub
struct
ModRefData
{
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
qualname
:
String
}
#[derive(Debug)]
pub
struct
StructData
{
pub
span
:
Span
,
pub
name
:
String
,
pub
id
:
NodeId
,
pub
ctor_id
:
NodeId
,
pub
qualname
:
String
,
pub
scope
:
NodeId
,
pub
value
:
String
,
pub
fields
:
Vec
<
NodeId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
#[derive(Debug)]
pub
struct
StructVariantData
{
pub
span
:
Span
,
pub
name
:
String
,
pub
id
:
NodeId
,
pub
qualname
:
String
,
pub
type_value
:
String
,
pub
value
:
String
,
pub
scope
:
NodeId
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
#[derive(Debug)]
pub
struct
TraitData
{
pub
span
:
Span
,
pub
id
:
NodeId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
scope
:
NodeId
,
pub
value
:
String
,
pub
items
:
Vec
<
NodeId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
#[derive(Debug)]
pub
struct
TupleVariantData
{
pub
span
:
Span
,
pub
id
:
NodeId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
type_value
:
String
,
pub
value
:
String
,
pub
scope
:
NodeId
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data for a typedef.
#[derive(Debug)]
pub
struct
TypeDefData
{
pub
id
:
NodeId
,
pub
name
:
String
,
pub
span
:
Span
,
pub
qualname
:
String
,
pub
value
:
String
,
pub
visibility
:
Visibility
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
/// Data for a reference to a type or trait.
#[derive(Clone,
Debug)]
pub
struct
TypeRefData
{
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
qualname
:
String
,
}
#[derive(Debug)]
pub
struct
UseData
{
pub
id
:
NodeId
,
pub
span
:
Span
,
pub
name
:
String
,
pub
mod_id
:
Option
<
DefId
>
,
pub
scope
:
NodeId
,
pub
visibility
:
Visibility
,
}
#[derive(Debug)]
pub
struct
UseGlobData
{
pub
id
:
NodeId
,
pub
span
:
Span
,
pub
names
:
Vec
<
String
>
,
pub
scope
:
NodeId
,
pub
visibility
:
Visibility
,
}
/// Data for local and global variables (consts and statics).
#[derive(Debug)]
pub
struct
VariableData
{
pub
id
:
NodeId
,
pub
kind
:
VariableKind
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
parent
:
Option
<
DefId
>
,
pub
value
:
String
,
pub
type_value
:
String
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
#[derive(Debug)]
pub
enum
VariableKind
{
Static
,
Const
,
Local
,
Field
,
}
/// Data for the use of some item (e.g., the use of a local variable, which
/// will refer to that variables declaration (by ref_id)).
#[derive(Debug)]
pub
struct
VariableRefData
{
pub
name
:
String
,
pub
span
:
Span
,
pub
scope
:
NodeId
,
pub
ref_id
:
DefId
,
}
src/librustc_save_analysis/dump.rs
已删除
100644 → 0
浏览文件 @
9a471606
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
external_data
::
*
;
use
rls_data
::
CratePreludeData
;
pub
trait
Dump
{
fn
crate_prelude
(
&
mut
self
,
_
:
CratePreludeData
)
{}
fn
enum_data
(
&
mut
self
,
_
:
EnumData
)
{}
fn
extern_crate
(
&
mut
self
,
_
:
ExternCrateData
)
{}
fn
impl_data
(
&
mut
self
,
_
:
ImplData
)
{}
fn
inheritance
(
&
mut
self
,
_
:
InheritanceData
)
{}
fn
function
(
&
mut
self
,
_
:
FunctionData
)
{}
fn
function_ref
(
&
mut
self
,
_
:
FunctionRefData
)
{}
fn
function_call
(
&
mut
self
,
_
:
FunctionCallData
)
{}
fn
method
(
&
mut
self
,
_
:
MethodData
)
{}
fn
method_call
(
&
mut
self
,
_
:
MethodCallData
)
{}
fn
macro_data
(
&
mut
self
,
_
:
MacroData
)
{}
fn
macro_use
(
&
mut
self
,
_
:
MacroUseData
)
{}
fn
mod_data
(
&
mut
self
,
_
:
ModData
)
{}
fn
mod_ref
(
&
mut
self
,
_
:
ModRefData
)
{}
fn
struct_data
(
&
mut
self
,
_
:
StructData
)
{}
fn
struct_variant
(
&
mut
self
,
_
:
StructVariantData
)
{}
fn
trait_data
(
&
mut
self
,
_
:
TraitData
)
{}
fn
tuple_variant
(
&
mut
self
,
_
:
TupleVariantData
)
{}
fn
type_ref
(
&
mut
self
,
_
:
TypeRefData
)
{}
fn
typedef
(
&
mut
self
,
_
:
TypeDefData
)
{}
fn
use_data
(
&
mut
self
,
_
:
UseData
)
{}
fn
use_glob
(
&
mut
self
,
_
:
UseGlobData
)
{}
fn
variable
(
&
mut
self
,
_
:
VariableData
)
{}
fn
variable_ref
(
&
mut
self
,
_
:
VariableRefData
)
{}
}
src/librustc_save_analysis/dump_visitor.rs
浏览文件 @
8a2857e6
...
...
@@ -8,10 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Write the output of rustc's analysis to an implementor of Dump. The data is
//! primarily designed to be used as input to the DXR tool, specifically its
//! Rust plugin. It could also be used by IDEs or other code browsing, search, or
//! cross-referencing tools.
//! Write the output of rustc's analysis to an implementor of Dump.
//!
//! Dumping the analysis is implemented by walking the AST and getting a bunch of
//! info out from all over the place. We use Def IDs to identify objects. The
...
...
@@ -27,16 +24,12 @@
//! is used for recording the output in a format-agnostic way (see CsvDumper
//! for an example).
use
rustc
::
hir
;
use
rustc
::
hir
::
def
::
Def
;
use
rustc
::
hir
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
rustc
::
hir
::
map
::{
Node
,
NodeItem
};
use
rustc
::
hir
::
def
::
Def
as
HirDef
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
hir
::
map
::
Node
;
use
rustc
::
session
::
Session
;
use
rustc
::
ty
::{
self
,
TyCtxt
,
AssociatedItemContainer
};
use
rustc
::
ty
::{
self
,
TyCtxt
};
use
std
::
collections
::
HashSet
;
use
std
::
collections
::
hash_map
::
DefaultHasher
;
use
std
::
hash
::
*
;
use
std
::
path
::
Path
;
use
syntax
::
ast
::{
self
,
NodeId
,
PatKind
,
Attribute
,
CRATE_NODE_ID
};
...
...
@@ -48,15 +41,12 @@
use
syntax
::
codemap
::
Spanned
;
use
syntax_pos
::
*
;
use
{
escape
,
generated_code
,
SaveContext
,
PathCollector
,
docs_for_attrs
};
use
data
::
*
;
use
dump
::
Dump
;
use
external_data
::{
Lower
,
make_def_id
};
use
recorder
;
use
{
escape
,
generated_code
,
SaveContext
,
PathCollector
,
docs_for_attrs
,
lower_attributes
,
Dump
};
use
span_utils
::
SpanUtils
;
use
sig
;
use
rls_data
::
ExternalCrateData
;
use
rls_data
::{
CratePreludeData
,
Import
,
ImportKind
,
SpanData
,
Ref
,
RefKind
,
Def
,
DefKind
,
Relation
,
RelationKind
};
macro_rules!
down_cast_data
{
(
$id:ident
,
$kind:ident
,
$sp:expr
)
=>
{
...
...
@@ -82,8 +72,7 @@ pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> {
// of macro use (callsite) spans. We store these to ensure
// we only write one macro def per unique macro definition, and
// one macro use per unique callsite span.
mac_defs
:
HashSet
<
Span
>
,
mac_uses
:
HashSet
<
Span
>
,
// mac_defs: HashSet<Span>,
}
impl
<
'l
,
'tcx
:
'l
,
'll
,
D
:
Dump
+
'll
>
DumpVisitor
<
'l
,
'tcx
,
'll
,
D
>
{
...
...
@@ -98,8 +87,7 @@ pub fn new(save_ctxt: SaveContext<'l, 'tcx>,
dumper
:
dumper
,
span
:
span_utils
.clone
(),
cur_scope
:
CRATE_NODE_ID
,
mac_defs
:
HashSet
::
new
(),
mac_uses
:
HashSet
::
new
(),
// mac_defs: HashSet::new(),
}
}
...
...
@@ -127,6 +115,10 @@ fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
}
}
fn
span_from_span
(
&
self
,
span
:
Span
)
->
SpanData
{
self
.save_ctxt
.span_from_span
(
span
)
}
pub
fn
dump_crate_info
(
&
mut
self
,
name
:
&
str
,
krate
:
&
ast
::
Crate
)
{
let
source_file
=
self
.tcx.sess.local_crate_source_file
.as_ref
();
let
crate_root
=
source_file
.map
(|
source_file
|
{
...
...
@@ -137,25 +129,14 @@ pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
}
});
// Info about all the external crates referenced from this crate.
let
external_crates
=
self
.save_ctxt
.get_external_crates
()
.into_iter
()
.map
(|
c
|
{
let
lo_loc
=
self
.span.sess
.codemap
()
.lookup_char_pos
(
c
.span.lo
);
ExternalCrateData
{
name
:
c
.name
,
num
:
c
.number
,
file_name
:
SpanUtils
::
make_path_string
(
&
lo_loc
.file.name
),
}
})
.collect
();
// The current crate.
let
data
=
CratePreludeData
{
crate_name
:
name
.into
(),
crate_root
:
crate_root
.unwrap_or
(
"<no source>"
.to_owned
()),
external_crates
:
external_crates
,
span
:
krate
.span
,
external_crates
:
self
.save_ctxt
.get_external_crates
()
,
span
:
self
.span_from_span
(
krate
.span
)
,
};
self
.dumper
.crate_prelude
(
data
.lower
(
self
.tcx
)
);
self
.dumper
.crate_prelude
(
data
);
}
// Return all non-empty prefixes of a path.
...
...
@@ -211,13 +192,13 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
fn
write_sub_paths
(
&
mut
self
,
path
:
&
ast
::
Path
)
{
let
sub_paths
=
self
.process_path_prefixes
(
path
);
for
(
span
,
qualname
)
in
sub_paths
{
self
.dumper
.mod_ref
(
ModRefData
{
span
:
span
,
qualname
:
qualname
,
s
cope
:
self
.cur_scope
,
ref_id
:
None
}
.lower
(
self
.tcx
)
);
for
(
span
,
_
)
in
sub_paths
{
let
span
=
self
.span_from_span
(
span
);
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Mod
,
s
pan
,
ref_id
:
::
null_id
(),
});
}
}
...
...
@@ -230,13 +211,13 @@ fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
return
;
}
for
(
span
,
qualname
)
in
sub_paths
.into_iter
()
.take
(
len
-
1
)
{
self
.dumper
.mod_ref
(
ModRefData
{
span
:
span
,
qualname
:
qualname
,
s
cope
:
self
.cur_scope
,
ref_id
:
None
}
.lower
(
self
.tcx
)
);
for
(
span
,
_
)
in
sub_paths
.into_iter
()
.take
(
len
-
1
)
{
let
span
=
self
.span_from_span
(
span
);
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Mod
,
s
pan
,
ref_id
:
::
null_id
(),
});
}
}
...
...
@@ -251,32 +232,32 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
let
sub_paths
=
&
sub_paths
[
..
(
len
-
1
)];
// write the trait part of the sub-path
let
(
ref
span
,
ref
qualname
)
=
sub_paths
[
len
-
2
];
self
.dumper
.type_ref
(
TypeRefData
{
ref_id
:
None
,
span
:
*
span
,
qualname
:
qualname
.to_owne
d
(),
s
cope
:
CRATE_NODE_ID
}
.lower
(
self
.tcx
)
);
let
(
ref
span
,
_
)
=
sub_paths
[
len
-
2
];
let
span
=
self
.span_from_span
(
*
span
);
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Type
,
ref_id
:
::
null_i
d
(),
s
pan
,
});
// write the other sub-paths
if
len
<=
2
{
return
;
}
let
sub_paths
=
&
sub_paths
[
..
len
-
2
];
for
&
(
ref
span
,
ref
qualname
)
in
sub_paths
{
self
.dumper
.mod_ref
(
ModRefData
{
span
:
*
span
,
qualname
:
qualname
.to_owned
()
,
s
cope
:
self
.cur_scope
,
ref_id
:
None
}
.lower
(
self
.tcx
)
);
for
&
(
ref
span
,
_
)
in
sub_paths
{
let
span
=
self
.span_from_span
(
*
span
);
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Mod
,
s
pan
,
ref_id
:
::
null_id
(),
});
}
}
fn
lookup_def_id
(
&
self
,
ref_id
:
NodeId
)
->
Option
<
DefId
>
{
match
self
.save_ctxt
.get_path_def
(
ref_id
)
{
Def
::
PrimTy
(
..
)
|
Def
::
SelfTy
(
..
)
|
Def
::
Err
=>
None
,
HirDef
::
PrimTy
(
..
)
|
HirDef
::
SelfTy
(
..
)
|
Hir
Def
::
Err
=>
None
,
def
=>
Some
(
def
.def_id
()),
}
}
...
...
@@ -285,67 +266,67 @@ fn process_def_kind(&mut self,
ref_id
:
NodeId
,
span
:
Span
,
sub_span
:
Option
<
Span
>
,
def_id
:
DefId
,
scope
:
NodeId
)
{
def_id
:
DefId
)
{
if
self
.span
.filter_generated
(
sub_span
,
span
)
{
return
;
}
let
def
=
self
.save_ctxt
.get_path_def
(
ref_id
);
match
def
{
Def
::
Mod
(
_
)
=>
{
self
.dumper
.mod_ref
(
ModRefData
{
span
:
sub_span
.expect
(
"No span found for mod ref"
),
ref_id
:
Some
(
def_id
)
,
s
cope
:
scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
)
);
Hir
Def
::
Mod
(
_
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for mod ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Mod
,
s
pan
,
ref_id
:
::
id_from_def_id
(
def_id
),
});
}
Def
::
Struct
(
..
)
|
Def
::
Variant
(
..
)
|
Def
::
Union
(
..
)
|
Def
::
Enum
(
..
)
|
Def
::
TyAlias
(
..
)
|
Def
::
Trait
(
_
)
=>
{
self
.dumper
.type_ref
(
TypeRefData
{
span
:
sub_span
.expect
(
"No span found for type ref"
),
ref_id
:
Some
(
def_id
)
,
s
cope
:
scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
)
);
Hir
Def
::
Struct
(
..
)
|
Hir
Def
::
Variant
(
..
)
|
Hir
Def
::
Union
(
..
)
|
Hir
Def
::
Enum
(
..
)
|
Hir
Def
::
TyAlias
(
..
)
|
Hir
Def
::
Trait
(
_
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for type ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Type
,
s
pan
,
ref_id
:
::
id_from_def_id
(
def_id
),
});
}
Def
::
Static
(
..
)
|
Def
::
Const
(
..
)
|
Def
::
StructCtor
(
..
)
|
Def
::
VariantCtor
(
..
)
=>
{
self
.dumper
.variable_ref
(
VariableRefData
{
span
:
sub_span
.expect
(
"No span found for var ref"
),
ref_id
:
def_id
,
s
cope
:
scope
,
name
:
String
::
new
()
}
.lower
(
self
.tcx
)
);
Hir
Def
::
Static
(
..
)
|
Hir
Def
::
Const
(
..
)
|
Hir
Def
::
StructCtor
(
..
)
|
Hir
Def
::
VariantCtor
(
..
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for var ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Variable
,
s
pan
,
ref_id
:
::
id_from_def_id
(
def_id
),
});
}
Def
::
Fn
(
..
)
=>
{
self
.dumper
.function_ref
(
FunctionRefData
{
span
:
sub_span
.expect
(
"No span found for fn ref"
),
ref_id
:
def_id
,
scope
:
scope
}
.lower
(
self
.tcx
));
HirDef
::
Fn
(
..
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for fn ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Function
,
span
,
ref_id
:
::
id_from_def_id
(
def_id
),
});
}
// With macros 2.0, we can legitimately get a ref to a macro, but
// we don't handle it properly for now (FIXME).
Def
::
Macro
(
..
)
=>
{}
Def
::
Local
(
..
)
|
Def
::
Upvar
(
..
)
|
Def
::
SelfTy
(
..
)
|
Def
::
Label
(
_
)
|
Def
::
TyParam
(
..
)
|
Def
::
Method
(
..
)
|
Def
::
AssociatedTy
(
..
)
|
Def
::
AssociatedConst
(
..
)
|
Def
::
PrimTy
(
_
)
|
Def
::
GlobalAsm
(
_
)
|
Def
::
Err
=>
{
Hir
Def
::
Macro
(
..
)
=>
{}
Hir
Def
::
Local
(
..
)
|
Hir
Def
::
Upvar
(
..
)
|
Hir
Def
::
SelfTy
(
..
)
|
Hir
Def
::
Label
(
_
)
|
Hir
Def
::
TyParam
(
..
)
|
Hir
Def
::
Method
(
..
)
|
Hir
Def
::
AssociatedTy
(
..
)
|
Hir
Def
::
AssociatedConst
(
..
)
|
Hir
Def
::
PrimTy
(
_
)
|
Hir
Def
::
GlobalAsm
(
_
)
|
Hir
Def
::
Err
=>
{
span_bug!
(
span
,
"process_def_kind for unexpected item: {:?}"
,
def
);
...
...
@@ -368,21 +349,23 @@ fn process_formals(&mut self, formals: &'l [ast::Arg], qualname: &str) {
// variable name, but who knows?)
let
sub_span
=
span_utils
.span_for_last_ident
(
p
.span
);
if
!
self
.span
.filter_generated
(
sub_span
,
p
.span
)
{
self
.dumper
.variable
(
VariableData
{
id
:
id
,
kind
:
VariableKind
::
Local
,
span
:
sub_span
.expect
(
"No span found for variable"
),
let
id
=
::
id_from_node_id
(
id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for variable"
));
self
.dumper
.dump_def
(
false
,
Def
{
kind
:
DefKind
::
Local
,
id
,
span
,
name
:
path_to_string
(
p
),
qualname
:
format!
(
"{}::{}"
,
qualname
,
path_to_string
(
p
)),
type_value
:
typ
,
value
:
String
::
new
(),
scope
:
CRATE_NODE_ID
,
value
:
typ
,
parent
:
None
,
visibility
:
Visibility
::
Inherited
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
None
,
attributes
:
vec!
[],
}
.lower
(
self
.tcx
)
);
attributes
:
vec!
[],
});
}
}
}
...
...
@@ -393,12 +376,11 @@ fn process_method(&mut self,
body
:
Option
<&
'l
ast
::
Block
>
,
id
:
ast
::
NodeId
,
name
:
ast
::
Ident
,
vis
:
Visibility
,
attrs
:
&
'l
[
Attribute
],
vis
:
ast
::
Visibility
,
span
:
Span
)
{
debug!
(
"process_method: {}:{}"
,
id
,
name
);
if
let
Some
(
method_data
)
=
self
.save_ctxt
.get_method_data
(
id
,
name
.name
,
span
)
{
if
let
Some
(
m
ut
m
ethod_data
)
=
self
.save_ctxt
.get_method_data
(
id
,
name
.name
,
span
)
{
let
sig_str
=
::
make_signature
(
&
sig
.decl
,
&
sig
.generics
);
if
body
.is_some
()
{
...
...
@@ -407,61 +389,11 @@ fn process_method(&mut self,
});
}
// If the method is defined in an impl, then try and find the corresponding
// method decl in a trait, and if there is one, make a decl_id for it. This
// requires looking up the impl, then the trait, then searching for a method
// with the right name.
if
!
self
.span
.filter_generated
(
Some
(
method_data
.span
),
span
)
{
let
container
=
self
.tcx
.associated_item
(
self
.tcx.hir
.local_def_id
(
id
))
.container
;
let
mut
trait_id
;
let
mut
decl_id
=
None
;
match
container
{
AssociatedItemContainer
::
ImplContainer
(
id
)
=>
{
trait_id
=
self
.tcx
.trait_id_of_impl
(
id
);
match
trait_id
{
Some
(
id
)
=>
{
for
item
in
self
.tcx
.associated_items
(
id
)
{
if
item
.kind
==
ty
::
AssociatedKind
::
Method
{
if
item
.name
==
name
.name
{
decl_id
=
Some
(
item
.def_id
);
break
;
}
}
}
}
None
=>
{
if
let
Some
(
NodeItem
(
item
))
=
self
.tcx.hir
.get_if_local
(
id
)
{
if
let
hir
::
ItemImpl
(
_
,
_
,
_
,
_
,
_
,
ref
ty
,
_
)
=
item
.node
{
trait_id
=
self
.lookup_def_id
(
ty
.id
);
}
}
}
}
}
AssociatedItemContainer
::
TraitContainer
(
id
)
=>
{
trait_id
=
Some
(
id
);
}
}
self
.dumper
.method
(
MethodData
{
id
:
method_data
.id
,
name
:
method_data
.name
,
span
:
method_data
.span
,
scope
:
method_data
.scope
,
qualname
:
method_data
.qualname
.clone
(),
value
:
sig_str
,
decl_id
:
decl_id
,
parent
:
trait_id
,
visibility
:
vis
,
docs
:
docs_for_attrs
(
attrs
),
sig
:
sig
::
method_signature
(
id
,
name
,
sig
,
&
self
.save_ctxt
),
attributes
:
attrs
.to_vec
(),
}
.lower
(
self
.tcx
));
}
self
.process_generic_params
(
&
sig
.generics
,
span
,
&
method_data
.qualname
,
id
);
method_data
.value
=
sig_str
;
method_data
.sig
=
sig
::
method_signature
(
id
,
name
,
sig
,
&
self
.save_ctxt
);
self
.dumper
.dump_def
(
vis
==
ast
::
Visibility
::
Public
,
method_data
);
}
// walk arg and return types
...
...
@@ -480,22 +412,17 @@ fn process_method(&mut self,
}
fn
process_trait_ref
(
&
mut
self
,
trait_ref
:
&
'l
ast
::
TraitRef
)
{
let
trait_ref_data
=
self
.save_ctxt
.get_trait_ref_data
(
trait_ref
,
self
.cur_scope
);
let
trait_ref_data
=
self
.save_ctxt
.get_trait_ref_data
(
trait_ref
);
if
let
Some
(
trait_ref_data
)
=
trait_ref_data
{
if
!
self
.span
.filter_generated
(
Some
(
trait_ref_data
.span
),
trait_ref
.path.span
)
{
self
.dumper
.type_ref
(
trait_ref_data
.lower
(
self
.tcx
));
}
self
.dumper
.dump_ref
(
trait_ref_data
);
}
self
.process_path
(
trait_ref
.ref_id
,
&
trait_ref
.path
,
Some
(
recorder
::
TypeRef
)
);
self
.process_path
(
trait_ref
.ref_id
,
&
trait_ref
.path
);
}
fn
process_struct_field_def
(
&
mut
self
,
field
:
&
ast
::
StructField
,
parent_id
:
NodeId
)
{
let
field_data
=
self
.save_ctxt
.get_field_data
(
field
,
parent_id
);
if
let
Some
(
mut
field_data
)
=
field_data
{
if
!
self
.span
.filter_generated
(
Some
(
field_data
.span
),
field
.span
)
{
field_data
.value
=
String
::
new
();
self
.dumper
.variable
(
field_data
.lower
(
self
.tcx
));
}
if
let
Some
(
field_data
)
=
field_data
{
self
.dumper
.dump_def
(
field
.vis
==
ast
::
Visibility
::
Public
,
field_data
);
}
}
...
...
@@ -519,18 +446,23 @@ fn process_generic_params(&mut self,
name
,
id
);
if
!
self
.span
.filter_generated
(
Some
(
param_ss
),
full_span
)
{
self
.dumper
.typedef
(
TypeDefData
{
span
:
param_ss
,
name
:
name
,
id
:
param
.id
,
qualname
:
qualname
,
let
id
=
::
id_from_node_id
(
param
.id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
param_ss
);
self
.dumper
.dump_def
(
false
,
Def
{
kind
:
DefKind
::
Type
,
id
,
span
,
name
,
qualname
,
value
:
String
::
new
(),
visibility
:
Visibility
::
Inherited
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
None
,
attributes
:
vec!
[],
}
.lower
(
self
.tcx
)
);
});
}
}
self
.visit_generics
(
generics
);
...
...
@@ -542,13 +474,10 @@ fn process_fn(&mut self,
ty_params
:
&
'l
ast
::
Generics
,
body
:
&
'l
ast
::
Block
)
{
if
let
Some
(
fn_data
)
=
self
.save_ctxt
.get_item_data
(
item
)
{
down_cast_data!
(
fn_data
,
FunctionData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
fn_data
.span
),
item
.span
)
{
self
.dumper
.function
(
fn_data
.clone
()
.lower
(
self
.tcx
));
}
down_cast_data!
(
fn_data
,
DefData
,
item
.span
);
self
.nest_tables
(
item
.id
,
|
v
|
v
.process_formals
(
&
decl
.inputs
,
&
fn_data
.qualname
));
self
.process_generic_params
(
ty_params
,
item
.span
,
&
fn_data
.qualname
,
item
.id
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
fn_data
);
}
for
arg
in
&
decl
.inputs
{
...
...
@@ -567,10 +496,8 @@ fn process_static_or_const_item(&mut self,
typ
:
&
'l
ast
::
Ty
,
expr
:
&
'l
ast
::
Expr
)
{
if
let
Some
(
var_data
)
=
self
.save_ctxt
.get_item_data
(
item
)
{
down_cast_data!
(
var_data
,
VariableData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
var_data
.span
),
item
.span
)
{
self
.dumper
.variable
(
var_data
.lower
(
self
.tcx
));
}
down_cast_data!
(
var_data
,
DefData
,
item
.span
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
var_data
);
}
self
.visit_ty
(
&
typ
);
self
.visit_expr
(
expr
);
...
...
@@ -583,29 +510,31 @@ fn process_assoc_const(&mut self,
typ
:
&
'l
ast
::
Ty
,
expr
:
Option
<&
'l
ast
::
Expr
>
,
parent_id
:
DefId
,
vis
:
Visibility
,
vis
:
ast
::
Visibility
,
attrs
:
&
'l
[
Attribute
])
{
let
qualname
=
format!
(
"::{}"
,
self
.tcx
.node_path_str
(
id
));
let
sub_span
=
self
.span
.sub_span_after_keyword
(
span
,
keywords
::
Const
);
let
value
=
expr
.map
(|
e
|
self
.span
.snippet
(
e
.span
))
.unwrap_or
(
String
::
new
());
if
!
self
.span
.filter_generated
(
sub_span
,
span
)
{
self
.dumper
.variable
(
VariableData
{
span
:
sub_span
.expect
(
"No span found for variable"
),
kind
:
VariableKind
::
Const
,
id
:
id
,
let
sig
=
sig
::
assoc_const_signature
(
id
,
name
,
typ
,
expr
,
&
self
.save_ctxt
);
let
id
=
::
id_from_node_id
(
id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for variable"
));
self
.dumper
.dump_def
(
vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Const
,
id
,
span
,
name
:
name
.to_string
(),
qualname
:
qualname
,
value
:
value
,
type_value
:
ty_to_string
(
&
typ
),
scope
:
self
.cur_scope
,
parent
:
Some
(
parent_id
),
visibility
:
vis
,
qualname
,
value
:
ty_to_string
(
&
typ
),
parent
:
Some
(::
id_from_def_id
(
parent_id
)),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
attrs
),
sig
:
sig
::
assoc_const_signature
(
id
,
name
,
typ
,
expr
,
&
self
.save_ctxt
)
,
attributes
:
attrs
.to_vec
(
),
}
.lower
(
self
.tcx
)
);
sig
,
attributes
:
lower_attributes
(
attrs
.to_owned
(),
&
self
.save_ctxt
),
});
}
// walk type and init value
...
...
@@ -624,7 +553,7 @@ fn process_struct(&mut self,
let
qualname
=
format!
(
"::{}"
,
self
.tcx
.node_path_str
(
item
.id
));
let
sub_span
=
self
.span
.sub_span_after_keyword
(
item
.span
,
keywords
::
Struct
);
let
(
val
,
fields
)
=
let
(
val
ue
,
fields
)
=
if
let
ast
::
ItemKind
::
Struct
(
ast
::
VariantData
::
Struct
(
ref
fields
,
_
),
_
)
=
item
.node
{
let
fields_str
=
fields
.iter
()
...
...
@@ -633,26 +562,28 @@ fn process_struct(&mut self,
.unwrap_or
(
i
.to_string
()))
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
);
(
format!
(
"{} {{ {} }}"
,
name
,
fields_str
),
fields
.iter
()
.map
(|
f
|
f
.id
)
.collect
())
(
format!
(
"{} {{ {} }}"
,
name
,
fields_str
),
fields
.iter
()
.map
(|
f
|
::
id_from_node_id
(
f
.id
,
&
self
.save_ctxt
))
.collect
())
}
else
{
(
String
::
new
(),
vec!
[])
};
if
!
self
.span
.filter_generated
(
sub_span
,
item
.span
)
{
self
.dumper
.struct_data
(
StructData
{
span
:
sub_span
.expect
(
"No span found for struct"
),
id
:
item
.id
,
name
:
name
,
ctor_id
:
def
.id
(),
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for struct"
));
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Struct
,
id
:
::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
),
span
,
name
,
qualname
:
qualname
.clone
(),
scope
:
self
.cur_scop
e
,
value
:
val
,
fields
:
fields
,
visibility
:
From
::
from
(
&
item
.vis
)
,
valu
e
,
parent
:
None
,
children
:
fields
,
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
&
self
.save_ctxt
),
attributes
:
item
.attrs
.clone
(
),
}
.lower
(
self
.tcx
)
);
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
for
field
in
def
.fields
()
{
...
...
@@ -672,10 +603,7 @@ fn process_enum(&mut self,
None
=>
return
,
Some
(
data
)
=>
data
,
};
down_cast_data!
(
enum_data
,
EnumData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
enum_data
.span
),
item
.span
)
{
self
.dumper
.enum_data
(
enum_data
.clone
()
.lower
(
self
.tcx
));
}
down_cast_data!
(
enum_data
,
DefData
,
item
.span
);
for
variant
in
&
enum_definition
.variants
{
let
name
=
variant
.node.name.name
.to_string
();
...
...
@@ -692,48 +620,62 @@ fn process_enum(&mut self,
.unwrap_or
(
i
.to_string
()))
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
);
let
val
=
format!
(
"{}::{} {{ {} }}"
,
enum_data
.name
,
name
,
fields_str
);
let
val
ue
=
format!
(
"{}::{} {{ {} }}"
,
enum_data
.name
,
name
,
fields_str
);
if
!
self
.span
.filter_generated
(
sub_span
,
variant
.span
)
{
self
.dumper
.struct_variant
(
StructVariantData
{
span
:
sub_span
.expect
(
"No span found for struct variant"
),
id
:
variant
.node.data
.id
(),
name
:
name
,
qualname
:
qualname
,
type_value
:
enum_data
.qualname
.clone
(),
value
:
val
,
scope
:
enum_data
.scope
,
parent
:
Some
(
make_def_id
(
item
.id
,
&
self
.tcx.hir
)),
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for struct variant"
));
let
id
=
::
id_from_node_id
(
variant
.node.data
.id
(),
&
self
.save_ctxt
);
let
parent
=
Some
(::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
));
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Struct
,
id
,
span
,
name
,
qualname
,
value
,
parent
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
variant
.node.attrs
),
sig
:
sig
::
variant_signature
(
variant
,
&
self
.save_ctxt
),
attributes
:
variant
.node.attrs
.clone
(),
}
.lower
(
self
.tcx
));
attributes
:
lower_attributes
(
variant
.node.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
}
ref
v
=>
{
let
sub_span
=
self
.span
.span_for_first_ident
(
variant
.span
);
let
mut
val
=
format!
(
"{}::{}"
,
enum_data
.name
,
name
);
let
mut
val
ue
=
format!
(
"{}::{}"
,
enum_data
.name
,
name
);
if
let
&
ast
::
VariantData
::
Tuple
(
ref
fields
,
_
)
=
v
{
val
.push
(
'('
);
val
.push_str
(
&
fields
.iter
()
.map
(|
f
|
ty_to_string
(
&
f
.ty
))
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
));
val
.push
(
')'
);
val
ue
.push
(
'('
);
val
ue
.push_str
(
&
fields
.iter
()
.map
(|
f
|
ty_to_string
(
&
f
.ty
))
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
));
val
ue
.push
(
')'
);
}
if
!
self
.span
.filter_generated
(
sub_span
,
variant
.span
)
{
self
.dumper
.tuple_variant
(
TupleVariantData
{
span
:
sub_span
.expect
(
"No span found for tuple variant"
),
id
:
variant
.node.data
.id
(),
name
:
name
,
qualname
:
qualname
,
type_value
:
enum_data
.qualname
.clone
(),
value
:
val
,
scope
:
enum_data
.scope
,
parent
:
Some
(
make_def_id
(
item
.id
,
&
self
.tcx.hir
)),
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for tuple variant"
));
let
id
=
::
id_from_node_id
(
variant
.node.data
.id
(),
&
self
.save_ctxt
);
let
parent
=
Some
(::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
));
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Tuple
,
id
,
span
,
name
,
qualname
,
value
,
parent
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
variant
.node.attrs
),
sig
:
sig
::
variant_signature
(
variant
,
&
self
.save_ctxt
),
attributes
:
variant
.node.attrs
.clone
(),
}
.lower
(
self
.tcx
));
attributes
:
lower_attributes
(
variant
.node.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
}
}
...
...
@@ -744,7 +686,8 @@ fn process_enum(&mut self,
self
.visit_ty
(
&
field
.ty
);
}
}
self
.process_generic_params
(
ty_params
,
item
.span
,
&
enum_data
.qualname
,
enum_data
.id
);
self
.process_generic_params
(
ty_params
,
item
.span
,
&
enum_data
.qualname
,
item
.id
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
enum_data
);
}
fn
process_impl
(
&
mut
self
,
...
...
@@ -754,25 +697,17 @@ fn process_impl(&mut self,
typ
:
&
'l
ast
::
Ty
,
impl_items
:
&
'l
[
ast
::
ImplItem
])
{
if
let
Some
(
impl_data
)
=
self
.save_ctxt
.get_item_data
(
item
)
{
down_cast_data!
(
impl_data
,
ImplData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
impl_data
.span
),
item
.span
)
{
self
.dumper
.impl_data
(
ImplData
{
id
:
impl_data
.id
,
span
:
impl_data
.span
,
scope
:
impl_data
.scope
,
trait_ref
:
impl_data
.trait_ref
.map
(|
d
|
d
.ref_id
.unwrap
()),
self_ref
:
impl_data
.self_ref
.map
(|
d
|
d
.ref_id
.unwrap
())
}
.lower
(
self
.tcx
));
}
down_cast_data!
(
impl_data
,
RelationData
,
item
.span
);
self
.dumper
.dump_relation
(
impl_data
);
}
self
.visit_ty
(
&
typ
);
if
let
&
Some
(
ref
trait_ref
)
=
trait_ref
{
self
.process_path
(
trait_ref
.ref_id
,
&
trait_ref
.path
,
Some
(
recorder
::
TypeRef
)
);
self
.process_path
(
trait_ref
.ref_id
,
&
trait_ref
.path
);
}
self
.process_generic_params
(
type_parameters
,
item
.span
,
""
,
item
.id
);
for
impl_item
in
impl_items
{
let
map
=
&
self
.tcx.hir
;
self
.process_impl_item
(
impl_item
,
ma
ke_def_id
(
item
.id
,
map
));
self
.process_impl_item
(
impl_item
,
ma
p
.local_def_id
(
item
.id
));
}
}
...
...
@@ -793,19 +728,24 @@ fn process_trait(&mut self,
}
let
sub_span
=
self
.span
.sub_span_after_keyword
(
item
.span
,
keywords
::
Trait
);
if
!
self
.span
.filter_generated
(
sub_span
,
item
.span
)
{
self
.dumper
.trait_data
(
TraitData
{
span
:
sub_span
.expect
(
"No span found for trait"
),
id
:
item
.id
,
name
:
name
,
let
id
=
::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for trait"
));
let
children
=
methods
.iter
()
.map
(|
i
|
::
id_from_node_id
(
i
.id
,
&
self
.save_ctxt
))
.collect
();
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Trait
,
id
,
span
,
name
,
qualname
:
qualname
.clone
(),
scope
:
self
.cur_scope
,
value
:
val
,
items
:
methods
.iter
()
.map
(|
i
|
i
.id
)
.collect
(),
visibility
:
From
::
from
(
&
item
.vis
),
parent
:
None
,
children
,
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
&
self
.save_ctxt
),
attributes
:
item
.attrs
.clone
(
),
}
.lower
(
self
.tcx
)
);
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
// super-traits
...
...
@@ -823,21 +763,22 @@ fn process_trait(&mut self,
if
let
Some
(
id
)
=
self
.lookup_def_id
(
trait_ref
.ref_id
)
{
let
sub_span
=
self
.span
.sub_span_for_type_name
(
trait_ref
.path.span
);
if
!
self
.span
.filter_generated
(
sub_span
,
trait_ref
.path.span
)
{
self
.dumper
.type_ref
(
TypeRefData
{
span
:
sub_span
.expect
(
"No span found for trait ref"
),
ref_id
:
Some
(
id
)
,
s
cope
:
self
.cur_scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
)
);
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for trait ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Type
,
s
pan
,
ref_id
:
::
id_from_def_id
(
id
),
});
}
if
!
self
.span
.filter_generated
(
sub_span
,
trait_ref
.path.span
)
{
let
sub_span
=
sub_span
.expect
(
"No span for inheritance"
);
self
.dumper
.inheritance
(
InheritanceData
{
let
sub_span
=
self
.span_from_span
(
sub_span
.expect
(
"No span for inheritance"
));
self
.dumper
.dump_relation
(
Relation
{
kind
:
RelationKind
::
SuperTrait
,
span
:
sub_span
,
base_id
:
id
,
deriv_id
:
item
.id
}
.lower
(
self
.tcx
)
);
from
:
::
id_from_def_id
(
id
)
,
to
:
::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
),
});
}
}
}
...
...
@@ -846,21 +787,19 @@ fn process_trait(&mut self,
self
.process_generic_params
(
generics
,
item
.span
,
&
qualname
,
item
.id
);
for
method
in
methods
{
let
map
=
&
self
.tcx.hir
;
self
.process_trait_item
(
method
,
ma
ke_def_id
(
item
.id
,
map
))
self
.process_trait_item
(
method
,
ma
p
.local_def_id
(
item
.id
))
}
}
// `item` is the module in question, represented as an item.
fn
process_mod
(
&
mut
self
,
item
:
&
ast
::
Item
)
{
if
let
Some
(
mod_data
)
=
self
.save_ctxt
.get_item_data
(
item
)
{
down_cast_data!
(
mod_data
,
ModData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
mod_data
.span
),
item
.span
)
{
self
.dumper
.mod_data
(
mod_data
.lower
(
self
.tcx
));
}
down_cast_data!
(
mod_data
,
DefData
,
item
.span
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
mod_data
);
}
}
fn
process_path
(
&
mut
self
,
id
:
NodeId
,
path
:
&
ast
::
Path
,
ref_kind
:
Option
<
recorder
::
Row
>
)
{
fn
process_path
(
&
mut
self
,
id
:
NodeId
,
path
:
&
ast
::
Path
)
{
let
path_data
=
self
.save_ctxt
.get_path_data
(
id
,
path
);
if
generated_code
(
path
.span
)
&&
path_data
.is_none
()
{
return
;
...
...
@@ -873,81 +812,29 @@ fn process_path(&mut self, id: NodeId, path: &ast::Path, ref_kind: Option<record
}
};
match
path_data
{
Data
::
VariableRefData
(
vrd
)
=>
{
// FIXME: this whole block duplicates the code in process_def_kind
if
!
self
.span
.filter_generated
(
Some
(
vrd
.span
),
path
.span
)
{
match
ref_kind
{
Some
(
recorder
::
TypeRef
)
=>
{
self
.dumper
.type_ref
(
TypeRefData
{
span
:
vrd
.span
,
ref_id
:
Some
(
vrd
.ref_id
),
scope
:
vrd
.scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
));
}
Some
(
recorder
::
FnRef
)
=>
{
self
.dumper
.function_ref
(
FunctionRefData
{
span
:
vrd
.span
,
ref_id
:
vrd
.ref_id
,
scope
:
vrd
.scope
}
.lower
(
self
.tcx
));
}
Some
(
recorder
::
ModRef
)
=>
{
self
.dumper
.mod_ref
(
ModRefData
{
span
:
vrd
.span
,
ref_id
:
Some
(
vrd
.ref_id
),
scope
:
vrd
.scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
));
}
Some
(
recorder
::
VarRef
)
|
None
=>
self
.dumper
.variable_ref
(
vrd
.lower
(
self
.tcx
))
}
}
}
Data
::
TypeRefData
(
trd
)
=>
{
if
!
self
.span
.filter_generated
(
Some
(
trd
.span
),
path
.span
)
{
self
.dumper
.type_ref
(
trd
.lower
(
self
.tcx
));
}
}
Data
::
MethodCallData
(
mcd
)
=>
{
if
!
self
.span
.filter_generated
(
Some
(
mcd
.span
),
path
.span
)
{
self
.dumper
.method_call
(
mcd
.lower
(
self
.tcx
));
}
}
Data
::
FunctionCallData
(
fcd
)
=>
{
if
!
self
.span
.filter_generated
(
Some
(
fcd
.span
),
path
.span
)
{
self
.dumper
.function_call
(
fcd
.lower
(
self
.tcx
));
}
}
_
=>
{
span_bug!
(
path
.span
,
"Unexpected data: {:?}"
,
path_data
);
}
}
self
.dumper
.dump_ref
(
path_data
);
// Modules or types in the path prefix.
match
self
.save_ctxt
.get_path_def
(
id
)
{
Def
::
Method
(
did
)
=>
{
Hir
Def
::
Method
(
did
)
=>
{
let
ti
=
self
.tcx
.associated_item
(
did
);
if
ti
.kind
==
ty
::
AssociatedKind
::
Method
&&
ti
.method_has_self_argument
{
self
.write_sub_path_trait_truncated
(
path
);
}
}
Def
::
Fn
(
..
)
|
Def
::
Const
(
..
)
|
Def
::
Static
(
..
)
|
Def
::
StructCtor
(
..
)
|
Def
::
VariantCtor
(
..
)
|
Def
::
AssociatedConst
(
..
)
|
Def
::
Local
(
..
)
|
Def
::
Upvar
(
..
)
|
Def
::
Struct
(
..
)
|
Def
::
Union
(
..
)
|
Def
::
Variant
(
..
)
|
Def
::
TyAlias
(
..
)
|
Def
::
AssociatedTy
(
..
)
=>
self
.write_sub_paths_truncated
(
path
),
Hir
Def
::
Fn
(
..
)
|
Hir
Def
::
Const
(
..
)
|
Hir
Def
::
Static
(
..
)
|
Hir
Def
::
StructCtor
(
..
)
|
Hir
Def
::
VariantCtor
(
..
)
|
Hir
Def
::
AssociatedConst
(
..
)
|
Hir
Def
::
Local
(
..
)
|
Hir
Def
::
Upvar
(
..
)
|
Hir
Def
::
Struct
(
..
)
|
Hir
Def
::
Union
(
..
)
|
Hir
Def
::
Variant
(
..
)
|
Hir
Def
::
TyAlias
(
..
)
|
Hir
Def
::
AssociatedTy
(
..
)
=>
self
.write_sub_paths_truncated
(
path
),
_
=>
{}
}
}
...
...
@@ -961,20 +848,15 @@ fn process_struct_lit(&mut self,
self
.write_sub_paths_truncated
(
path
);
if
let
Some
(
struct_lit_data
)
=
self
.save_ctxt
.get_expr_data
(
ex
)
{
down_cast_data!
(
struct_lit_data
,
Type
RefData
,
ex
.span
);
if
!
self
.span
.filter_generated
(
Some
(
struct_lit_data
.span
),
ex
.span
)
{
self
.dumper
.
type_ref
(
struct_lit_data
.lower
(
self
.tcx
)
);
down_cast_data!
(
struct_lit_data
,
RefData
,
ex
.span
);
if
!
generated_code
(
ex
.span
)
{
self
.dumper
.
dump_ref
(
struct_lit_data
);
}
let
scope
=
self
.save_ctxt
.enclosing_scope
(
ex
.id
);
for
field
in
fields
{
if
let
Some
(
field_data
)
=
self
.save_ctxt
.get_field_ref_data
(
field
,
variant
,
scope
)
{
if
!
self
.span
.filter_generated
(
Some
(
field_data
.span
),
field
.ident.span
)
{
self
.dumper
.variable_ref
(
field_data
.lower
(
self
.tcx
));
}
.get_field_ref_data
(
field
,
variant
)
{
self
.dumper
.dump_ref
(
field_data
);
}
self
.visit_expr
(
&
field
.expr
)
...
...
@@ -986,9 +868,9 @@ fn process_struct_lit(&mut self,
fn
process_method_call
(
&
mut
self
,
ex
:
&
'l
ast
::
Expr
,
args
:
&
'l
[
P
<
ast
::
Expr
>
])
{
if
let
Some
(
mcd
)
=
self
.save_ctxt
.get_expr_data
(
ex
)
{
down_cast_data!
(
mcd
,
MethodCall
Data
,
ex
.span
);
if
!
self
.span
.filter_generated
(
Some
(
mcd
.span
),
ex
.span
)
{
self
.dumper
.
method_call
(
mcd
.lower
(
self
.tcx
)
);
down_cast_data!
(
mcd
,
Ref
Data
,
ex
.span
);
if
!
generated_code
(
ex
.span
)
{
self
.dumper
.
dump_ref
(
mcd
);
}
}
...
...
@@ -1013,12 +895,13 @@ fn process_pat(&mut self, p: &'l ast::Pat) {
let
sub_span
=
self
.span
.span_for_first_ident
(
span
);
if
let
Some
(
f
)
=
variant
.find_field_named
(
field
.ident.name
)
{
if
!
self
.span
.filter_generated
(
sub_span
,
span
)
{
self
.dumper
.variable_ref
(
VariableRefData
{
span
:
sub_span
.expect
(
"No span fund for var ref"
),
ref_id
:
f
.did
,
scope
:
self
.cur_scope
,
name
:
String
::
new
()
}
.lower
(
self
.tcx
));
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span fund for var ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Variable
,
span
,
ref_id
:
::
id_from_def_id
(
f
.did
),
});
}
}
self
.visit_pat
(
&
field
.pat
);
...
...
@@ -1036,7 +919,7 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) {
collector
.visit_pat
(
&
p
);
self
.visit_pat
(
&
p
);
for
&
(
id
,
ref
p
,
immut
,
_
)
in
&
collector
.collected_paths
{
for
&
(
id
,
ref
p
,
immut
)
in
&
collector
.collected_paths
{
let
mut
value
=
match
immut
{
ast
::
Mutability
::
Immutable
=>
value
.to_string
(),
_
=>
String
::
new
(),
...
...
@@ -1058,21 +941,24 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) {
let
sub_span
=
self
.span
.span_for_last_ident
(
p
.span
);
// Rust uses the id of the pattern for var lookups, so we'll use it too.
if
!
self
.span
.filter_generated
(
sub_span
,
p
.span
)
{
self
.dumper
.variable
(
VariableData
{
span
:
sub_span
.expect
(
"No span found for variable"
),
kind
:
VariableKind
::
Local
,
id
:
id
,
let
qualname
=
format!
(
"{}${}"
,
path_to_string
(
p
),
id
);
let
id
=
::
id_from_node_id
(
id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for variable"
));
self
.dumper
.dump_def
(
false
,
Def
{
kind
:
DefKind
::
Local
,
id
,
span
,
name
:
path_to_string
(
p
),
qualname
:
format!
(
"{}${}"
,
path_to_string
(
p
),
id
),
value
:
value
,
type_value
:
typ
,
scope
:
CRATE_NODE_ID
,
qualname
,
value
:
typ
,
parent
:
None
,
visibility
:
Visibility
::
Inherited
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
None
,
attributes
:
vec!
[],
}
.lower
(
self
.tcx
)
);
attributes
:
vec!
[],
});
}
}
}
...
...
@@ -1084,46 +970,36 @@ fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) {
/// If the span is not macro-generated, do nothing, else use callee and
/// callsite spans to record macro definition and use data, using the
/// mac_uses and mac_defs sets to prevent multiples.
fn
process_macro_use
(
&
mut
self
,
span
:
Span
,
id
:
NodeId
)
{
let
data
=
match
self
.save_ctxt
.get_macro_use_data
(
span
,
id
)
{
fn
process_macro_use
(
&
mut
self
,
span
:
Span
)
{
let
data
=
match
self
.save_ctxt
.get_macro_use_data
(
span
)
{
None
=>
return
,
Some
(
data
)
=>
data
,
};
let
mut
hasher
=
DefaultHasher
::
new
();
data
.callee_span
.hash
(
&
mut
hasher
);
let
hash
=
hasher
.finish
();
let
qualname
=
format!
(
"{}::{}"
,
data
.name
,
hash
);
// FIXME write the macro def
// let mut hasher = DefaultHasher::new();
// data.callee_span.hash(&mut hasher);
// let hash = hasher.finish();
// let qualname = format!("{}::{}", data.name, hash);
// Don't write macro definition for imported macros
if
!
self
.mac_defs
.contains
(
&
data
.callee_span
)
&&
!
data
.imported
{
self
.mac_defs
.insert
(
data
.callee_span
);
if
let
Some
(
sub_span
)
=
self
.span
.span_for_macro_def_name
(
data
.callee_span
)
{
self
.dumper
.macro_data
(
MacroData
{
span
:
sub_span
,
name
:
data
.name
.clone
(),
qualname
:
qualname
.clone
(),
// FIXME where do macro docs come from?
docs
:
String
::
new
(),
}
.lower
(
self
.tcx
));
}
}
if
!
self
.mac_uses
.contains
(
&
data
.span
)
{
self
.mac_uses
.insert
(
data
.span
);
if
let
Some
(
sub_span
)
=
self
.span
.span_for_macro_use_name
(
data
.span
)
{
self
.dumper
.macro_use
(
MacroUseData
{
span
:
sub_span
,
name
:
data
.name
,
qualname
:
qualname
,
scope
:
data
.scope
,
callee_span
:
data
.callee_span
,
imported
:
data
.imported
,
}
.lower
(
self
.tcx
));
}
}
// if !self.mac_defs.contains(&data.callee_span)
// && !data.imported {
// self.mac_defs.insert(data.callee_span);
// if let Some(sub_span) = self.span.span_for_macro_def_name(data.callee_span) {
// self.dumper.macro_data(MacroData {
// span: sub_span,
// name: data.name.clone(),
// qualname: qualname.clone(),
// // FIXME where do macro docs come from?
// docs: String::new(),
// }.lower(self.tcx));
// }
// }
self
.dumper
.macro_use
(
data
);
}
fn
process_trait_item
(
&
mut
self
,
trait_item
:
&
'l
ast
::
TraitItem
,
trait_id
:
DefId
)
{
self
.process_macro_use
(
trait_item
.span
,
trait_item
.id
);
self
.process_macro_use
(
trait_item
.span
);
match
trait_item
.node
{
ast
::
TraitItemKind
::
Const
(
ref
ty
,
ref
expr
)
=>
{
self
.process_assoc_const
(
trait_item
.id
,
...
...
@@ -1132,7 +1008,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
&
ty
,
expr
.as_ref
()
.map
(|
e
|
&**
e
),
trait_id
,
Visibility
::
Public
,
ast
::
Visibility
::
Public
,
&
trait_item
.attrs
);
}
ast
::
TraitItemKind
::
Method
(
ref
sig
,
ref
body
)
=>
{
...
...
@@ -1140,8 +1016,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
body
.as_ref
()
.map
(|
x
|
&**
x
),
trait_item
.id
,
trait_item
.ident
,
Visibility
::
Public
,
&
trait_item
.attrs
,
ast
::
Visibility
::
Public
,
trait_item
.span
);
}
ast
::
TraitItemKind
::
Type
(
ref
bounds
,
ref
default_ty
)
=>
{
...
...
@@ -1151,22 +1026,27 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
let
sub_span
=
self
.span
.sub_span_after_keyword
(
trait_item
.span
,
keywords
::
Type
);
if
!
self
.span
.filter_generated
(
sub_span
,
trait_item
.span
)
{
self
.dumper
.typedef
(
TypeDefData
{
span
:
sub_span
.expect
(
"No span found for assoc type"
),
name
:
name
,
id
:
trait_item
.id
,
qualname
:
qualname
,
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for assoc type"
));
let
id
=
::
id_from_node_id
(
trait_item
.id
,
&
self
.save_ctxt
);
self
.dumper
.dump_def
(
true
,
Def
{
kind
:
DefKind
::
Type
,
id
,
span
,
name
,
qualname
,
value
:
self
.span
.snippet
(
trait_item
.span
),
visibility
:
Visibility
::
Public
,
parent
:
Some
(
trait_id
),
parent
:
Some
(::
id_from_def_id
(
trait_id
)),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
trait_item
.attrs
),
sig
:
sig
::
assoc_type_signature
(
trait_item
.id
,
trait_item
.ident
,
Some
(
bounds
),
default_ty
.as_ref
()
.map
(|
ty
|
&**
ty
),
&
self
.save_ctxt
),
attributes
:
trait_item
.attrs
.clone
(
),
}
.lower
(
self
.tcx
)
);
attributes
:
lower_attributes
(
trait_item
.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
if
let
&
Some
(
ref
default_ty
)
=
default_ty
{
...
...
@@ -1178,7 +1058,7 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
}
fn
process_impl_item
(
&
mut
self
,
impl_item
:
&
'l
ast
::
ImplItem
,
impl_id
:
DefId
)
{
self
.process_macro_use
(
impl_item
.span
,
impl_item
.id
);
self
.process_macro_use
(
impl_item
.span
);
match
impl_item
.node
{
ast
::
ImplItemKind
::
Const
(
ref
ty
,
ref
expr
)
=>
{
self
.process_assoc_const
(
impl_item
.id
,
...
...
@@ -1187,7 +1067,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) {
&
ty
,
Some
(
expr
),
impl_id
,
From
::
from
(
&
impl_item
.vis
),
impl_item
.vis
.clone
(
),
&
impl_item
.attrs
);
}
ast
::
ImplItemKind
::
Method
(
ref
sig
,
ref
body
)
=>
{
...
...
@@ -1195,8 +1075,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) {
Some
(
body
),
impl_item
.id
,
impl_item
.ident
,
From
::
from
(
&
impl_item
.vis
),
&
impl_item
.attrs
,
impl_item
.vis
.clone
(),
impl_item
.span
);
}
ast
::
ImplItemKind
::
Type
(
ref
ty
)
=>
{
...
...
@@ -1220,25 +1099,30 @@ fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], i
let
cm
=
self
.tcx.sess
.codemap
();
let
filename
=
cm
.span_to_filename
(
span
);
self
.dumper
.mod_data
(
ModData
{
id
:
id
,
let
data_id
=
::
id_from_node_id
(
id
,
&
self
.save_ctxt
);
let
children
=
m
.items
.iter
()
.map
(|
i
|
::
id_from_node_id
(
i
.id
,
&
self
.save_ctxt
))
.collect
();
let
span
=
self
.span_from_span
(
span
);
self
.dumper
.dump_def
(
true
,
Def
{
kind
:
DefKind
::
Mod
,
id
:
data_id
,
name
:
String
::
new
(),
qualname
:
qualname
,
span
:
span
,
scope
:
id
,
filename
:
filename
,
items
:
m
.items
.iter
()
.map
(|
i
|
i
.id
)
.collect
()
,
visibility
:
Visibility
::
Public
,
qualname
,
span
,
value
:
filename
,
children
,
parent
:
None
,
decl_id
:
None
,
docs
:
docs_for_attrs
(
attrs
),
sig
:
None
,
attributes
:
attrs
.to_owned
(
),
}
.lower
(
self
.tcx
)
);
attributes
:
lower_attributes
(
attrs
.to_owned
(),
&
self
.save_ctxt
),
});
self
.nest_scope
(
id
,
|
v
|
visit
::
walk_mod
(
v
,
m
));
}
fn
visit_item
(
&
mut
self
,
item
:
&
'l
ast
::
Item
)
{
use
syntax
::
ast
::
ItemKind
::
*
;
self
.process_macro_use
(
item
.span
,
item
.id
);
self
.process_macro_use
(
item
.span
);
match
item
.node
{
Use
(
ref
use_item
)
=>
{
match
use_item
.node
{
...
...
@@ -1246,9 +1130,7 @@ fn visit_item(&mut self, item: &'l ast::Item) {
let
sub_span
=
self
.span
.span_for_last_ident
(
path
.span
);
let
mod_id
=
match
self
.lookup_def_id
(
item
.id
)
{
Some
(
def_id
)
=>
{
let
scope
=
self
.cur_scope
;
self
.process_def_kind
(
item
.id
,
path
.span
,
sub_span
,
def_id
,
scope
);
self
.process_def_kind
(
item
.id
,
path
.span
,
sub_span
,
def_id
);
Some
(
def_id
)
}
None
=>
None
,
...
...
@@ -1263,14 +1145,15 @@ fn visit_item(&mut self, item: &'l ast::Item) {
};
if
!
self
.span
.filter_generated
(
sub_span
,
path
.span
)
{
self
.dumper
.use_data
(
UseData
{
span
:
sub_span
.expect
(
"No span found for use"
),
id
:
item
.id
,
mod_id
:
mod_id
,
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for use"
));
self
.dumper
.import
(
item
.vis
==
ast
::
Visibility
::
Public
,
Import
{
kind
:
ImportKind
::
Use
,
ref_id
:
mod_id
.map
(|
id
|
::
id_from_def_id
(
id
)),
span
,
name
:
ident
.to_string
(),
scope
:
self
.cur_scope
,
visibility
:
From
::
from
(
&
item
.vis
),
}
.lower
(
self
.tcx
));
value
:
String
::
new
(),
});
}
self
.write_sub_paths_truncated
(
path
);
}
...
...
@@ -1288,23 +1171,24 @@ fn visit_item(&mut self, item: &'l ast::Item) {
let
sub_span
=
self
.span
.sub_span_of_token
(
item
.span
,
token
::
BinOp
(
token
::
Star
));
if
!
self
.span
.filter_generated
(
sub_span
,
item
.span
)
{
self
.dumper
.use_glob
(
UseGlobData
{
span
:
sub_span
.expect
(
"No span found for use glob"
),
id
:
item
.id
,
names
:
names
,
scope
:
self
.cur_scope
,
visibility
:
From
::
from
(
&
item
.vis
),
}
.lower
(
self
.tcx
));
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for use glob"
));
self
.dumper
.import
(
item
.vis
==
ast
::
Visibility
::
Public
,
Import
{
kind
:
ImportKind
::
GlobUse
,
ref_id
:
None
,
span
,
name
:
"*"
.to_owned
(),
value
:
names
.join
(
", "
),
});
}
self
.write_sub_paths
(
path
);
}
ast
::
ViewPathList
(
ref
path
,
ref
list
)
=>
{
for
plid
in
list
{
let
scope
=
self
.cur_scope
;
let
id
=
plid
.node.id
;
if
let
Some
(
def_id
)
=
self
.lookup_def_id
(
id
)
{
let
span
=
plid
.span
;
self
.process_def_kind
(
id
,
span
,
Some
(
span
),
def_id
,
scope
);
self
.process_def_kind
(
id
,
span
,
Some
(
span
),
def_id
);
}
}
...
...
@@ -1312,26 +1196,19 @@ fn visit_item(&mut self, item: &'l ast::Item) {
}
}
}
ExternCrate
(
ref
s
)
=>
{
let
location
=
match
*
s
{
Some
(
s
)
=>
s
.to_string
(),
None
=>
item
.ident
.to_string
(),
};
ExternCrate
(
_
)
=>
{
let
alias_span
=
self
.span
.span_for_last_ident
(
item
.span
);
let
cnum
=
match
self
.sess.cstore
.extern_mod_stmt_cnum
(
item
.id
)
{
Some
(
cnum
)
=>
cnum
,
None
=>
LOCAL_CRATE
,
};
if
!
self
.span
.filter_generated
(
alias_span
,
item
.span
)
{
self
.dumper
.extern_crate
(
ExternCrateData
{
id
:
item
.id
,
let
span
=
self
.span_from_span
(
alias_span
.expect
(
"No span found for extern crate"
));
self
.dumper
.import
(
false
,
Import
{
kind
:
ImportKind
::
ExternCrate
,
ref_id
:
None
,
span
,
name
:
item
.ident
.to_string
(),
crate_num
:
cnum
,
location
:
location
,
span
:
alias_span
.expect
(
"No span found for extern crate"
),
scope
:
self
.cur_scope
,
}
.lower
(
self
.tcx
));
value
:
String
::
new
(),
});
}
}
Fn
(
ref
decl
,
..
,
ref
ty_params
,
ref
body
)
=>
...
...
@@ -1360,18 +1237,23 @@ fn visit_item(&mut self, item: &'l ast::Item) {
let
value
=
ty_to_string
(
&
ty
);
let
sub_span
=
self
.span
.sub_span_after_keyword
(
item
.span
,
keywords
::
Type
);
if
!
self
.span
.filter_generated
(
sub_span
,
item
.span
)
{
self
.dumper
.typedef
(
TypeDefData
{
span
:
sub_span
.expect
(
"No span found for typedef"
),
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for typedef"
));
let
id
=
::
id_from_node_id
(
item
.id
,
&
self
.save_ctxt
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
Def
{
kind
:
DefKind
::
Type
,
id
,
span
,
name
:
item
.ident
.to_string
(),
id
:
item
.id
,
qualname
:
qualname
.clone
(),
value
:
value
,
visibility
:
From
::
from
(
&
item
.vis
),
value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
&
self
.save_ctxt
),
attributes
:
item
.attrs
.clone
(
),
}
.lower
(
self
.tcx
)
);
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
&
self
.save_ctxt
),
});
}
self
.visit_ty
(
&
ty
);
...
...
@@ -1396,7 +1278,7 @@ fn visit_generics(&mut self, generics: &'l ast::Generics) {
}
fn
visit_ty
(
&
mut
self
,
t
:
&
'l
ast
::
Ty
)
{
self
.process_macro_use
(
t
.span
,
t
.id
);
self
.process_macro_use
(
t
.span
);
match
t
.node
{
ast
::
TyKind
::
Path
(
_
,
ref
path
)
=>
{
if
generated_code
(
t
.span
)
{
...
...
@@ -1405,12 +1287,12 @@ fn visit_ty(&mut self, t: &'l ast::Ty) {
if
let
Some
(
id
)
=
self
.lookup_def_id
(
t
.id
)
{
if
let
Some
(
sub_span
)
=
self
.span
.sub_span_for_type_name
(
t
.span
)
{
self
.dumper
.type_ref
(
TypeRefData
{
span
:
sub_span
,
ref_id
:
Some
(
id
)
,
s
cope
:
self
.cur_scope
,
qualname
:
String
::
new
()
}
.lower
(
self
.tcx
)
);
let
span
=
self
.span_from_span
(
sub_span
);
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Type
,
s
pan
,
ref_id
:
::
id_from_def_id
(
id
),
});
}
}
...
...
@@ -1427,7 +1309,7 @@ fn visit_ty(&mut self, t: &'l ast::Ty) {
fn
visit_expr
(
&
mut
self
,
ex
:
&
'l
ast
::
Expr
)
{
debug!
(
"visit_expr {:?}"
,
ex
.node
);
self
.process_macro_use
(
ex
.span
,
ex
.id
);
self
.process_macro_use
(
ex
.span
);
match
ex
.node
{
ast
::
ExprKind
::
Struct
(
ref
path
,
ref
fields
,
ref
base
)
=>
{
let
hir_expr
=
self
.save_ctxt.tcx.hir
.expect_expr
(
ex
.id
);
...
...
@@ -1446,9 +1328,9 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
self
.visit_expr
(
&
sub_ex
);
if
let
Some
(
field_data
)
=
self
.save_ctxt
.get_expr_data
(
ex
)
{
down_cast_data!
(
field_data
,
Variable
RefData
,
ex
.span
);
if
!
self
.span
.filter_generated
(
Some
(
field_data
.span
),
ex
.span
)
{
self
.dumper
.
variable_ref
(
field_data
.lower
(
self
.tcx
)
);
down_cast_data!
(
field_data
,
RefData
,
ex
.span
);
if
!
generated_code
(
ex
.span
)
{
self
.dumper
.
dump_ref
(
field_data
);
}
}
}
...
...
@@ -1474,12 +1356,13 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
ty
::
TyAdt
(
def
,
_
)
=>
{
let
sub_span
=
self
.span
.sub_span_after_token
(
ex
.span
,
token
::
Dot
);
if
!
self
.span
.filter_generated
(
sub_span
,
ex
.span
)
{
self
.dumper
.variable_ref
(
VariableRefData
{
span
:
sub_span
.expect
(
"No span found for var ref"
),
ref_id
:
def
.struct_variant
()
.fields
[
idx
.node
]
.did
,
scope
:
self
.cur_scope
,
name
:
String
::
new
()
}
.lower
(
self
.tcx
));
let
span
=
self
.span_from_span
(
sub_span
.expect
(
"No span found for var ref"
));
self
.dumper
.dump_ref
(
Ref
{
kind
:
RefKind
::
Variable
,
span
:
span
,
ref_id
:
::
id_from_def_id
(
def
.struct_variant
()
.fields
[
idx
.node
]
.did
),
});
}
}
ty
::
TyTuple
(
..
)
=>
{}
...
...
@@ -1540,7 +1423,7 @@ fn visit_mac(&mut self, mac: &'l ast::Mac) {
}
fn
visit_pat
(
&
mut
self
,
p
:
&
'l
ast
::
Pat
)
{
self
.process_macro_use
(
p
.span
,
p
.id
);
self
.process_macro_use
(
p
.span
);
self
.process_pat
(
p
);
}
...
...
@@ -1556,9 +1439,9 @@ fn visit_arm(&mut self, arm: &'l ast::Arm) {
let
mut
paths_to_process
=
vec!
[];
// process collected paths
for
&
(
id
,
ref
p
,
immut
,
ref_kind
)
in
&
collector
.collected_paths
{
for
&
(
id
,
ref
p
,
immut
)
in
&
collector
.collected_paths
{
match
self
.save_ctxt
.get_path_def
(
id
)
{
Def
::
Local
(
def_id
)
=>
{
Hir
Def
::
Local
(
def_id
)
=>
{
let
id
=
self
.tcx.hir
.as_local_node_id
(
def_id
)
.unwrap
();
let
mut
value
=
if
immut
==
ast
::
Mutability
::
Immutable
{
self
.span
.snippet
(
p
.span
)
.to_string
()
...
...
@@ -1573,53 +1456,56 @@ fn visit_arm(&mut self, arm: &'l ast::Arm) {
assert
!
(
p
.segments
.len
()
==
1
,
"qualified path for local variable def in arm"
);
if
!
self
.span
.filter_generated
(
Some
(
p
.span
),
p
.span
)
{
self
.dumper
.variable
(
VariableData
{
span
:
p
.span
,
kind
:
VariableKind
::
Local
,
id
:
id
,
let
qualname
=
format!
(
"{}${}"
,
path_to_string
(
p
),
id
);
let
id
=
::
id_from_node_id
(
id
,
&
self
.save_ctxt
);
let
span
=
self
.span_from_span
(
p
.span
);
self
.dumper
.dump_def
(
false
,
Def
{
kind
:
DefKind
::
Local
,
id
,
span
,
name
:
path_to_string
(
p
),
qualname
:
format!
(
"{}${}"
,
path_to_string
(
p
),
id
),
value
:
value
,
type_value
:
typ
,
scope
:
CRATE_NODE_ID
,
qualname
,
value
:
typ
,
parent
:
None
,
visibility
:
Visibility
::
Inherited
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
None
,
attributes
:
vec!
[],
}
.lower
(
self
.tcx
)
);
attributes
:
vec!
[],
});
}
}
Def
::
StructCtor
(
..
)
|
Def
::
VariantCtor
(
..
)
|
Def
::
Const
(
..
)
|
Def
::
AssociatedConst
(
..
)
|
Def
::
Struct
(
..
)
|
Def
::
Variant
(
..
)
|
Def
::
TyAlias
(
..
)
|
Def
::
AssociatedTy
(
..
)
|
Def
::
SelfTy
(
..
)
=>
{
paths_to_process
.push
((
id
,
p
.clone
()
,
Some
(
ref_kind
)
))
HirDef
::
StructCtor
(
..
)
|
Hir
Def
::
VariantCtor
(
..
)
|
HirDef
::
Const
(
..
)
|
Hir
Def
::
AssociatedConst
(
..
)
|
HirDef
::
Struct
(
..
)
|
Hir
Def
::
Variant
(
..
)
|
HirDef
::
TyAlias
(
..
)
|
Hir
Def
::
AssociatedTy
(
..
)
|
Hir
Def
::
SelfTy
(
..
)
=>
{
paths_to_process
.push
((
id
,
p
.clone
()))
}
def
=>
error!
(
"unexpected definition kind when processing collected paths: {:?}"
,
def
),
}
}
for
&
(
id
,
ref
path
,
ref_kind
)
in
&
paths_to_process
{
self
.process_path
(
id
,
path
,
ref_kind
);
for
&
(
id
,
ref
path
)
in
&
paths_to_process
{
self
.process_path
(
id
,
path
);
}
walk_list!
(
self
,
visit_expr
,
&
arm
.guard
);
self
.visit_expr
(
&
arm
.body
);
}
fn
visit_path
(
&
mut
self
,
p
:
&
'l
ast
::
Path
,
id
:
NodeId
)
{
self
.process_path
(
id
,
p
,
None
);
self
.process_path
(
id
,
p
);
}
fn
visit_stmt
(
&
mut
self
,
s
:
&
'l
ast
::
Stmt
)
{
self
.process_macro_use
(
s
.span
,
s
.id
);
self
.process_macro_use
(
s
.span
);
visit
::
walk_stmt
(
self
,
s
)
}
fn
visit_local
(
&
mut
self
,
l
:
&
'l
ast
::
Local
)
{
self
.process_macro_use
(
l
.span
,
l
.id
);
self
.process_macro_use
(
l
.span
);
let
value
=
l
.init
.as_ref
()
.map
(|
i
|
self
.span
.snippet
(
i
.span
))
.unwrap_or
(
String
::
new
());
self
.process_var_decl
(
&
l
.pat
,
value
);
...
...
@@ -1632,14 +1518,12 @@ fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
match
item
.node
{
ast
::
ForeignItemKind
::
Fn
(
ref
decl
,
ref
generics
)
=>
{
if
let
Some
(
fn_data
)
=
self
.save_ctxt
.get_extern_item_data
(
item
)
{
down_cast_data!
(
fn_data
,
FunctionData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
fn_data
.span
),
item
.span
)
{
self
.dumper
.function
(
fn_data
.clone
()
.lower
(
self
.tcx
));
}
down_cast_data!
(
fn_data
,
DefData
,
item
.span
);
self
.nest_tables
(
item
.id
,
|
v
|
v
.process_formals
(
&
decl
.inputs
,
&
fn_data
.qualname
));
self
.process_generic_params
(
generics
,
item
.span
,
&
fn_data
.qualname
,
item
.id
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
fn_data
);
}
for
arg
in
&
decl
.inputs
{
...
...
@@ -1652,10 +1536,8 @@ fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
}
ast
::
ForeignItemKind
::
Static
(
ref
ty
,
_
)
=>
{
if
let
Some
(
var_data
)
=
self
.save_ctxt
.get_extern_item_data
(
item
)
{
down_cast_data!
(
var_data
,
VariableData
,
item
.span
);
if
!
self
.span
.filter_generated
(
Some
(
var_data
.span
),
item
.span
)
{
self
.dumper
.variable
(
var_data
.lower
(
self
.tcx
));
}
down_cast_data!
(
var_data
,
DefData
,
item
.span
);
self
.dumper
.dump_def
(
item
.vis
==
ast
::
Visibility
::
Public
,
var_data
);
}
self
.visit_ty
(
ty
);
...
...
src/librustc_save_analysis/external_data.rs
已删除
100644 → 0
浏览文件 @
9a471606
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
rustc
::
hir
::
def_id
::{
CrateNum
,
DefId
,
DefIndex
};
use
rustc
::
hir
::
map
::
Map
;
use
rustc
::
ty
::
TyCtxt
;
use
syntax
::
ast
::{
self
,
NodeId
};
use
syntax
::
codemap
::
CodeMap
;
use
syntax
::
print
::
pprust
;
use
syntax_pos
::
Span
;
use
data
::{
self
,
Visibility
};
use
rls_data
::{
SpanData
,
CratePreludeData
,
Attribute
,
Signature
};
use
rls_span
::{
Column
,
Row
};
// FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
pub
trait
Lower
{
type
Target
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
Self
::
Target
;
}
pub
fn
make_def_id
(
id
:
NodeId
,
map
:
&
Map
)
->
DefId
{
map
.opt_local_def_id
(
id
)
.unwrap_or
(
null_def_id
())
}
pub
fn
null_def_id
()
->
DefId
{
DefId
{
krate
:
CrateNum
::
from_u32
(
u32
::
max_value
()),
index
:
DefIndex
::
from_u32
(
u32
::
max_value
())
}
}
pub
fn
span_from_span
(
span
:
Span
,
cm
:
&
CodeMap
)
->
SpanData
{
let
start
=
cm
.lookup_char_pos
(
span
.lo
);
let
end
=
cm
.lookup_char_pos
(
span
.hi
);
SpanData
{
file_name
:
start
.file.name
.clone
()
.into
(),
byte_start
:
span
.lo
.0
,
byte_end
:
span
.hi
.0
,
line_start
:
Row
::
new_one_indexed
(
start
.line
as
u32
),
line_end
:
Row
::
new_one_indexed
(
end
.line
as
u32
),
column_start
:
Column
::
new_one_indexed
(
start
.col
.0
as
u32
+
1
),
column_end
:
Column
::
new_one_indexed
(
end
.col
.0
as
u32
+
1
),
}
}
impl
Lower
for
Vec
<
ast
::
Attribute
>
{
type
Target
=
Vec
<
Attribute
>
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
Vec
<
Attribute
>
{
self
.into_iter
()
// Only retain real attributes. Doc comments are lowered separately.
.filter
(|
attr
|
attr
.path
!=
"doc"
)
.map
(|
mut
attr
|
{
// Remove the surrounding '#[..]' or '#![..]' of the pretty printed
// attribute. First normalize all inner attribute (#![..]) to outer
// ones (#[..]), then remove the two leading and the one trailing character.
attr
.style
=
ast
::
AttrStyle
::
Outer
;
let
value
=
pprust
::
attribute_to_string
(
&
attr
);
// This str slicing works correctly, because the leading and trailing characters
// are in the ASCII range and thus exactly one byte each.
let
value
=
value
[
2
..
value
.len
()
-
1
]
.to_string
();
Attribute
{
value
:
value
,
span
:
span_from_span
(
attr
.span
,
tcx
.sess
.codemap
()),
}
})
.collect
()
}
}
impl
Lower
for
data
::
CratePreludeData
{
type
Target
=
CratePreludeData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
CratePreludeData
{
CratePreludeData
{
crate_name
:
self
.crate_name
,
crate_root
:
self
.crate_root
,
external_crates
:
self
.external_crates
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
}
}
}
/// Data for enum declarations.
#[derive(Clone,
Debug)]
pub
struct
EnumData
{
pub
id
:
DefId
,
pub
value
:
String
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
variants
:
Vec
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
EnumData
{
type
Target
=
EnumData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
EnumData
{
EnumData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
value
:
self
.value
,
qualname
:
self
.qualname
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
variants
:
self
.variants
.into_iter
()
.map
(|
id
|
make_def_id
(
id
,
&
tcx
.hir
))
.collect
(),
visibility
:
self
.visibility
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for extern crates.
#[derive(Debug)]
pub
struct
ExternCrateData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
crate_num
:
CrateNum
,
pub
location
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
}
impl
Lower
for
data
::
ExternCrateData
{
type
Target
=
ExternCrateData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
ExternCrateData
{
ExternCrateData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
crate_num
:
self
.crate_num
,
location
:
self
.location
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
}
}
}
/// Data about a function call.
#[derive(Debug)]
pub
struct
FunctionCallData
{
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
DefId
,
}
impl
Lower
for
data
::
FunctionCallData
{
type
Target
=
FunctionCallData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
FunctionCallData
{
FunctionCallData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
}
}
}
/// Data for all kinds of functions and methods.
#[derive(Clone,
Debug)]
pub
struct
FunctionData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
declaration
:
Option
<
DefId
>
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
value
:
String
,
pub
visibility
:
Visibility
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
FunctionData
{
type
Target
=
FunctionData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
FunctionData
{
FunctionData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
qualname
:
self
.qualname
,
declaration
:
self
.declaration
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
value
:
self
.value
,
visibility
:
self
.visibility
,
parent
:
self
.parent
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data about a function call.
#[derive(Debug)]
pub
struct
FunctionRefData
{
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
DefId
,
}
impl
Lower
for
data
::
FunctionRefData
{
type
Target
=
FunctionRefData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
FunctionRefData
{
FunctionRefData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
}
}
}
#[derive(Debug)]
pub
struct
ImplData
{
pub
id
:
DefId
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
trait_ref
:
Option
<
DefId
>
,
pub
self_ref
:
Option
<
DefId
>
,
}
impl
Lower
for
data
::
ImplData
{
type
Target
=
ImplData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
ImplData
{
ImplData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
trait_ref
:
self
.trait_ref
,
self_ref
:
self
.self_ref
,
}
}
}
#[derive(Debug)]
pub
struct
InheritanceData
{
pub
span
:
SpanData
,
pub
base_id
:
DefId
,
pub
deriv_id
:
DefId
}
impl
Lower
for
data
::
InheritanceData
{
type
Target
=
InheritanceData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
InheritanceData
{
InheritanceData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
base_id
:
self
.base_id
,
deriv_id
:
make_def_id
(
self
.deriv_id
,
&
tcx
.hir
)
}
}
}
/// Data about a macro declaration.
#[derive(Debug)]
pub
struct
MacroData
{
pub
span
:
SpanData
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
docs
:
String
,
}
impl
Lower
for
data
::
MacroData
{
type
Target
=
MacroData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
MacroData
{
MacroData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
qualname
:
self
.qualname
,
docs
:
self
.docs
,
}
}
}
/// Data about a macro use.
#[derive(Debug)]
pub
struct
MacroUseData
{
pub
span
:
SpanData
,
pub
name
:
String
,
pub
qualname
:
String
,
// Because macro expansion happens before ref-ids are determined,
// we use the callee span to reference the associated macro definition.
pub
callee_span
:
SpanData
,
pub
scope
:
DefId
,
}
impl
Lower
for
data
::
MacroUseData
{
type
Target
=
MacroUseData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
MacroUseData
{
MacroUseData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
qualname
:
self
.qualname
,
callee_span
:
span_from_span
(
self
.callee_span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
}
}
}
/// Data about a method call.
#[derive(Debug)]
pub
struct
MethodCallData
{
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
decl_id
:
Option
<
DefId
>
,
}
impl
Lower
for
data
::
MethodCallData
{
type
Target
=
MethodCallData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
MethodCallData
{
MethodCallData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
decl_id
:
self
.decl_id
,
}
}
}
/// Data for method declarations (methods with a body are treated as functions).
#[derive(Clone,
Debug)]
pub
struct
MethodData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
value
:
String
,
pub
decl_id
:
Option
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
MethodData
{
type
Target
=
MethodData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
MethodData
{
MethodData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
qualname
:
self
.qualname
,
value
:
self
.value
,
decl_id
:
self
.decl_id
,
visibility
:
self
.visibility
,
parent
:
self
.parent
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for modules.
#[derive(Debug)]
pub
struct
ModData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
filename
:
String
,
pub
items
:
Vec
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
ModData
{
type
Target
=
ModData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
ModData
{
ModData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
qualname
:
self
.qualname
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
filename
:
self
.filename
,
items
:
self
.items
.into_iter
()
.map
(|
id
|
make_def_id
(
id
,
&
tcx
.hir
))
.collect
(),
visibility
:
self
.visibility
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for a reference to a module.
#[derive(Debug)]
pub
struct
ModRefData
{
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
qualname
:
String
}
impl
Lower
for
data
::
ModRefData
{
type
Target
=
ModRefData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
ModRefData
{
ModRefData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
qualname
:
self
.qualname
,
}
}
}
#[derive(Debug)]
pub
struct
StructData
{
pub
span
:
SpanData
,
pub
name
:
String
,
pub
id
:
DefId
,
pub
ctor_id
:
DefId
,
pub
qualname
:
String
,
pub
scope
:
DefId
,
pub
value
:
String
,
pub
fields
:
Vec
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
StructData
{
type
Target
=
StructData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
StructData
{
StructData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
ctor_id
:
make_def_id
(
self
.ctor_id
,
&
tcx
.hir
),
qualname
:
self
.qualname
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
value
:
self
.value
,
fields
:
self
.fields
.into_iter
()
.map
(|
id
|
make_def_id
(
id
,
&
tcx
.hir
))
.collect
(),
visibility
:
self
.visibility
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
#[derive(Debug)]
pub
struct
StructVariantData
{
pub
span
:
SpanData
,
pub
name
:
String
,
pub
id
:
DefId
,
pub
qualname
:
String
,
pub
type_value
:
String
,
pub
value
:
String
,
pub
scope
:
DefId
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
StructVariantData
{
type
Target
=
StructVariantData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
StructVariantData
{
StructVariantData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
qualname
:
self
.qualname
,
type_value
:
self
.type_value
,
value
:
self
.value
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
parent
:
self
.parent
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
#[derive(Debug)]
pub
struct
TraitData
{
pub
span
:
SpanData
,
pub
name
:
String
,
pub
id
:
DefId
,
pub
qualname
:
String
,
pub
scope
:
DefId
,
pub
value
:
String
,
pub
items
:
Vec
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
TraitData
{
type
Target
=
TraitData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
TraitData
{
TraitData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
qualname
:
self
.qualname
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
value
:
self
.value
,
items
:
self
.items
.into_iter
()
.map
(|
id
|
make_def_id
(
id
,
&
tcx
.hir
))
.collect
(),
visibility
:
self
.visibility
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
#[derive(Debug)]
pub
struct
TupleVariantData
{
pub
span
:
SpanData
,
pub
id
:
DefId
,
pub
name
:
String
,
pub
qualname
:
String
,
pub
type_value
:
String
,
pub
value
:
String
,
pub
scope
:
DefId
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
TupleVariantData
{
type
Target
=
TupleVariantData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
TupleVariantData
{
TupleVariantData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
qualname
:
self
.qualname
,
type_value
:
self
.type_value
,
value
:
self
.value
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
parent
:
self
.parent
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for a typedef.
#[derive(Debug)]
pub
struct
TypeDefData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
span
:
SpanData
,
pub
qualname
:
String
,
pub
value
:
String
,
pub
visibility
:
Visibility
,
pub
parent
:
Option
<
DefId
>
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
TypeDefData
{
type
Target
=
TypeDefData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
TypeDefData
{
TypeDefData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
name
:
self
.name
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
qualname
:
self
.qualname
,
value
:
self
.value
,
visibility
:
self
.visibility
,
parent
:
self
.parent
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for a reference to a type or trait.
#[derive(Clone,
Debug)]
pub
struct
TypeRefData
{
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
Option
<
DefId
>
,
pub
qualname
:
String
,
}
impl
Lower
for
data
::
TypeRefData
{
type
Target
=
TypeRefData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
TypeRefData
{
TypeRefData
{
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
qualname
:
self
.qualname
,
}
}
}
#[derive(Debug)]
pub
struct
UseData
{
pub
id
:
DefId
,
pub
span
:
SpanData
,
pub
name
:
String
,
pub
mod_id
:
Option
<
DefId
>
,
pub
scope
:
DefId
,
pub
visibility
:
Visibility
,
}
impl
Lower
for
data
::
UseData
{
type
Target
=
UseData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
UseData
{
UseData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
name
:
self
.name
,
mod_id
:
self
.mod_id
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
visibility
:
self
.visibility
,
}
}
}
#[derive(Debug)]
pub
struct
UseGlobData
{
pub
id
:
DefId
,
pub
span
:
SpanData
,
pub
names
:
Vec
<
String
>
,
pub
scope
:
DefId
,
pub
visibility
:
Visibility
,
}
impl
Lower
for
data
::
UseGlobData
{
type
Target
=
UseGlobData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
UseGlobData
{
UseGlobData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
names
:
self
.names
,
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
visibility
:
self
.visibility
,
}
}
}
/// Data for local and global variables (consts and statics).
#[derive(Debug)]
pub
struct
VariableData
{
pub
id
:
DefId
,
pub
name
:
String
,
pub
kind
:
data
::
VariableKind
,
pub
qualname
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
value
:
String
,
pub
type_value
:
String
,
pub
parent
:
Option
<
DefId
>
,
pub
visibility
:
Visibility
,
pub
docs
:
String
,
pub
sig
:
Option
<
Signature
>
,
pub
attributes
:
Vec
<
Attribute
>
,
}
impl
Lower
for
data
::
VariableData
{
type
Target
=
VariableData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
VariableData
{
VariableData
{
id
:
make_def_id
(
self
.id
,
&
tcx
.hir
),
kind
:
self
.kind
,
name
:
self
.name
,
qualname
:
self
.qualname
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
value
:
self
.value
,
type_value
:
self
.type_value
,
parent
:
self
.parent
,
visibility
:
self
.visibility
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
.lower
(
tcx
),
}
}
}
/// Data for the use of some item (e.g., the use of a local variable, which
/// will refer to that variables declaration (by ref_id)).
#[derive(Debug)]
pub
struct
VariableRefData
{
pub
name
:
String
,
pub
span
:
SpanData
,
pub
scope
:
DefId
,
pub
ref_id
:
DefId
,
}
impl
Lower
for
data
::
VariableRefData
{
type
Target
=
VariableRefData
;
fn
lower
(
self
,
tcx
:
TyCtxt
)
->
VariableRefData
{
VariableRefData
{
name
:
self
.name
,
span
:
span_from_span
(
self
.span
,
tcx
.sess
.codemap
()),
scope
:
make_def_id
(
self
.scope
,
&
tcx
.hir
),
ref_id
:
self
.ref_id
,
}
}
}
src/librustc_save_analysis/json_api_dumper.rs
浏览文件 @
8a2857e6
...
...
@@ -12,12 +12,9 @@
use
rustc_serialize
::
json
::
as_json
;
use
external_data
::
*
;
use
data
::{
VariableKind
,
Visibility
};
use
dump
::
Dump
;
use
id_from_def_id
;
use
Dump
;
use
rls_data
::{
Analysis
,
Import
,
ImportKind
,
Def
,
DefKind
,
CratePreludeData
,
Format
};
use
rls_data
::{
Analysis
,
Import
,
Def
,
CratePreludeData
,
Format
,
Relation
};
// A dumper to dump a restricted set of JSON information, designed for use with
...
...
@@ -47,306 +44,23 @@ fn drop(&mut self) {
}
}
macro_rules!
impl_fn
{
(
$fn_name
:
ident
,
$data_type
:
ident
,
$bucket
:
ident
)
=>
{
fn
$fn_name
(
&
mut
self
,
data
:
$data_type
)
{
if
let
Some
(
datum
)
=
data
.into
()
{
self
.result
.
$bucket
.push
(
datum
);
}
}
}
}
impl
<
'b
,
W
:
Write
+
'b
>
Dump
for
JsonApiDumper
<
'b
,
W
>
{
fn
crate_prelude
(
&
mut
self
,
data
:
CratePreludeData
)
{
self
.result.prelude
=
Some
(
data
)
}
impl_fn!
(
use_data
,
UseData
,
imports
);
impl_fn!
(
use_glob
,
UseGlobData
,
imports
);
impl_fn!
(
enum_data
,
EnumData
,
defs
);
impl_fn!
(
tuple_variant
,
TupleVariantData
,
defs
);
impl_fn!
(
struct_variant
,
StructVariantData
,
defs
);
impl_fn!
(
struct_data
,
StructData
,
defs
);
impl_fn!
(
trait_data
,
TraitData
,
defs
);
impl_fn!
(
function
,
FunctionData
,
defs
);
impl_fn!
(
method
,
MethodData
,
defs
);
impl_fn!
(
macro_data
,
MacroData
,
defs
);
impl_fn!
(
mod_data
,
ModData
,
defs
);
impl_fn!
(
typedef
,
TypeDefData
,
defs
);
impl_fn!
(
variable
,
VariableData
,
defs
);
fn
impl_data
(
&
mut
self
,
data
:
ImplData
)
{
if
data
.self_ref
.is_some
()
{
self
.result.relations
.push
(
data
.into
());
}
}
fn
inheritance
(
&
mut
self
,
data
:
InheritanceData
)
{
self
.result.relations
.push
(
data
.into
());
fn
dump_relation
(
&
mut
self
,
data
:
Relation
)
{
self
.result.relations
.push
(
data
);
}
}
// FIXME methods. The defs have information about possible overriding and the
// refs have decl information (e.g., a trait method where we know the required
// method, but not the supplied method). In both cases, we are currently
// ignoring it.
impl
Into
<
Option
<
Import
>>
for
UseData
{
fn
into
(
self
)
->
Option
<
Import
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Import
{
kind
:
ImportKind
::
Use
,
ref_id
:
self
.mod_id
.map
(|
id
|
id_from_def_id
(
id
)),
span
:
self
.span
,
name
:
self
.name
,
value
:
String
::
new
(),
}),
_
=>
None
,
fn
import
(
&
mut
self
,
public
:
bool
,
import
:
Import
)
{
if
public
{
self
.result.imports
.push
(
import
);
}
}
}
impl
Into
<
Option
<
Import
>>
for
UseGlobData
{
fn
into
(
self
)
->
Option
<
Import
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Import
{
kind
:
ImportKind
::
GlobUse
,
ref_id
:
None
,
span
:
self
.span
,
name
:
"*"
.to_owned
(),
value
:
self
.names
.join
(
", "
),
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
EnumData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Enum
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
self
.variants
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
TupleVariantData
{
fn
into
(
self
)
->
Option
<
Def
>
{
Some
(
Def
{
kind
:
DefKind
::
Tuple
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
})
}
}
impl
Into
<
Option
<
Def
>>
for
StructVariantData
{
fn
into
(
self
)
->
Option
<
Def
>
{
Some
(
Def
{
kind
:
DefKind
::
Struct
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
})
}
}
impl
Into
<
Option
<
Def
>>
for
StructData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Struct
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
self
.fields
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
TraitData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Trait
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
children
:
self
.items
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
parent
:
None
,
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
FunctionData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Function
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
children
:
vec!
[],
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
MethodData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Method
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
children
:
vec!
[],
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
decl_id
:
self
.decl_id
.map
(|
id
|
id_from_def_id
(
id
)),
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
MacroData
{
fn
into
(
self
)
->
Option
<
Def
>
{
Some
(
Def
{
kind
:
DefKind
::
Macro
,
id
:
id_from_def_id
(
null_def_id
()),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
String
::
new
(),
children
:
vec!
[],
parent
:
None
,
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
None
,
attributes
:
vec!
[],
})
}
}
impl
Into
<
Option
<
Def
>>
for
ModData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Mod
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.filename
,
children
:
self
.items
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
parent
:
None
,
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
.map
(|
s
|
s
.into
()),
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
TypeDefData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
DefKind
::
Type
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
children
:
vec!
[],
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
self
.sig
.map
(|
s
|
s
.into
()),
attributes
:
vec!
[],
}),
_
=>
None
,
}
}
}
impl
Into
<
Option
<
Def
>>
for
VariableData
{
fn
into
(
self
)
->
Option
<
Def
>
{
match
self
.visibility
{
Visibility
::
Public
=>
Some
(
Def
{
kind
:
match
self
.kind
{
VariableKind
::
Static
=>
DefKind
::
Static
,
VariableKind
::
Const
=>
DefKind
::
Const
,
VariableKind
::
Local
=>
{
return
None
}
VariableKind
::
Field
=>
DefKind
::
Field
,
},
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
children
:
vec!
[],
parent
:
self
.parent
.map
(|
id
|
id_from_def_id
(
id
)),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
.map
(|
s
|
s
.into
()),
attributes
:
vec!
[],
}),
_
=>
None
,
fn
dump_def
(
&
mut
self
,
public
:
bool
,
mut
data
:
Def
)
{
if
public
{
data
.attributes
=
vec!
[];
self
.result.defs
.push
(
data
);
}
}
}
src/librustc_save_analysis/json_dumper.rs
浏览文件 @
8a2857e6
...
...
@@ -12,14 +12,11 @@
use
rustc_serialize
::
json
::
as_json
;
use
rls_data
::{
self
,
Id
,
Analysis
,
Import
,
ImportKind
,
Def
,
DefKind
,
Ref
,
RefKind
,
MacroRef
,
Relation
,
RelationKind
,
CratePreludeData
};
use
rls_data
::{
self
,
Analysis
,
Import
,
Def
,
DefKind
,
Ref
,
RefKind
,
MacroRef
,
Relation
,
CratePreludeData
};
use
rls_span
::{
Column
,
Row
};
use
external_data
::
*
;
use
data
::
VariableKind
;
use
dump
::
Dump
;
use
id_from_def_id
;
use
Dump
;
pub
struct
JsonDumper
<
O
:
DumpOutput
>
{
result
:
Analysis
,
...
...
@@ -70,71 +67,35 @@ fn drop(&mut self) {
}
}
macro_rules!
impl_fn
{
(
$fn_name
:
ident
,
$data_type
:
ident
,
$bucket
:
ident
)
=>
{
fn
$fn_name
(
&
mut
self
,
data
:
$data_type
)
{
self
.result
.
$bucket
.push
(
data
.into
());
}
}
}
impl
<
'b
,
O
:
DumpOutput
+
'b
>
Dump
for
JsonDumper
<
O
>
{
fn
crate_prelude
(
&
mut
self
,
data
:
CratePreludeData
)
{
self
.result.prelude
=
Some
(
data
)
}
impl_fn!
(
extern_crate
,
ExternCrateData
,
imports
);
impl_fn!
(
use_data
,
UseData
,
imports
);
impl_fn!
(
use_glob
,
UseGlobData
,
imports
);
impl_fn!
(
enum_data
,
EnumData
,
defs
);
impl_fn!
(
tuple_variant
,
TupleVariantData
,
defs
);
impl_fn!
(
struct_variant
,
StructVariantData
,
defs
);
impl_fn!
(
struct_data
,
StructData
,
defs
);
impl_fn!
(
trait_data
,
TraitData
,
defs
);
impl_fn!
(
function
,
FunctionData
,
defs
);
impl_fn!
(
method
,
MethodData
,
defs
);
impl_fn!
(
macro_data
,
MacroData
,
defs
);
impl_fn!
(
typedef
,
TypeDefData
,
defs
);
impl_fn!
(
variable
,
VariableData
,
defs
);
impl_fn!
(
function_ref
,
FunctionRefData
,
refs
);
impl_fn!
(
function_call
,
FunctionCallData
,
refs
);
impl_fn!
(
method_call
,
MethodCallData
,
refs
);
impl_fn!
(
mod_ref
,
ModRefData
,
refs
);
impl_fn!
(
type_ref
,
TypeRefData
,
refs
);
impl_fn!
(
variable_ref
,
VariableRefData
,
refs
);
fn
macro_use
(
&
mut
self
,
data
:
MacroRef
)
{
self
.result.macro_refs
.push
(
data
);
}
impl_fn!
(
macro_use
,
MacroUseData
,
macro_refs
);
fn
import
(
&
mut
self
,
_
:
bool
,
import
:
Import
)
{
self
.result.imports
.push
(
import
);
}
fn
mod_data
(
&
mut
self
,
data
:
ModData
)
{
let
id
:
Id
=
id_from_def_id
(
data
.id
);
let
mut
def
=
Def
{
kind
:
DefKind
::
Mod
,
id
:
id
,
span
:
data
.span
.into
(),
name
:
data
.name
,
qualname
:
data
.qualname
,
value
:
data
.filename
,
parent
:
None
,
children
:
data
.items
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
data
.docs
,
sig
:
data
.sig
,
attributes
:
data
.attributes
.into_iter
()
.map
(|
a
|
a
.into
())
.collect
(),
};
if
def
.span.file_name
.to_str
()
.unwrap
()
!=
def
.value
{
fn
dump_ref
(
&
mut
self
,
data
:
Ref
)
{
self
.result.refs
.push
(
data
);
}
fn
dump_def
(
&
mut
self
,
_
:
bool
,
mut
data
:
Def
)
{
if
data
.kind
==
DefKind
::
Mod
&&
data
.span.file_name
.to_str
()
.unwrap
()
!=
data
.value
{
// If the module is an out-of-line defintion, then we'll make the
// defintion the first character in the module's file and turn the
// the declaration into a reference to it.
let
rf
=
Ref
{
kind
:
RefKind
::
Mod
,
span
:
d
ef
.span
,
ref_id
:
id
,
span
:
d
ata
.span
,
ref_id
:
data
.
id
,
};
self
.result.refs
.push
(
rf
);
d
ef
.span
=
rls_data
::
SpanData
{
file_name
:
d
ef
.value
.clone
()
.into
(),
d
ata
.span
=
rls_data
::
SpanData
{
file_name
:
d
ata
.value
.clone
()
.into
(),
byte_start
:
0
,
byte_end
:
0
,
line_start
:
Row
::
new_one_indexed
(
1
),
...
...
@@ -143,330 +104,10 @@ fn mod_data(&mut self, data: ModData) {
column_end
:
Column
::
new_one_indexed
(
1
),
}
}
self
.result.defs
.push
(
def
);
}
fn
impl_data
(
&
mut
self
,
data
:
ImplData
)
{
if
data
.self_ref
.is_some
()
{
self
.result.relations
.push
(
data
.into
());
}
}
fn
inheritance
(
&
mut
self
,
data
:
InheritanceData
)
{
self
.result.relations
.push
(
data
.into
());
}
}
// FIXME do we want to change ExternalData to this mode? It will break DXR.
// FIXME methods. The defs have information about possible overriding and the
// refs have decl information (e.g., a trait method where we know the required
// method, but not the supplied method). In both cases, we are currently
// ignoring it.
impl
Into
<
Import
>
for
ExternCrateData
{
fn
into
(
self
)
->
Import
{
Import
{
kind
:
ImportKind
::
ExternCrate
,
ref_id
:
None
,
span
:
self
.span
,
name
:
self
.name
,
value
:
String
::
new
(),
}
}
}
impl
Into
<
Import
>
for
UseData
{
fn
into
(
self
)
->
Import
{
Import
{
kind
:
ImportKind
::
Use
,
ref_id
:
self
.mod_id
.map
(|
id
|
id_from_def_id
(
id
)),
span
:
self
.span
,
name
:
self
.name
,
value
:
String
::
new
(),
}
}
}
impl
Into
<
Import
>
for
UseGlobData
{
fn
into
(
self
)
->
Import
{
Import
{
kind
:
ImportKind
::
GlobUse
,
ref_id
:
None
,
span
:
self
.span
,
name
:
"*"
.to_owned
(),
value
:
self
.names
.join
(
", "
),
}
}
}
impl
Into
<
Def
>
for
EnumData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Enum
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
self
.variants
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
TupleVariantData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Tuple
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
StructVariantData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Struct
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
StructData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Struct
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
self
.fields
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
TraitData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Trait
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
self
.items
.into_iter
()
.map
(|
id
|
id_from_def_id
(
id
))
.collect
(),
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
FunctionData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Function
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
MethodData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Method
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
self
.decl_id
.map
(|
id
|
id_from_def_id
(
id
)),
docs
:
self
.docs
,
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Def
>
for
MacroData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Macro
,
id
:
id_from_def_id
(
null_def_id
()),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
String
::
new
(),
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
None
,
attributes
:
vec!
[],
}
}
}
impl
Into
<
Def
>
for
TypeDefData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
DefKind
::
Type
,
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
String
::
new
(),
sig
:
self
.sig
,
attributes
:
self
.attributes
,
}
self
.result.defs
.push
(
data
);
}
}
impl
Into
<
Def
>
for
VariableData
{
fn
into
(
self
)
->
Def
{
Def
{
kind
:
match
self
.kind
{
VariableKind
::
Static
=>
DefKind
::
Static
,
VariableKind
::
Const
=>
DefKind
::
Const
,
VariableKind
::
Local
=>
DefKind
::
Local
,
VariableKind
::
Field
=>
DefKind
::
Field
,
},
id
:
id_from_def_id
(
self
.id
),
span
:
self
.span
,
name
:
self
.name
,
qualname
:
self
.qualname
,
value
:
self
.type_value
,
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
self
.docs
,
sig
:
None
,
attributes
:
self
.attributes
,
}
}
}
impl
Into
<
Ref
>
for
FunctionRefData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Function
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
),
}
}
}
impl
Into
<
Ref
>
for
FunctionCallData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Function
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
),
}
}
}
impl
Into
<
Ref
>
for
MethodCallData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Function
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
.or
(
self
.decl_id
)
.unwrap_or
(
null_def_id
())),
}
}
}
impl
Into
<
Ref
>
for
ModRefData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Mod
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
.unwrap_or
(
null_def_id
())),
}
}
}
impl
Into
<
Ref
>
for
TypeRefData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Type
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
.unwrap_or
(
null_def_id
())),
}
}
}
impl
Into
<
Ref
>
for
VariableRefData
{
fn
into
(
self
)
->
Ref
{
Ref
{
kind
:
RefKind
::
Variable
,
span
:
self
.span
,
ref_id
:
id_from_def_id
(
self
.ref_id
),
}
}
}
impl
Into
<
MacroRef
>
for
MacroUseData
{
fn
into
(
self
)
->
MacroRef
{
MacroRef
{
span
:
self
.span
,
qualname
:
self
.qualname
,
callee_span
:
self
.callee_span
.into
(),
}
}
}
impl
Into
<
Relation
>
for
ImplData
{
fn
into
(
self
)
->
Relation
{
Relation
{
span
:
self
.span
,
kind
:
RelationKind
::
Impl
,
from
:
id_from_def_id
(
self
.self_ref
.unwrap_or
(
null_def_id
())),
to
:
id_from_def_id
(
self
.trait_ref
.unwrap_or
(
null_def_id
())),
}
}
}
impl
Into
<
Relation
>
for
InheritanceData
{
fn
into
(
self
)
->
Relation
{
Relation
{
span
:
self
.span
,
kind
:
RelationKind
::
SuperTrait
,
from
:
id_from_def_id
(
self
.base_id
),
to
:
id_from_def_id
(
self
.deriv_id
),
}
fn
dump_relation
(
&
mut
self
,
data
:
Relation
)
{
self
.result.relations
.push
(
data
);
}
}
src/librustc_save_analysis/lib.rs
浏览文件 @
8a2857e6
...
...
@@ -37,17 +37,14 @@
mod
json_api_dumper
;
mod
json_dumper
;
mod
data
;
mod
dump
;
mod
dump_visitor
;
pub
mod
external_data
;
#[macro_use]
pub
mod
span_utils
;
mod
span_utils
;
mod
sig
;
use
rustc
::
hir
;
use
rustc
::
hir
::
def
::
Def
;
use
rustc
::
hir
::
map
::
Node
;
use
rustc
::
hir
::
def
::
Def
as
HirDef
;
use
rustc
::
hir
::
map
::
{
Node
,
NodeItem
}
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
session
::
config
::
CrateType
::
CrateTypeExecutable
;
use
rustc
::
session
::
Session
;
...
...
@@ -61,32 +58,21 @@
use
syntax
::
ast
::{
self
,
NodeId
,
PatKind
,
Attribute
,
CRATE_NODE_ID
};
use
syntax
::
parse
::
lexer
::
comments
::
strip_doc_comment_decoration
;
use
syntax
::
parse
::
token
;
use
syntax
::
print
::
pprust
;
use
syntax
::
symbol
::
keywords
;
use
syntax
::
visit
::{
self
,
Visitor
};
use
syntax
::
print
::
pprust
::{
ty_to_string
,
arg_to_string
};
use
syntax
::
codemap
::
MacroAttribute
;
use
syntax_pos
::
*
;
pub
use
self
::
json_api_dumper
::
JsonApiDumper
;
pub
use
self
::
json_dumper
::
JsonDumper
;
pub
use
self
::
data
::
*
;
pub
use
self
::
external_data
::
make_def_id
;
pub
use
self
::
dump
::
Dump
;
pub
use
self
::
dump_visitor
::
DumpVisitor
;
use
self
::
span_utils
::
SpanUtils
;
// FIXME this is legacy code and should be removed
pub
mod
recorder
{
pub
use
self
::
Row
::
*
;
#[derive(Copy,
Clone,
Debug,
Eq,
PartialEq)]
pub
enum
Row
{
TypeRef
,
ModRef
,
VarRef
,
FnRef
,
}
}
pub
use
json_api_dumper
::
JsonApiDumper
;
pub
use
json_dumper
::
JsonDumper
;
use
dump_visitor
::
DumpVisitor
;
use
span_utils
::
SpanUtils
;
use
rls_data
::{
Ref
,
RefKind
,
SpanData
,
MacroRef
,
Def
,
DefKind
,
Relation
,
RelationKind
,
ExternalCrateData
,
Import
,
CratePreludeData
};
pub
struct
SaveContext
<
'l
,
'tcx
:
'l
>
{
tcx
:
TyCtxt
<
'l
,
'tcx
,
'tcx
>
,
...
...
@@ -95,13 +81,49 @@ pub struct SaveContext<'l, 'tcx: 'l> {
span_utils
:
SpanUtils
<
'tcx
>
,
}
#[derive(Debug)]
pub
enum
Data
{
/// Data about a macro use.
MacroUseData
(
MacroRef
),
RefData
(
Ref
),
DefData
(
Def
),
RelationData
(
Relation
),
}
pub
trait
Dump
{
fn
crate_prelude
(
&
mut
self
,
_
:
CratePreludeData
);
fn
macro_use
(
&
mut
self
,
_
:
MacroRef
)
{}
fn
import
(
&
mut
self
,
_
:
bool
,
_
:
Import
);
fn
dump_ref
(
&
mut
self
,
_
:
Ref
)
{}
fn
dump_def
(
&
mut
self
,
_
:
bool
,
_
:
Def
);
fn
dump_relation
(
&
mut
self
,
data
:
Relation
);
}
macro_rules!
option_try
(
(
$e:expr
)
=>
(
match
$e
{
Some
(
e
)
=>
e
,
None
=>
return
None
})
);
impl
<
'l
,
'tcx
:
'l
>
SaveContext
<
'l
,
'tcx
>
{
fn
span_from_span
(
&
self
,
span
:
Span
)
->
SpanData
{
use
rls_span
::{
Row
,
Column
};
let
cm
=
self
.tcx.sess
.codemap
();
let
start
=
cm
.lookup_char_pos
(
span
.lo
);
let
end
=
cm
.lookup_char_pos
(
span
.hi
);
SpanData
{
file_name
:
start
.file.name
.clone
()
.into
(),
byte_start
:
span
.lo
.0
,
byte_end
:
span
.hi
.0
,
line_start
:
Row
::
new_one_indexed
(
start
.line
as
u32
),
line_end
:
Row
::
new_one_indexed
(
end
.line
as
u32
),
column_start
:
Column
::
new_one_indexed
(
start
.col
.0
as
u32
+
1
),
column_end
:
Column
::
new_one_indexed
(
end
.col
.0
as
u32
+
1
),
}
}
// List external crates used by the current crate.
pub
fn
get_external_crates
(
&
self
)
->
Vec
<
CrateData
>
{
pub
fn
get_external_crates
(
&
self
)
->
Vec
<
External
CrateData
>
{
let
mut
result
=
Vec
::
new
();
for
n
in
self
.tcx.sess.cstore
.crates
()
{
...
...
@@ -112,10 +134,11 @@ pub fn get_external_crates(&self) -> Vec<CrateData> {
continue
;
}
};
result
.push
(
CrateData
{
let
lo_loc
=
self
.span_utils.sess
.codemap
()
.lookup_char_pos
(
span
.lo
);
result
.push
(
ExternalCrateData
{
name
:
self
.tcx.sess.cstore
.crate_name
(
n
)
.to_string
(),
num
ber
:
n
.as_u32
(),
span
:
span
,
num
:
n
.as_u32
(),
file_name
:
SpanUtils
::
make_path_string
(
&
lo_loc
.file.name
)
,
});
}
...
...
@@ -128,39 +151,43 @@ pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
ast
::
ForeignItemKind
::
Fn
(
ref
decl
,
ref
generics
)
=>
{
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keywords
::
Fn
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
FunctionData
(
FunctionData
{
id
:
item
.id
,
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Function
,
id
:
id_from_node_id
(
item
.id
,
self
),
span
:
self
.span_from_span
(
sub_span
.unwrap
()),
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
declaration
:
None
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
item
.id
),
qualname
,
value
:
make_signature
(
decl
,
generics
),
visibility
:
From
::
from
(
&
item
.vis
),
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
foreign_item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
ast
::
ForeignItemKind
::
Static
(
ref
ty
,
m
)
=>
{
let
keyword
=
if
m
{
keywords
::
Mut
}
else
{
keywords
::
Static
};
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keyword
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
VariableData
(
VariableData
{
id
:
item
.id
,
kind
:
VariableKind
::
Static
,
let
id
=
::
id_from_node_id
(
item
.id
,
self
);
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Static
,
id
,
span
,
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
item
.id
),
qualname
,
value
:
ty_to_string
(
ty
),
parent
:
None
,
value
:
String
::
new
(),
type_value
:
ty_to_string
(
ty
),
visibility
:
From
::
from
(
&
item
.vis
),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
foreign_item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
}
...
...
@@ -172,70 +199,71 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
let
qualname
=
format!
(
"::{}"
,
self
.tcx
.node_path_str
(
item
.id
));
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keywords
::
Fn
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
FunctionData
(
FunctionData
{
id
:
item
.id
,
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Function
,
id
:
id_from_node_id
(
item
.id
,
self
),
span
:
self
.span_from_span
(
sub_span
.unwrap
())
,
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
declaration
:
None
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
item
.id
),
qualname
,
value
:
make_signature
(
decl
,
generics
),
visibility
:
From
::
from
(
&
item
.vis
),
parent
:
None
,
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
ast
::
ItemKind
::
Static
(
ref
typ
,
mt
,
ref
expr
)
=>
{
ast
::
ItemKind
::
Static
(
ref
typ
,
mt
,
_
)
=>
{
let
qualname
=
format!
(
"::{}"
,
self
.tcx
.node_path_str
(
item
.id
));
// If the variable is immutable, save the initialising expression.
let
(
value
,
keyword
)
=
match
mt
{
ast
::
Mutability
::
Mutable
=>
(
String
::
from
(
"<mutable>"
),
keywords
::
Mut
),
ast
::
Mutability
::
Immutable
=>
{
(
self
.span_utils
.snippet
(
expr
.span
),
keywords
::
Static
)
},
let
keyword
=
match
mt
{
ast
::
Mutability
::
Mutable
=>
keywords
::
Mut
,
ast
::
Mutability
::
Immutable
=>
keywords
::
Static
,
};
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keyword
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
VariableData
(
VariableData
{
id
:
item
.id
,
kind
:
VariableKind
::
Static
,
let
id
=
id_from_node_id
(
item
.id
,
self
);
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Static
,
id
,
span
,
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
item
.id
),
qualname
,
value
:
ty_to_string
(
&
typ
),
parent
:
None
,
value
:
value
,
type_value
:
ty_to_string
(
&
typ
),
visibility
:
From
::
from
(
&
item
.vis
),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
ast
::
ItemKind
::
Const
(
ref
typ
,
ref
expr
)
=>
{
ast
::
ItemKind
::
Const
(
ref
typ
,
_
)
=>
{
let
qualname
=
format!
(
"::{}"
,
self
.tcx
.node_path_str
(
item
.id
));
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keywords
::
Const
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
VariableData
(
VariableData
{
id
:
item
.id
,
kind
:
VariableKind
::
Const
,
let
id
=
id_from_node_id
(
item
.id
,
self
);
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Const
,
id
,
span
,
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
item
.id
),
qualname
,
value
:
ty_to_string
(
typ
),
parent
:
None
,
value
:
self
.span_utils
.snippet
(
expr
.span
),
type_value
:
ty_to_string
(
&
typ
),
visibility
:
From
::
from
(
&
item
.vis
),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
ast
::
ItemKind
::
Mod
(
ref
m
)
=>
{
...
...
@@ -247,18 +275,19 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
item
.span
,
keywords
::
Mod
);
filter!
(
self
.span_utils
,
sub_span
,
item
.span
,
None
);
Some
(
Data
::
ModData
(
ModData
{
id
:
item
.id
,
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Mod
,
id
:
id_from_node_id
(
item
.id
,
self
),
name
:
item
.ident
.to_string
(),
qualname
:
qualname
,
span
:
s
ub_span
.unwrap
(
),
scope
:
self
.enclosing_scope
(
item
.id
)
,
filename
:
filenam
e
,
items
:
m
.items
.iter
()
.map
(|
i
|
i
.id
)
.collect
(),
visibility
:
From
::
from
(
&
item
.vis
)
,
qualname
,
span
:
s
elf
.span_from_span
(
sub_span
.unwrap
()
),
value
:
filename
,
parent
:
Non
e
,
children
:
m
.items
.iter
()
.map
(|
i
|
id_from_node_id
(
i
.id
,
self
)
)
.collect
(),
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.clone
(),
self
),
}))
}
ast
::
ItemKind
::
Enum
(
ref
def
,
_
)
=>
{
...
...
@@ -270,61 +299,47 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
.map
(|
v
|
v
.node.name
.to_string
())
.collect
::
<
Vec
<
_
>>
()
.join
(
", "
);
let
val
=
format!
(
"{}::{{{}}}"
,
name
,
variants_str
);
Some
(
Data
::
EnumData
(
EnumData
{
id
:
item
.id
,
name
:
name
,
value
:
val
,
span
:
sub_span
.unwrap
(),
qualname
:
qualname
,
scope
:
self
.enclosing_scope
(
item
.id
),
variants
:
def
.variants
.iter
()
.map
(|
v
|
v
.node.data
.id
())
.collect
(),
visibility
:
From
::
from
(
&
item
.vis
),
let
value
=
format!
(
"{}::{{{}}}"
,
name
,
variants_str
);
Some
(
Data
::
DefData
(
Def
{
kind
:
DefKind
::
Enum
,
id
:
id_from_node_id
(
item
.id
,
self
),
span
:
self
.span_from_span
(
sub_span
.unwrap
()),
name
,
qualname
,
value
,
parent
:
None
,
children
:
def
.variants
.iter
()
.map
(|
v
|
id_from_node_id
(
v
.node.data
.id
(),
self
))
.collect
(),
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
item
.attrs
),
sig
:
sig
::
item_signature
(
item
,
self
),
attributes
:
item
.attrs
.clone
(
),
attributes
:
lower_attributes
(
item
.attrs
.to_owned
(),
self
),
}))
}
ast
::
ItemKind
::
Impl
(
..
,
ref
trait_ref
,
ref
typ
,
_
)
=>
{
let
mut
type_data
=
None
;
let
sub_span
;
let
parent
=
self
.enclosing_scope
(
item
.id
);
match
typ
.node
{
if
let
ast
::
TyKind
::
Path
(
None
,
ref
path
)
=
typ
.node
{
// Common case impl for a struct or something basic.
ast
::
TyKind
::
Path
(
None
,
ref
path
)
=>
{
if
generated_code
(
path
.span
)
{
return
None
;
}
sub_span
=
self
.span_utils
.sub_span_for_type_name
(
path
.span
);
type_data
=
self
.lookup_ref_id
(
typ
.id
)
.map
(|
id
|
{
TypeRefData
{
span
:
sub_span
.unwrap
(),
scope
:
parent
,
ref_id
:
Some
(
id
),
qualname
:
String
::
new
()
// FIXME: generate the real qualname
}
});
}
_
=>
{
// Less useful case, impl for a compound type.
let
span
=
typ
.span
;
sub_span
=
self
.span_utils
.sub_span_for_type_name
(
span
)
.or
(
Some
(
span
));
if
generated_code
(
path
.span
)
{
return
None
;
}
let
sub_span
=
self
.span_utils
.sub_span_for_type_name
(
path
.span
);
filter!
(
self
.span_utils
,
sub_span
,
typ
.span
,
None
);
let
type_data
=
self
.lookup_ref_id
(
typ
.id
);
type_data
.map
(|
type_data
|
Data
::
RelationData
(
Relation
{
kind
:
RelationKind
::
Impl
,
span
:
self
.span_from_span
(
sub_span
.unwrap
()),
from
:
id_from_def_id
(
type_data
),
to
:
trait_ref
.as_ref
()
.and_then
(|
t
|
self
.lookup_ref_id
(
t
.ref_id
))
.map
(
id_from_def_id
)
.unwrap_or
(
null_id
()),
}))
}
else
{
None
}
let
trait_data
=
trait_ref
.as_ref
()
.and_then
(|
tr
|
self
.get_trait_ref_data
(
tr
,
parent
));
filter!
(
self
.span_utils
,
sub_span
,
typ
.span
,
None
);
Some
(
Data
::
ImplData
(
ImplData2
{
id
:
item
.id
,
span
:
sub_span
.unwrap
(),
scope
:
parent
,
trait_ref
:
trait_data
,
self_ref
:
type_data
,
}))
}
_
=>
{
// FIXME
...
...
@@ -336,7 +351,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
pub
fn
get_field_data
(
&
self
,
field
:
&
ast
::
StructField
,
scope
:
NodeId
)
->
Option
<
VariableData
>
{
->
Option
<
Def
>
{
if
let
Some
(
ident
)
=
field
.ident
{
let
name
=
ident
.to_string
();
let
qualname
=
format!
(
"::{}::{}"
,
self
.tcx
.node_path_str
(
scope
),
ident
);
...
...
@@ -345,20 +360,23 @@ pub fn get_field_data(&self,
let
def_id
=
self
.tcx.hir
.local_def_id
(
field
.id
);
let
typ
=
self
.tcx
.type_of
(
def_id
)
.to_string
();
Some
(
VariableData
{
id
:
field
.id
,
kind
:
VariableKind
::
Field
,
name
:
name
,
qualname
:
qualname
,
span
:
sub_span
.unwrap
(),
scope
:
scope
,
parent
:
Some
(
make_def_id
(
scope
,
&
self
.tcx.hir
)),
value
:
""
.to_owned
(),
type_value
:
typ
,
visibility
:
From
::
from
(
&
field
.vis
),
let
id
=
id_from_node_id
(
field
.id
,
self
);
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Def
{
kind
:
DefKind
::
Field
,
id
,
span
,
name
,
qualname
,
value
:
typ
,
parent
:
Some
(
id_from_node_id
(
scope
,
self
)),
children
:
vec!
[],
decl_id
:
None
,
docs
:
docs_for_attrs
(
&
field
.attrs
),
sig
:
sig
::
field_signature
(
field
,
self
),
attributes
:
field
.attrs
.clone
(
),
attributes
:
lower_attributes
(
field
.attrs
.clone
(),
self
),
})
}
else
{
None
...
...
@@ -371,10 +389,10 @@ pub fn get_method_data(&self,
id
:
ast
::
NodeId
,
name
:
ast
::
Name
,
span
:
Span
)
->
Option
<
FunctionData
>
{
->
Option
<
Def
>
{
// The qualname for a method is the trait name or name of the struct in an impl in
// which the method is declared in, followed by the method's name.
let
(
qualname
,
parent_scope
,
decl_id
,
vis
,
docs
,
attributes
)
=
let
(
qualname
,
parent_scope
,
decl_id
,
docs
,
attributes
)
=
match
self
.tcx
.impl_of_method
(
self
.tcx.hir
.local_def_id
(
id
))
{
Some
(
impl_id
)
=>
match
self
.tcx.hir
.get_if_local
(
impl_id
)
{
Some
(
Node
::
NodeItem
(
item
))
=>
{
...
...
@@ -383,7 +401,7 @@ pub fn get_method_data(&self,
let
mut
result
=
String
::
from
(
"<"
);
result
.push_str
(
&
self
.tcx.hir
.node_to_pretty_string
(
ty
.id
));
let
trait_id
=
self
.tcx
.trait_id_of_impl
(
impl_id
);
let
mut
trait_id
=
self
.tcx
.trait_id_of_impl
(
impl_id
);
let
mut
decl_id
=
None
;
if
let
Some
(
def_id
)
=
trait_id
{
result
.push_str
(
" as "
);
...
...
@@ -391,11 +409,16 @@ pub fn get_method_data(&self,
self
.tcx
.associated_items
(
def_id
)
.find
(|
item
|
item
.name
==
name
)
.map
(|
item
|
decl_id
=
Some
(
item
.def_id
));
}
else
{
if
let
Some
(
NodeItem
(
item
))
=
self
.tcx.hir
.find
(
id
)
{
if
let
hir
::
ItemImpl
(
_
,
_
,
_
,
_
,
_
,
ref
ty
,
_
)
=
item
.node
{
trait_id
=
self
.lookup_ref_id
(
ty
.id
);
}
}
}
result
.push_str
(
">"
);
(
result
,
trait_id
,
decl_id
,
From
::
from
(
&
item
.vis
),
docs_for_attrs
(
&
item
.attrs
),
item
.attrs
.to_vec
())
}
...
...
@@ -421,7 +444,6 @@ pub fn get_method_data(&self,
Some
(
Node
::
NodeItem
(
item
))
=>
{
(
format!
(
"::{}"
,
self
.tcx
.item_path_str
(
def_id
)),
Some
(
def_id
),
None
,
From
::
from
(
&
item
.vis
),
docs_for_attrs
(
&
item
.attrs
),
item
.attrs
.to_vec
())
}
...
...
@@ -449,27 +471,26 @@ pub fn get_method_data(&self,
let
sub_span
=
self
.span_utils
.sub_span_after_keyword
(
span
,
keywords
::
Fn
);
filter!
(
self
.span_utils
,
sub_span
,
span
,
None
);
Some
(
FunctionData
{
id
:
id
,
Some
(
Def
{
kind
:
DefKind
::
Method
,
id
:
id_from_node_id
(
id
,
self
),
span
:
self
.span_from_span
(
sub_span
.unwrap
()),
name
:
name
.to_string
(),
qualname
:
qualname
,
declaration
:
decl_id
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
id
),
qualname
,
// FIXME you get better data here by using the visitor.
value
:
String
::
new
(),
visibility
:
vis
,
parent
:
parent_scope
,
docs
:
docs
,
parent
:
parent_scope
.map
(|
id
|
id_from_def_id
(
id
)),
children
:
vec!
[],
decl_id
:
decl_id
.map
(|
id
|
id_from_def_id
(
id
)),
docs
,
sig
:
None
,
attributes
:
attributes
,
attributes
:
lower_attributes
(
attributes
,
self
)
,
})
}
pub
fn
get_trait_ref_data
(
&
self
,
trait_ref
:
&
ast
::
TraitRef
,
parent
:
NodeId
)
->
Option
<
TypeRefData
>
{
trait_ref
:
&
ast
::
TraitRef
)
->
Option
<
Ref
>
{
self
.lookup_ref_id
(
trait_ref
.ref_id
)
.and_then
(|
def_id
|
{
let
span
=
trait_ref
.path.span
;
if
generated_code
(
span
)
{
...
...
@@ -477,11 +498,11 @@ pub fn get_trait_ref_data(&self,
}
let
sub_span
=
self
.span_utils
.sub_span_for_type_name
(
span
)
.or
(
Some
(
span
));
filter!
(
self
.span_utils
,
sub_span
,
span
,
None
);
Some
(
TypeRefData
{
span
:
sub_span
.unwrap
(),
scope
:
parent
,
ref_id
:
Some
(
def_id
)
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Type
,
span
,
ref_id
:
id_from_def_id
(
def_id
),
})
})
}
...
...
@@ -507,11 +528,11 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
let
f
=
def
.struct_variant
()
.field_named
(
ident
.node.name
);
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
expr
.span
);
filter!
(
self
.span_utils
,
sub_span
,
expr
.span
,
None
);
return
Some
(
Data
::
VariableRefData
(
VariableRefData
{
name
:
ident
.node
.to_string
(),
span
:
sub_span
.unwrap
()
,
s
cope
:
self
.enclosing_scope
(
expr
.id
)
,
ref_id
:
f
.did
,
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
return
Some
(
Data
::
RefData
(
Ref
{
kind
:
RefKind
::
Variable
,
s
pan
,
ref_id
:
id_from_def_id
(
f
.did
)
,
}));
}
_
=>
{
...
...
@@ -525,11 +546,11 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
ty
::
TyAdt
(
def
,
_
)
if
!
def
.is_enum
()
=>
{
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
path
.span
);
filter!
(
self
.span_utils
,
sub_span
,
path
.span
,
None
);
Some
(
Data
::
TypeRefData
(
TypeRefData
{
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
expr
.id
)
,
ref_id
:
Some
(
def
.did
)
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Data
::
RefData
(
Ref
{
kind
:
RefKind
::
Type
,
span
,
ref_id
:
id_from_def_id
(
def
.did
),
}))
}
_
=>
{
...
...
@@ -548,16 +569,15 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
};
let
sub_span
=
self
.span_utils
.sub_span_for_meth_name
(
expr
.span
);
filter!
(
self
.span_utils
,
sub_span
,
expr
.span
,
None
);
let
parent
=
self
.enclosing_scope
(
expr
.id
);
Some
(
Data
::
MethodCallData
(
MethodCallData
{
span
:
sub_span
.unwrap
(),
scope
:
parent
,
ref_id
:
def_id
,
decl_id
:
decl_id
,
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Data
::
RefData
(
Ref
{
kind
:
RefKind
::
Function
,
span
,
ref_id
:
def_id
.or
(
decl_id
)
.map
(|
id
|
id_from_def_id
(
id
))
.unwrap_or
(
null_id
()),
}))
}
ast
::
ExprKind
::
Path
(
_
,
ref
path
)
=>
{
self
.get_path_data
(
expr
.id
,
path
)
self
.get_path_data
(
expr
.id
,
path
)
.map
(|
d
|
Data
::
RefData
(
d
))
}
_
=>
{
// FIXME
...
...
@@ -566,7 +586,7 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
}
}
pub
fn
get_path_def
(
&
self
,
id
:
NodeId
)
->
Def
{
pub
fn
get_path_def
(
&
self
,
id
:
NodeId
)
->
Hir
Def
{
match
self
.tcx.hir
.get
(
id
)
{
Node
::
NodeTraitRef
(
tr
)
=>
tr
.path.def
,
...
...
@@ -582,7 +602,7 @@ pub fn get_path_def(&self, id: NodeId) -> Def {
}
Node
::
NodeLocal
(
&
hir
::
Pat
{
node
:
hir
::
PatKind
::
Binding
(
_
,
def_id
,
..
),
..
})
=>
{
Def
::
Local
(
def_id
)
Hir
Def
::
Local
(
def_id
)
}
Node
::
NodeTy
(
ty
)
=>
{
...
...
@@ -595,58 +615,58 @@ pub fn get_path_def(&self, id: NodeId) -> Def {
for
item
in
self
.tcx
.associated_items
(
proj
.trait_ref.def_id
)
{
if
item
.kind
==
ty
::
AssociatedKind
::
Type
{
if
item
.name
==
proj
.item_name
(
self
.tcx
)
{
return
Def
::
AssociatedTy
(
item
.def_id
);
return
Hir
Def
::
AssociatedTy
(
item
.def_id
);
}
}
}
}
Def
::
Err
Hir
Def
::
Err
}
}
}
else
{
Def
::
Err
Hir
Def
::
Err
}
}
_
=>
Def
::
Err
_
=>
Hir
Def
::
Err
}
}
pub
fn
get_path_data
(
&
self
,
id
:
NodeId
,
path
:
&
ast
::
Path
)
->
Option
<
Data
>
{
pub
fn
get_path_data
(
&
self
,
id
:
NodeId
,
path
:
&
ast
::
Path
)
->
Option
<
Ref
>
{
let
def
=
self
.get_path_def
(
id
);
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
path
.span
);
filter!
(
self
.span_utils
,
sub_span
,
path
.span
,
None
);
match
def
{
Def
::
Upvar
(
..
)
|
Def
::
Local
(
..
)
|
Def
::
Static
(
..
)
|
Def
::
Const
(
..
)
|
Def
::
AssociatedConst
(
..
)
|
Def
::
StructCtor
(
..
)
|
Def
::
VariantCtor
(
..
)
=>
{
Some
(
Data
::
VariableRefData
(
VariableRefData
{
name
:
self
.span_utils
.snippet
(
sub_span
.unwrap
()),
span
:
sub_span
.unwrap
()
,
s
cope
:
self
.enclosing_scope
(
id
)
,
ref_id
:
def
.def_id
(
),
})
)
Hir
Def
::
Upvar
(
..
)
|
Hir
Def
::
Local
(
..
)
|
Hir
Def
::
Static
(
..
)
|
Hir
Def
::
Const
(
..
)
|
Hir
Def
::
AssociatedConst
(
..
)
|
Hir
Def
::
StructCtor
(
..
)
|
Hir
Def
::
VariantCtor
(
..
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Variable
,
s
pan
,
ref_id
:
id_from_def_id
(
def
.def_id
()
),
})
}
Def
::
Struct
(
def_id
)
|
Def
::
Variant
(
def_id
,
..
)
|
Def
::
Union
(
def_id
)
|
Def
::
Enum
(
def_id
)
|
Def
::
TyAlias
(
def_id
)
|
Def
::
AssociatedTy
(
def_id
)
|
Def
::
Trait
(
def_id
)
|
Def
::
TyParam
(
def_id
)
=>
{
Some
(
Data
::
TypeRefData
(
TypeRefData
{
span
:
sub_span
.unwrap
(),
ref_id
:
Some
(
def_id
)
,
s
cope
:
self
.enclosing_scope
(
id
)
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
})
)
Hir
Def
::
Struct
(
def_id
)
|
Hir
Def
::
Variant
(
def_id
,
..
)
|
Hir
Def
::
Union
(
def_id
)
|
Hir
Def
::
Enum
(
def_id
)
|
Hir
Def
::
TyAlias
(
def_id
)
|
Hir
Def
::
AssociatedTy
(
def_id
)
|
Hir
Def
::
Trait
(
def_id
)
|
Hir
Def
::
TyParam
(
def_id
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Type
,
s
pan
,
ref_id
:
id_from_def_id
(
def_id
),
})
}
Def
::
Method
(
decl_id
)
=>
{
Hir
Def
::
Method
(
decl_id
)
=>
{
let
sub_span
=
self
.span_utils
.sub_span_for_meth_name
(
path
.span
);
filter!
(
self
.span_utils
,
sub_span
,
path
.span
,
None
);
let
def_id
=
if
decl_id
.is_local
()
{
...
...
@@ -657,60 +677,60 @@ pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> {
}
else
{
None
};
Some
(
Data
::
MethodCallData
(
MethodCallData
{
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
id
)
,
ref_id
:
def_id
,
decl_id
:
Some
(
decl_id
),
})
)
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Function
,
span
,
ref_id
:
id_from_def_id
(
def_id
.unwrap_or
(
decl_id
)
),
})
}
Def
::
Fn
(
def_id
)
=>
{
Some
(
Data
::
FunctionCallData
(
FunctionCallData
{
ref_id
:
def_id
,
span
:
sub_span
.unwrap
(),
scope
:
self
.enclosing_scope
(
id
),
}))
HirDef
::
Fn
(
def_id
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Function
,
span
,
ref_id
:
id_from_def_id
(
def_id
),
})
}
Def
::
Mod
(
def_id
)
=>
{
Some
(
Data
::
ModRefData
(
ModRefData
{
ref_id
:
Some
(
def_id
),
span
:
sub_span
.unwrap
()
,
s
cope
:
self
.enclosing_scope
(
id
)
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
})
)
Hir
Def
::
Mod
(
def_id
)
=>
{
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Mod
,
s
pan
,
ref_id
:
id_from_def_id
(
def_id
),
})
}
Def
::
PrimTy
(
..
)
|
Def
::
SelfTy
(
..
)
|
Def
::
Label
(
..
)
|
Def
::
Macro
(
..
)
|
Def
::
GlobalAsm
(
..
)
|
Def
::
Err
=>
None
,
Hir
Def
::
PrimTy
(
..
)
|
Hir
Def
::
SelfTy
(
..
)
|
Hir
Def
::
Label
(
..
)
|
Hir
Def
::
Macro
(
..
)
|
Hir
Def
::
GlobalAsm
(
..
)
|
Hir
Def
::
Err
=>
None
,
}
}
pub
fn
get_field_ref_data
(
&
self
,
field_ref
:
&
ast
::
Field
,
variant
:
&
ty
::
VariantDef
,
parent
:
NodeId
)
->
Option
<
VariableRefData
>
{
variant
:
&
ty
::
VariantDef
)
->
Option
<
Ref
>
{
let
f
=
variant
.field_named
(
field_ref
.ident.node.name
);
// We don't really need a sub-span here, but no harm done
let
sub_span
=
self
.span_utils
.span_for_last_ident
(
field_ref
.ident.span
);
filter!
(
self
.span_utils
,
sub_span
,
field_ref
.ident.span
,
None
);
Some
(
VariableRefData
{
name
:
field_ref
.ident.node
.to_string
(),
span
:
sub_span
.unwrap
()
,
s
cope
:
parent
,
ref_id
:
f
.did
,
let
span
=
self
.span_from_span
(
sub_span
.unwrap
());
Some
(
Ref
{
kind
:
RefKind
::
Variable
,
s
pan
,
ref_id
:
id_from_def_id
(
f
.did
)
,
})
}
/// Attempt to return Macro
UseData
for any AST node.
/// Attempt to return Macro
Ref
for any AST node.
///
/// For a given piece of AST defined by the supplied Span and NodeId,
/// returns None if the node is not macro-generated or the span is malformed,
/// else uses the expansion callsite and callee to return some Macro
UseData
.
pub
fn
get_macro_use_data
(
&
self
,
span
:
Span
,
id
:
NodeId
)
->
Option
<
MacroUseData
>
{
/// else uses the expansion callsite and callee to return some Macro
Ref
.
pub
fn
get_macro_use_data
(
&
self
,
span
:
Span
)
->
Option
<
MacroRef
>
{
if
!
generated_code
(
span
)
{
return
None
;
}
...
...
@@ -718,6 +738,7 @@ pub fn get_macro_use_data(&self, span: Span, id: NodeId) -> Option<MacroUseData>
// nested expansions and ensure we only generate data for source-visible
// macro uses.
let
callsite
=
span
.source_callsite
();
let
callsite_span
=
self
.span_from_span
(
callsite
);
let
callee
=
option_try!
(
span
.source_callee
());
let
callee_span
=
option_try!
(
callee
.span
);
...
...
@@ -731,34 +752,25 @@ pub fn get_macro_use_data(&self, span: Span, id: NodeId) -> Option<MacroUseData>
// when read in, and no longer correspond to the source.
if
let
Some
(
mac
)
=
self
.tcx.sess.imported_macro_spans
.borrow
()
.get
(
&
callee_span
)
{
let
&
(
ref
mac_name
,
mac_span
)
=
mac
;
return
Some
(
MacroUseData
{
span
:
callsite
,
name
:
mac_name
.clone
(),
callee_span
:
mac_span
,
scope
:
self
.enclosing_scope
(
id
),
imported
:
true
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
});
let
mac_span
=
self
.span_from_span
(
mac_span
);
return
Some
(
MacroRef
{
span
:
callsite_span
,
qualname
:
mac_name
.clone
(),
// FIXME: generate the real qualname
callee_span
:
mac_span
,
});
}
Some
(
MacroUseData
{
span
:
callsite
,
name
:
callee
.name
()
.to_string
(),
callee_span
:
callee_span
,
scope
:
self
.enclosing_scope
(
id
),
imported
:
false
,
qualname
:
String
::
new
()
// FIXME: generate the real qualname
let
callee_span
=
self
.span_from_span
(
callee_span
);
Some
(
MacroRef
{
span
:
callsite_span
,
qualname
:
callee
.name
()
.to_string
(),
// FIXME: generate the real qualname
callee_span
,
})
}
pub
fn
get_data_for_id
(
&
self
,
_
id
:
&
NodeId
)
->
Data
{
// FIXME
bug!
();
}
fn
lookup_ref_id
(
&
self
,
ref_id
:
NodeId
)
->
Option
<
DefId
>
{
match
self
.get_path_def
(
ref_id
)
{
Def
::
PrimTy
(
_
)
|
Def
::
SelfTy
(
..
)
|
Def
::
Err
=>
None
,
HirDef
::
PrimTy
(
_
)
|
HirDef
::
SelfTy
(
..
)
|
Hir
Def
::
Err
=>
None
,
def
=>
Some
(
def
.def_id
()),
}
}
...
...
@@ -800,7 +812,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
// An AST visitor for collecting paths from patterns.
struct
PathCollector
{
// The Row field identifies the kind of pattern.
collected_paths
:
Vec
<
(
NodeId
,
ast
::
Path
,
ast
::
Mutability
,
recorder
::
Row
)
>
,
collected_paths
:
Vec
<
(
NodeId
,
ast
::
Path
,
ast
::
Mutability
)
>
,
}
impl
PathCollector
{
...
...
@@ -814,12 +826,12 @@ fn visit_pat(&mut self, p: &ast::Pat) {
match
p
.node
{
PatKind
::
Struct
(
ref
path
,
..
)
=>
{
self
.collected_paths
.push
((
p
.id
,
path
.clone
(),
ast
::
Mutability
::
Mutable
,
recorder
::
TypeRef
));
ast
::
Mutability
::
Mutable
));
}
PatKind
::
TupleStruct
(
ref
path
,
..
)
|
PatKind
::
Path
(
_
,
ref
path
)
=>
{
self
.collected_paths
.push
((
p
.id
,
path
.clone
(),
ast
::
Mutability
::
Mutable
,
recorder
::
VarRef
));
ast
::
Mutability
::
Mutable
));
}
PatKind
::
Ident
(
bm
,
ref
path1
,
_
)
=>
{
debug!
(
"PathCollector, visit ident in pat {}: {:?} {:?}"
,
...
...
@@ -835,7 +847,7 @@ fn visit_pat(&mut self, p: &ast::Pat) {
};
// collect path for either visit_local or visit_arm
let
path
=
ast
::
Path
::
from_ident
(
path1
.span
,
path1
.node
);
self
.collected_paths
.push
((
p
.id
,
path
,
immut
,
recorder
::
VarRef
));
self
.collected_paths
.push
((
p
.id
,
path
,
immut
));
}
_
=>
{}
}
...
...
@@ -1032,6 +1044,34 @@ fn id_from_def_id(id: DefId) -> rls_data::Id {
}
fn
id_from_node_id
(
id
:
NodeId
,
scx
:
&
SaveContext
)
->
rls_data
::
Id
{
let
def_id
=
scx
.tcx.hir
.local_def_id
(
id
);
id_from_def_id
(
def_id
)
let
def_id
=
scx
.tcx.hir
.opt_local_def_id
(
id
);
def_id
.map
(|
id
|
id_from_def_id
(
id
))
.unwrap_or_else
(
null_id
)
}
fn
null_id
()
->
rls_data
::
Id
{
rls_data
::
Id
{
krate
:
u32
::
max_value
(),
index
:
u32
::
max_value
(),
}
}
fn
lower_attributes
(
attrs
:
Vec
<
Attribute
>
,
scx
:
&
SaveContext
)
->
Vec
<
rls_data
::
Attribute
>
{
attrs
.into_iter
()
// Only retain real attributes. Doc comments are lowered separately.
.filter
(|
attr
|
attr
.path
!=
"doc"
)
.map
(|
mut
attr
|
{
// Remove the surrounding '#[..]' or '#![..]' of the pretty printed
// attribute. First normalize all inner attribute (#![..]) to outer
// ones (#[..]), then remove the two leading and the one trailing character.
attr
.style
=
ast
::
AttrStyle
::
Outer
;
let
value
=
pprust
::
attribute_to_string
(
&
attr
);
// This str slicing works correctly, because the leading and trailing characters
// are in the ASCII range and thus exactly one byte each.
let
value
=
value
[
2
..
value
.len
()
-
1
]
.to_string
();
rls_data
::
Attribute
{
value
:
value
,
span
:
scx
.span_from_span
(
attr
.span
),
}
})
.collect
()
}
src/librustc_save_analysis/span_utils.rs
浏览文件 @
8a2857e6
...
...
@@ -20,7 +20,6 @@
use
syntax
::
parse
::
lexer
::{
self
,
StringReader
};
use
syntax
::
parse
::
token
::{
self
,
Token
};
use
syntax
::
symbol
::
keywords
;
use
syntax
::
tokenstream
::
TokenTree
;
use
syntax_pos
::
*
;
#[derive(Clone)]
...
...
@@ -277,45 +276,6 @@ pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> V
}
}
/// `span` must be the span for an item such as a function or struct. This
/// function returns the program text from the start of the span until the
/// end of the 'signature' part, that is up to, but not including an opening
/// brace or semicolon.
pub
fn
signature_string_for_span
(
&
self
,
span
:
Span
)
->
String
{
let
mut
toks
=
self
.retokenise_span
(
span
);
toks
.real_token
();
let
mut
toks
=
toks
.parse_all_token_trees
()
.unwrap
()
.trees
();
let
mut
prev
=
toks
.next
()
.unwrap
();
let
first_span
=
prev
.span
();
let
mut
angle_count
=
0
;
for
tok
in
toks
{
if
let
TokenTree
::
Token
(
_
,
ref
tok
)
=
prev
{
angle_count
+=
match
*
tok
{
token
::
Eof
=>
{
break
;
}
token
::
Lt
=>
1
,
token
::
Gt
=>
-
1
,
token
::
BinOp
(
token
::
Shl
)
=>
2
,
token
::
BinOp
(
token
::
Shr
)
=>
-
2
,
_
=>
0
,
};
}
if
angle_count
>
0
{
prev
=
tok
;
continue
;
}
if
let
TokenTree
::
Token
(
_
,
token
::
Semi
)
=
tok
{
return
self
.snippet
(
first_span
.to
(
prev
.span
()));
}
else
if
let
TokenTree
::
Delimited
(
_
,
ref
d
)
=
tok
{
if
d
.delim
==
token
::
Brace
{
return
self
.snippet
(
first_span
.to
(
prev
.span
()));
}
}
prev
=
tok
;
}
self
.snippet
(
span
)
}
pub
fn
sub_span_before_token
(
&
self
,
span
:
Span
,
tok
:
Token
)
->
Option
<
Span
>
{
let
mut
toks
=
self
.retokenise_span
(
span
);
let
mut
prev
=
toks
.real_token
();
...
...
@@ -385,57 +345,44 @@ pub fn spans_for_ty_params(&self, span: Span, number: isize) -> Vec<Span> {
self
.spans_with_brackets
(
span
,
1
,
number
)
}
pub
fn
report_span_err
(
&
self
,
kind
:
&
str
,
span
:
Span
)
{
let
loc
=
self
.sess
.codemap
()
.lookup_char_pos
(
span
.lo
);
info!
(
"({}) Could not find sub_span in `{}` in {}, line {}"
,
kind
,
self
.snippet
(
span
),
loc
.file.name
,
loc
.line
);
self
.err_count
.set
(
self
.err_count
.get
()
+
1
);
if
self
.err_count
.get
()
>
1000
{
bug!
(
"span errors reached 1000, giving up"
);
}
}
// Return the name for a macro definition (identifier after first `!`)
pub
fn
span_for_macro_def_name
(
&
self
,
span
:
Span
)
->
Option
<
Span
>
{
let
mut
toks
=
self
.retokenise_span
(
span
);
loop
{
let
ts
=
toks
.real_token
();
if
ts
.tok
==
token
::
Eof
{
return
None
;
}
if
ts
.tok
==
token
::
Not
{
let
ts
=
toks
.real_token
();
if
ts
.tok
.is_ident
()
{
return
Some
(
ts
.sp
);
}
else
{
return
None
;
}
}
}
}
// Return the name for a macro use (identifier before first `!`).
pub
fn
span_for_macro_use_name
(
&
self
,
span
:
Span
)
->
Option
<
Span
>
{
let
mut
toks
=
self
.retokenise_span
(
span
);
let
mut
prev
=
toks
.real_token
();
loop
{
if
prev
.tok
==
token
::
Eof
{
return
None
;
}
let
ts
=
toks
.real_token
();
if
ts
.tok
==
token
::
Not
{
if
prev
.tok
.is_ident
()
{
return
Some
(
prev
.sp
);
}
else
{
return
None
;
}
}
prev
=
ts
;
}
}
// // Return the name for a macro definition (identifier after first `!`)
// pub fn span_for_macro_def_name(&self, span: Span) -> Option<Span> {
// let mut toks = self.retokenise_span(span);
// loop {
// let ts = toks.real_token();
// if ts.tok == token::Eof {
// return None;
// }
// if ts.tok == token::Not {
// let ts = toks.real_token();
// if ts.tok.is_ident() {
// return Some(ts.sp);
// } else {
// return None;
// }
// }
// }
// }
// // Return the name for a macro use (identifier before first `!`).
// pub fn span_for_macro_use_name(&self, span:Span) -> Option<Span> {
// let mut toks = self.retokenise_span(span);
// let mut prev = toks.real_token();
// loop {
// if prev.tok == token::Eof {
// return None;
// }
// let ts = toks.real_token();
// if ts.tok == token::Not {
// if prev.tok.is_ident() {
// return Some(prev.sp);
// } else {
// return None;
// }
// }
// prev = ts;
// }
// }
/// Return true if the span is generated code, and
/// it is not a subspan of the root callsite.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录