#![allow(clippy::collapsible_match)]
pub mod codegen;
pub mod errors;
pub mod options;
pub mod transforms;
pub use codegen::*;
pub use errors::*;
pub use options::*;
pub use transforms::*;
pub use vize_atelier_core::{
ast, codegen as core_codegen, errors as core_errors, parser, runtime_helpers, tokenizer,
transform, Allocator, CompilerError, Namespace, RootNode, RuntimeHelper, TemplateChildNode,
};
use vize_atelier_core::{
options::{ParserOptions, TransformOptions},
parser::parse_with_options,
transform::transform as do_transform,
};
use vize_carton::Bump;
pub fn compile_ssr<'a>(
allocator: &'a Bump,
source: &'a str,
) -> (RootNode<'a>, Vec<CompilerError>, SsrCodegenResult) {
compile_ssr_with_options(allocator, source, SsrCompilerOptions::default())
}
pub fn compile_ssr_with_options<'a>(
allocator: &'a Bump,
source: &'a str,
options: SsrCompilerOptions,
) -> (RootNode<'a>, Vec<CompilerError>, SsrCodegenResult) {
let parser_opts = ParserOptions {
is_void_tag: vize_carton::is_void_tag,
is_native_tag: Some(vize_carton::is_native_tag),
is_pre_tag: |tag| tag == "pre",
get_namespace,
comments: options.comments,
..ParserOptions::default()
};
let (mut root, errors) = parse_with_options(allocator, source, parser_opts);
if !errors.is_empty() {
let codegen_result = SsrCodegenResult {
code: String::new(),
preamble: String::new(),
};
return (root, errors.to_vec(), codegen_result);
}
let transform_opts = TransformOptions {
prefix_identifiers: true, hoist_static: false, cache_handlers: false, scope_id: options.scope_id.clone(),
ssr: true,
is_ts: options.is_ts,
inline: options.inline,
..Default::default()
};
do_transform(allocator, &mut root, transform_opts, None);
let codegen_ctx = SsrCodegenContext::new(allocator, &options);
let codegen_result = codegen_ctx.generate(&root);
(root, errors.to_vec(), codegen_result)
}
fn get_namespace(tag: &str, parent: Option<&str>) -> Namespace {
if vize_carton::is_svg_tag(tag) {
return Namespace::Svg;
}
if vize_carton::is_math_ml_tag(tag) {
return Namespace::MathMl;
}
if let Some(parent_tag) = parent {
if vize_carton::is_svg_tag(parent_tag) && tag != "foreignObject" {
return Namespace::Svg;
}
if vize_carton::is_math_ml_tag(parent_tag)
&& tag != "annotation-xml"
&& tag != "foreignObject"
{
return Namespace::MathMl;
}
}
Namespace::Html
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_compile_simple_element() {
let allocator = Bump::new();
let (root, errors, result) = compile_ssr(&allocator, "<div>hello</div>");
assert!(errors.is_empty());
assert_eq!(root.children.len(), 1);
assert!(
result.code.contains("_push"),
"Expected output to contain _push, got:\n{}",
result.code
);
}
#[test]
fn test_compile_interpolation() {
let allocator = Bump::new();
let (_, errors, result) = compile_ssr(&allocator, "<div>{{ msg }}</div>");
assert!(errors.is_empty());
assert!(
result.code.contains("ssrInterpolate") || result.code.contains("_ssrInterpolate"),
"Expected ssrInterpolate, got:\n{}",
result.code
);
}
}