Skip to content

Commit

Permalink
fix(parser): hashbang comment should not keep the end newline char (#…
Browse files Browse the repository at this point in the history
…5844)

Previously it included a newline in the value

```
  "hashbang": {
    "type": "Hashbang",
    "start": 0,
    "end": 16,
    "value": "/usr/bin/node\n"
  },
```

This change will also make the lexer emit a `\n` token, which will make comment position detection correct.
  • Loading branch information
Boshen committed Sep 18, 2024
1 parent 65a1734 commit 42dcadf
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl<'a> Gen for Hashbang<'a> {
fn gen(&self, p: &mut Codegen, _ctx: Context) {
p.print_str("#!");
p.print_str(self.value.as_str());
p.print_hard_newline();
}
}

Expand Down
5 changes: 5 additions & 0 deletions crates/oxc_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ impl<'a> Codegen<'a> {
}
}

#[inline]
fn print_hard_newline(&mut self) {
self.print_char(b'\n');
}

#[inline]
fn print_semicolon(&mut self) {
self.print_char(b';');
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_parser/src/lexer/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,11 @@ impl<'a> Lexer<'a> {

/// Section 12.5 Hashbang Comments
pub(super) fn read_hashbang_comment(&mut self) -> Kind {
while let Some(c) = self.next_char().as_ref() {
while let Some(c) = self.peek_char().as_ref() {
if is_line_terminator(*c) {
break;
}
self.consume_char();
}
self.token.is_on_new_line = true;
Kind::HashbangComment
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_parser/src/lexer/trivia_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ token
kind: CommentKind::Block,
position: CommentPosition::Leading,
attached_to: 36,
preceded_by_newline: false, // hashbang comment always end in newline
preceded_by_newline: true,
followed_by_newline: true,
}];
assert_eq!(comments, expected);
Expand Down
9 changes: 9 additions & 0 deletions crates/oxc_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,15 @@ mod test {
}
}

#[test]
fn hashbang() {
let allocator = Allocator::default();
let source_type = SourceType::default();
let source = "#!/usr/bin/node\n;";
let ret = Parser::new(&allocator, source, source_type).parse();
assert_eq!(ret.program.hashbang.unwrap().value.as_str(), "/usr/bin/node");
}

#[test]
fn unambiguous() {
let allocator = Allocator::default();
Expand Down
17 changes: 11 additions & 6 deletions crates/oxc_prettier/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use cow_utils::CowUtils;
use oxc_allocator::{Box, Vec};
use oxc_ast::{ast::*, AstKind};
use oxc_span::GetSpan;
use oxc_syntax::identifier::is_identifier_name;
use oxc_syntax::identifier::{is_identifier_name, is_line_terminator};

use self::{array::Array, object::ObjectLike, template_literal::TemplateLiteralPrinter};
use crate::{
Expand Down Expand Up @@ -60,10 +60,6 @@ impl<'a> Format<'a> for Program<'a> {
let mut parts = p.vec();
if let Some(hashbang) = &self.hashbang {
parts.push(hashbang.format(p));
let c = p.source_text[..hashbang.span.end as usize].chars().last().unwrap();
if p.is_next_line_empty_after_index(hashbang.span.end - c.len_utf8() as u32) {
parts.extend(hardline!());
}
}
if let Some(doc) = block::print_block_body(
p,
Expand All @@ -81,7 +77,16 @@ impl<'a> Format<'a> for Program<'a> {

impl<'a> Format<'a> for Hashbang<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
Doc::Str(self.span.source_text(p.source_text))
let mut parts = p.vec();
parts.push(ss!(self.span.source_text(p.source_text)));
parts.extend(hardline!());
// Preserve original newline
if let Some(c) = p.source_text[self.span.end as usize..].chars().nth(1) {
if is_line_terminator(c) {
parts.extend(hardline!());
}
}
Doc::Array(parts)
}
}

Expand Down

0 comments on commit 42dcadf

Please sign in to comment.