Struct cstree::build::GreenNodeBuilder
source · pub struct GreenNodeBuilder<'cache, 'interner, S: Syntax, I = TokenInterner> { /* private fields */ }
Expand description
A builder for green trees.
Construct with new
, with_cache
, or
from_cache
. To add tree nodes, start them with
start_node
, add token
s and then
finish_node
. When the whole tree is constructed, call
finish
to obtain the root.
Examples
// Build a tree
let mut builder: GreenNodeBuilder<MySyntax> = GreenNodeBuilder::new();
builder.start_node(Root);
builder.token(Int, "42");
builder.finish_node();
let (tree, cache) = builder.finish();
// Check it out!
assert_eq!(tree.kind(), MySyntax::into_raw(Root));
let int = tree.children().next().unwrap();
assert_eq!(int.kind(), MySyntax::into_raw(Int));
let resolver = cache.unwrap().into_interner().unwrap();
assert_eq!(int.as_token().unwrap().text(&resolver), Some("42"));
Implementations§
source§impl<S: Syntax> GreenNodeBuilder<'static, 'static, S>
impl<S: Syntax> GreenNodeBuilder<'static, 'static, S>
source§impl<'cache, 'interner, S, I> GreenNodeBuilder<'cache, 'interner, S, I>where
S: Syntax,
I: Interner<TokenKey>,
impl<'cache, 'interner, S, I> GreenNodeBuilder<'cache, 'interner, S, I>where S: Syntax, I: Interner<TokenKey>,
sourcepub fn with_cache(cache: &'cache mut NodeCache<'interner, I>) -> Self
pub fn with_cache(cache: &'cache mut NodeCache<'interner, I>) -> Self
Reusing a NodeCache
between multiple builders saves memory, as it allows to structurally
share underlying trees.
sourcepub fn from_cache(cache: NodeCache<'interner, I>) -> Self
pub fn from_cache(cache: NodeCache<'interner, I>) -> Self
Reusing a NodeCache
between multiple builders saves memory, as it allows to structurally
share underlying trees.
The cache
given will be returned on finish
.
Examples
// Construct a builder from our own cache
let cache = NodeCache::new();
let mut builder: GreenNodeBuilder<MySyntax> = GreenNodeBuilder::from_cache(cache);
// Build a tree
parse(&mut builder, "42");
let (tree, cache) = builder.finish();
// Use the tree
let interner = cache.unwrap().into_interner().unwrap();
assert_eq!(tree.kind(), MySyntax::into_raw(Root));
let int = tree.children().next().unwrap();
assert_eq!(int.kind(), MySyntax::into_raw(Int));
assert_eq!(int.as_token().unwrap().text(&interner), Some("42"));
sourcepub fn with_interner(interner: &'interner mut I) -> Self
pub fn with_interner(interner: &'interner mut I) -> Self
Shortcut to construct a builder that uses an existing interner.
This is equivalent to using from_cache
with a node cache
obtained from NodeCache::with_interner
.
sourcepub fn from_interner(interner: I) -> Self
pub fn from_interner(interner: I) -> Self
Shortcut to construct a builder that uses an existing interner.
This is equivalent to using from_cache
with a node cache
obtained from NodeCache::from_interner
.
sourcepub fn interner(&self) -> &I
pub fn interner(&self) -> &I
Get a reference to the interner used to deduplicate source text (strings).
This is the same interner as used by the underlying NodeCache
.
See also interner_mut
.
sourcepub fn interner_mut(&mut self) -> &mut I
pub fn interner_mut(&mut self) -> &mut I
Get a mutable reference to the interner used to deduplicate source text (strings).
This is the same interner as used by the underlying NodeCache
.
Examples
let mut builder: GreenNodeBuilder<MySyntax> = GreenNodeBuilder::new();
let interner = builder.interner_mut();
let key = interner.get_or_intern("foo");
assert_eq!(interner.resolve(key), "foo");
sourcepub fn token(&mut self, kind: S, text: &str)
pub fn token(&mut self, kind: S, text: &str)
Add a new token with the given text
to the current node.
Panics
In debug mode, if kind
has static text, this function will verify that text
matches that text.
sourcepub fn static_token(&mut self, kind: S)
pub fn static_token(&mut self, kind: S)
Add a new token to the current node without storing an explicit section of text.
This is be useful if the text can always be inferred from the token’s kind
, for example
when using kinds for specific operators or punctuation.
For tokens whose textual representation is not static, such as numbers or identifiers, use
token
.
Panics
If kind
does not have static text, i.e., L::static_text(kind)
returns None
.
sourcepub fn start_node(&mut self, kind: S)
pub fn start_node(&mut self, kind: S)
Start new node of the given kind
and make it current.
sourcepub fn finish_node(&mut self)
pub fn finish_node(&mut self)
Finish the current branch and restore the previous branch as current.
sourcepub fn checkpoint(&self) -> Checkpoint
pub fn checkpoint(&self) -> Checkpoint
Prepare for maybe wrapping the next node with a surrounding node.
The way wrapping works is that you first get a checkpoint, then you add nodes and tokens as
normal, and then you maybe call start_node_at
.
Examples
let checkpoint = builder.checkpoint();
parser.parse_expr();
if let Some(Plus) = parser.peek() {
// 1 + 2 = Add(1, 2)
builder.start_node_at(checkpoint, Operation);
parser.parse_expr();
builder.finish_node();
}
sourcepub fn start_node_at(&mut self, checkpoint: Checkpoint, kind: S)
pub fn start_node_at(&mut self, checkpoint: Checkpoint, kind: S)
Wrap the previous branch marked by checkpoint
in a new
branch and make it current.
sourcepub fn finish(self) -> (GreenNode, Option<NodeCache<'interner, I>>)
pub fn finish(self) -> (GreenNode, Option<NodeCache<'interner, I>>)
Complete building the tree.
Make sure that calls to start_node
/
start_node_at
and
finish_node
are balanced, i.e. that every started node has
been completed!
If this builder was constructed with new
or
from_cache
, this method returns the cache used to deduplicate tree nodes
as its second return value to allow re-using the cache or extracting the underlying string
Interner
. See also NodeCache::into_interner
.