Skip to content

Commit f2f8a36

Browse files
committed
collected all the imports and names
1 parent 52127b8 commit f2f8a36

File tree

2 files changed

+101
-34
lines changed

2 files changed

+101
-34
lines changed

clippy_lints/src/macro_use.rs

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
11
use crate::utils::{snippet, span_lint_and_sugg, in_macro};
22
use if_chain::if_chain;
33
use rustc_ast::ast;
4-
use rustc_data_structures::fx::FxHashSet;
4+
use rustc_data_structures::fx::FxHashMap;
55
use rustc_errors::Applicability;
6-
use rustc_lint::{EarlyContext, EarlyLintPass};
6+
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext, Lint};
77
use rustc_session::{impl_lint_pass, declare_tool_lint};
88
use rustc_span::{edition::Edition, Span};
9+
use rustc_hir as hir;
10+
11+
const PRELUDE: &[&str] = &[
12+
"marker", "ops", "convert", "iter", "option", "result", "borrow", "boxed", "string", "vec",
13+
"macros"
14+
];
15+
16+
pub type SuggFn = Box<dyn FnOnce(EarlyContext<'_>, &'static Lint, Span, &str, &str, String, Applicability)>;
17+
pub type SaveFn = Box<dyn FnOnce()>;
18+
19+
pub struct ImportData {
20+
name: String,
21+
path: String,
22+
}
23+
24+
impl ImportData {
25+
pub fn new(name: String, span: Span, ecx: &EarlyContext<'_>) -> Self {
26+
let path = ecx.sess.source_map().span_to_filename(span);
27+
let path = ecx.sess.source_map().span_to_unmapped_path(span);
28+
println!("{:?} {:?}", name, path);
29+
Self { name: name.to_string(), path: path.to_string(), }
30+
}
31+
}
932

