Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
1614d92f
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,发现更多精彩内容 >>
提交
1614d92f
编写于
12月 19, 2014
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_resolve: move unused import checking into its own module.
上级
c54fc980
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
178 addition
and
141 deletion
+178
-141
src/librustc_resolve/check_unused.rs
src/librustc_resolve/check_unused.rs
+161
-0
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+17
-141
未找到文件。
src/librustc_resolve/check_unused.rs
0 → 100644
浏览文件 @
1614d92f
// 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.
//
// Unused import checking
//
// Although this is mostly a lint pass, it lives in here because it depends on
// resolve data structures and because it finalises the privacy information for
// `use` directives.
//
use
Resolver
;
use
Namespace
::{
TypeNS
,
ValueNS
};
use
rustc
::
lint
;
use
rustc
::
middle
::
privacy
::{
DependsOn
,
LastImport
,
Used
,
Unused
};
use
syntax
::
ast
;
use
syntax
::
ast
::{
ViewItem
,
ViewItemExternCrate
,
ViewItemUse
};
use
syntax
::
ast
::{
ViewPathGlob
,
ViewPathList
,
ViewPathSimple
};
use
syntax
::
codemap
::{
Span
,
DUMMY_SP
};
use
syntax
::
visit
::{
mod
,
Visitor
};
struct
UnusedImportCheckVisitor
<
'a
,
'b
:
'a
>
{
resolver
:
&
'a
mut
Resolver
<
'b
>
}
// Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver.
impl
<
'a
,
'b
>
Deref
<
Resolver
<
'b
>>
for
UnusedImportCheckVisitor
<
'a
,
'b
>
{
fn
deref
<
'c
>
(
&
'c
self
)
->
&
'c
Resolver
<
'b
>
{
&*
self
.resolver
}
}
impl
<
'a
,
'b
>
DerefMut
<
Resolver
<
'b
>>
for
UnusedImportCheckVisitor
<
'a
,
'b
>
{
fn
deref_mut
<
'c
>
(
&
'c
mut
self
)
->
&
'c
mut
Resolver
<
'b
>
{
&
mut
*
self
.resolver
}
}
impl
<
'a
,
'b
>
UnusedImportCheckVisitor
<
'a
,
'b
>
{
// We have information about whether `use` (import) directives are actually used now.
// If an import is not used at all, we signal a lint error. If an import is only used
// for a single namespace, we remove the other namespace from the recorded privacy
// information. That means in privacy.rs, we will only check imports and namespaces
// which are used. In particular, this means that if an import could name either a
// public or private item, we will check the correct thing, dependent on how the import
// is used.
fn
finalize_import
(
&
mut
self
,
id
:
ast
::
NodeId
,
span
:
Span
)
{
debug!
(
"finalizing import uses for {}"
,
self
.session
.codemap
()
.span_to_snippet
(
span
));
if
!
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
&&
!
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_IMPORTS
,
id
,
span
,
"unused import"
.to_string
());
}
let
(
v_priv
,
t_priv
)
=
match
self
.last_private
.get
(
&
id
)
{
Some
(
&
LastImport
{
value_priv
:
v
,
value_used
:
_
,
type_priv
:
t
,
type_used
:
_
})
=>
(
v
,
t
),
Some
(
_
)
=>
{
panic!
(
"we should only have LastImport for `use` directives"
)
}
_
=>
return
,
};
let
mut
v_used
=
if
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
Used
}
else
{
Unused
};
let
t_used
=
if
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
{
Used
}
else
{
Unused
};
match
(
v_priv
,
t_priv
)
{
// Since some items may be both in the value _and_ type namespaces (e.g., structs)
// we might have two LastPrivates pointing at the same thing. There is no point
// checking both, so lets not check the value one.
(
Some
(
DependsOn
(
def_v
)),
Some
(
DependsOn
(
def_t
)))
if
def_v
==
def_t
=>
v_used
=
Unused
,
_
=>
{},
}
self
.last_private
.insert
(
id
,
LastImport
{
value_priv
:
v_priv
,
value_used
:
v_used
,
type_priv
:
t_priv
,
type_used
:
t_used
});
}
}
impl
<
'a
,
'b
,
'v
>
Visitor
<
'v
>
for
UnusedImportCheckVisitor
<
'a
,
'b
>
{
fn
visit_view_item
(
&
mut
self
,
vi
:
&
ViewItem
)
{
// Ignore is_public import statements because there's no way to be sure
// whether they're used or not. Also ignore imports with a dummy span
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if
vi
.vis
==
ast
::
Public
||
vi
.span
==
DUMMY_SP
{
visit
::
walk_view_item
(
self
,
vi
);
return
;
}
match
vi
.node
{
ViewItemExternCrate
(
_
,
_
,
id
)
=>
{
if
let
Some
(
crate_num
)
=
self
.session.cstore
.find_extern_mod_stmt_cnum
(
id
)
{
if
!
self
.used_crates
.contains
(
&
crate_num
)
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_EXTERN_CRATES
,
id
,
vi
.span
,
"unused extern crate"
.to_string
());
}
}
},
ViewItemUse
(
ref
p
)
=>
{
match
p
.node
{
ViewPathSimple
(
_
,
_
,
id
)
=>
{
self
.finalize_import
(
id
,
p
.span
)
}
ViewPathList
(
_
,
ref
list
,
_
)
=>
{
for
i
in
list
.iter
()
{
self
.finalize_import
(
i
.node
.id
(),
i
.span
);
}
}
ViewPathGlob
(
_
,
id
)
=>
{
if
!
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
&&
!
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_IMPORTS
,
id
,
p
.span
,
"unused import"
.to_string
());
}
}
}
}
}
visit
::
walk_view_item
(
self
,
vi
);
}
}
pub
fn
check_crate
(
resolver
:
&
mut
Resolver
,
krate
:
&
ast
::
Crate
)
{
let
mut
visitor
=
UnusedImportCheckVisitor
{
resolver
:
resolver
};
visit
::
walk_crate
(
&
mut
visitor
,
krate
);
}
src/librustc_resolve/lib.rs
浏览文件 @
1614d92f
...
...
@@ -96,6 +96,8 @@
use
std
::
rc
::{
Rc
,
Weak
};
use
std
::
uint
;
mod
check_unused
;
#[deriving(Copy)]
struct
BindingInfo
{
span
:
Span
,
...
...
@@ -935,17 +937,6 @@ fn visit_block(&mut self, block: &Block) {
}
struct
UnusedImportCheckVisitor
<
'a
,
'b
:
'a
>
{
resolver
:
&
'a
mut
Resolver
<
'b
>
}
impl
<
'a
,
'b
,
'v
>
Visitor
<
'v
>
for
UnusedImportCheckVisitor
<
'a
,
'b
>
{
fn
visit_view_item
(
&
mut
self
,
vi
:
&
ViewItem
)
{
self
.resolver
.check_for_item_unused_imports
(
vi
);
visit
::
walk_view_item
(
self
,
vi
);
}
}
#[deriving(PartialEq)]
enum
FallbackChecks
{
Everything
,
...
...
@@ -1006,22 +997,6 @@ fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
emit_errors
:
true
,
}
}
/// The main name resolution procedure.
fn
resolve
(
&
mut
self
,
krate
:
&
ast
::
Crate
)
{
self
.build_reduced_graph
(
krate
);
self
.session
.abort_if_errors
();
self
.resolve_imports
();
self
.session
.abort_if_errors
();
self
.record_exports
();
self
.session
.abort_if_errors
();
self
.resolve_crate
(
krate
);
self
.session
.abort_if_errors
();
self
.check_for_unused_imports
(
krate
);
}
//
// Reduced graph building
...
...
@@ -6068,119 +6043,6 @@ fn enforce_default_binding_mode(&mut self,
}
}
//
// Unused import checking
//
// Although this is mostly a lint pass, it lives in here because it depends on
// resolve data structures and because it finalises the privacy information for
// `use` directives.
//
fn
check_for_unused_imports
(
&
mut
self
,
krate
:
&
ast
::
Crate
)
{
let
mut
visitor
=
UnusedImportCheckVisitor
{
resolver
:
self
};
visit
::
walk_crate
(
&
mut
visitor
,
krate
);
}
fn
check_for_item_unused_imports
(
&
mut
self
,
vi
:
&
ViewItem
)
{
// Ignore is_public import statements because there's no way to be sure
// whether they're used or not. Also ignore imports with a dummy span
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if
vi
.vis
==
Public
{
return
}
if
vi
.span
==
DUMMY_SP
{
return
}
match
vi
.node
{
ViewItemExternCrate
(
_
,
_
,
id
)
=>
{
if
let
Some
(
crate_num
)
=
self
.session.cstore
.find_extern_mod_stmt_cnum
(
id
)
{
if
!
self
.used_crates
.contains
(
&
crate_num
)
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_EXTERN_CRATES
,
id
,
vi
.span
,
"unused extern crate"
.to_string
());
}
}
},
ViewItemUse
(
ref
p
)
=>
{
match
p
.node
{
ViewPathSimple
(
_
,
_
,
id
)
=>
self
.finalize_import
(
id
,
p
.span
),
ViewPathList
(
_
,
ref
list
,
_
)
=>
{
for
i
in
list
.iter
()
{
self
.finalize_import
(
i
.node
.id
(),
i
.span
);
}
},
ViewPathGlob
(
_
,
id
)
=>
{
if
!
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
&&
!
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_IMPORTS
,
id
,
p
.span
,
"unused import"
.to_string
());
}
},
}
}
}
}
// We have information about whether `use` (import) directives are actually used now.
// If an import is not used at all, we signal a lint error. If an import is only used
// for a single namespace, we remove the other namespace from the recorded privacy
// information. That means in privacy.rs, we will only check imports and namespaces
// which are used. In particular, this means that if an import could name either a
// public or private item, we will check the correct thing, dependent on how the import
// is used.
fn
finalize_import
(
&
mut
self
,
id
:
NodeId
,
span
:
Span
)
{
debug!
(
"finalizing import uses for {}"
,
self
.session
.codemap
()
.span_to_snippet
(
span
));
if
!
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
&&
!
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
self
.session
.add_lint
(
lint
::
builtin
::
UNUSED_IMPORTS
,
id
,
span
,
"unused import"
.to_string
());
}
let
(
v_priv
,
t_priv
)
=
match
self
.last_private
.get
(
&
id
)
{
Some
(
&
LastImport
{
value_priv
:
v
,
value_used
:
_
,
type_priv
:
t
,
type_used
:
_
})
=>
(
v
,
t
),
Some
(
_
)
=>
{
panic!
(
"we should only have LastImport for `use` directives"
)
}
_
=>
return
,
};
let
mut
v_used
=
if
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
Used
}
else
{
Unused
};
let
t_used
=
if
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
{
Used
}
else
{
Unused
};
match
(
v_priv
,
t_priv
)
{
// Since some items may be both in the value _and_ type namespaces (e.g., structs)
// we might have two LastPrivates pointing at the same thing. There is no point
// checking both, so lets not check the value one.
(
Some
(
DependsOn
(
def_v
)),
Some
(
DependsOn
(
def_t
)))
if
def_v
==
def_t
=>
v_used
=
Unused
,
_
=>
{},
}
self
.last_private
.insert
(
id
,
LastImport
{
value_priv
:
v_priv
,
value_used
:
v_used
,
type_priv
:
t_priv
,
type_used
:
t_used
});
}
//
// Diagnostics
//
...
...
@@ -6268,7 +6130,21 @@ pub fn resolve_crate(session: &Session,
krate
:
&
Crate
)
->
CrateMap
{
let
mut
resolver
=
Resolver
::
new
(
session
,
krate
.span
);
resolver
.resolve
(
krate
);
resolver
.build_reduced_graph
(
krate
);
session
.abort_if_errors
();
resolver
.resolve_imports
();
session
.abort_if_errors
();
resolver
.record_exports
();
session
.abort_if_errors
();
resolver
.resolve_crate
(
krate
);
session
.abort_if_errors
();
check_unused
::
check_crate
(
&
mut
resolver
,
krate
);
CrateMap
{
def_map
:
resolver
.def_map
,
freevars
:
resolver
.freevars
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录