Import params pending def

This commit is contained in:
Agus Zubiaga 2024-05-09 19:33:16 -03:00
parent 97639cca7d
commit 5e2ccdbfd5
No known key found for this signature in database
2 changed files with 76 additions and 11 deletions

View file

@ -164,6 +164,11 @@ enum PendingValueDef<'a> {
&'a Loc<ast::TypeAnnotation<'a>>,
&'a Loc<ast::Expr<'a>>,
),
/// Module params from an import
ImportParams(
Loc<Pattern>,
ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>,
),
/// Ingested file
IngestedFile(
Loc<Pattern>,
@ -178,6 +183,7 @@ impl PendingValueDef<'_> {
PendingValueDef::AnnotationOnly(_, loc_pattern, _) => loc_pattern,
PendingValueDef::Body(loc_pattern, _) => loc_pattern,
PendingValueDef::TypedBody(_, loc_pattern, _, _) => loc_pattern,
PendingValueDef::ImportParams(loc_pattern, _) => loc_pattern,
PendingValueDef::IngestedFile(loc_pattern, _, _) => loc_pattern,
}
}
@ -1111,8 +1117,21 @@ fn canonicalize_value_defs<'a>(
PendingValue::ExpectFx(pending_expect) => {
pending_expect_fx.push(pending_expect);
}
PendingValue::ModuleImport(introduced_import) => {
imports_introduced.push(introduced_import);
PendingValue::ModuleImport {
module_id,
region,
exposed_symbols,
params,
} => {
imports_introduced.push(IntroducedImport {
module_id,
region,
exposed_symbols,
});
if let Some((loc_pattern, params)) = params {
pending_value_defs.push(PendingValueDef::ImportParams(loc_pattern, params));
}
}
PendingValue::InvalidIngestedFile => { /* skip */ }
PendingValue::ImportNameConflict => { /* skip */ }
@ -2354,6 +2373,9 @@ fn canonicalize_pending_value_def<'a>(
None,
)
}
ImportParams(_, _) => {
todo!("agus: handle import params def")
}
IngestedFile(loc_pattern, opt_loc_ann, path_literal) => {
let relative_path =
if let ast::StrLiteral::PlainLine(ingested_path) = path_literal.value {
@ -2895,7 +2917,15 @@ enum PendingValue<'a> {
Dbg(PendingExpectOrDbg<'a>),
Expect(PendingExpectOrDbg<'a>),
ExpectFx(PendingExpectOrDbg<'a>),
ModuleImport(IntroducedImport),
ModuleImport {
module_id: ModuleId,
region: Region,
exposed_symbols: Vec<(Symbol, Region)>,
params: Option<(
Loc<Pattern>,
ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>,
)>,
},
SignatureDefMismatch,
InvalidIngestedFile,
ImportNameConflict,
@ -3056,10 +3086,25 @@ fn to_pending_value_def<'a>(
None => module_name.clone(),
};
let params = if let Some(params) = module_import.params {
let name_str = name_with_alias.as_str();
// todo(agus): params specific loc
match scope.introduce_str(format!("#{name_str}").as_str(), region) {
Ok(sym) => Some((sym, params)),
Err(_) => {
// Ignore conflict, it will be handled right after
None
}
}
} else {
None
};
if let Err(existing_import) =
scope
.modules
.insert(name_with_alias.clone(), module_id, region)
.insert(name_with_alias.clone(), module_id, params.map(|(sym, _)| sym), region)
{
env.problems.push(Problem::ImportNameConflict {
name: name_with_alias,
@ -3070,7 +3115,7 @@ fn to_pending_value_def<'a>(
});
return PendingValue::ImportNameConflict;
}
};
let exposed_names = module_import
.exposed
@ -3125,11 +3170,18 @@ fn to_pending_value_def<'a>(
}
PendingValue::ModuleImport(IntroducedImport {
let params =
params.map(|(sym, params)| {
// todo(agus): params specific loc
(Loc::at(region, Pattern::Identifier(sym)), params.params)
});
PendingValue::ModuleImport {
module_id,
region,
exposed_symbols,
})
params,
}
}
IngestedFileImport(ingested_file) => {
let loc_name = ingested_file.name.item;

View file

@ -625,7 +625,8 @@ impl ModuleIds {
#[derive(Debug, Clone)]
pub struct ScopeModules {
modules: VecMap<ModuleName, ModuleId>,
sources: VecMap<ModuleId, ScopeModuleSource>,
sources: VecMap<ModuleId, ScopeModuleSource>, // todo(agus): why not Vec?
params: Vec<Option<Symbol>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -652,6 +653,7 @@ impl ScopeModules {
&mut self,
module_name: ModuleName,
module_id: ModuleId,
params_symbol: Option<Symbol>,
region: Region,
) -> Result<(), ScopeModuleSource> {
if let Some(existing_module_id) = self.modules.get(&module_name) {
@ -665,22 +667,26 @@ impl ScopeModules {
self.modules.insert(module_name, module_id);
self.sources
.insert(module_id, ScopeModuleSource::Import(region));
self.params.push(params_symbol);
Ok(())
}
pub fn len(&self) -> usize {
debug_assert_eq!(self.modules.len(), self.sources.len());
debug_assert_eq!(self.modules.len(), self.params.len());
self.modules.len()
}
pub fn is_empty(&self) -> bool {
debug_assert_eq!(self.modules.is_empty(), self.sources.is_empty());
debug_assert_eq!(self.modules.is_empty(), self.params.is_empty());
self.modules.is_empty()
}
pub fn truncate(&mut self, len: usize) {
self.modules.truncate(len);
self.sources.truncate(len);
self.params.truncate(len);
}
}
@ -1031,22 +1037,29 @@ macro_rules! define_builtins {
let mut modules = VecMap::with_capacity(capacity);
let mut sources = VecMap::with_capacity(capacity);
let mut params = Vec::with_capacity(capacity);
modules.insert(home_name, home_id);
sources.insert(home_id, ScopeModuleSource::Current);
// todo(agus): Use insert
if !home_id.is_builtin() {
modules.insert(home_name, home_id);
sources.insert(home_id, ScopeModuleSource::Current);
params.push(None);
}
let mut insert_both = |id: ModuleId, name_str: &'static str| {
let name: ModuleName = name_str.into();
modules.insert(name, id);
sources.insert(id, ScopeModuleSource::Builtin);
params.push(None);
};
$(
insert_both(ModuleId::$module_const, $module_name);
)+
ScopeModules { modules, sources }
ScopeModules { modules, sources, params }
}
}