terrified to start testing
This commit is contained in:
@@ -9,39 +9,45 @@ use memo_map::MemoMap;
|
||||
use orchid_base::{IStr, NameLike, VPath, es, iv};
|
||||
use task_local::task_local;
|
||||
|
||||
use crate::api;
|
||||
use crate::entrypoint::request;
|
||||
use crate::system::sys_id;
|
||||
use crate::{api, request, sys_id};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReflMemData {
|
||||
// None for inferred steps
|
||||
struct ReflMemData {
|
||||
/// None for inferred steps
|
||||
public: OnceCell<bool>,
|
||||
kind: ReflMemKind,
|
||||
}
|
||||
/// Potentially partial reflected information about a member inside a module
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ReflMem(Rc<ReflMemData>);
|
||||
impl ReflMem {
|
||||
pub fn kind(&self) -> ReflMemKind { self.0.kind.clone() }
|
||||
}
|
||||
|
||||
/// The kind of [ReflMem]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ReflMemKind {
|
||||
/// A plain constant. Information about constants can be obtained by passing a
|
||||
/// [crate::gen_expr::GExprKind::Const] to the interpreter
|
||||
Const,
|
||||
/// A module that can be reflected further
|
||||
Mod(ReflMod),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReflModData {
|
||||
struct ReflModData {
|
||||
inferred: Mutex<bool>,
|
||||
path: VPath,
|
||||
members: MemoMap<IStr, ReflMem>,
|
||||
}
|
||||
|
||||
/// A module whose members can be listed and inspected
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ReflMod(Rc<ReflModData>);
|
||||
impl ReflMod {
|
||||
/// Retrieve the path of the module
|
||||
pub fn path(&self) -> &[IStr] { &self.0.path[..] }
|
||||
/// Whether this path is the root or if it has a parent
|
||||
pub fn is_root(&self) -> bool { self.0.path.is_empty() }
|
||||
async fn try_populate(&self) -> Result<(), api::LsModuleError> {
|
||||
let path_tok = iv(&self.0.path[..]).await;
|
||||
@@ -70,6 +76,7 @@ impl ReflMod {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Find a child by name within the module
|
||||
pub async fn get_child(&self, key: &IStr) -> Option<ReflMem> {
|
||||
let inferred_g = self.0.inferred.lock().await;
|
||||
if let Some(mem) = self.0.members.get(key) {
|
||||
@@ -90,6 +97,9 @@ impl ReflMod {
|
||||
}
|
||||
self.0.members.get(key).cloned()
|
||||
}
|
||||
/// Find a descendant by sub-path within the module. Note that this is not the
|
||||
/// same as the paths accepted by import statements, as the `self` and `super`
|
||||
/// keywords don't work
|
||||
pub async fn get_by_path(&self, path: &[IStr]) -> Result<ReflMem, InvalidPathError> {
|
||||
let (next, tail) = path.split_first().expect("Attempted to walk by empty path");
|
||||
let inferred_g = self.0.inferred.lock().await;
|
||||
@@ -138,8 +148,11 @@ task_local! {
|
||||
static REFL_ROOTS: RefCell<HashMap<api::SysId, ReflMod>>
|
||||
}
|
||||
|
||||
/// Indicates that the caller provided a path that does not exist
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct InvalidPathError {
|
||||
/// When unwinding a recursive path lookup, decides whether the temporary
|
||||
/// member created for the parent object should be kept or deleted
|
||||
keep_ancestry: bool,
|
||||
}
|
||||
|
||||
@@ -154,12 +167,18 @@ fn default_member(is_root: bool, kind: ReflMemKind) -> ReflMem {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Obtains the root module for reflection. This function may only be called in
|
||||
/// callbacks provided by [crate::OwnedAtom] except for
|
||||
/// [crate::OwnedAtom::free], callbacks provided by [crate::ThinAtom], the
|
||||
/// callback for [crate::ParsedLine::cnst], [crate::gen_expr] callbacks, and
|
||||
/// other places where we know that the interpreter is running and holding a
|
||||
/// reference to the module tree
|
||||
pub fn refl() -> ReflMod {
|
||||
REFL_ROOTS.with(|tbl| {
|
||||
tbl.borrow_mut().entry(sys_id()).or_insert_with(|| default_module(VPath::new([]))).clone()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn with_refl_roots<'a>(fut: LocalBoxFuture<'a, ()>) -> LocalBoxFuture<'a, ()> {
|
||||
pub(crate) fn with_refl_roots<'a>(fut: LocalBoxFuture<'a, ()>) -> LocalBoxFuture<'a, ()> {
|
||||
Box::pin(REFL_ROOTS.scope(RefCell::default(), fut))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user