feat(parse): run in parallel

This commit is contained in:
rvcas 2024-03-06 17:05:07 -05:00 committed by Lucas
parent 9c5556aa1e
commit f8377af0c8
2 changed files with 85 additions and 44 deletions

View File

@ -564,60 +564,91 @@ 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>> {
let mut errors = Vec::new(); use rayon::prelude::*;
let mut parsed_modules = HashMap::with_capacity(self.sources.len());
for Source { let (parsed_modules, errors) = self
path, .sources
name, .par_drain(0..)
code, .fold(
kind, || (ParsedModules::new(), Vec::new()),
} in self.sources.drain(0..) |(mut parsed_modules, mut errors), elem| {
{ let Source {
match aiken_lang::parser::module(&code, kind) {
Ok((mut ast, extra)) => {
// Store the name
ast.name = name.clone();
let module = ParsedModule {
kind,
ast,
code,
name,
path, path,
extra, name,
package: package_name.to_string(), code,
}; kind,
} = elem;
if let Some(first) = self match aiken_lang::parser::module(&code, kind) {
.defined_modules Ok((mut ast, extra)) => {
.insert(module.name.clone(), module.path.clone()) // Store the name
{ ast.name = name.clone();
return Err(Error::DuplicateModule {
module: module.name.clone(), let module = ParsedModule {
first, kind,
second: module.path, ast,
code,
name,
path,
extra,
package: package_name.to_string(),
};
parsed_modules.insert(module.name.clone(), module);
(parsed_modules, errors)
} }
.into()); Err(errs) => {
} for error in errs {
errors.push((
path.clone(),
code.clone(),
NamedSource::new(path.display().to_string(), code.clone()),
Box::new(error),
))
}
parsed_modules.insert(module.name.clone(), module); (parsed_modules, errors)
} }
Err(errs) => {
for error in errs {
errors.push(Error::Parse {
path: path.clone(),
src: code.clone(),
named: NamedSource::new(path.display().to_string(), code.clone()),
error: Box::new(error),
})
} }
} },
)
.reduce(
|| (ParsedModules::new(), Vec::new()),
|(mut parsed_modules, mut errors), (mut parsed, errs)| {
parsed_modules.extend(parsed.drain());
errors.extend(errs);
(parsed_modules, errors)
},
);
let mut errors: Vec<Error> = errors
.into_iter()
.map(|(path, src, named, error)| Error::Parse {
path,
src,
named,
error,
})
.collect();
for parsed_module in parsed_modules.values() {
if let Some(first) = self
.defined_modules
.insert(parsed_module.name.clone(), parsed_module.path.clone())
{
errors.push(Error::DuplicateModule {
module: parsed_module.name.clone(),
first,
second: parsed_module.path.clone(),
});
} }
} }
if errors.is_empty() { if errors.is_empty() {
Ok(parsed_modules.into()) Ok(parsed_modules)
} else { } else {
Err(errors) Err(errors)
} }

View File

@ -42,6 +42,10 @@ impl ParsedModule {
pub struct ParsedModules(HashMap<String, ParsedModule>); pub struct ParsedModules(HashMap<String, ParsedModule>);
impl ParsedModules { impl ParsedModules {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn sequence(&self) -> Result<Vec<String>, Error> { pub fn sequence(&self) -> Result<Vec<String>, Error> {
let inputs = self let inputs = self
.0 .0
@ -103,6 +107,12 @@ impl ParsedModules {
} }
} }
impl Default for ParsedModules {
fn default() -> Self {
Self::new()
}
}
impl From<HashMap<String, ParsedModule>> for ParsedModules { impl From<HashMap<String, ParsedModule>> for ParsedModules {
fn from(parsed_modules: HashMap<String, ParsedModule>) -> Self { fn from(parsed_modules: HashMap<String, ParsedModule>) -> Self {
ParsedModules(parsed_modules) ParsedModules(parsed_modules)