mirror of
https://gitee.com/openharmony/third_party_rust_syn
synced 2024-11-27 18:01:03 +00:00
153 lines
5.1 KiB
Rust
153 lines
5.1 KiB
Rust
#![cfg(not(syn_disable_nightly_tests))]
|
|
#![recursion_limit = "1024"]
|
|
#![feature(rustc_private)]
|
|
|
|
extern crate rustc_ast;
|
|
extern crate rustc_errors;
|
|
extern crate rustc_expand;
|
|
extern crate rustc_parse as parse;
|
|
extern crate rustc_session;
|
|
extern crate rustc_span;
|
|
|
|
use quote::quote;
|
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
|
use rustc_ast::ast;
|
|
use rustc_errors::PResult;
|
|
use rustc_session::parse::ParseSess;
|
|
use rustc_span::source_map::FilePathMapping;
|
|
use rustc_span::FileName;
|
|
use walkdir::{DirEntry, WalkDir};
|
|
|
|
use std::fs::File;
|
|
use std::io::Read;
|
|
use std::panic;
|
|
use std::process;
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
use std::time::Instant;
|
|
|
|
#[macro_use]
|
|
mod macros;
|
|
|
|
#[allow(dead_code)]
|
|
mod common;
|
|
|
|
mod repo;
|
|
|
|
use common::eq::SpanlessEq;
|
|
|
|
#[test]
|
|
fn test_round_trip() {
|
|
common::rayon_init();
|
|
repo::clone_rust();
|
|
let abort_after = common::abort_after();
|
|
if abort_after == 0 {
|
|
panic!("Skipping all round_trip tests");
|
|
}
|
|
|
|
let failed = AtomicUsize::new(0);
|
|
|
|
WalkDir::new("tests/rust")
|
|
.sort_by(|a, b| a.file_name().cmp(b.file_name()))
|
|
.into_iter()
|
|
.filter_entry(repo::base_dir_filter)
|
|
.collect::<Result<Vec<DirEntry>, walkdir::Error>>()
|
|
.unwrap()
|
|
.into_par_iter()
|
|
.for_each(|entry| {
|
|
let path = entry.path();
|
|
if path.is_dir() {
|
|
return;
|
|
}
|
|
|
|
let mut file = File::open(path).unwrap();
|
|
let mut content = String::new();
|
|
file.read_to_string(&mut content).unwrap();
|
|
|
|
let start = Instant::now();
|
|
let (krate, elapsed) = match syn::parse_file(&content) {
|
|
Ok(krate) => (krate, start.elapsed()),
|
|
Err(msg) => {
|
|
errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
|
|
let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
|
|
if prev_failed + 1 >= abort_after {
|
|
process::exit(1);
|
|
}
|
|
return;
|
|
}
|
|
};
|
|
let back = quote!(#krate).to_string();
|
|
let edition = repo::edition(path).parse().unwrap();
|
|
|
|
let equal = panic::catch_unwind(|| {
|
|
rustc_ast::with_globals(edition, || {
|
|
let sess = ParseSess::new(FilePathMapping::empty());
|
|
let before = match librustc_parse(content, &sess) {
|
|
Ok(before) => before,
|
|
Err(mut diagnostic) => {
|
|
diagnostic.cancel();
|
|
if diagnostic
|
|
.message()
|
|
.starts_with("file not found for module")
|
|
{
|
|
errorf!("=== {}: ignore\n", path.display());
|
|
} else {
|
|
errorf!(
|
|
"=== {}: ignore - librustc failed to parse original content: {}\n",
|
|
path.display(),
|
|
diagnostic.message()
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
let after = match librustc_parse(back, &sess) {
|
|
Ok(after) => after,
|
|
Err(mut diagnostic) => {
|
|
errorf!("=== {}: librustc failed to parse", path.display());
|
|
diagnostic.emit();
|
|
return false;
|
|
}
|
|
};
|
|
|
|
if SpanlessEq::eq(&before, &after) {
|
|
errorf!(
|
|
"=== {}: pass in {}ms\n",
|
|
path.display(),
|
|
elapsed.as_secs() * 1000
|
|
+ u64::from(elapsed.subsec_nanos()) / 1_000_000
|
|
);
|
|
true
|
|
} else {
|
|
errorf!(
|
|
"=== {}: FAIL\nbefore: {:#?}\nafter: {:#?}\n",
|
|
path.display(),
|
|
before,
|
|
after,
|
|
);
|
|
false
|
|
}
|
|
})
|
|
});
|
|
match equal {
|
|
Err(_) => errorf!("=== {}: ignoring librustc panic\n", path.display()),
|
|
Ok(true) => {}
|
|
Ok(false) => {
|
|
let prev_failed = failed.fetch_add(1, Ordering::SeqCst);
|
|
if prev_failed + 1 >= abort_after {
|
|
process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
let failed = failed.load(Ordering::SeqCst);
|
|
if failed > 0 {
|
|
panic!("{} failures", failed);
|
|
}
|
|
}
|
|
|
|
fn librustc_parse(content: String, sess: &ParseSess) -> PResult<ast::Crate> {
|
|
let name = FileName::Custom("test_round_trip".to_string());
|
|
parse::parse_crate_from_source_str(name, content, sess)
|
|
}
|