pub mod json_schema;
pub mod python;
pub mod shell;
pub mod typescript;
use std::collections::HashSet;
use std::path::Path;
use crate::error::Result;
use crate::ir::execution_surface::*;
use crate::ir::{ArgumentSource, Language, SourceLocation};
#[derive(Debug, Clone, Default)]
pub struct ParsedFile {
pub commands: Vec<CommandInvocation>,
pub file_operations: Vec<FileOperation>,
pub network_operations: Vec<NetworkOperation>,
pub env_accesses: Vec<EnvAccess>,
pub dynamic_exec: Vec<DynamicExec>,
pub function_params: Vec<FunctionParam>,
pub function_defs: Vec<FunctionDef>,
pub call_sites: Vec<CallSite>,
pub sanitized_vars: HashSet<String>,
}
#[derive(Debug, Clone)]
pub struct FunctionParam {
pub function_name: String,
pub param_name: String,
pub location: SourceLocation,
}
#[derive(Debug, Clone)]
pub struct FunctionDef {
pub name: String,
pub params: Vec<String>,
pub is_exported: bool,
pub location: SourceLocation,
}
#[derive(Debug, Clone)]
pub struct CallSite {
pub callee: String,
pub arguments: Vec<ArgumentSource>,
pub caller: Option<String>,
pub location: SourceLocation,
}
pub trait LanguageParser: Send + Sync {
fn language(&self) -> Language;
fn parse_file(&self, path: &Path, content: &str) -> Result<ParsedFile>;
}
pub fn parser_for_language(lang: Language) -> Option<Box<dyn LanguageParser>> {
match lang {
Language::Python => Some(Box::new(python::PythonParser)),
Language::TypeScript | Language::JavaScript => Some(Box::new(typescript::TypeScriptParser)),
Language::Shell => Some(Box::new(shell::ShellParser)),
_ => None,
}
}