use crate::prelude::internal::*;
mod visitor;
pub use visitor::*;
#[derive(Default)]
pub struct GtpResolve {
pub definitions: HashMap<GtModuleId, Vec<GtDefinitionId>>,
pub imports: HashMap<GtModuleId, Vec<GtDefinitionId>>,
pub paths: HashMap<GtModuleId, HashMap<String, GtModuleId>>,
pub path_module_ids: HashMap<GtPathModuleId, GtModuleId>,
}
impl GtpResolve {
pub fn new() -> GtpResolve {
Default::default()
}
}
impl TryFrom<&Vec<GtProjectModuleParse>> for GtpResolve {
type Error = miette::Error;
fn try_from(modules_parse: &Vec<GtProjectModuleParse>) -> Result<GtpResolve> {
let mut definitions: HashMap<GtModuleId, Vec<GtDefinitionId>> = HashMap::new();
for module in modules_parse {
let module_definitions = module
.1
.resolve
.exports
.iter()
.map(|export| GtDefinitionId(module.1.module.id.clone(), export.1.clone()))
.collect();
definitions.insert(module.1.module.id.clone(), module_definitions);
}
let mut paths: HashMap<GtModuleId, HashMap<String, GtModuleId>> = HashMap::new();
let mut path_module_ids: HashMap<GtPathModuleId, GtModuleId> = HashMap::new();
let mut imports: HashMap<GtModuleId, Vec<GtDefinitionId>> = HashMap::new();
for module in modules_parse {
let mut module_paths: HashMap<String, GtModuleId> = HashMap::new();
module.1.module.imports.iter().for_each(|import| {
if import.path.kind() != GtPathKind::Package {
return;
}
let package_module_id = GtModuleId(import.path.source_str().to_owned().into());
let mut definitions = vec![];
match &import.reference {
GtImportReference::Name(_, name) => {
definitions.push(GtDefinitionId(package_module_id.clone(), name.1.clone()))
}
GtImportReference::Names(_, names) => {
names.iter().for_each(|name| match name {
GtImportName::Name(_, name) => definitions
.push(GtDefinitionId(package_module_id.clone(), name.1.clone())),
GtImportName::Alias(_, _, alias) => definitions
.push(GtDefinitionId(package_module_id.clone(), alias.1.clone())),
})
}
GtImportReference::Glob(_) => {}
}
imports
.entry(module.1.module.id.clone())
.or_default()
.extend(definitions.clone());
});
for tree_path in module.1.resolve.deps.iter() {
let module_id: GtModuleId =
if let Some(module_id) = module_paths.get(tree_path.source_str()) {
module_id.clone()
} else if tree_path.kind() == GtPathKind::Package {
let id = GtModuleId(tree_path.source_str().to_owned().into());
module_paths.insert(tree_path.source_str().into(), id.clone());
id
} else {
let module_path = module.0.resolve(tree_path);
let id: GtModuleId = module_path.into();
module_paths.insert(tree_path.source_str().into(), id.clone());
id
};
path_module_ids.insert(tree_path.id.clone(), module_id.clone());
if let Some(definitions) = definitions.get(&module_id) {
imports
.entry(module.1.module.id.clone())
.or_default()
.extend(definitions.clone());
}
}
paths.insert(module.1.module.id.clone(), module_paths);
}
Ok(GtpResolve {
definitions,
paths,
imports,
path_module_ids,
})
}
}