diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index b04645054..0046d10ad 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -62,15 +62,18 @@ impl<'a> Parser<'a> { if expecting_diretives { if let Statement::ExpressionStatement(expr) = &stmt { if let Expression::StringLiteral(string) = &expr.expression { - let src = &self.source_text - [string.span.start as usize + 1..string.span.end as usize - 1]; - let directive = self.ast.directive( - expr.span, - (*string).clone(), - Atom::from(src), - ); - directives.push(directive); - continue; + // span start will mismatch if they are parenthesized when `preserve_parens = false` + if expr.span.start == string.span.start { + let src = &self.source_text[string.span.start as usize + 1 + ..string.span.end as usize - 1]; + let directive = self.ast.directive( + expr.span, + (*string).clone(), + Atom::from(src), + ); + directives.push(directive); + continue; + } } } expecting_diretives = false; diff --git a/crates/oxc_prettier/src/format/block.rs b/crates/oxc_prettier/src/format/block.rs index e6533333c..49af5fb27 100644 --- a/crates/oxc_prettier/src/format/block.rs +++ b/crates/oxc_prettier/src/format/block.rs @@ -1,4 +1,3 @@ -use oxc_allocator::Vec; use oxc_ast::{ast::*, AstKind}; use crate::{doc::Doc, hardline, indent, ss, Prettier}; @@ -7,8 +6,8 @@ use super::statement; pub(super) fn print_block<'a>( p: &mut Prettier<'a>, - stmts: &Vec<'a, Statement<'a>>, - directives: Option<&Vec<'a, Directive>>, + stmts: &[Statement<'a>], + directives: Option<&[Directive]>, ) -> Doc<'a> { let mut parts = p.vec(); parts.push(ss!("{")); @@ -38,10 +37,10 @@ pub(super) fn print_block<'a>( pub(super) fn print_block_body<'a>( p: &mut Prettier<'a>, - stmts: &Vec<'a, Statement<'a>>, - directives: Option<&Vec<'a, Directive>>, + stmts: &[Statement<'a>], + directives: Option<&[Directive]>, remove_last_statement_hardline: bool, - is_program: bool, + is_root: bool, ) -> Option> { let has_directives = directives.is_some_and(|directives| !directives.is_empty()); let has_body = stmts.iter().any(|stmt| !matches!(stmt, Statement::EmptyStatement(_))); @@ -62,7 +61,7 @@ pub(super) fn print_block_body<'a>( parts.extend(statement::print_statement_sequence(p, stmts, remove_last_statement_hardline)); } - if is_program { + if is_root { parts.push(hardline!()); } diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index 6c3d70327..737a2ef78 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -64,9 +64,13 @@ impl<'a> Format<'a> for Program<'a> { parts.push(hardline!()); } } - if let Some(doc) = - block::print_block_body(p, &self.body, Some(&self.directives), false, true) - { + if let Some(doc) = block::print_block_body( + p, + &self.body, + Some(&self.directives), + false, + /* is_root */ true, + ) { parts.push(doc); } p.leave_node(); @@ -82,7 +86,15 @@ impl<'a> Format<'a> for Hashbang { impl<'a> Format<'a> for Directive { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - Doc::Line + let mut parts = p.vec(); + parts.push( + p.str(&string::print_string(self.expression.value.as_str(), p.options.single_quote)), + ); + if p.options.semi { + parts.push(ss!(";")); + } + parts.push(hardline!()); + Doc::Array(parts) } } diff --git a/crates/oxc_prettier/src/format/statement.rs b/crates/oxc_prettier/src/format/statement.rs index 18fd502ae..67f92f97a 100644 --- a/crates/oxc_prettier/src/format/statement.rs +++ b/crates/oxc_prettier/src/format/statement.rs @@ -10,7 +10,7 @@ use super::Format; pub(super) fn print_statement_sequence<'a, F: Format<'a> + GetSpan>( p: &mut Prettier<'a>, - stmts: &Vec<'a, F>, + stmts: &[F], remove_last_statement_hardline: bool, ) -> Vec<'a, Doc<'a>> { let mut parts = p.vec(); diff --git a/tasks/prettier_conformance/prettier.snap.md b/tasks/prettier_conformance/prettier.snap.md index ebfe49450..e749b7137 100644 --- a/tasks/prettier_conformance/prettier.snap.md +++ b/tasks/prettier_conformance/prettier.snap.md @@ -1,4 +1,4 @@ -Compatibility: 139/597 (23.28%) +Compatibility: 140/597 (23.45%) # Failed @@ -289,7 +289,6 @@ Compatibility: 139/597 (23.28%) * directives/last-line-1.js * directives/last-line-2.js * directives/newline.js -* directives/no-newline.js * directives/test.js ### empty-paren-comment