2020-08-14 12:20:25 +03:00
|
|
|
#![feature(test)]
|
2021-08-13 12:39:13 +03:00
|
|
|
#![feature(bench_black_box)]
|
2020-08-14 12:20:25 +03:00
|
|
|
|
|
|
|
extern crate test;
|
|
|
|
|
|
|
|
use anyhow::Error;
|
|
|
|
use dashmap::DashMap;
|
|
|
|
use std::{env, path::PathBuf};
|
|
|
|
use swc_common::{
|
|
|
|
comments::{Comment, CommentKind, Comments},
|
2021-07-13 18:59:13 +03:00
|
|
|
BytePos, DUMMY_SP,
|
2020-08-14 12:20:25 +03:00
|
|
|
};
|
|
|
|
use swc_ecma_parser::{lexer::Lexer, EsConfig, Parser, StringInput, Syntax};
|
|
|
|
use test::{test_main, DynTestFn, ShouldPanic::No, TestDesc, TestDescAndFn, TestName, TestType};
|
|
|
|
use testing::NormalizedOutput;
|
|
|
|
use walkdir::WalkDir;
|
|
|
|
|
|
|
|
fn add_test<F: FnOnce() + Send + 'static>(
|
|
|
|
tests: &mut Vec<TestDescAndFn>,
|
|
|
|
name: String,
|
|
|
|
ignore: bool,
|
|
|
|
f: F,
|
|
|
|
) {
|
|
|
|
tests.push(TestDescAndFn {
|
|
|
|
desc: TestDesc {
|
|
|
|
test_type: TestType::UnitTest,
|
|
|
|
name: TestName::DynTestName(name),
|
|
|
|
ignore,
|
|
|
|
should_panic: No,
|
|
|
|
allow_fail: false,
|
2021-08-13 12:39:13 +03:00
|
|
|
compile_fail: false,
|
|
|
|
no_run: false,
|
2020-08-14 12:20:25 +03:00
|
|
|
},
|
|
|
|
testfn: DynTestFn(Box::new(f)),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn fixture() {
|
|
|
|
let args: Vec<_> = env::args().collect();
|
|
|
|
let mut tests = Vec::new();
|
|
|
|
add_fixture(&mut tests).unwrap();
|
|
|
|
test_main(&args, tests, Some(test::Options::new()));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_fixture(tests: &mut Vec<TestDescAndFn>) -> Result<(), Error> {
|
|
|
|
for entry in WalkDir::new(
|
|
|
|
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
|
|
|
|
.join("tests")
|
|
|
|
.join("fixtures"),
|
|
|
|
) {
|
|
|
|
let entry = entry.expect("WalkDir failed");
|
|
|
|
if entry.file_type().is_dir() {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if entry.path().to_string_lossy().ends_with(".js") {
|
|
|
|
add_test(
|
|
|
|
tests,
|
|
|
|
format!("jsdoc::fixture::{}", entry.path().display()),
|
|
|
|
false,
|
|
|
|
move || {
|
|
|
|
testing::run_test2(false, |cm, handler| {
|
|
|
|
let comments = SwcComments::default();
|
|
|
|
|
|
|
|
let fm = cm
|
|
|
|
.load_file(entry.path())
|
2021-02-22 18:33:11 +03:00
|
|
|
.expect("failed to load fixture file");
|
2020-08-14 12:20:25 +03:00
|
|
|
|
|
|
|
let lexer = Lexer::new(
|
|
|
|
Syntax::Es(EsConfig {
|
|
|
|
jsx: true,
|
|
|
|
..Default::default()
|
|
|
|
}),
|
|
|
|
Default::default(),
|
|
|
|
StringInput::from(&*fm),
|
|
|
|
Some(&comments),
|
|
|
|
);
|
|
|
|
let mut p = Parser::new_from(lexer);
|
|
|
|
|
|
|
|
match p.parse_module() {
|
|
|
|
Err(err) => {
|
|
|
|
err.into_diagnostic(&handler).emit();
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
for err in p.take_errors() {
|
|
|
|
err.into_diagnostic(&handler).emit();
|
|
|
|
}
|
|
|
|
if handler.has_errors() {
|
|
|
|
return Err(());
|
|
|
|
}
|
|
|
|
let mut res = vec![];
|
|
|
|
let mut comments: Vec<_> = comments.leading.into_iter().collect();
|
|
|
|
comments.sort_by_key(|v| v.0);
|
|
|
|
|
|
|
|
for (_, comments) in comments {
|
|
|
|
for cmt in &comments {
|
|
|
|
if cmt.kind == CommentKind::Line {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !cmt.text.starts_with("*") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
println!(
|
|
|
|
"==================== {} ====================\n{}",
|
|
|
|
entry.path().display(),
|
|
|
|
cmt.text
|
|
|
|
);
|
|
|
|
let (_, parsed) = jsdoc::parse(cmt.into()).unwrap();
|
|
|
|
res.push(parsed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let s = NormalizedOutput::from(format!("{:#?}", res));
|
|
|
|
s.compare_to_file(entry.path().with_extension("debug"))
|
|
|
|
.unwrap();
|
|
|
|
Ok(())
|
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
type CommentMap = DashMap<BytePos, Vec<Comment>>;
|
|
|
|
|
|
|
|
/// Multi-threaded implementation of [Comments]
|
|
|
|
#[derive(Clone, Default)]
|
|
|
|
pub struct SwcComments {
|
|
|
|
leading: CommentMap,
|
|
|
|
trailing: CommentMap,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Comments for SwcComments {
|
|
|
|
fn add_leading(&self, pos: BytePos, cmt: Comment) {
|
|
|
|
self.leading.entry(pos).or_default().push(cmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_leading_comments(&self, pos: BytePos, comments: Vec<Comment>) {
|
|
|
|
self.leading.entry(pos).or_default().extend(comments);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn has_leading(&self, pos: BytePos) -> bool {
|
|
|
|
self.leading.contains_key(&pos)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn move_leading(&self, from: BytePos, to: BytePos) {
|
|
|
|
let cmt = self.leading.remove(&from);
|
|
|
|
|
|
|
|
if let Some(cmt) = cmt {
|
|
|
|
self.leading.entry(to).or_default().extend(cmt.1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn take_leading(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
|
|
|
self.leading.remove(&pos).map(|v| v.1)
|
|
|
|
}
|
|
|
|
|
2021-07-13 18:59:13 +03:00
|
|
|
fn get_leading(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
|
|
|
self.leading.get(&pos).map(|v| v.to_owned())
|
|
|
|
}
|
|
|
|
|
2020-08-14 12:20:25 +03:00
|
|
|
fn add_trailing(&self, pos: BytePos, cmt: Comment) {
|
|
|
|
self.trailing.entry(pos).or_default().push(cmt)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_trailing_comments(&self, pos: BytePos, comments: Vec<Comment>) {
|
|
|
|
self.trailing.entry(pos).or_default().extend(comments)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn has_trailing(&self, pos: BytePos) -> bool {
|
|
|
|
self.trailing.contains_key(&pos)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn move_trailing(&self, from: BytePos, to: BytePos) {
|
|
|
|
let cmt = self.trailing.remove(&from);
|
|
|
|
|
|
|
|
if let Some(cmt) = cmt {
|
|
|
|
self.trailing.entry(to).or_default().extend(cmt.1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn take_trailing(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
|
|
|
self.trailing.remove(&pos).map(|v| v.1)
|
|
|
|
}
|
2021-07-13 18:59:13 +03:00
|
|
|
|
|
|
|
fn get_trailing(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
|
|
|
self.trailing.get(&pos).map(|v| v.to_owned())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn add_pure_comment(&self, pos: BytePos) {
|
|
|
|
let mut leading = self.leading.entry(pos).or_default();
|
|
|
|
let pure_comment = Comment {
|
|
|
|
kind: CommentKind::Block,
|
|
|
|
span: DUMMY_SP,
|
|
|
|
text: "#__PURE__".into(),
|
|
|
|
};
|
|
|
|
|
|
|
|
if !leading.iter().any(|c| c.text == pure_comment.text) {
|
|
|
|
leading.push(pure_comment);
|
|
|
|
}
|
|
|
|
}
|
2020-08-14 12:20:25 +03:00
|
|
|
}
|