mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Import params pending def
This commit is contained in:
parent
97639cca7d
commit
5e2ccdbfd5
2 changed files with 76 additions and 11 deletions
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue