//! el-ui-compiler — Transforms `.el` component files into JavaScript. //! //! Pipeline: //! source text → lexer → tokens → parser → AST → codegen → JavaScript //! //! The output JavaScript uses the el-ui runtime (`el-ui.js`) to register //! components, manage a spreading-activation graph for state, and patch the DOM. pub mod ast; pub mod codegen; pub mod error; pub mod lexer; pub mod parser; pub use ast::{Attr, Component, Method, PropDef, StateDef, Template, TemplateNode}; #[cfg(test)] mod tests; pub use codegen::Codegen; pub use error::{CompileError, CompileResult}; /// High-level compiler entry point. pub struct Compiler { /// Runtime import path (default: `./el-ui.js`) pub runtime_path: String, } impl Default for Compiler { fn default() -> Self { Self { runtime_path: "./el-ui.js".into() } } } impl Compiler { pub fn new() -> Self { Self::default() } pub fn with_runtime_path(mut self, path: impl Into) -> Self { self.runtime_path = path.into(); self } /// Compile a single `.el` source file containing one or more components. /// Returns the JavaScript module string. pub fn compile_component(&self, source: &str) -> CompileResult { let tokens = lexer::tokenize(source)?; let components = parser::parse(&tokens)?; let gen = Codegen::new(&self.runtime_path); gen.generate(&components) } /// Compile an app entry point, pulling in named component sources. /// `components` is a slice of `(name, source)` pairs. /// Returns a single JavaScript module that imports from the runtime. pub fn compile_app( &self, entry_source: &str, components: &[(&str, &str)], ) -> CompileResult { let mut all_components: Vec = Vec::new(); for (_name, src) in components { let tokens = lexer::tokenize(src)?; let mut parsed = parser::parse(&tokens)?; all_components.append(&mut parsed); } // Parse entry last (may reference previously defined components) let entry_tokens = lexer::tokenize(entry_source)?; let mut entry_parsed = parser::parse(&entry_tokens)?; all_components.append(&mut entry_parsed); let gen = Codegen::new(&self.runtime_path); gen.generate(&all_components) } }