From 8e977e0101d388ec863f5f9b07d270b44dc9ef37 Mon Sep 17 00:00:00 2001 From: Aron Zwaan Date: Wed, 6 Dec 2023 14:45:09 +0100 Subject: [PATCH] Document all public API's; finetune API --- scopegraphs-lib/src/completeness.rs | 89 ++++++- scopegraphs-lib/src/label.rs | 1 + scopegraphs-lib/src/lib.rs | 230 ++++++++++++------ scopegraphs-lib/src/resolve/containers/env.rs | 25 +- scopegraphs-lib/src/resolve/containers/mod.rs | 4 + .../src/resolve/containers/path.rs | 35 +-- .../src/resolve/containers/scope.rs | 18 +- .../src/resolve/{topdown.rs => lookup.rs} | 189 +++++++++----- scopegraphs-lib/src/resolve/mod.rs | 54 ++-- 9 files changed, 440 insertions(+), 205 deletions(-) rename scopegraphs-lib/src/resolve/{topdown.rs => lookup.rs} (66%) diff --git a/scopegraphs-lib/src/completeness.rs b/scopegraphs-lib/src/completeness.rs index 5c61560..6efc091 100644 --- a/scopegraphs-lib/src/completeness.rs +++ b/scopegraphs-lib/src/completeness.rs @@ -1,3 +1,17 @@ +//! This module contains several utilities to guarantee query stability. +//! Query stability means that the result of a query, once resolved, will remain valid after future +//! additions to the scope graph. +//! This allows safe interleaving of name resolution and scope graph construction. +//! +//! The main trait of this module is [`Completeness`]. An instance of this trait should be passed +//! to [`super::ScopeGraph::new`] to obtain a correct scope graph instance. +//! +//! Currently the module contains two safe implementations. +//! [`ImplicitClose`] is the easiest to use, and most likely the preferred choice for simple +//! sequential type checkers. +//! [`ExplicitClose`] requires some manual bookkeeping, but allows more flexible handling of +//! queries. This is the most suitable choice for type checkers that need to do dynamic scheduling. + use std::{collections::HashSet, hash::Hash}; use crate::label::Label; @@ -12,6 +26,26 @@ use private::Sealed; /*** Completeness trait ***/ +/// Types implementing this trait have the responsibility to guarantee query stability. +/// +/// This means that the result of a query, once computed, may not be invalidated by later extensions +/// of the scope graph. +/// +/// A [`super::ScopeGraph`] will call the handlers of its completeness on each operation. +/// For scope addition and data access, it can update some internal state. +/// For edge addition and retrieval, it can override/augment the default result as well. +/// +/// The way query stability is guaranteed is very flexible. Current implementations use +/// - critical edges, explicitly closed by the client ([`ExplicitClose`]). +/// - critical edges, implicitly closed when retrieved ([`ImplicitClose`]). +/// +/// Future implementations may also: +/// - delay retrieval of edges until it is closed (by returning a future). +/// - guarantee stability by retaining residual queries, and checking those do not return any +/// results for later additions. +/// - ... +/// +/// This trait is sealed to ensure only verified implementations are available. pub trait Completeness: Sealed { fn cmpl_new_scope(&mut self, inner_scope_graph: &InnerScopeGraph, scope: Scope); @@ -44,10 +78,25 @@ pub trait Completeness: Sealed { /*** Unchecked Completeness Implementation ***/ -#[derive(Debug, Default)] +/// No-Op implementation of [`Completeness`]. +#[derive(Debug)] pub struct UncheckedCompleteness {} impl Sealed for UncheckedCompleteness {} +impl UncheckedCompleteness { + /// Constructs a new instance of [`UncheckedCompleteness`]. + /// + /// # Safety + /// + /// Marked as `unsafe`, as it does adhere to its contract (guaranteeing stability). + /// + /// Unless you are sure you really need this, consider alternatives + /// such as [`ImplicitClose`] or [`ExplicitClose`]. + pub unsafe fn new() -> Self { + Self {} + } +} + impl Completeness for UncheckedCompleteness { fn cmpl_new_scope(&mut self, _: &InnerScopeGraph, _: Scope) {} @@ -109,15 +158,23 @@ impl CriticalEdgeSet