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 tokens 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>

source

pub fn new() -> Self

Creates new builder with an empty NodeCache.

source§

impl<'cache, 'interner, S, I> GreenNodeBuilder<'cache, 'interner, S, I>where S: Syntax, I: Interner<TokenKey>,

source

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.

source

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"));
source

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.

source

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.

source

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.

source

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");
source

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.

source

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.

source

pub fn start_node(&mut self, kind: S)

Start new node of the given kind and make it current.

source

pub fn finish_node(&mut self)

Finish the current branch and restore the previous branch as current.

source

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();
}
source

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.

source

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.

Trait Implementations§

source§

impl<'cache, 'interner, S: Debug + Syntax, I: Debug> Debug for GreenNodeBuilder<'cache, 'interner, S, I>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S: Syntax> Default for GreenNodeBuilder<'static, 'static, S>

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'cache, 'interner, S, I> RefUnwindSafe for GreenNodeBuilder<'cache, 'interner, S, I>where I: RefUnwindSafe, S: RefUnwindSafe,

§

impl<'cache, 'interner, S, I> Send for GreenNodeBuilder<'cache, 'interner, S, I>where I: Send, S: Send,

§

impl<'cache, 'interner, S, I> Sync for GreenNodeBuilder<'cache, 'interner, S, I>where I: Sync, S: Sync,

§

impl<'cache, 'interner, S, I> Unpin for GreenNodeBuilder<'cache, 'interner, S, I>where I: Unpin, S: Unpin,

§

impl<'cache, 'interner, S, I = TokenInterner> !UnwindSafe for GreenNodeBuilder<'cache, 'interner, S, I>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.