use std::collections::HashMap;
use crate::{
error::{FrontendError, FrontendResult},
paths::{require_local_name, split_crate_path},
};
use super::imports::ImportFragment;
pub struct LowerContext<'a> {
pub imports: &'a mut Vec<ImportFragment>,
pub module_prefix: &'a str,
pub bare_import_renames: HashMap<String, String>,
}
impl LowerContext<'_> {
pub fn prefixed_local(&self, module_path: &str) -> String {
let base = require_local_name(module_path);
if self.module_prefix.is_empty() {
base
} else {
format!("{}_{}", self.module_prefix, base)
}
}
pub fn normalize_bare_import_path(&self, segments: &mut [String]) {
if self.bare_import_renames.is_empty() {
return;
}
if let Some(first) = segments.first()
&& let Some(renamed) = self.bare_import_renames.get(first.as_str())
{
segments[0].clone_from(renamed);
}
}
fn register_crate_module(&mut self, module: &str) {
if self
.imports
.iter()
.any(|fragment| fragment.module == module)
{
return;
}
self.imports.push(ImportFragment {
module: module.to_string(),
require_local: self.prefixed_local(module),
item: None,
});
}
pub fn normalize_crate_path(&mut self, segments: &mut Vec<String>) -> FrontendResult<()> {
if segments.first().map(String::as_str) != Some("crate") {
return Ok(());
}
segments.remove(0);
if segments.is_empty() {
return Err(FrontendError::UnsupportedExpression {
location: "crate".to_string(),
});
}
let (module_path, rest) = split_crate_path(segments);
if module_path.is_empty() {
return Err(FrontendError::UnsupportedExpression {
location: segments.join("::"),
});
}
self.register_crate_module(&module_path);
let local = self.prefixed_local(&module_path);
*segments = if rest.is_empty() {
vec![local]
} else {
let mut rewritten = vec![local];
rewritten.extend(rest);
rewritten
};
Ok(())
}
}