1033
declare_clippy_lint! {
1134
/// **What it does:** Checks for `#[macro_use] use...`.
@@ -27,13 +50,20 @@ declare_clippy_lint! {
2750

2851
#[derive(Default)]
2952
pub struct MacroUseImport {
30-
collected: FxHashSet<Span>,
53+
imports: Vec<(String, Span)>,
54+
collected: FxHashMap<Span, ImportData>,
55+
}
56+
57+
impl MacroUseImport {
58+
fn import_path_mac(&self, name: &str) -> String {
59+
println!("{:?}", name);
60+
String::default()
61+
}
3162
}
3263

3364
impl_lint_pass!(MacroUseImport => [MACRO_USE_IMPORT]);
3465

3566
impl EarlyLintPass for MacroUseImport {
36-
3767
fn check_item(&mut self, ecx: &EarlyContext<'_>, item: &ast::Item) {
3868
if_chain! {
3969
if ecx.sess.opts.edition == Edition::Edition2018;
@@ -44,58 +74,77 @@ impl EarlyLintPass for MacroUseImport {
4474
.find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
4575
then {
4676
let import_path = snippet(ecx, use_tree.span, "_");
47-
let mac_names = find_used_macros(ecx, &import_path);
48-
let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition";
49-
let help = format!("use {}::<macro name>", import_path);
50-
span_lint_and_sugg(
51-
ecx,
52-
MACRO_USE_IMPORT,
53-
mac_attr.span,
54-
msg,
55-
// "remove the attribute and import the macro directly, try",
56-
"",
57-
help,
58-
Applicability::HasPlaceholders,
59-
);
77+
let span = mac_attr.span.clone();
78+
self.imports.push((import_path.to_string(), span));
6079
}
6180
}
6281
}
6382

6483
fn check_expr(&mut self, ecx: &EarlyContext<'_>, expr: &ast::Expr) {
6584
if in_macro(expr.span) {
66-
let name = snippet(ecx, ecx.sess.source_map().span_until_char(expr.span.source_callsite(), '!'), "_");
85+
let call_site = expr.span.source_callsite();
86+
let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_");
6787
if let Some(callee) = expr.span.source_callee() {
68-
if self.collected.insert(callee.def_site) {
69-
println!("EXPR {:#?}", name);
70-
}
88+
self.collected.entry(call_site)
89+
.or_insert_with(|| {
90+
println!("EXPR {:?}", name);
91+
ImportData::new(name.to_string(), callee.def_site, ecx)
92+
});
7193
}
7294
}
7395
}
7496
fn check_stmt(&mut self, ecx: &EarlyContext<'_>, stmt: &ast::Stmt) {
7597
if in_macro(stmt.span) {
76-
let name = snippet(ecx, ecx.sess.source_map().span_until_char(stmt.span.source_callsite(), '!'), "_");
98+
let call_site = stmt.span.source_callsite();
99+
let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_");
77100
if let Some(callee) = stmt.span.source_callee() {
78-
println!("EXPR {:#?}", name);
101+
self.collected.entry(call_site)
102+
.or_insert_with(|| {
103+
println!("STMT {:?}", name);
104+
ImportData::new(name.to_string(), callee.def_site, ecx)
105+
});
79106
}
80107
}
81108
}
82109
fn check_pat(&mut self, ecx: &EarlyContext<'_>, pat: &ast::Pat) {
83110
if in_macro(pat.span) {
84-
let name = snippet(ecx, ecx.sess.source_map().span_until_char(pat.span.source_callsite(), '!'), "_");
111+
let call_site = pat.span.source_callsite();
112+
let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_");
85113
if let Some(callee) = pat.span.source_callee() {
86-
println!("EXPR {:#?}", name);
114+
self.collected.entry(call_site)
115+
.or_insert_with(|| {
116+
println!("PAT {:?}", name);
117+
ImportData::new(name.to_string(), callee.def_site, ecx)
118+
});
87119
}
88120
}
89121
}
90-
}
91-
92-
fn find_used_macros(ecx: &EarlyContext<'_>, path: &str) {
93-
for it in ecx.krate.module.items.iter() {
94-
if in_macro(it.span) {
95-
// println!("{:#?}", it)
122+
fn check_mac(&mut self, ecx: &EarlyContext<'_>, mac: &ast::Mac) {
123+
let call_site = mac.span().source_callsite();
124+
let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_");
125+
if let Some(callee) = mac.span().source_callee() {
126+
self.collected.entry(call_site)
127+
.or_insert_with(|| {
128+
println!("MAC {:?}", name);
129+
ImportData::new(name.to_string(), callee.def_site, ecx)
130+
});
96131
}
97132
}
98-
for x in ecx.sess.imported_macro_spans.borrow().iter() {
99-
// println!("{:?}", x);
133+
fn check_crate_post(&mut self, ecx: &EarlyContext<'_>, krate: &ast::Crate) {
134+
for (name, span) in self.imports.iter() {
135+
let import_path = self.import_path_mac(&name);
136+
let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition";
137+
let help = format!("use {}::{}", import_path, name);
138+
span_lint_and_sugg(
139+
ecx,
140+
MACRO_USE_IMPORT,
141+
*span,
142+
msg,
143+
// "remove the attribute and import the macro directly, try",
144+
"",
145+
help,
146+
Applicability::HasPlaceholders,
147+
)
148+
}
100149
}
101150
}

tests/ui/macro_use_import.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
// compile-flags: --edition 2018
22
#![warn(clippy::macro_use_import)]
3+
#![feature(rustc_private)]
34

45
use std::collections::HashMap;
56
#[macro_use]
67
use std::prelude;
8+
#[macro_use]
9+
extern crate rustc_session;
710

811
fn main() {
912
let _ = HashMap::<u8, u8>::new();
10-
serde_if_integer128!("");
13+
here!();
1114
println!();
15+
declare_tool_lint! {
16+
pub clippy::TEST_LINT,
17+
Warn,
18+
"",
19+
report_in_external_macro: true
20+
}
21+
}
22+
23+
mod a {
24+
#[macro_export]
25+
macro_rules! here {
26+
() => {
27+
()
28+
};
29+
}
1230
}

0 commit comments

Comments
 (0)