use harn_lexer::{FixEdit, Span};
#[derive(Debug, Clone)]
pub(super) struct ValueReferenceSite {
pub(super) name: String,
pub(super) span: Span,
}
pub(super) fn wrap_value_reference_edit(
source: &str,
site: Span,
callable_name: &str,
param_names: &[String],
) -> Option<FixEdit> {
let region = source.get(site.start..site.end)?;
if region != callable_name {
return None;
}
let params = param_names.join(", ");
let replacement = if params.is_empty() {
format!("{{ -> {callable_name}() }}")
} else {
format!("{{ {params} -> {callable_name}({params}) }}")
};
Some(FixEdit {
span: site,
replacement,
})
}
pub(super) fn format_escape_sites(sites: &[(String, usize)]) -> String {
if sites.is_empty() {
return String::new();
}
let rendered = sites
.iter()
.map(|(file, line)| format!("{file}:{line}"))
.collect::<Vec<_>>()
.join(", ");
format!("; escaping reference(s) at {rendered}")
}
#[cfg(test)]
mod tests {
use super::*;
use harn_lexer::Span;
#[test]
fn wrap_keeps_declared_arity_in_the_closure() {
let source = "handler: web_search_handler,";
let start = source.find("web_search_handler").unwrap();
let span = Span::with_offsets(start, start + "web_search_handler".len(), 1, 1);
let edit =
wrap_value_reference_edit(source, span, "web_search_handler", &["args".to_string()])
.expect("wrap");
assert_eq!(edit.replacement, "{ args -> web_search_handler(args) }");
}
}