WIP file interns
This commit is contained in:
@@ -26,7 +26,7 @@ use kerolox_ir::EnumRepr;
|
||||
use salsa::Update;
|
||||
use strum::EnumIter;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::{prelude::*, workspace::File};
|
||||
|
||||
/// A complete definition for a Kerolox scope which can be accessed by paths.
|
||||
#[salsa::tracked]
|
||||
@@ -225,6 +225,80 @@ pub fn expr<'db>(
|
||||
|
||||
/// Resolve a reference to a relation by name.
|
||||
pub fn relation_name<'db>(db: &'db dyn Database, name: ast::Name) -> RelationLabel<'db> {
|
||||
// get table of interns for the name's file
|
||||
let interns = file_interns(db, name.ast.file(db));
|
||||
|
||||
assert!(name.path.len() == 1, "relation name paths are unsupported");
|
||||
|
||||
// look up the relation by its last path segment
|
||||
let tail = name.path.last().unwrap();
|
||||
match interns.get(&tail.inner) {
|
||||
None => RelationLabel::Unknown(name.clone()),
|
||||
Some(NamespaceItem::Relation(rel)) => RelationLabel::Relation(*rel),
|
||||
Some(_) => todo!("handle non-relation lookups gracefully"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a file's internal name table.
|
||||
#[salsa::tracked]
|
||||
pub fn file_interns<'db>(
|
||||
db: &'db dyn Database,
|
||||
file: File,
|
||||
) -> BTreeMap<String, NamespaceItem<'db>> {
|
||||
// add top-level entries to a complete list of names
|
||||
let mut names = Vec::new();
|
||||
for item in ast::items(db, file) {
|
||||
// get name info based on kind of item
|
||||
use ast::ItemKind::*;
|
||||
let entry = match item.kind(db) {
|
||||
// some items do not define names
|
||||
Rule | Assumption => continue,
|
||||
// add relations
|
||||
Relation => {
|
||||
let relation = ast::relation(db, item.ast(db));
|
||||
(relation.name(db), NamespaceItem::Relation(relation))
|
||||
}
|
||||
// add type aliases
|
||||
TypeAlias => {
|
||||
let type_alias = ast::type_alias(db, item.ast(db));
|
||||
(type_alias.name(db), NamespaceItem::TypeAlias(type_alias))
|
||||
}
|
||||
// add imports separately
|
||||
Import => {
|
||||
let import = ast::import(db, item.ast(db));
|
||||
names.extend(import_items(db, import));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// add entry to list of names
|
||||
names.push(entry);
|
||||
}
|
||||
|
||||
// build table with only one entry per name
|
||||
let mut table = BTreeMap::new();
|
||||
for (name, item) in names {
|
||||
use std::collections::btree_map::Entry;
|
||||
match table.entry(name.clone().inner) {
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(item);
|
||||
}
|
||||
Entry::Occupied(_) => {
|
||||
todo!("handle duplicate definitions");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the completed table
|
||||
table
|
||||
}
|
||||
|
||||
/// Resolves an import item to a table of namespace items.
|
||||
#[salsa::tracked]
|
||||
pub fn import_items<'db>(
|
||||
db: &'db dyn Database,
|
||||
import: ast::Import<'db>,
|
||||
) -> Vec<(WithAst<String>, NamespaceItem<'db>)> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user