2021-08-13 12:39:13 +03:00
|
|
|
#![feature(bench_black_box)]
|
2020-08-14 12:20:25 +03:00
|
|
|
|
|
|
|
use dashmap::DashMap;
|
2021-08-14 09:34:04 +03:00
|
|
|
use std::path::PathBuf;
|
2020-08-14 12:20:25 +03:00
|
|
|
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 testing::NormalizedOutput;
|
|
|
|
|
2021-08-14 09:34:04 +03:00
|
|
|
#[testing::fixture("tests/fixtures/**/*.js")]
|
|
|
|
fn fixture(path: PathBuf) {
|
|
|
|
testing::run_test2(false, |cm, handler| {
|
|
|
|
let comments = SwcComments::default();
|
|
|
|
|
|
|
|
let fm = cm.load_file(&path).expect("failed to load fixture file");
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
_ => {}
|
2020-08-14 12:20:25 +03:00
|
|
|
}
|
2021-08-14 09:34:04 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-01-13 17:06:11 +03:00
|
|
|
if !cmt.text.starts_with('*') {
|
2021-08-14 09:34:04 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
println!(
|
|
|
|
"==================== {} ====================\n{}",
|
|
|
|
path.display(),
|
|
|
|
cmt.text
|
|
|
|
);
|
|
|
|
let (_, parsed) = jsdoc::parse(cmt.into()).unwrap();
|
|
|
|
res.push(parsed);
|
|
|
|
}
|
2020-08-14 12:20:25 +03:00
|
|
|
}
|
|
|
|
|
2021-08-14 09:34:04 +03:00
|
|
|
let s = NormalizedOutput::from(format!("{:#?}", res));
|
|
|
|
s.compare_to_file(path.with_extension("debug")).unwrap();
|
|
|
|
Ok(())
|
|
|
|
})
|
|
|
|
.unwrap();
|
2020-08-14 12:20:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|