use crate::ast::FunctionNode;
use anyhow::Result;
pub trait LanguageParser {
fn parse(&self, source: &str, filename: &str) -> Result<Box<dyn ParsedModule>>;
}
pub trait ParsedModule {
fn discover_functions(&self, file_index: usize, source: &str) -> Vec<FunctionNode>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::FunctionId;
use crate::language::{FunctionBody, SourceSpan};
struct TestModule {
function_count: usize,
}
impl ParsedModule for TestModule {
fn discover_functions(&self, file_index: usize, _source: &str) -> Vec<FunctionNode> {
(0..self.function_count)
.map(|i| FunctionNode {
id: FunctionId {
file_index,
local_index: i,
},
name: Some(format!("test_fn_{}", i)),
span: SourceSpan::new(i * 10, (i + 1) * 10, (i + 1) as u32, (i + 1) as u32, 0),
body: FunctionBody::ecmascript(swc_ecma_ast::BlockStmt {
span: swc_common::DUMMY_SP,
ctxt: Default::default(),
stmts: vec![],
}),
suppression_reason: None,
})
.collect()
}
}
struct TestParser {
function_count: usize,
}
impl LanguageParser for TestParser {
fn parse(&self, _source: &str, _filename: &str) -> Result<Box<dyn ParsedModule>> {
Ok(Box::new(TestModule {
function_count: self.function_count,
}))
}
}
#[test]
fn test_parser_trait() {
let parser = TestParser { function_count: 3 };
let module = parser.parse("test source", "test.ts").unwrap();
let functions = module.discover_functions(0, "test source");
assert_eq!(functions.len(), 3);
assert_eq!(functions[0].name, Some("test_fn_0".to_string()));
assert_eq!(functions[1].name, Some("test_fn_1".to_string()));
assert_eq!(functions[2].name, Some("test_fn_2".to_string()));
}
#[test]
fn test_parsed_module_trait() {
let module = TestModule { function_count: 2 };
let functions = module.discover_functions(5, "source");
assert_eq!(functions.len(), 2);
assert_eq!(functions[0].id.file_index, 5);
assert_eq!(functions[0].id.local_index, 0);
assert_eq!(functions[1].id.local_index, 1);
}
#[test]
fn test_empty_module() {
let module = TestModule { function_count: 0 };
let functions = module.discover_functions(0, "");
assert_eq!(functions.len(), 0);
}
}