Add minimal syntax tree implementation

This commit is contained in:
Aleksey Kladov 2017-12-22 16:28:04 +03:00
parent b878f3b636
commit 6ff019c25f
2 changed files with 88 additions and 2 deletions

68
minirust.rs Normal file
View file

@ -0,0 +1,68 @@
pub struct NodeKind(u16);
pub struct File {
text: String,
nodes: Vec<NodeData>,
}
struct NodeData {
kind: NodeKind,
range: (u32, u32),
parent: Option<u32>,
first_child: Option<u32>,
next_sibling: Option<u32>,
}
#[derive(Clone, Copy)]
pub struct Node<'f> {
file: &'f File,
idx: u32,
}
pub struct Children<'f> {
next: Option<Node<'f>>,
}
impl File {
pub fn root<'f>(&'f self) -> Node<'f> {
assert!(!self.nodes.is_empty());
Node { file: self, idx: 0 }
}
}
impl<'f> Node<'f> {
pub fn kind(&self) -> NodeKind {
self.data().kind
}
pub fn text(&self) -> &'f str {
let (start, end) = self.data().range;
&self.file.text[start as usize..end as usize]
}
pub fn parent(&self) -> Option<Node<'f>> {
self.as_node(self.data().parent)
}
pub fn children(&self) -> Children<'f> {
Children { next: self.as_node(self.data().first_child) }
}
fn data(&self) -> &'f NodeData {
&self.file.nodes[self.idx as usize]
}
fn as_node(&self, idx: Option<u32>) -> Option<Node<'f>> {
idx.map(|idx| Node { file: self.file, idx })
}
}
impl<'f> Iterator for Children<'f> {
type Item = Node<'f>;
fn next(&mut self) -> Option<Node<'f>> {
let next = self.next;
self.next = next.and_then(|node| node.as_node(node.data().next_sibling));
next
}
}

22
rfc.md
View file

@ -80,7 +80,10 @@ simpler ones.
In contrast, for IDEs it is crucial to have a lossless view of the In contrast, for IDEs it is crucial to have a lossless view of the
source code because, for example, it's important to preserve comments source code because, for example, it's important to preserve comments
during refactorings. during refactorings. Ideally, IDEs should be able to incrementally
relex and reparse the file as the user types, because syntax tree is
necessary to correctly handle certain code-editing actions like
autoindentation or joining lines.
Currently rustc uses the AST approach, which preserves the source code Currently rustc uses the AST approach, which preserves the source code
information to some extent by storing spans in the AST. information to some extent by storing spans in the AST.
@ -98,7 +101,7 @@ Not applicable.
This section proposes a new syntax tree data structure, which should This section proposes a new syntax tree data structure, which should
be suitable for both compiler and IDE. It is heavily inspired by [PSI] be suitable for both compiler and IDE. It is heavily inspired by [PSI]
data structure which used in [IntelliJ] based IDEs and in the Kotlin data structure which used in [IntelliJ] based IDEs and in the [Kotlin]
compiler. compiler.
@ -107,6 +110,21 @@ compiler.
[Kotlin]: https://kotlinlang.org/ [Kotlin]: https://kotlinlang.org/
The main idea is to store the minimal amount of information in the
tree itself, and instead lean heavily on the source code string for
the actual data about identifier names, constant values etc.
All nodes in the tree are of the same type and store a constant for
the syntactic category of the element and a range in the source code.
Here is a minimal implementation of this data structure:
```Rust
```
# Drawbacks # Drawbacks
[drawbacks]: #drawbacks [drawbacks]: #drawbacks