mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 04:23:25 +00:00
Improve tree building
This commit is contained in:
parent
1fa5b2ffbc
commit
a5dc5f1b5c
5 changed files with 34 additions and 46 deletions
|
@ -16,3 +16,6 @@ parking_lot = "0.6.0"
|
|||
|
||||
[dev-dependencies]
|
||||
testutils = { path = "./tests/testutils" }
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
|
@ -47,6 +47,7 @@ fn main() -> Result<()> {
|
|||
println!("{}", file.syntax_tree());
|
||||
}
|
||||
eprintln!("parsing: {:?}", elapsed);
|
||||
::std::mem::forget(file);
|
||||
}
|
||||
("symbols", _) => {
|
||||
let file = file()?;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use {
|
||||
parser_impl::Sink,
|
||||
yellow::{GreenNode, GreenNodeBuilder, SyntaxError, SyntaxNode, SyntaxRoot},
|
||||
yellow::{GreenNode, SyntaxError, SyntaxNode, SyntaxRoot},
|
||||
SyntaxKind, TextRange, TextUnit,
|
||||
};
|
||||
|
||||
pub(crate) struct GreenBuilder<'a> {
|
||||
text: &'a str,
|
||||
stack: Vec<GreenNodeBuilder>,
|
||||
parents: Vec<(SyntaxKind, usize)>,
|
||||
children: Vec<GreenNode>,
|
||||
pos: TextUnit,
|
||||
root: Option<GreenNode>,
|
||||
errors: Vec<SyntaxError>,
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,9 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
|||
fn new(text: &'a str) -> Self {
|
||||
GreenBuilder {
|
||||
text,
|
||||
stack: Vec::new(),
|
||||
parents: Vec::new(),
|
||||
children: Vec::new(),
|
||||
pos: 0.into(),
|
||||
root: None,
|
||||
errors: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -29,23 +29,24 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
|||
let range = TextRange::offset_len(self.pos, len);
|
||||
self.pos += len;
|
||||
let text = &self.text[range];
|
||||
let leaf = GreenNodeBuilder::new_leaf(kind, text);
|
||||
let parent = self.stack.last_mut().unwrap();
|
||||
parent.push_child(leaf)
|
||||
self.children.push(
|
||||
GreenNode::new_leaf(kind, text)
|
||||
);
|
||||
}
|
||||
|
||||
fn start_internal(&mut self, kind: SyntaxKind) {
|
||||
self.stack.push(GreenNodeBuilder::new_internal(kind))
|
||||
let len = self.children.len();
|
||||
self.parents.push((kind, len));
|
||||
}
|
||||
|
||||
fn finish_internal(&mut self) {
|
||||
let builder = self.stack.pop().unwrap();
|
||||
let node = builder.build();
|
||||
if let Some(parent) = self.stack.last_mut() {
|
||||
parent.push_child(node);
|
||||
} else {
|
||||
self.root = Some(node);
|
||||
}
|
||||
let (kind, first_child) = self.parents.pop().unwrap();
|
||||
let children = self.children
|
||||
.drain(first_child..)
|
||||
.collect();
|
||||
self.children.push(
|
||||
GreenNode::new_branch(kind, children)
|
||||
);
|
||||
}
|
||||
|
||||
fn error(&mut self, message: String) {
|
||||
|
@ -55,8 +56,10 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn finish(self) -> SyntaxNode {
|
||||
let root = SyntaxRoot::new(self.root.unwrap(), self.errors);
|
||||
fn finish(mut self) -> SyntaxNode {
|
||||
assert_eq!(self.children.len(), 1);
|
||||
let root = self.children.pop().unwrap();
|
||||
let root = SyntaxRoot::new(root, self.errors);
|
||||
SyntaxNode::new_owned(root)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,14 @@ pub(crate) enum GreenNode {
|
|||
}
|
||||
|
||||
impl GreenNode {
|
||||
pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
|
||||
GreenNode::Leaf(GreenLeaf::new(kind, text))
|
||||
}
|
||||
|
||||
pub(crate) fn new_branch(kind: SyntaxKind, children: Vec<GreenNode>) -> GreenNode {
|
||||
GreenNode::Branch(Arc::new(GreenBranch::new(kind, children)))
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> SyntaxKind {
|
||||
match self {
|
||||
GreenNode::Leaf(l) => l.kind(),
|
||||
|
@ -46,33 +54,6 @@ impl GreenNode {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct GreenNodeBuilder {
|
||||
kind: SyntaxKind,
|
||||
children: Vec<GreenNode>,
|
||||
}
|
||||
|
||||
impl GreenNodeBuilder {
|
||||
pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode {
|
||||
GreenNode::Leaf(GreenLeaf::new(kind, text))
|
||||
}
|
||||
|
||||
pub(crate) fn new_internal(kind: SyntaxKind) -> GreenNodeBuilder {
|
||||
GreenNodeBuilder {
|
||||
kind,
|
||||
children: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn push_child(&mut self, node: GreenNode) {
|
||||
self.children.push(node)
|
||||
}
|
||||
|
||||
pub(crate) fn build(self) -> GreenNode {
|
||||
let branch = GreenBranch::new(self.kind, self.children);
|
||||
GreenNode::Branch(Arc::new(branch))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_send_sync() {
|
||||
fn f<T: Send + Sync>() {}
|
||||
|
|
|
@ -6,7 +6,7 @@ mod syntax;
|
|||
pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot};
|
||||
pub(crate) use self::{
|
||||
builder::GreenBuilder,
|
||||
green::{GreenNode, GreenNodeBuilder},
|
||||
green::GreenNode,
|
||||
red::RedNode,
|
||||
syntax::SyntaxError,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue