Skip to content

Commit

Permalink
std lib with dummy fn
Browse files Browse the repository at this point in the history
  • Loading branch information
g-r-a-n-t committed Dec 4, 2021
1 parent 724dae7 commit cc236ae
Show file tree
Hide file tree
Showing 28 changed files with 556 additions and 275 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/analyzer/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ pub trait AnalyzerDb {
fn ingot_all_modules(&self, ingot: IngotId) -> Rc<Vec<ModuleId>>;
#[salsa::invoke(queries::ingots::ingot_main_module)]
fn ingot_main_module(&self, ingot: IngotId) -> Analysis<Option<ModuleId>>;
#[salsa::invoke(queries::ingots::ingot_lib_module)]
fn ingot_lib_module(&self, ingot: IngotId) -> Analysis<Option<ModuleId>>;

// Module
#[salsa::invoke(queries::module::module_all_items)]
Expand Down
71 changes: 54 additions & 17 deletions crates/analyzer/src/db/queries/ingots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,26 @@ pub fn ingot_all_modules(db: &dyn AnalyzerDb, ingot_id: IngotId) -> Rc<Vec<Modul
})
.collect::<IndexSet<_>>()
.into_iter()
.map(|dir| {
let module = Module {
name: dir
.file_name()
.expect("missing file name")
.to_str()
.expect("could not convert dir name to string")
.to_string(),
ast: ast::Module { body: vec![] },
context: ModuleContext::Ingot(ingot_id),
file_content: ModuleFileContent::Dir {
dir_path: dir
.filter_map(|dir| {
if let Some(file_name) = dir.file_name() {
let module = Module {
name: file_name
.to_str()
.expect("could not convert dir path to string")
.expect("could not convert dir name to string")
.to_string(),
},
};

db.intern_module(Rc::new(module))
ast: ast::Module { body: vec![] },
context: ModuleContext::Ingot(ingot_id),
file_content: ModuleFileContent::Dir {
dir_path: dir
.to_str()
.expect("could not convert dir path to string")
.to_string(),
},
};
Some(db.intern_module(Rc::new(module)))
} else {
None
}
})
.collect::<Vec<ModuleId>>();

Expand Down Expand Up @@ -103,3 +104,39 @@ pub fn ingot_main_module(db: &dyn AnalyzerDb, ingot_id: IngotId) -> Analysis<Opt
}),
}
}

pub fn ingot_lib_module(db: &dyn AnalyzerDb, ingot_id: IngotId) -> Analysis<Option<ModuleId>> {
let lib_id = ingot_id
.all_modules(db)
.iter()
.find(|module_id| {
module_id.name(db) == "lib" && {
if let Some(parent_id) = module_id.parent_module(db) {
parent_id.name(db) == "src"
} else {
false
}
}
})
.copied();

Analysis {
value: lib_id,
diagnostics: Rc::new({
if lib_id.is_none() {
vec![Diagnostic {
severity: Severity::Error,
message: format!(
"The ingot named \"{}\" is missing a lib module. \
\nPlease add a `src/lib.fe` file to the base directory.",
ingot_id.name(db)
),
labels: vec![],
notes: vec![],
}]
} else {
vec![]
}
}),
}
}
63 changes: 50 additions & 13 deletions crates/analyzer/src/db/queries/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ pub fn module_item_map(

let mut map = IndexMap::<String, Item>::new();

for (name, ingot) in module.global_ingots(db).into_iter() {
if map.insert(name, Item::Ingot(ingot)).is_some() {
panic!("included library conflicts with other name?")
}
}

for item in module.all_items(db).iter() {
let item_name = item.name(db);
if let Some(builtin) = builtin_items.get(&item_name) {
Expand All @@ -131,23 +137,35 @@ pub fn module_item_map(
continue;
}

match map.entry(item_name) {
match map.entry(item_name.clone()) {
Entry::Occupied(entry) => {
diagnostics.push(errors::fancy_error(
"duplicate type name",
vec![
Label::primary(
entry.get().name_span(db).unwrap(),
format!("`{}` first defined here", entry.key()),
if let Some(entry_name_span) = entry.get().name_span(db) {
diagnostics.push(errors::duplicate_name_error(
&format!(
"a {} named \"{}\" has already been defined",
entry.get().item_kind_display_name(),
item_name
),
Label::secondary(
&item_name,
entry_name_span,
item.name_span(db)
.expect("used-defined item does not have name span"),
));
} else {
diagnostics.push(errors::fancy_error(
&format!(
"a {} named \"{}\" has already been defined",
entry.get().item_kind_display_name(),
item_name
),
vec![Label::primary(
item.name_span(db)
.expect("built-in conflicts with user-defined name?"),
.expect("used-defined item does not have name span"),
format!("`{}` redefined here", entry.key()),
),
],
vec![],
));
)],
vec![],
));
}
}
Entry::Vacant(entry) => {
entry.insert(*item);
Expand Down Expand Up @@ -248,6 +266,25 @@ pub fn module_used_item_map(
diagnostics.extend(items.diagnostics.deref().clone());

for (name, (name_span, item)) in items.value.iter() {
if let Some(ingot) = module.global_ingots(db).get(name) {
if *item == Item::Ingot(*ingot) {
diagnostics.push(errors::fancy_error(
format!("the ingot named \"{}\" is already defined", name),
vec![
Label::primary(*name_span, "redefined here"),
Label::secondary(*name_span, "hint: delete this import"),
],
vec![],
))
} else {
diagnostics.push(errors::error(
format!("an ingot named \"{}\" has already been defined", name),
*name_span,
format!("conflicts with the ingot named \"{}\"", name),
))
}
}

if let Some((other_name_span, other_item)) =
accum.insert(name.to_owned(), (*name_span, *item))
{
Expand Down
Loading

0 comments on commit cc236ae

Please sign in to comment.