use std::collections::HashMap;
use std::path::PathBuf;
use syn::visit::Visit;
use crate::error::{Error, Result};
pub(crate) use crate::ir::{EdgeKind, NodeId, NodeKind, TaintGraph};
pub(crate) use crate::labels::LabelSet;
mod expr;
mod labels_default;
mod visitor;
pub use labels_default::default_label_set;
use labels_default::apply_labels;
use visitor::RustParser;
pub fn parse_rust_with_labels(
source: &str,
filename: &str,
labels: Option<&LabelSet>,
) -> Result<TaintGraph> {
let syntax = syn::parse_file(source)
.map_err(|err| Error::Analysis(format!("Fix: parse Rust file `{filename}`: {err}")))?;
let mut parser = RustParser::new(PathBuf::from(filename));
parser.visit_file(&syntax);
let mut graph = parser.into_graph();
let label_set = labels.map_or_else(default_label_set, Clone::clone);
apply_labels(&mut graph, &label_set);
graph.set_label_set(label_set);
Ok(graph)
}
pub fn parse_rust(source: &str, filename: &str) -> Result<TaintGraph> {
parse_rust_with_labels(source, filename, None)
}
#[derive(Clone, Debug)]
pub(crate) struct EvalResult {
pub(crate) node: NodeId,
pub(crate) descriptor: Option<String>,
pub(crate) literal: Option<String>,
}
#[derive(Clone, Debug)]
pub(crate) struct FunctionInfo {
pub(crate) node: NodeId,
pub(crate) params: Vec<NodeId>,
}
#[derive(Default)]
pub(crate) struct Scope {
values: HashMap<String, NodeId>,
}
impl Scope {
pub(crate) fn define(&mut self, name: String, node: NodeId) {
self.values.insert(name, node);
}
pub(crate) fn resolve(&self, name: &str) -> Option<NodeId> {
self.values.get(name).copied()
}
}