Retrieve top-level item metadata

This commit is contained in:
2026-04-29 17:37:10 -06:00
parent 1928690597
commit e864ea9145

View File

@@ -22,18 +22,63 @@ use strum::{EnumDiscriminants, EnumIter};
use crate::prelude::*;
// TODO: migrate AST logic (after redesigning grammar)
// TODO: AST unit tests? executing on examples may be sufficient
/// Retrieves, but does not parse, all top-level items in a file.
// TODO: is `Vec` the most efficient to incrementally update here?
#[salsa::tracked]
pub fn items<'db>(db: &'db dyn Database, file: workspace::File) -> Vec<ItemMeta<'db>> {
todo!()
// track running documentation comments
let mut docs = Vec::new();
// iterate over each top-level AST node
let mut items = Vec::new();
for ast in file.ast(db).get_children(db) {
// convert the AST symbol into an item kind
let kind = match ast.symbol(db) {
// if there is an empty line, clear ongoing doc comments
"newline" => {
docs.clear();
continue;
}
// if this is a comment, add it to the doc comments
"comment" => {
docs.push(ast);
continue;
}
// otherwise, convert the symbol directly into the item kind
"type_alias" => ItemKind::TypeAlias,
"import" => ItemKind::Import,
"definition" => ItemKind::Relation, // TODO: rename grammar node
"rule" => ItemKind::Rule,
"assumption" => ItemKind::Assumption,
// any other symbol should be impossible by conentional means
symbol => unimplemented!("unrecognized top-level AST symbol {symbol:?}"),
};
// create an item from the kind
let item = ItemMeta::new(db, docs.clone(), ast, kind);
items.push(item);
// reset docs for next item
docs.clear();
}
// return the completed items
items
}
/// Parses an [ItemMeta] into its corresponding [Item].
pub fn item<'db>(db: &'db dyn Database, meta: ItemMeta<'db>) -> WithAst<Item<'db>> {
todo!()
match meta.kind(db) {
ItemKind::Relation => todo!(),
ItemKind::TypeAlias => todo!(),
ItemKind::Import => todo!(),
ItemKind::Rule => todo!(),
ItemKind::Assumption => todo!(),
}
}
/// Common information on top-level items.
@@ -54,13 +99,51 @@ pub struct ItemMeta<'db> {
#[strum_discriminants(name(ItemKind))]
#[strum_discriminants(derive(Hash))]
pub enum Item<'db> {
TypeAlias(TypeAlias<'db>),
Import,
Relation(Relation<'db>),
Rule,
Assumption,
TypeAlias(TypeAlias<'db>),
Import(Import<'db>),
Rule(Rule<'db>),
Assumption(Assumption<'db>),
}
/// A definition of a relation.
#[salsa::tracked]
pub struct Relation<'db> {
/// The name of this relation.
pub name: WithAst<String>,
/// Whether this relation is a decision.
pub is_decision: bool,
/// The IO of this relation.
pub io: ir::RelationIO,
/// This relation's abstract type (pure syntax).
pub ty: WithAst<Type>,
}
/// An abstract type alias (syntax representation).
#[salsa::tracked]
pub struct TypeAlias<'db> {
/// The type alias's name.
pub name: WithAst<String>,
/// The type alias's abstract type.
pub ty: WithAst<Type>,
}
/// An abstract rule.
#[salsa::tracked]
pub struct Rule<'db> {}
/// An abstract import item.
#[salsa::tracked]
pub struct Import<'db> {}
/// An abstract assumption.
#[salsa::tracked]
pub struct Assumption<'db> {}
/// Parse an expression from the AST.
#[salsa::tracked]
pub fn expr(db: &dyn Database, ast: AstNode) -> Expr {
@@ -234,41 +317,6 @@ impl ir::EnumRepr for RedundantBinaryOpKind {
}
}
/// A definition of a relation.
// TODO: add commment above definition AST node for documentation
#[salsa::tracked]
#[derive(Debug)]
pub struct Relation<'db> {
/// The AST node this relation corresponds to.
pub ast: AstNode,
/// The name of this relation.
pub name: WithAst<String>,
/// Whether this relation is a decision.
pub is_decision: bool,
/// The IO of this relation.
pub io: ir::RelationIO,
/// This relation's abstract type (pure syntax).
pub ty: WithAst<Type>,
}
/// An abstract type alias (syntax representation).
#[salsa::tracked]
#[derive(Debug)]
pub struct TypeAlias<'db> {
/// The AST node of this type alias.
pub ast: AstNode,
/// The type alias's name.
pub name: WithAst<String>,
/// The type alias's abstract type.
pub ty: WithAst<Type>,
}
/// An abstract type definition.
///
/// This just represents the literal, syntactic type representation, without