#![allow(clippy::unwrap_used, clippy::expect_used)]
#[path = "src/grammar.rs"]
mod grammar;
use grammar::typescript_grammar;
fn main() {
let grammar = typescript_grammar();
let compiled = grammar.build_optimized_with_memoization();
let mut code = compiled.generate();
code.push_str(PARSE_PROGRAM_IMPL);
let out_dir = std::env::var("OUT_DIR").unwrap();
let dest = std::path::Path::new(&out_dir).join("parser_generated.rs");
std::fs::write(&dest, code).expect("Failed to write parser_generated.rs");
println!("cargo:rerun-if-changed=src/grammar.rs");
println!("cargo:rerun-if-changed=trampoline-parser/src/codegen.rs");
println!("cargo:rerun-if-changed=build.rs");
}
const PARSE_PROGRAM_IMPL: &str = r#"
impl ParseResult {
/// Get a combined span for the result
pub fn combined_span(&self) -> Span {
self.span()
}
/// Convert result to text (for captured tokens)
pub fn into_text(self) -> JsString {
match self {
ParseResult::Text(s, _) => s,
ParseResult::List(items) => {
// Combine text from list items
let mut result = String::new();
for item in items {
if let ParseResult::Text(s, _) = item {
result.push_str(s.as_ref());
}
}
JsString::from(result)
}
ParseResult::None => JsString::from(""),
// AST variants don't contain text
ParseResult::Expr(_) | ParseResult::Stmt(_) | ParseResult::Ident(_)
| ParseResult::Pat(_) | ParseResult::Prog(_)
| ParseResult::ClassBody(_) | ParseResult::ClassMember(_)
| ParseResult::SwitchCase(_) => JsString::from(""),
}
}
/// Convert result to a list
pub fn into_list(self) -> Vec<ParseResult> {
match self {
ParseResult::List(items) => items,
other => vec![other],
}
}
}
impl<'a> Parser<'a> {
/// Parse a complete program, returning the AST
pub fn parse_program(&mut self) -> Result<Program, ParseError> {
let result = self.parse()?;
// Check that all input was consumed
if self.pos < self.input.len() {
let remaining = self.input.get(self.pos..).unwrap_or("");
let preview: String = remaining.chars().take(20).collect();
return Err(ParseError {
message: format!("Unexpected input: '{}'", preview),
span: Span { start: self.pos, end: self.input.len(), line: self.line, column: self.column },
});
}
// Extract Program from the parse result
match result {
ParseResult::Prog(program) => Ok(program),
ParseResult::List(items) => {
// If we got a list, try to convert items to statements
let mut statements = Vec::new();
for item in items {
match item {
ParseResult::Stmt(stmt) => statements.push(stmt),
ParseResult::Prog(prog) => return Ok(prog),
_ => {} // Skip non-statement items
}
}
Ok(Program {
body: Rc::from(statements),
source_type: SourceType::Module,
})
}
_ => {
// Fallback: return empty program
Ok(Program {
body: Rc::from(vec![]),
source_type: SourceType::Module,
})
}
}
}
}
"#;