mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 04:15:08 +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]
|
[dev-dependencies]
|
||||||
testutils = { path = "./tests/testutils" }
|
testutils = { path = "./tests/testutils" }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
|
@ -47,6 +47,7 @@ fn main() -> Result<()> {
|
||||||
println!("{}", file.syntax_tree());
|
println!("{}", file.syntax_tree());
|
||||||
}
|
}
|
||||||
eprintln!("parsing: {:?}", elapsed);
|
eprintln!("parsing: {:?}", elapsed);
|
||||||
|
::std::mem::forget(file);
|
||||||
}
|
}
|
||||||
("symbols", _) => {
|
("symbols", _) => {
|
||||||
let file = file()?;
|
let file = file()?;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use {
|
use {
|
||||||
parser_impl::Sink,
|
parser_impl::Sink,
|
||||||
yellow::{GreenNode, GreenNodeBuilder, SyntaxError, SyntaxNode, SyntaxRoot},
|
yellow::{GreenNode, SyntaxError, SyntaxNode, SyntaxRoot},
|
||||||
SyntaxKind, TextRange, TextUnit,
|
SyntaxKind, TextRange, TextUnit,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct GreenBuilder<'a> {
|
pub(crate) struct GreenBuilder<'a> {
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
stack: Vec<GreenNodeBuilder>,
|
parents: Vec<(SyntaxKind, usize)>,
|
||||||
|
children: Vec<GreenNode>,
|
||||||
pos: TextUnit,
|
pos: TextUnit,
|
||||||
root: Option<GreenNode>,
|
|
||||||
errors: Vec<SyntaxError>,
|
errors: Vec<SyntaxError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
||||||
fn new(text: &'a str) -> Self {
|
fn new(text: &'a str) -> Self {
|
||||||
GreenBuilder {
|
GreenBuilder {
|
||||||
text,
|
text,
|
||||||
stack: Vec::new(),
|
parents: Vec::new(),
|
||||||
|
children: Vec::new(),
|
||||||
pos: 0.into(),
|
pos: 0.into(),
|
||||||
root: None,
|
|
||||||
errors: Vec::new(),
|
errors: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,23 +29,24 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
||||||
let range = TextRange::offset_len(self.pos, len);
|
let range = TextRange::offset_len(self.pos, len);
|
||||||
self.pos += len;
|
self.pos += len;
|
||||||
let text = &self.text[range];
|
let text = &self.text[range];
|
||||||
let leaf = GreenNodeBuilder::new_leaf(kind, text);
|
self.children.push(
|
||||||
let parent = self.stack.last_mut().unwrap();
|
GreenNode::new_leaf(kind, text)
|
||||||
parent.push_child(leaf)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_internal(&mut self, kind: SyntaxKind) {
|
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) {
|
fn finish_internal(&mut self) {
|
||||||
let builder = self.stack.pop().unwrap();
|
let (kind, first_child) = self.parents.pop().unwrap();
|
||||||
let node = builder.build();
|
let children = self.children
|
||||||
if let Some(parent) = self.stack.last_mut() {
|
.drain(first_child..)
|
||||||
parent.push_child(node);
|
.collect();
|
||||||
} else {
|
self.children.push(
|
||||||
self.root = Some(node);
|
GreenNode::new_branch(kind, children)
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, message: String) {
|
fn error(&mut self, message: String) {
|
||||||
|
@ -55,8 +56,10 @@ impl<'a> Sink<'a> for GreenBuilder<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(self) -> SyntaxNode {
|
fn finish(mut self) -> SyntaxNode {
|
||||||
let root = SyntaxRoot::new(self.root.unwrap(), self.errors);
|
assert_eq!(self.children.len(), 1);
|
||||||
|
let root = self.children.pop().unwrap();
|
||||||
|
let root = SyntaxRoot::new(root, self.errors);
|
||||||
SyntaxNode::new_owned(root)
|
SyntaxNode::new_owned(root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,14 @@ pub(crate) enum GreenNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
pub fn kind(&self) -> SyntaxKind {
|
||||||
match self {
|
match self {
|
||||||
GreenNode::Leaf(l) => l.kind(),
|
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]
|
#[test]
|
||||||
fn assert_send_sync() {
|
fn assert_send_sync() {
|
||||||
fn f<T: Send + Sync>() {}
|
fn f<T: Send + Sync>() {}
|
||||||
|
|
|
@ -6,7 +6,7 @@ mod syntax;
|
||||||
pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot};
|
pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot};
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
builder::GreenBuilder,
|
builder::GreenBuilder,
|
||||||
green::{GreenNode, GreenNodeBuilder},
|
green::GreenNode,
|
||||||
red::RedNode,
|
red::RedNode,
|
||||||
syntax::SyntaxError,
|
syntax::SyntaxError,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue