diff --git a/Cargo.lock b/Cargo.lock index e6c7da51f0..09909b60a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1267,6 +1267,7 @@ dependencies = [ "once_cell", "ra_parser", "ra_text_edit", + "rayon", "rowan", "rustc-ap-rustc_lexer", "rustc-hash", diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index cb21b8053f..57cc09854b 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -33,3 +33,4 @@ serde = { version = "1.0.106", features = ["derive"] } test_utils = { path = "../test_utils" } expect = { path = "../expect" } walkdir = "2.3.1" +rayon = "1" diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs index aa78735da6..8447dcad70 100644 --- a/crates/ra_syntax/src/tests.rs +++ b/crates/ra_syntax/src/tests.rs @@ -1,10 +1,11 @@ use std::{ fmt::Write, fs, - path::{Component, Path, PathBuf}, + path::{Path, PathBuf}, }; use expect::expect_file; +use rayon::prelude::*; use test_utils::project_dir; use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextSize, Token}; @@ -121,33 +122,43 @@ fn reparse_fuzz_tests() { /// FIXME: Use this as a benchmark #[test] fn self_hosting_parsing() { - use std::ffi::OsStr; let dir = project_dir().join("crates"); - let mut count = 0; - for entry in walkdir::WalkDir::new(dir) + let files = walkdir::WalkDir::new(dir) .into_iter() .filter_entry(|entry| { - !entry.path().components().any(|component| { - // Get all files which are not in the crates/ra_syntax/test_data folder - component == Component::Normal(OsStr::new("test_data")) - }) + // Get all files which are not in the crates/ra_syntax/test_data folder + !entry.path().components().any(|component| component.as_os_str() == "test_data") }) .map(|e| e.unwrap()) .filter(|entry| { // Get all `.rs ` files - !entry.path().is_dir() && (entry.path().extension() == Some(OsStr::new("rs"))) + !entry.path().is_dir() && (entry.path().extension().unwrap_or_default() == "rs") }) - { - count += 1; - let text = read_text(entry.path()); - if let Err(errors) = SourceFile::parse(&text).ok() { - panic!("Parsing errors:\n{:?}\n{}\n", errors, entry.path().display()); - } - } + .map(|entry| entry.into_path()) + .collect::>(); assert!( - count > 30, + files.len() > 100, "self_hosting_parsing found too few files - is it running in the right directory?" - ) + ); + + let errors = files + .into_par_iter() + .filter_map(|file| { + let text = read_text(&file); + match SourceFile::parse(&text).ok() { + Ok(_) => None, + Err(err) => Some((file, err)), + } + }) + .collect::>(); + + if !errors.is_empty() { + let errors = errors + .into_iter() + .map(|(path, err)| format!("{}: {:?}\n", path.display(), err)) + .collect::(); + panic!("Parsing errors:\n{}\n", errors); + } } fn test_data_dir() -> PathBuf {