summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/incremental.rs81
-rw-r--r--src/parse/mod.rs34
-rw-r--r--src/parse/parser.rs30
3 files changed, 72 insertions, 73 deletions
diff --git a/src/parse/incremental.rs b/src/parse/incremental.rs
index 26f97c52..d81a5a23 100644
--- a/src/parse/incremental.rs
+++ b/src/parse/incremental.rs
@@ -1,36 +1,39 @@
use std::ops::Range;
use std::sync::Arc;
-use crate::syntax::{Green, GreenNode, NodeKind};
+use crate::syntax::{InnerNode, NodeKind, SyntaxNode};
use super::{
is_newline, parse, reparse_code_block, reparse_content_block, reparse_markup_elements,
};
-/// Refresh the given green node with as little parsing as possible.
+/// Refresh the given syntax node with as little parsing as possible.
///
/// Takes the new source, the range in the old source that was replaced and the
/// length of the replacement.
///
/// Returns the range in the new source that was ultimately reparsed.
pub fn reparse(
- green: &mut Arc<GreenNode>,
+ root: &mut SyntaxNode,
src: &str,
replaced: Range<usize>,
replacement_len: usize,
) -> Range<usize> {
- Reparser { src, replaced, replacement_len }
- .reparse_step(Arc::make_mut(green), 0, true)
- .unwrap_or_else(|| {
- *green = parse(src);
- 0 .. src.len()
- })
+ if let SyntaxNode::Inner(inner) = root {
+ let reparser = Reparser { src, replaced, replacement_len };
+ if let Some(range) = reparser.reparse_step(Arc::make_mut(inner), 0, true) {
+ return range;
+ }
+ }
+
+ *root = parse(src);
+ 0 .. src.len()
}
-/// Allows partial refreshs of the [`Green`] node tree.
+/// Allows partial refreshs of the syntax tree.
///
/// This struct holds a description of a change. Its methods can be used to try
-/// and apply the change to a green tree.
+/// and apply the change to a syntax tree.
struct Reparser<'a> {
/// The new source code, with the change applied.
src: &'a str,
@@ -44,12 +47,12 @@ impl Reparser<'_> {
/// Try to reparse inside the given node.
fn reparse_step(
&self,
- green: &mut GreenNode,
+ node: &mut InnerNode,
mut offset: usize,
outermost: bool,
) -> Option<Range<usize>> {
- let is_markup = matches!(green.kind(), NodeKind::Markup(_));
- let original_count = green.children().len();
+ let is_markup = matches!(node.kind(), NodeKind::Markup(_));
+ let original_count = node.children().len();
let original_offset = offset;
let mut search = SearchState::default();
@@ -62,8 +65,8 @@ impl Reparser<'_> {
let mut child_outermost = false;
// Find the the first child in the range of children to reparse.
- for (i, child) in green.children().iter().enumerate() {
- let pos = GreenPos { idx: i, offset };
+ for (i, child) in node.children().enumerate() {
+ let pos = NodePos { idx: i, offset };
let child_span = offset .. offset + child.len();
match search {
@@ -122,24 +125,24 @@ impl Reparser<'_> {
// If we were looking for a non-whitespace element and hit the end of
// the file here, we instead use EOF as the end of the span.
if let SearchState::RequireNonTrivia(start) = search {
- search = SearchState::SpanFound(start, GreenPos {
- idx: green.children().len() - 1,
- offset: offset - green.children().last().unwrap().len(),
+ search = SearchState::SpanFound(start, NodePos {
+ idx: node.children().len() - 1,
+ offset: offset - node.children().last().unwrap().len(),
})
}
if let SearchState::Contained(pos) = search {
- let child = &mut green.children_mut()[pos.idx];
+ let child = &mut node.children_mut()[pos.idx];
let prev_len = child.len();
if let Some(range) = match child {
- Green::Node(node) => {
+ SyntaxNode::Inner(node) => {
self.reparse_step(Arc::make_mut(node), pos.offset, child_outermost)
}
- Green::Token(_) => None,
+ SyntaxNode::Leaf(_) => None,
} {
let new_len = child.len();
- green.update_parent(new_len, prev_len);
+ node.update_parent(new_len, prev_len);
return Some(range);
}
@@ -154,7 +157,7 @@ impl Reparser<'_> {
// treat it as a markup element.
if let Some(func) = func {
if let Some(result) = self.replace(
- green,
+ node,
func,
pos.idx .. pos.idx + 1,
superseded_span,
@@ -166,14 +169,14 @@ impl Reparser<'_> {
}
// Save the current indent if this is a markup node and stop otherwise.
- let indent = match green.kind() {
+ let indent = match node.kind() {
NodeKind::Markup(n) => *n,
_ => return None,
};
let (mut start, end) = search.done()?;
if let Some((ahead, ahead_at_start)) = ahead_nontrivia {
- let ahead_kind = green.children()[ahead.idx].kind();
+ let ahead_kind = node.children().as_slice()[ahead.idx].kind();
if start.offset == self.replaced.start
|| ahead_kind.only_at_start()
@@ -183,14 +186,14 @@ impl Reparser<'_> {
at_start = ahead_at_start;
}
} else {
- start = GreenPos { idx: 0, offset: original_offset };
+ start = NodePos { idx: 0, offset: original_offset };
}
let superseded_span =
- start.offset .. end.offset + green.children()[end.idx].len();
+ start.offset .. end.offset + node.children().as_slice()[end.idx].len();
self.replace(
- green,
+ node,
ReparseMode::MarkupElements(at_start, indent),
start.idx .. end.idx + 1,
superseded_span,
@@ -200,7 +203,7 @@ impl Reparser<'_> {
fn replace(
&self,
- green: &mut GreenNode,
+ node: &mut InnerNode,
mode: ReparseMode,
superseded_idx: Range<usize>,
superseded_span: Range<usize>,
@@ -237,7 +240,7 @@ impl Reparser<'_> {
&self.src[newborn_span.start ..],
newborn_span.len(),
differential,
- &green.children()[superseded_start ..],
+ &node.children().as_slice()[superseded_start ..],
at_start,
indent,
),
@@ -249,14 +252,14 @@ impl Reparser<'_> {
return None;
}
- green.replace_children(superseded_start .. superseded_start + amount, newborns);
+ node.replace_children(superseded_start .. superseded_start + amount, newborns);
Some(newborn_span)
}
}
-/// The position of a green node.
+/// The position of a syntax node.
#[derive(Clone, Copy, Debug, PartialEq)]
-struct GreenPos {
+struct NodePos {
/// The index in the parent node.
idx: usize,
/// The byte offset in the string.
@@ -272,15 +275,15 @@ enum SearchState {
NoneFound,
/// The search has concluded by finding a node that fully contains the
/// modifications.
- Contained(GreenPos),
+ Contained(NodePos),
/// The search has found the start of the modified nodes.
- Inside(GreenPos),
+ Inside(NodePos),
/// The search has found the end of the modified nodes but the change
/// touched its boundries so another non-trivia node is needed.
- RequireNonTrivia(GreenPos),
+ RequireNonTrivia(NodePos),
/// The search has concluded by finding a start and an end index for nodes
/// with a pending reparse.
- SpanFound(GreenPos, GreenPos),
+ SpanFound(NodePos, NodePos),
}
impl Default for SearchState {
@@ -290,7 +293,7 @@ impl Default for SearchState {
}
impl SearchState {
- fn done(self) -> Option<(GreenPos, GreenPos)> {
+ fn done(self) -> Option<(NodePos, NodePos)> {
match self {
Self::NoneFound => None,
Self::Contained(s) => Some((s, s)),
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index 4ef1c96f..98d6470c 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -10,24 +10,20 @@ pub use parser::*;
pub use tokens::*;
use std::collections::HashSet;
-use std::sync::Arc;
use crate::syntax::ast::{Associativity, BinOp, UnOp};
-use crate::syntax::{ErrorPos, Green, GreenNode, NodeKind};
+use crate::syntax::{ErrorPos, NodeKind, SyntaxNode};
use crate::util::EcoString;
/// Parse a source file.
-pub fn parse(src: &str) -> Arc<GreenNode> {
+pub fn parse(src: &str) -> SyntaxNode {
let mut p = Parser::new(src, TokenMode::Markup);
markup(&mut p, true);
- match p.finish().into_iter().next() {
- Some(Green::Node(node)) => node,
- _ => unreachable!(),
- }
+ p.finish().into_iter().next().unwrap()
}
/// Parse code directly, only used for syntax highlighting.
-pub fn parse_code(src: &str) -> Vec<Green> {
+pub fn parse_code(src: &str) -> Vec<SyntaxNode> {
let mut p = Parser::new(src, TokenMode::Code);
code(&mut p);
p.finish()
@@ -40,7 +36,7 @@ fn reparse_code_block(
prefix: &str,
src: &str,
end_pos: usize,
-) -> Option<(Vec<Green>, bool, usize)> {
+) -> Option<(Vec<SyntaxNode>, bool, usize)> {
let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
if !p.at(NodeKind::LeftBrace) {
return None;
@@ -48,8 +44,8 @@ fn reparse_code_block(
code_block(&mut p);
- let (mut green, terminated) = p.consume()?;
- let first = green.remove(0);
+ let (mut node, terminated) = p.consume()?;
+ let first = node.remove(0);
if first.len() != end_pos {
return None;
}
@@ -64,7 +60,7 @@ fn reparse_content_block(
prefix: &str,
src: &str,
end_pos: usize,
-) -> Option<(Vec<Green>, bool, usize)> {
+) -> Option<(Vec<SyntaxNode>, bool, usize)> {
let mut p = Parser::with_prefix(prefix, src, TokenMode::Code);
if !p.at(NodeKind::LeftBracket) {
return None;
@@ -72,8 +68,8 @@ fn reparse_content_block(
content_block(&mut p);
- let (mut green, terminated) = p.consume()?;
- let first = green.remove(0);
+ let (mut node, terminated) = p.consume()?;
+ let first = node.remove(0);
if first.len() != end_pos {
return None;
}
@@ -89,13 +85,13 @@ fn reparse_markup_elements(
src: &str,
end_pos: usize,
differential: isize,
- reference: &[Green],
+ reference: &[SyntaxNode],
mut at_start: bool,
column: usize,
-) -> Option<(Vec<Green>, bool, usize)> {
+) -> Option<(Vec<SyntaxNode>, bool, usize)> {
let mut p = Parser::with_prefix(prefix, src, TokenMode::Markup);
- let mut node: Option<&Green> = None;
+ let mut node: Option<&SyntaxNode> = None;
let mut iter = reference.iter();
let mut offset = differential;
let mut replaced = 0;
@@ -683,7 +679,7 @@ fn dict(p: &mut Parser, marker: Marker) {
kind if kind.is_paren() => Ok(()),
NodeKind::Named | NodeKind::Keyed => {
if let Some(NodeKind::Ident(key) | NodeKind::Str(key)) =
- x.children().first().map(|child| child.kind())
+ x.children().next().map(|child| child.kind())
{
if !used.insert(key.clone()) {
return Err("pair has duplicate key");
@@ -770,7 +766,7 @@ fn args(p: &mut Parser, direct: bool, brackets: bool) -> ParseResult {
marker.filter_children(p, |x| match x.kind() {
NodeKind::Named => {
if let Some(NodeKind::Ident(ident)) =
- x.children().first().map(|child| child.kind())
+ x.children().next().map(|child| child.kind())
{
if !used.insert(ident.clone()) {
return Err("duplicate argument");
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index f3a3ffd1..3d7cac45 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -3,7 +3,7 @@ use std::mem;
use std::ops::Range;
use super::{TokenMode, Tokens};
-use crate::syntax::{ErrorPos, Green, GreenData, GreenNode, NodeKind};
+use crate::syntax::{ErrorPos, InnerNode, NodeData, NodeKind, SyntaxNode};
use crate::util::EcoString;
/// A convenient token-based parser.
@@ -21,7 +21,7 @@ pub struct Parser<'s> {
/// The stack of open groups.
groups: Vec<GroupEntry>,
/// The children of the currently built node.
- children: Vec<Green>,
+ children: Vec<SyntaxNode>,
/// Whether the last group was not correctly terminated.
unterminated_group: bool,
/// Whether a group terminator was found, that did not close a group.
@@ -54,14 +54,14 @@ impl<'s> Parser<'s> {
}
/// End the parsing process and return the parsed children.
- pub fn finish(self) -> Vec<Green> {
+ pub fn finish(self) -> Vec<SyntaxNode> {
self.children
}
/// End the parsing process and return the parsed children and whether the
/// last token was terminated if all groups were terminated correctly or
/// `None` otherwise.
- pub fn consume(self) -> Option<(Vec<Green>, bool)> {
+ pub fn consume(self) -> Option<(Vec<SyntaxNode>, bool)> {
self.terminated().then(|| (self.children, self.tokens.terminated()))
}
@@ -94,11 +94,11 @@ impl<'s> Parser<'s> {
if self.tokens.mode() == TokenMode::Code {
// Trailing trivia should not be wrapped into the new node.
let idx = self.children.len();
- self.children.push(Green::default());
+ self.children.push(SyntaxNode::default());
self.children.extend(children.drain(until.0 ..));
- self.children[idx] = GreenNode::with_children(kind, children).into();
+ self.children[idx] = InnerNode::with_children(kind, children).into();
} else {
- self.children.push(GreenNode::with_children(kind, children).into());
+ self.children.push(InnerNode::with_children(kind, children).into());
}
output
@@ -291,7 +291,7 @@ impl<'s> Parser<'s> {
if group_mode == TokenMode::Code {
let start = self.trivia_start().0;
target = self.current_start
- - self.children[start ..].iter().map(Green::len).sum::<usize>();
+ - self.children[start ..].iter().map(SyntaxNode::len).sum::<usize>();
self.children.truncate(start);
}
@@ -314,7 +314,7 @@ impl<'s> Parser<'s> {
fn bump(&mut self) {
let kind = self.current.take().unwrap();
let len = self.tokens.cursor() - self.current_start;
- self.children.push(GreenData::new(kind, len).into());
+ self.children.push(NodeData::new(kind, len).into());
self.current_start = self.tokens.cursor();
self.current = self.tokens.next();
}
@@ -399,7 +399,7 @@ impl Parser<'_> {
pub fn expected_at(&mut self, marker: Marker, what: &str) {
let msg = format_eco!("expected {}", what);
let error = NodeKind::Error(ErrorPos::Full, msg);
- self.children.insert(marker.0, GreenData::new(error, 0).into());
+ self.children.insert(marker.0, NodeData::new(error, 0).into());
}
/// Eat the current token and add an error that it is not the expected
@@ -422,12 +422,12 @@ pub struct Marker(usize);
impl Marker {
/// Peek at the child directly before the marker.
- pub fn before<'a>(self, p: &'a Parser) -> Option<&'a Green> {
+ pub fn before<'a>(self, p: &'a Parser) -> Option<&'a SyntaxNode> {
p.children.get(self.0.checked_sub(1)?)
}
/// Peek at the child directly after the marker.
- pub fn after<'a>(self, p: &'a Parser) -> Option<&'a Green> {
+ pub fn after<'a>(self, p: &'a Parser) -> Option<&'a SyntaxNode> {
p.children.get(self.0)
}
@@ -455,13 +455,13 @@ impl Marker {
let until = p.trivia_start();
let children = p.children.drain(self.0 .. until.0).collect();
p.children
- .insert(self.0, GreenNode::with_children(kind, children).into());
+ .insert(self.0, InnerNode::with_children(kind, children).into());
}
/// Wrap all children that do not fulfill the predicate in error nodes.
pub fn filter_children<F>(self, p: &mut Parser, mut f: F)
where
- F: FnMut(&Green) -> Result<(), &'static str>,
+ F: FnMut(&SyntaxNode) -> Result<(), &'static str>,
{
for child in &mut p.children[self.0 ..] {
// Don't expose errors.
@@ -482,7 +482,7 @@ impl Marker {
}
let error = NodeKind::Error(ErrorPos::Full, msg);
let inner = mem::take(child);
- *child = GreenNode::with_child(error, inner).into();
+ *child = InnerNode::with_child(error, inner).into();
}
}
}