Handle relative paths in module_files lints
This commit is contained in:
parent
fe7254ff6f
commit
10a6d872d4
@ -1,13 +1,10 @@
|
|||||||
use std::{
|
|
||||||
ffi::OsString,
|
|
||||||
path::{Component, Path},
|
|
||||||
};
|
|
||||||
|
|
||||||
use rustc_ast::ast;
|
use rustc_ast::ast;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||||
use rustc_span::{FileName, RealFileName, SourceFile, Span, SyntaxContext};
|
use rustc_span::{FileName, RealFileName, SourceFile, Span, SyntaxContext};
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::path::{Component, Path};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
@ -82,11 +79,7 @@ impl EarlyLintPass for ModStyle {
|
|||||||
|
|
||||||
let files = cx.sess().source_map().files();
|
let files = cx.sess().source_map().files();
|
||||||
|
|
||||||
let trim_to_src = if let RealFileName::LocalPath(p) = &cx.sess().opts.working_dir {
|
let RealFileName::LocalPath(trim_to_src) = &cx.sess().opts.working_dir else { return };
|
||||||
p.to_string_lossy()
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// `folder_segments` is all unique folder path segments `path/to/foo.rs` gives
|
// `folder_segments` is all unique folder path segments `path/to/foo.rs` gives
|
||||||
// `[path, to]` but not foo
|
// `[path, to]` but not foo
|
||||||
@ -97,26 +90,27 @@ impl EarlyLintPass for ModStyle {
|
|||||||
// `{ foo => path/to/foo.rs, .. }
|
// `{ foo => path/to/foo.rs, .. }
|
||||||
let mut file_map = FxHashMap::default();
|
let mut file_map = FxHashMap::default();
|
||||||
for file in files.iter() {
|
for file in files.iter() {
|
||||||
match &file.name {
|
if let FileName::Real(RealFileName::LocalPath(lp)) = &file.name {
|
||||||
FileName::Real(RealFileName::LocalPath(lp))
|
let path = if lp.is_relative() {
|
||||||
if lp.to_string_lossy().starts_with(trim_to_src.as_ref()) =>
|
lp
|
||||||
{
|
} else if let Ok(relative) = lp.strip_prefix(trim_to_src) {
|
||||||
let p = lp.to_string_lossy();
|
relative
|
||||||
let path = Path::new(p.trim_start_matches(trim_to_src.as_ref()));
|
} else {
|
||||||
if let Some(stem) = path.file_stem() {
|
continue;
|
||||||
file_map.insert(stem.to_os_string(), (file, path.to_owned()));
|
};
|
||||||
}
|
|
||||||
process_paths_for_mod_files(path, &mut folder_segments, &mut mod_folders);
|
if let Some(stem) = path.file_stem() {
|
||||||
check_self_named_mod_exists(cx, path, file);
|
file_map.insert(stem, (file, path));
|
||||||
},
|
}
|
||||||
_ => {},
|
process_paths_for_mod_files(path, &mut folder_segments, &mut mod_folders);
|
||||||
|
check_self_named_mod_exists(cx, path, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for folder in &folder_segments {
|
for folder in &folder_segments {
|
||||||
if !mod_folders.contains(folder) {
|
if !mod_folders.contains(folder) {
|
||||||
if let Some((file, path)) = file_map.get(folder) {
|
if let Some((file, path)) = file_map.get(folder) {
|
||||||
let mut correct = path.clone();
|
let mut correct = path.to_path_buf();
|
||||||
correct.pop();
|
correct.pop();
|
||||||
correct.push(folder);
|
correct.push(folder);
|
||||||
correct.push("mod.rs");
|
correct.push("mod.rs");
|
||||||
@ -138,25 +132,17 @@ impl EarlyLintPass for ModStyle {
|
|||||||
|
|
||||||
/// For each `path` we add each folder component to `folder_segments` and if the file name
|
/// For each `path` we add each folder component to `folder_segments` and if the file name
|
||||||
/// is `mod.rs` we add it's parent folder to `mod_folders`.
|
/// is `mod.rs` we add it's parent folder to `mod_folders`.
|
||||||
fn process_paths_for_mod_files(
|
fn process_paths_for_mod_files<'a>(
|
||||||
path: &Path,
|
path: &'a Path,
|
||||||
folder_segments: &mut FxHashSet<OsString>,
|
folder_segments: &mut FxHashSet<&'a OsStr>,
|
||||||
mod_folders: &mut FxHashSet<OsString>,
|
mod_folders: &mut FxHashSet<&'a OsStr>,
|
||||||
) {
|
) {
|
||||||
let mut comp = path.components().rev().peekable();
|
let mut comp = path.components().rev().peekable();
|
||||||
let _ = comp.next();
|
let _ = comp.next();
|
||||||
if path.ends_with("mod.rs") {
|
if path.ends_with("mod.rs") {
|
||||||
mod_folders.insert(comp.peek().map(|c| c.as_os_str().to_owned()).unwrap_or_default());
|
mod_folders.insert(comp.peek().map(|c| c.as_os_str()).unwrap_or_default());
|
||||||
}
|
}
|
||||||
let folders = comp
|
let folders = comp.filter_map(|c| if let Component::Normal(s) = c { Some(s) } else { None });
|
||||||
.filter_map(|c| {
|
|
||||||
if let Component::Normal(s) = c {
|
|
||||||
Some(s.to_os_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
folder_segments.extend(folders);
|
folder_segments.extend(folders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
error: `mod.rs` files are required, found `/bad/inner.rs`
|
error: `mod.rs` files are required, found `bad/inner.rs`
|
||||||
--> $DIR/bad/inner.rs:1:1
|
--> $DIR/bad/inner.rs:1:1
|
||||||
|
|
|
|
||||||
LL | pub mod stuff;
|
LL | pub mod stuff;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::self-named-module-files` implied by `-D warnings`
|
= note: `-D clippy::self-named-module-files` implied by `-D warnings`
|
||||||
= help: move `/bad/inner.rs` to `/bad/inner/mod.rs`
|
= help: move `bad/inner.rs` to `bad/inner/mod.rs`
|
||||||
|
|
||||||
error: `mod.rs` files are required, found `/bad/inner/stuff.rs`
|
error: `mod.rs` files are required, found `bad/inner/stuff.rs`
|
||||||
--> $DIR/bad/inner/stuff.rs:1:1
|
--> $DIR/bad/inner/stuff.rs:1:1
|
||||||
|
|
|
|
||||||
LL | pub mod most;
|
LL | pub mod most;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= help: move `/bad/inner/stuff.rs` to `/bad/inner/stuff/mod.rs`
|
= help: move `bad/inner/stuff.rs` to `bad/inner/stuff/mod.rs`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
error: `mod.rs` files are not allowed, found `/bad/mod.rs`
|
error: `mod.rs` files are not allowed, found `bad/mod.rs`
|
||||||
--> $DIR/bad/mod.rs:1:1
|
--> $DIR/bad/mod.rs:1:1
|
||||||
|
|
|
|
||||||
LL | pub struct Thing;
|
LL | pub struct Thing;
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
= note: `-D clippy::mod-module-files` implied by `-D warnings`
|
= note: `-D clippy::mod-module-files` implied by `-D warnings`
|
||||||
= help: move `/bad/mod.rs` to `/bad.rs`
|
= help: move `bad/mod.rs` to `bad.rs`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user