Detect and report duplicate module names during parsing
Funny enough, we thought about that but only across packages. Now, the situation gets a little tricky because of folder structure, it's easy to define a module "foo" in `env`, `lib` and/or `validators`. From the compiler's perspective, they all have the same name.
This commit is contained in:
parent
f8be81baa5
commit
038f6ecbfd
|
@ -24,7 +24,7 @@ use zip::result::ZipError;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(thiserror::Error)]
|
#[derive(thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("I just found two modules with the same name: '{module}'")]
|
#[error("I just found two modules with the same name: '{}'", module.if_supports_color(Stderr, |s| s.yellow()))]
|
||||||
DuplicateModule {
|
DuplicateModule {
|
||||||
module: String,
|
module: String,
|
||||||
first: PathBuf,
|
first: PathBuf,
|
||||||
|
@ -353,9 +353,9 @@ impl Diagnostic for Error {
|
||||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
match self {
|
match self {
|
||||||
Error::DuplicateModule { first, second, .. } => Some(Box::new(format!(
|
Error::DuplicateModule { first, second, .. } => Some(Box::new(format!(
|
||||||
"Rename either {} or {}",
|
"Rename either of them:\n- {}\n- {}",
|
||||||
first.display(),
|
first.display().if_supports_color(Stderr, |s| s.yellow()),
|
||||||
second.display()
|
second.display().if_supports_color(Stderr, |s| s.yellow()),
|
||||||
))),
|
))),
|
||||||
Error::FileIo { error, .. } => Some(Box::new(format!("{error}"))),
|
Error::FileIo { error, .. } => Some(Box::new(format!("{error}"))),
|
||||||
Error::Blueprint(e) => e.help(),
|
Error::Blueprint(e) => e.help(),
|
||||||
|
|
|
@ -52,7 +52,7 @@ use package_name::PackageName;
|
||||||
use pallas_addresses::{Address, Network, ShelleyAddress, ShelleyDelegationPart, StakePayload};
|
use pallas_addresses::{Address, Network, ShelleyAddress, ShelleyDelegationPart, StakePayload};
|
||||||
use pallas_primitives::conway::PolicyId;
|
use pallas_primitives::conway::PolicyId;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeSet, HashMap},
|
collections::{BTreeSet, HashMap, HashSet},
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::BufReader,
|
io::BufReader,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
@ -698,12 +698,12 @@ where
|
||||||
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Vec<Error>> {
|
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Vec<Error>> {
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
let (parsed_modules, errors) = self
|
let (parsed_modules, parse_errors, duplicates) = self
|
||||||
.sources
|
.sources
|
||||||
.par_drain(0..)
|
.par_drain(0..)
|
||||||
.fold(
|
.fold(
|
||||||
|| (ParsedModules::new(), Vec::new()),
|
|| (ParsedModules::new(), Vec::new(), Vec::new()),
|
||||||
|(mut parsed_modules, mut errors), elem| {
|
|(mut parsed_modules, mut parse_errors, mut duplicates), elem| {
|
||||||
let Source {
|
let Source {
|
||||||
path,
|
path,
|
||||||
name,
|
name,
|
||||||
|
@ -720,19 +720,24 @@ where
|
||||||
kind,
|
kind,
|
||||||
ast,
|
ast,
|
||||||
code,
|
code,
|
||||||
name,
|
name: name.clone(),
|
||||||
path,
|
path,
|
||||||
extra,
|
extra,
|
||||||
package: package_name.to_string(),
|
package: package_name.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
parsed_modules.insert(module.name.clone(), module);
|
let path = module.path.clone();
|
||||||
|
|
||||||
(parsed_modules, errors)
|
if let Some(first) = parsed_modules.insert(module.name.clone(), module)
|
||||||
|
{
|
||||||
|
duplicates.push((name, first.path.clone(), path))
|
||||||
|
}
|
||||||
|
|
||||||
|
(parsed_modules, parse_errors, duplicates)
|
||||||
}
|
}
|
||||||
Err(errs) => {
|
Err(errs) => {
|
||||||
for error in errs {
|
for error in errs {
|
||||||
errors.push((
|
parse_errors.push((
|
||||||
path.clone(),
|
path.clone(),
|
||||||
code.clone(),
|
code.clone(),
|
||||||
NamedSource::new(path.display().to_string(), code.clone()),
|
NamedSource::new(path.display().to_string(), code.clone()),
|
||||||
|
@ -740,23 +745,53 @@ where
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
(parsed_modules, errors)
|
(parsed_modules, parse_errors, duplicates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (ParsedModules::new(), Vec::new()),
|
|| (ParsedModules::new(), Vec::new(), Vec::new()),
|
||||||
|(mut parsed_modules, mut errors), (mut parsed, mut errs)| {
|
|(mut parsed_modules, mut parse_errors, mut duplicates),
|
||||||
|
(mut parsed, mut errs, mut dups)| {
|
||||||
|
let keys_left = parsed_modules.keys().collect::<HashSet<_>>();
|
||||||
|
let keys_right = parsed.keys().collect::<HashSet<_>>();
|
||||||
|
|
||||||
|
for module in keys_left.intersection(&keys_right) {
|
||||||
|
duplicates.push((
|
||||||
|
module.to_string(),
|
||||||
|
parsed_modules
|
||||||
|
.get(module.as_str())
|
||||||
|
.map(|m| m.path.clone())
|
||||||
|
.unwrap(),
|
||||||
|
parsed.get(module.as_str()).map(|m| m.path.clone()).unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
parsed_modules.extend(parsed.drain());
|
parsed_modules.extend(parsed.drain());
|
||||||
|
|
||||||
errors.append(&mut errs);
|
parse_errors.append(&mut errs);
|
||||||
|
duplicates.append(&mut dups);
|
||||||
|
|
||||||
(parsed_modules, errors)
|
(parsed_modules, parse_errors, duplicates)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut errors: Vec<Error> = errors
|
let mut errors: Vec<Error> = Vec::new();
|
||||||
|
|
||||||
|
errors.extend(
|
||||||
|
duplicates
|
||||||
|
.into_iter()
|
||||||
|
.map(|(module, first, second)| Error::DuplicateModule {
|
||||||
|
module,
|
||||||
|
first,
|
||||||
|
second,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
errors.extend(
|
||||||
|
parse_errors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, src, named, error)| Error::Parse {
|
.map(|(path, src, named, error)| Error::Parse {
|
||||||
path,
|
path,
|
||||||
|
@ -764,7 +799,8 @@ where
|
||||||
named: named.into(),
|
named: named.into(),
|
||||||
error,
|
error,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect::<Vec<_>>(),
|
||||||
|
);
|
||||||
|
|
||||||
for parsed_module in parsed_modules.values() {
|
for parsed_module in parsed_modules.values() {
|
||||||
if let Some(first) = self
|
if let Some(first) = self
|
||||||
|
|
Loading…
Reference in New Issue