mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Add minimal syntax tree implementation
This commit is contained in:
parent
b878f3b636
commit
6ff019c25f
2 changed files with 88 additions and 2 deletions
68
minirust.rs
Normal file
68
minirust.rs
Normal 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
22
rfc.md
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue