Skip to main content

oak_core/builder/
mod.rs

1use crate::{
2    Language,
3    errors::OakDiagnostics,
4    source::{Source, TextEdit},
5    tree::GreenNode,
6};
7
8/// Output of a builder operation.
9pub type BuildOutput<L: Language> = OakDiagnostics<L::TypedRoot>;
10
11/// Trait for building higher-level structures (like ASTs) from a green tree.
12///
13/// While the [`Parser`] produces a generic [`GreenNode`] tree, the `Builder` is
14/// responsible for "lowering" or "binding" this tree into a more ergonomic,
15/// language-specific structure (e.g., an AST with typed nodes).
16///
17/// # Usage Scenario
18///
19/// The `Builder` is typically used after parsing to:
20/// 1. Traverse the produced [`GreenNode`] tree.
21/// 2. Construct typed AST nodes.
22/// 3. Cache these typed nodes for incremental updates.
23pub trait Builder<L: Language> {
24    /// Builds the higher-level structure (typically an AST) from the source text.
25    ///
26    /// This method is the primary entry point for converting a raw source or a
27    /// syntax tree into a typed AST. It handles incremental rebuilding if
28    /// edits and a cache are provided.
29    ///
30    /// # Arguments
31    ///
32    /// * `text` - The source text to build from.
33    /// * `edits` - A slice of [`TextEdit`]s representing changes since the last build.
34    ///             Empty if building from scratch.
35    /// * `cache` - A [`BuilderCache`] for incremental reuse and resource management.
36    ///
37    /// # Returns
38    ///
39    /// A [`BuildOutput`] containing the typed root node and any diagnostics.
40    fn build<'a, S: Source + ?Sized>(&self, text: &S, edits: &[TextEdit], cache: &'a mut impl BuilderCache<L>) -> BuildOutput<L>;
41}
42
43/// Cache trait for builder operations used by lexers and parsers.
44///
45/// This trait defines the interface for building green tree nodes incrementally.
46/// It provides methods for adding tokens and nodes to the tree structure.
47pub trait BuilderCache<L: Language>: crate::parser::ParseCache<L> {
48    /// Gets a cached typed node for a given green node.
49    fn get_typed_node<T: 'static + Send + Sync + Clone>(&self, green: &GreenNode<L>) -> Option<T>;
50
51    /// Caches a typed node for a given green node.
52    fn set_typed_node<T: 'static + Send + Sync>(&mut self, green: &GreenNode<L>, typed: T);
53}
54
55impl<'a, L: Language, C: BuilderCache<L> + ?Sized> BuilderCache<L> for &'a mut C {
56    fn get_typed_node<T: 'static + Send + Sync + Clone>(&self, green: &GreenNode<L>) -> Option<T> {
57        (**self).get_typed_node(green)
58    }
59
60    fn set_typed_node<T: 'static + Send + Sync>(&mut self, green: &GreenNode<L>, typed: T) {
61        (**self).set_typed_node(green, typed)
62    }
63}
64
65impl<L: Language + Send + Sync> BuilderCache<L> for crate::parser::ParseSession<L> {
66    fn get_typed_node<T: 'static + Send + Sync + Clone>(&self, green: &GreenNode<L>) -> Option<T> {
67        self.get_typed_node(green)
68    }
69
70    fn set_typed_node<T: 'static + Send + Sync>(&mut self, green: &GreenNode<L>, typed: T) {
71        self.set_typed_node(green, typed)
72    }
73}