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}