1 // FIXME(CAD97): I don't understand this mod well enough to stub out docs for the public symbols yet
2 #![allow(missing_docs)]
4 use {SyntaxKind, TextRange, TextUnit};
5 use super::{File, NodeData, NodeIdx, SyntaxErrorData};
8 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
9 fn start_internal(&mut self, kind: SyntaxKind);
10 fn finish_internal(&mut self);
11 fn error(&mut self) -> ErrorBuilder;
15 pub struct FileBuilder {
18 errors: Vec<SyntaxErrorData>,
19 in_progress: Vec<(NodeIdx, Option<NodeIdx>)>, // (parent, last_child)
23 impl Sink for FileBuilder {
24 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) {
27 range: TextRange::from_len(self.pos, len),
33 let id = self.push_child(leaf);
37 fn start_internal(&mut self, kind: SyntaxKind) {
40 range: TextRange::from_len(self.pos, 0.into()),
45 let id = if self.in_progress.is_empty() {
50 self.in_progress.push((id, None))
53 fn finish_internal(&mut self) {
54 let (id, _) = self.in_progress
56 .expect("trying to complete a node, but there are no in-progress nodes");
57 if !self.in_progress.is_empty() {
62 fn error(&mut self) -> ErrorBuilder {
63 ErrorBuilder::new(self)
68 pub fn new(text: String) -> FileBuilder {
73 in_progress: Vec::new(),
74 pos: TextUnit::new(0),
78 pub fn finish(self) -> File {
80 self.in_progress.is_empty(),
81 "some nodes in FileBuilder are unfinished: {:?}",
84 .map(|&(idx, _)| self.nodes[idx].kind)
89 (self.text.len() as u32).into(),
90 "nodes in FileBuilder do not cover the whole file"
99 fn new_node(&mut self, data: NodeData) -> NodeIdx {
100 let id = NodeIdx(self.nodes.len() as u32);
101 self.nodes.push(data);
105 fn push_child(&mut self, mut child: NodeData) -> NodeIdx {
106 child.parent = Some(self.current_id());
107 let id = self.new_node(child);
109 let (parent, sibling) = *self.in_progress.last().unwrap();
110 let slot = if let Some(idx) = sibling {
111 &mut self.nodes[idx].next_sibling
113 &mut self.nodes[parent].first_child
117 self.in_progress.last_mut().unwrap().1 = Some(id);
121 fn add_len(&mut self, child: NodeIdx) {
122 let range = self.nodes[child].range;
123 grow(&mut self.current_parent().range, range);
126 fn current_id(&self) -> NodeIdx {
127 self.in_progress.last().unwrap().0
130 fn current_parent(&mut self) -> &mut NodeData {
131 let idx = self.current_id();
136 fn fill<T>(slot: &mut Option<T>, value: T) {
137 assert!(slot.is_none());
141 fn grow(left: &mut TextRange, right: TextRange) {
142 assert_eq!(left.end(), right.start());
143 *left = TextRange::from_to(left.start(), right.end())
147 pub struct ErrorBuilder<'f> {
148 message: Option<String>,
149 builder: &'f mut FileBuilder,
152 impl<'f> ErrorBuilder<'f> {
153 fn new(builder: &'f mut FileBuilder) -> Self {
160 pub fn message<M: Into<String>>(mut self, m: M) -> Self {
161 self.message = Some(m.into());
166 let message = self.message.expect("Error message not set");
167 let &(node, after_child) = self.builder.in_progress.last().unwrap();
168 self.builder.errors.push(SyntaxErrorData {