use super::expressions::write_expression;
use super::statements::{write_block_statement, write_statement, write_variable_declaration};
use super::{
Ctx, JsonWriter, close_node, node_header, write_array, write_identifier_plain, write_or_null,
};
use crate::ast;
use tsv_lang::Span;
pub(super) fn write_if_statement(
w: &mut JsonWriter,
if_stmt: &ast::IfStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "IfStatement", span, ctx);
w.raw(",\"test\":");
write_expression(w, if_stmt.test, ctx);
w.raw(",\"consequent\":");
write_statement(w, if_stmt.consequent, ctx);
w.raw(",\"alternate\":");
write_or_null(w, if_stmt.alternate.as_ref(), |w, alt| {
write_statement(w, alt, ctx);
});
close_node(w, "IfStatement", span, ctx);
}
pub(super) fn write_for_statement(
w: &mut JsonWriter,
for_stmt: &ast::ForStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "ForStatement", span, ctx);
w.raw(",\"init\":");
match &for_stmt.init {
Some(ast::ForInit::VariableDeclaration(decl)) => {
write_variable_declaration(w, decl, ctx, false);
}
Some(ast::ForInit::Expression(expr)) => write_expression(w, expr, ctx),
None => w.null(),
}
w.raw(",\"test\":");
write_or_null(w, for_stmt.test.as_ref(), |w, test| {
write_expression(w, test, ctx);
});
w.raw(",\"update\":");
write_or_null(w, for_stmt.update.as_ref(), |w, update| {
write_expression(w, update, ctx);
});
w.raw(",\"body\":");
write_statement(w, for_stmt.body, ctx);
close_node(w, "ForStatement", span, ctx);
}
fn write_for_in_of_left(w: &mut JsonWriter, left: &ast::ForInOfLeft<'_>, ctx: &Ctx<'_>) {
match left {
ast::ForInOfLeft::VariableDeclaration(decl) => {
write_variable_declaration(w, decl, ctx, false);
}
ast::ForInOfLeft::Pattern(expr) => write_expression(w, expr, ctx),
}
}
pub(super) fn write_for_in_statement(
w: &mut JsonWriter,
for_in: &ast::ForInStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "ForInStatement", span, ctx);
w.raw(",\"left\":");
write_for_in_of_left(w, for_in.left, ctx);
w.raw(",\"right\":");
write_expression(w, for_in.right, ctx);
w.raw(",\"body\":");
write_statement(w, for_in.body, ctx);
close_node(w, "ForInStatement", span, ctx);
}
pub(super) fn write_for_of_statement(
w: &mut JsonWriter,
for_of: &ast::ForOfStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "ForOfStatement", span, ctx);
w.raw(",\"await\":");
w.bool(for_of.r#await);
w.raw(",\"left\":");
write_for_in_of_left(w, for_of.left, ctx);
w.raw(",\"right\":");
write_expression(w, for_of.right, ctx);
w.raw(",\"body\":");
write_statement(w, for_of.body, ctx);
close_node(w, "ForOfStatement", span, ctx);
}
pub(super) fn write_while_statement(
w: &mut JsonWriter,
while_stmt: &ast::WhileStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "WhileStatement", span, ctx);
w.raw(",\"test\":");
write_expression(w, while_stmt.test, ctx);
w.raw(",\"body\":");
write_statement(w, while_stmt.body, ctx);
close_node(w, "WhileStatement", span, ctx);
}
pub(super) fn write_with_statement(
w: &mut JsonWriter,
with_stmt: &ast::WithStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "WithStatement", span, ctx);
w.raw(",\"object\":");
write_expression(w, with_stmt.object, ctx);
w.raw(",\"body\":");
write_statement(w, with_stmt.body, ctx);
close_node(w, "WithStatement", span, ctx);
}
pub(super) fn write_do_while_statement(
w: &mut JsonWriter,
do_while: &ast::DoWhileStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "DoWhileStatement", span, ctx);
w.raw(",\"body\":");
write_statement(w, do_while.body, ctx);
w.raw(",\"test\":");
write_expression(w, do_while.test, ctx);
close_node(w, "DoWhileStatement", span, ctx);
}
pub(super) fn write_switch_statement(
w: &mut JsonWriter,
switch_stmt: &ast::SwitchStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "SwitchStatement", span, ctx);
w.raw(",\"discriminant\":");
write_expression(w, switch_stmt.discriminant, ctx);
w.raw(",\"cases\":");
write_array(w, switch_stmt.cases, |w, case| {
node_header(w, "SwitchCase", case.span, ctx);
w.raw(",\"consequent\":");
write_array(w, case.consequent, |w, s| {
write_statement(w, s, ctx);
});
w.raw(",\"test\":");
write_or_null(w, case.test.as_ref(), |w, t| write_expression(w, t, ctx));
close_node(w, "SwitchCase", case.span, ctx);
});
close_node(w, "SwitchStatement", span, ctx);
}
pub(super) fn write_try_statement(
w: &mut JsonWriter,
try_stmt: &ast::TryStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "TryStatement", span, ctx);
w.raw(",\"block\":");
write_block_statement(w, &try_stmt.block, ctx);
w.raw(",\"handler\":");
write_or_null(w, try_stmt.handler.as_ref(), |w, clause| {
node_header(w, "CatchClause", clause.span, ctx);
w.raw(",\"param\":");
write_or_null(w, clause.param.as_ref(), |w, p| write_expression(w, p, ctx));
w.raw(",\"body\":");
write_block_statement(w, &clause.body, ctx);
close_node(w, "CatchClause", clause.span, ctx);
});
w.raw(",\"finalizer\":");
write_or_null(w, try_stmt.finalizer.as_ref(), |w, f| {
write_block_statement(w, f, ctx);
});
close_node(w, "TryStatement", span, ctx);
}
pub(super) fn write_throw_statement(
w: &mut JsonWriter,
throw_stmt: &ast::ThrowStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "ThrowStatement", span, ctx);
w.raw(",\"argument\":");
write_expression(w, throw_stmt.argument, ctx);
close_node(w, "ThrowStatement", span, ctx);
}
pub(super) fn write_break_statement(
w: &mut JsonWriter,
break_stmt: &ast::BreakStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "BreakStatement", span, ctx);
w.raw(",\"label\":");
write_or_null(w, break_stmt.label.as_ref(), |w, id| {
write_identifier_plain(w, id, ctx);
});
close_node(w, "BreakStatement", span, ctx);
}
pub(super) fn write_continue_statement(
w: &mut JsonWriter,
continue_stmt: &ast::ContinueStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "ContinueStatement", span, ctx);
w.raw(",\"label\":");
write_or_null(w, continue_stmt.label.as_ref(), |w, id| {
write_identifier_plain(w, id, ctx);
});
close_node(w, "ContinueStatement", span, ctx);
}
pub(super) fn write_labeled_statement(
w: &mut JsonWriter,
labeled: &ast::LabeledStatement<'_>,
span: Span,
ctx: &Ctx<'_>,
) {
node_header(w, "LabeledStatement", span, ctx);
w.raw(",\"body\":");
write_statement(w, labeled.body, ctx);
w.raw(",\"label\":");
write_identifier_plain(w, &labeled.label, ctx);
close_node(w, "LabeledStatement", span, ctx);
}