Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion src/generation/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ fn gen_node_with_inner_gen<'a>(node: Node<'a>, context: &mut Context<'a>, inner_
Node::VarDecl(node) => gen_var_decl(node, context),
Node::VarDeclarator(node) => gen_var_declarator(node, context),
Node::WhileStmt(node) => gen_while_stmt(node, context),
Node::WithStmt(node) => gen_with_stmt(node, context),
/* types */
Node::TsArrayType(node) => gen_array_type(node, context),
Node::TsConditionalType(node) => gen_conditional_type(node, context),
Expand Down Expand Up @@ -348,7 +349,7 @@ fn gen_node_with_inner_gen<'a>(node: Node<'a>, context: &mut Context<'a>, inner_
Node::TsTypeRef(node) => gen_type_reference(node, context),
Node::TsUnionType(node) => gen_union_type(node, context),
/* These should never be matched. Return its text if so */
Node::Class(_) | Node::Function(_) | Node::Invalid(_) | Node::WithStmt(_) | Node::TsModuleBlock(_) => {
Node::Class(_) | Node::Function(_) | Node::Invalid(_) | Node::TsModuleBlock(_) => {
if cfg!(debug_assertions) {
panic!("Debug panic! Did not expect to generate IR for node of type {}.", node.kind());
}
Expand Down Expand Up @@ -5678,6 +5679,49 @@ fn gen_while_stmt<'a>(node: &WhileStmt<'a>, context: &mut Context<'a>) -> PrintI
items
}

fn gen_with_stmt<'a>(node: &WithStmt<'a>, context: &mut Context<'a>) -> PrintItems {
// `with` statements are deprecated and forbidden in strict mode, but still valid
// syntax. Reuse the while statement configuration since the shapes are identical
// (keyword, parenthesized expression, body statement).
let start_header_ln = LineNumber::new("startHeader");
let start_header_lsil = LineStartIndentLevel::new("startHeader");
let end_header_ln = LineNumber::new("endHeader");
let mut items = PrintItems::new();
items.push_info(start_header_ln);
items.push_info(start_header_lsil);
items.push_sc(sc!("with"));
if context.config.while_statement_space_after_while_keyword {
items.push_space();
}
items.extend(gen_node_in_parens(
|context| gen_node(node.obj.into(), context),
GenNodeInParensOptions {
inner_range: node.obj.range(),
prefer_hanging: context.config.while_statement_prefer_hanging,
allow_open_paren_trailing_comments: false,
single_line_space_around: context.config.while_statement_space_around,
},
context,
));
items.push_info(end_header_ln);
items.extend(
gen_conditional_brace_body(
GenConditionalBraceBodyOptions {
body_node: node.body.into(),
use_braces: context.config.while_statement_use_braces,
brace_position: context.config.while_statement_brace_position,
single_body_position: Some(context.config.while_statement_single_body_position),
requires_braces_condition_ref: None,
start_header_info: Some((start_header_ln, start_header_lsil)),
end_header_info: Some(end_header_ln),
},
context,
)
.generated_node,
);
items
}

/* types */

fn gen_array_type<'a>(node: &TsArrayType<'a>, context: &mut Context<'a>) -> PrintItems {
Expand Down
184 changes: 184 additions & 0 deletions tests/specs/statements/withStatement/WithStatement_All.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
~~ lineWidth: 40 ~~
== should print ==
with (obj) {
a;
b;
}

[expect]
with (obj) {
a;
b;
}

== should print multi-line ==
with (thisIsA && veryLongHeader && that) {
a;
b;
}

[expect]
with (
thisIsA && veryLongHeader && that
) {
a;
b;
}

== should print multi-line when exceeding width twice ==
with (thisIsA && veryLongHeader && thatWillExceedTwice) {
a;
b;
}

[expect]
with (
thisIsA && veryLongHeader
&& thatWillExceedTwice
) {
a;
b;
}

== should use multiple lines if open paren is on a different line than condition ==
with (
true) {
}

[expect]
with (
true
) {
}

== should print empty with statement on same line when on same line ==
with (obj) {}

[expect]
with (obj) {}

== should print empty with statement on different line when close brace on different line ==
with (obj) {
}

[expect]
with (obj) {
}

== should handle empty with comments ==
with (true) { /* 1 */ }
with (true) {
/* test */}
with (true) { // 1
//2
/* 3*/}

[expect]
with (true) { /* 1 */ }
with (true) {
/* test */
}
with (true) { // 1
// 2
/* 3*/
}

== should handle block comment on first line with statement ==
with (true) { /* 1 */
s;}
with (true) { /* 1 */ s; /* 2 */}

[expect]
with (true) {
/* 1 */
s;
}
with (true) /* 1 */ s; /* 2 */

== should print when only has an empty statement ==
with (true);

[expect]
with (true);

== should print when only has an empty statement on next line ==
with (true)
;

[expect]
with (true);

== should support comments in header ==
with (
// testing
test
) {
a;
}

[expect]
with (
// testing
test
) {
a;
}

== should move trailing header comment to next line ==
with (// testing
test
) {
a;
}

[expect]
with (
// testing
test
) {
a;
}

== should remain stable with trailing line comment after open brace (issue #787) ==
with (a) { //
}

[expect]
with (a) { //
}

== should remain stable with non-block body and trailing line comment ==
with (a) 1; //

[expect]
with (a) 1; //

== should normalize spacing ==
with(a){//
}

[expect]
with (a) { //
}

== should handle interior comments ==
with (a) {
// inner
b;
// tail
}

[expect]
with (a) {
// inner
b;
// tail
}

== should handle prettier with/indent.js cases ==
with (0) {}
with (0) 1;

[expect]
with (0) {}
with (0) 1;
Loading