use starlark_syntax::codemap::CodeMap;
use starlark_syntax::codemap::Pos;
use starlark_syntax::codemap::Span;
use crate::analysis::unused_loads::find::find_unused_loads;
struct Out<'a> {
codemap: &'a CodeMap,
out: String,
pos: Pos,
}
impl<'a> Out<'a> {
fn append_to(&mut self, pos: Pos) {
assert!(self.pos <= pos);
assert!(pos <= self.codemap.full_span().end());
self.out
.push_str(self.codemap.source_span(Span::new(self.pos, pos)));
self.pos = pos;
}
fn skip_to(&mut self, pos: Pos) {
assert!(self.pos <= pos);
assert!(pos <= self.codemap.full_span().end());
self.pos = pos;
}
fn skip_span(&mut self, span: Span) {
self.append_to(span.begin());
self.skip_to(span.end());
}
}
pub fn remove_unused_loads(name: &str, program: &str) -> crate::Result<Option<String>> {
let (codemap, unused_loads) = find_unused_loads(name, program)?;
if unused_loads.is_empty() {
return Ok(None);
}
let mut out = Out {
codemap: &codemap,
out: String::new(),
pos: Pos::new(0),
};
for load in unused_loads {
if load.all_unused() {
out.skip_span(load.load.span);
} else {
for arg in load.unused_args {
out.skip_span(arg.span_with_trailing_comma());
}
}
}
out.append_to(codemap.full_span().end());
Ok(Some(out.out))
}