ezno-parser 0.1.1

Parser and AST definitions for Ezno
Documentation
use ezno_parser::{
	statements::UnconditionalElseStatement,
	visiting::{Chain, StatementOrDeclarationMut, VisitSettings, VisitorMut, VisitorsMut},
	ASTNode, Expression, Module, SourceId, Span, Statement, ToStringOptions,
};
use pretty_assertions::assert_eq;

#[test]
fn visiting() {
	let input = r#"
        const x = "hello world";
        function y() {
            if (condition) {
                do_thing("hello world" + " test")
            }
        }
        "#;

	let mut module =
		Module::from_string(input.to_owned(), Default::default(), SourceId::NULL, None).unwrap();

	let mut visitors = VisitorsMut {
		expression_visitors_mut: vec![Box::new(MakeStringsUppercase)],
		statement_visitors_mut: vec![Box::new(AddElseClause)],
		jsx_element_visitors_mut: Default::default(),
		variable_visitors_mut: Default::default(),
		block_visitors_mut: Default::default(),
	};
	module.visit_mut(&mut visitors, &mut (), &VisitSettings::default());

	let output = module.to_string(&ToStringOptions::minified());

	let expected = r#"const x="HELLO WORLD";function y(){if(condition){do_thing("HELLO WORLD"+" TEST")}else console.log("ELSE!")}"#;
	assert_eq!(output, expected);
}

/// Uppercase all string literals
struct MakeStringsUppercase;

impl VisitorMut<Expression, ()> for MakeStringsUppercase {
	fn visit_mut(&mut self, item: &mut Expression, _data: &mut (), _chain: &Chain) {
		if let Expression::StringLiteral(content, _quoted, _) = item {
			*content = content.to_uppercase();
		}
	}
}

/// Add else cases to if statements without one. In the else statements, it logs "else!"
struct AddElseClause;

impl VisitorMut<StatementOrDeclarationMut<'_>, ()> for AddElseClause {
	fn visit_mut(&mut self, item: &mut StatementOrDeclarationMut, _data: &mut (), _chain: &Chain) {
		if let StatementOrDeclarationMut::Statement(Statement::IfStatement(if_statement)) = item {
			if if_statement.trailing_else.is_none() {
				let inner = Statement::from_string(
					"console.log(\"else!\")".to_owned(),
					Default::default(),
					SourceId::NULL,
					None,
				)
				.unwrap()
				.into();

				if_statement.trailing_else =
					Some(UnconditionalElseStatement { inner, position: Span::NULL_SPAN })
			}
		}
	}
}