mirror of
https://github.com/swc-project/swc.git
synced 2024-12-27 15:42:51 +03:00
Attach comments to correct node (#541)
This commit is contained in:
parent
3cf1caa4b1
commit
702800e0d9
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_common"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
|
@ -27,10 +27,18 @@ impl Comments {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn take_trailing_comments(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
||||
self.trailing.remove(&pos)
|
||||
}
|
||||
|
||||
pub fn trailing_comments(&self, pos: BytePos) -> Option<ReadGuard<'_, BytePos, Vec<Comment>>> {
|
||||
self.trailing.get(&pos)
|
||||
}
|
||||
|
||||
pub fn take_leading_comments(&self, pos: BytePos) -> Option<Vec<Comment>> {
|
||||
self.leading.remove(&pos)
|
||||
}
|
||||
|
||||
pub fn leading_comments(&self, pos: BytePos) -> Option<ReadGuard<'_, BytePos, Vec<Comment>>> {
|
||||
self.leading.get(&pos)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.11.0"
|
||||
version = "0.12.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -12,7 +12,7 @@ edition = "2018"
|
||||
bitflags = "1"
|
||||
hashbrown = "0.6"
|
||||
swc_atoms = { version = "0.2", path ="../../atoms" }
|
||||
swc_common = { version = "0.4.0", path ="../../common" }
|
||||
swc_common = { version = "0.4.4", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.13.0", path ="../ast" }
|
||||
swc_ecma_codegen_macros = { version = "0.4", path ="./macros" }
|
||||
sourcemap = "4.1.1"
|
||||
|
@ -119,7 +119,6 @@ fn emit_colors(b: &mut Bencher) {
|
||||
Some(&mut src_map_builder),
|
||||
),
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
emitter.emit_module(&module)
|
||||
|
@ -48,7 +48,7 @@ impl<'a> Emitter<'a> {
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
let cmts = comments.trailing_comments(pos);
|
||||
let cmts = comments.take_trailing_comments(pos);
|
||||
|
||||
write_comments!(self, prefix_space, &cmts)
|
||||
}
|
||||
@ -63,11 +63,6 @@ impl<'a> Emitter<'a> {
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
if self.pos_of_leading_comments.contains(&pos) {
|
||||
return Ok(());
|
||||
}
|
||||
self.pos_of_leading_comments.insert(pos);
|
||||
|
||||
write_comments!(self, false, comments.leading_comments(pos))
|
||||
write_comments!(self, false, comments.take_leading_comments(pos))
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use self::{
|
||||
text_writer::WriteJs,
|
||||
util::{SourceMapperExt, SpanExt, StartsWithAlphaNum},
|
||||
};
|
||||
use hashbrown::HashSet;
|
||||
use std::{io, sync::Arc};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{comments::Comments, BytePos, SourceMap, Span, Spanned, SyntaxContext, DUMMY_SP};
|
||||
@ -56,7 +55,6 @@ pub struct Emitter<'a> {
|
||||
pub comments: Option<&'a Comments>,
|
||||
pub wr: Box<(dyn 'a + WriteJs)>,
|
||||
pub handlers: Box<(dyn 'a + Handlers)>,
|
||||
pub pos_of_leading_comments: HashSet<BytePos>,
|
||||
}
|
||||
|
||||
impl<'a> Emitter<'a> {
|
||||
@ -1371,6 +1369,8 @@ impl<'a> Emitter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
child.emit_with(self)?;
|
||||
|
||||
// Emit this child.
|
||||
if should_emit_intervening_comments {
|
||||
let comment_range = child.comment_range();
|
||||
@ -1379,8 +1379,6 @@ impl<'a> Emitter<'a> {
|
||||
should_emit_intervening_comments = may_emit_intervening_comments;
|
||||
}
|
||||
|
||||
child.emit_with(self)?;
|
||||
|
||||
if should_decrease_indent_after_emit {
|
||||
self.wr.decrease_indent()?;
|
||||
should_decrease_indent_after_emit = false;
|
||||
@ -1684,10 +1682,8 @@ impl<'a> Emitter<'a> {
|
||||
let need_paren = if let Some(cmt) = self.comments {
|
||||
let lo = node.arg.span().lo();
|
||||
|
||||
!self.pos_of_leading_comments.contains(&lo) && {
|
||||
// see #415
|
||||
cmt.leading_comments(lo).is_some()
|
||||
}
|
||||
// see #415
|
||||
cmt.leading_comments(lo).is_some()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
@ -29,7 +29,6 @@ impl Builder {
|
||||
wr: Box::new(text_writer::JsWriter::new(self.cm.clone(), "\n", s, None)),
|
||||
comments: Some(&self.comments),
|
||||
handlers: Box::new(Noop),
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
let ret = op(&mut e);
|
||||
|
@ -7,8 +7,6 @@ c: {
|
||||
for(var b = 3; b < 4; b++){
|
||||
if (b > 5) break; // this break refers to the for, not to the switch; thus it
|
||||
|
||||
// this break refers to the for, not to the switch; thus it
|
||||
|
||||
// shouldn't ruin our optimization
|
||||
d.e(b);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
while(true){
|
||||
break; /* Multiline
|
||||
break;
|
||||
/* Multiline
|
||||
Comment */
|
||||
a;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
switch(a){
|
||||
case 1: b();
|
||||
case 1: /* perfect */
|
||||
b();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
b: while(1){
|
||||
continue; /*
*/
|
||||
continue;
|
||||
/*
*/
|
||||
a;
|
||||
}
|
||||
|
@ -2,6 +2,4 @@
|
||||
throw 'a';
|
||||
with (b); // This should be removed.
|
||||
|
||||
// This should be removed.
|
||||
|
||||
}());
|
||||
|
@ -1,3 +1,3 @@
|
||||
if (a) {
|
||||
b(); /* Some comment */
|
||||
b();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
b: while(1){
|
||||
continue; /*
*/
|
||||
continue;
|
||||
/*
*/
|
||||
a;
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
(a + b) * c;
|
||||
(a + /* assignment */
|
||||
b) * c;
|
||||
|
@ -1,4 +1,2 @@
|
||||
for(;;)continue; // should be empty statement
|
||||
|
||||
// should be empty statement
|
||||
|
||||
|
@ -1 +1 @@
|
||||
var //fooa = 1; //foo
|
||||
var a = 1//foo;
|
||||
|
@ -1,4 +1,5 @@
|
||||
({
|
||||
(/* comment */
|
||||
{
|
||||
a: null,
|
||||
b: null
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
b: while(1){
|
||||
continue; /*
|
||||
continue;
|
||||
/*
|
||||
*/
|
||||
a;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
({
|
||||
(/* comment */
|
||||
{
|
||||
a: null
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
while(true){
|
||||
continue; /* Multiline
|
||||
continue;
|
||||
/* Multiline
|
||||
Comment */
|
||||
a;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
({
|
||||
(/* comment */
|
||||
{
|
||||
/* comment 2 */
|
||||
a: null
|
||||
});
|
||||
|
@ -1 +1,2 @@
|
||||
throw a;
|
||||
throw /* */
|
||||
a;
|
||||
|
@ -22,8 +22,6 @@
|
||||
var a;
|
||||
if (b) return; // I would insert something there, but I'm sort of lazy so whatever.
|
||||
|
||||
// I would insert something there, but I'm sort of lazy so whatever.
|
||||
|
||||
a = new c();
|
||||
return a;
|
||||
})();
|
||||
|
@ -1,4 +1,3 @@
|
||||
switch(a){
|
||||
case 1: /* perfect */
|
||||
b(); /* perfect */
|
||||
case 1: b();
|
||||
}
|
||||
|
@ -1,4 +1,2 @@
|
||||
while(true)continue; // should be empty statement
|
||||
|
||||
// should be empty statement
|
||||
|
||||
|
@ -1,4 +1,2 @@
|
||||
for(var a in b)continue; // should be empty statement
|
||||
|
||||
// should be empty statement
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
b: while(1){
|
||||
continue; /*
*/
|
||||
continue;
|
||||
/*
*/
|
||||
a;
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
var /* comment */
|
||||
a;
|
||||
var a/* comment */
|
||||
;
|
||||
|
@ -1,5 +1,6 @@
|
||||
b: while(1){
|
||||
continue; /*
|
||||
continue;
|
||||
/*
|
||||
*/
|
||||
a;
|
||||
}
|
||||
|
@ -165,7 +165,6 @@ fn error_tests(tests: &mut Vec<TestDescAndFn>) -> Result<(), io::Error> {
|
||||
),
|
||||
comments: Some(&comments),
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
// Parse source
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.15.1"
|
||||
version = "0.15.2"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
|
@ -42,7 +42,10 @@ enum TokenType {
|
||||
JSXText,
|
||||
JSXTagStart,
|
||||
JSXTagEnd,
|
||||
Other { before_expr: bool },
|
||||
Other {
|
||||
before_expr: bool,
|
||||
can_have_trailing_comment: bool,
|
||||
},
|
||||
}
|
||||
impl TokenType {
|
||||
fn before_expr(self) -> bool {
|
||||
@ -57,7 +60,7 @@ impl TokenType {
|
||||
TokenType::JSXText | TokenType::Colon | TokenType::LBrace | TokenType::Semi => true,
|
||||
TokenType::BinOp(b) => b.before_expr(),
|
||||
TokenType::Keyword(k) => k.before_expr(),
|
||||
TokenType::Other { before_expr } => before_expr,
|
||||
TokenType::Other { before_expr, .. } => before_expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,6 +83,18 @@ impl<'a> From<&'a Token> for TokenType {
|
||||
Token::Word(Word::Keyword(k)) => TokenType::Keyword(k),
|
||||
_ => TokenType::Other {
|
||||
before_expr: t.before_expr(),
|
||||
can_have_trailing_comment: match *t {
|
||||
Token::Num(..)
|
||||
| Token::Str { .. }
|
||||
| Token::Word(Word::Ident(..))
|
||||
| Token::DollarLBrace
|
||||
| Token::Regex(..)
|
||||
| Token::BigInt(..)
|
||||
| Token::JSXText { .. }
|
||||
| Token::RBrace => true,
|
||||
|
||||
_ => false,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -278,9 +293,14 @@ impl State {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn last_was_return(&self) -> bool {
|
||||
pub fn can_have_trailing_comment(&self) -> bool {
|
||||
match self.token_type {
|
||||
Some(TokenType::Keyword(Keyword::Return)) => true,
|
||||
Some(TokenType::Keyword(..)) => false,
|
||||
Some(TokenType::Semi) | Some(TokenType::LBrace) => true,
|
||||
Some(TokenType::Other {
|
||||
can_have_trailing_comment,
|
||||
..
|
||||
}) => can_have_trailing_comment,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
false
|
||||
};
|
||||
|
||||
let is_for_next = self.state.had_line_break || self.state.last_was_return();
|
||||
let is_for_next = self.state.had_line_break || !self.state.can_have_trailing_comment();
|
||||
|
||||
while let Some(c) = self.cur() {
|
||||
if was_star && c == '/' {
|
||||
@ -234,13 +234,14 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
span: Span::new(start, pos, SyntaxContext::empty()),
|
||||
text: s.into(),
|
||||
};
|
||||
|
||||
let peek = self.input.peek();
|
||||
if is_for_next {
|
||||
self.leading_comments_buffer.as_mut().unwrap().push(cmt);
|
||||
} else {
|
||||
comments.add_trailing(self.state.prev_hi, cmt);
|
||||
}
|
||||
}
|
||||
// TODO: push comment
|
||||
return Ok(());
|
||||
}
|
||||
if c.is_line_break() {
|
||||
|
@ -212,7 +212,6 @@ fn exec(c: PresetConfig, dir: PathBuf) -> Result<(), Error> {
|
||||
None,
|
||||
),
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
emitter.emit_module(m).expect("failed to emit module");
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -31,7 +31,7 @@ smallvec = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { version = "0.4", path ="../../testing" }
|
||||
swc_ecma_codegen = { version = "0.11.0", path ="../codegen" }
|
||||
swc_ecma_codegen = { version = "0.12.0", path ="../codegen" }
|
||||
tempfile = "3"
|
||||
pretty_assertions = "0.6"
|
||||
sourcemap = "4.1.1"
|
@ -151,7 +151,6 @@ impl<'a> Tester<'a> {
|
||||
),
|
||||
comments: None,
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
// println!("Emitting: {:?}", module);
|
||||
|
@ -161,7 +161,6 @@ impl<'a> Tester<'a> {
|
||||
),
|
||||
comments: None,
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
// println!("Emitting: {:?}", module);
|
||||
|
@ -184,7 +184,6 @@ fn error_tests(tests: &mut Vec<TestDescAndFn>) -> Result<(), io::Error> {
|
||||
),
|
||||
comments: None,
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
let mut expected_emitter = Emitter {
|
||||
cfg: swc_ecma_codegen::Config { minify: false },
|
||||
@ -194,7 +193,6 @@ fn error_tests(tests: &mut Vec<TestDescAndFn>) -> Result<(), io::Error> {
|
||||
),
|
||||
comments: None,
|
||||
handlers: handlers2,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
// Parse source
|
||||
|
@ -161,7 +161,6 @@ impl Compiler {
|
||||
},
|
||||
),
|
||||
handlers,
|
||||
pos_of_leading_comments: Default::default(),
|
||||
};
|
||||
|
||||
emitter
|
||||
|
@ -298,3 +298,33 @@ fn env_query_chrome_71() {
|
||||
fn project_env() {
|
||||
project("tests/projects/env/");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_532() {
|
||||
let f = file("tests/projects/issue-532-block/input.js")
|
||||
.unwrap()
|
||||
.replace(" ", "");
|
||||
let f = f.trim();
|
||||
|
||||
println!("{}", f);
|
||||
|
||||
assert_eq!(
|
||||
f,
|
||||
"\
|
||||
/*pre:1*/
|
||||
test();
|
||||
test(123/*post:3*/
|
||||
);
|
||||
test(/*pre:4*/
|
||||
123);
|
||||
test(/*pre:5*/
|
||||
123/*post:6*/
|
||||
);
|
||||
test(/*pre:7*/
|
||||
123,/*pre:8*/
|
||||
456);
|
||||
test(123/*post:9*/
|
||||
,456/*post:10*/
|
||||
);"
|
||||
)
|
||||
}
|
||||
|
7
tests/projects/issue-532-block/input.js
Normal file
7
tests/projects/issue-532-block/input.js
Normal file
@ -0,0 +1,7 @@
|
||||
/*pre: 1*/
|
||||
test(/*2*/);
|
||||
test(123/*post: 3*/);
|
||||
test(/*pre: 4*/123);
|
||||
test(/*pre: 5*/123/*post: 6*/);
|
||||
test(/*pre: 7*/123,/*pre: 8*/456);
|
||||
test(123/*post: 9*/,456/*post: 10*/);
|
Loading…
Reference in New Issue
Block a user