2018-07-30 11:08:06 +00:00
|
|
|
mod builder;
|
2018-08-28 11:06:30 +00:00
|
|
|
mod syntax_text;
|
2018-07-29 10:51:55 +00:00
|
|
|
|
2018-10-15 21:44:23 +00:00
|
|
|
use self::syntax_text::SyntaxText;
|
|
|
|
use crate::{SmolStr, SyntaxKind, TextRange, TextUnit};
|
|
|
|
use rowan::Types;
|
2018-08-10 14:49:45 +00:00
|
|
|
use std::{
|
2018-10-02 14:07:12 +00:00
|
|
|
fmt,
|
|
|
|
hash::{Hash, Hasher},
|
2018-07-29 10:51:55 +00:00
|
|
|
};
|
2018-08-10 14:49:45 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
pub(crate) use self::builder::GreenBuilder;
|
2018-10-15 21:44:23 +00:00
|
|
|
pub use rowan::TreeRoot;
|
2018-10-02 14:07:12 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
pub enum RaTypes {}
|
|
|
|
impl Types for RaTypes {
|
|
|
|
type Kind = SyntaxKind;
|
|
|
|
type RootData = Vec<SyntaxError>;
|
2018-08-10 14:49:45 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
pub type OwnedRoot = ::rowan::OwnedRoot<RaTypes>;
|
|
|
|
pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
|
|
|
|
|
|
|
|
pub type GreenNode = ::rowan::GreenNode<RaTypes>;
|
2018-08-17 18:10:55 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
|
|
|
pub struct SyntaxError {
|
|
|
|
pub msg: String,
|
|
|
|
pub offset: TextUnit,
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
2018-08-10 14:49:45 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
#[derive(Clone, Copy)]
|
2018-10-15 21:44:23 +00:00
|
|
|
pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(::rowan::SyntaxNode<RaTypes, R>);
|
2018-10-02 14:07:12 +00:00
|
|
|
pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
|
|
|
|
|
|
|
|
impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>
|
|
|
|
where
|
|
|
|
R1: TreeRoot<RaTypes>,
|
|
|
|
R2: TreeRoot<RaTypes>,
|
|
|
|
{
|
|
|
|
fn eq(&self, other: &SyntaxNode<R1>) -> bool {
|
|
|
|
self.0 == other.0
|
2018-08-28 11:06:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
impl<R: TreeRoot<RaTypes>> Eq for SyntaxNode<R> {}
|
|
|
|
impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> {
|
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
self.0.hash(state)
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
2018-10-02 14:07:12 +00:00
|
|
|
}
|
2018-08-17 18:10:55 +00:00
|
|
|
|
2018-10-02 14:50:56 +00:00
|
|
|
impl SyntaxNode {
|
2018-10-02 14:07:12 +00:00
|
|
|
pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
|
|
|
|
SyntaxNode(::rowan::SyntaxNode::new(green, errors))
|
|
|
|
}
|
|
|
|
}
|
2018-10-02 15:14:33 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
pub enum Direction {
|
|
|
|
Next,
|
|
|
|
Prev,
|
|
|
|
}
|
|
|
|
|
2018-10-02 14:50:56 +00:00
|
|
|
impl<'a> SyntaxNodeRef<'a> {
|
2018-10-02 14:07:12 +00:00
|
|
|
pub fn leaf_text(self) -> Option<&'a SmolStr> {
|
|
|
|
self.0.leaf_text()
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
2018-10-15 21:44:23 +00:00
|
|
|
pub fn ancestors(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
|
2018-10-15 16:55:32 +00:00
|
|
|
crate::algo::generate(Some(self), |&node| node.parent())
|
2018-10-02 15:02:57 +00:00
|
|
|
}
|
2018-10-15 21:44:23 +00:00
|
|
|
pub fn descendants(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
|
2018-10-15 16:55:32 +00:00
|
|
|
crate::algo::walk::walk(self).filter_map(|event| match event {
|
|
|
|
crate::algo::walk::WalkEvent::Enter(node) => Some(node),
|
|
|
|
crate::algo::walk::WalkEvent::Exit(_) => None,
|
2018-10-02 15:02:57 +00:00
|
|
|
})
|
|
|
|
}
|
2018-10-15 21:44:23 +00:00
|
|
|
pub fn siblings(self, direction: Direction) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
|
2018-10-15 16:55:32 +00:00
|
|
|
crate::algo::generate(Some(self), move |&node| match direction {
|
2018-10-02 15:14:33 +00:00
|
|
|
Direction::Next => node.next_sibling(),
|
|
|
|
Direction::Prev => node.prev_sibling(),
|
|
|
|
})
|
|
|
|
}
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
|
|
|
|
pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
|
|
|
|
self.0.root_data()
|
|
|
|
}
|
|
|
|
pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
|
|
|
|
self.0.replace_with(replacement)
|
|
|
|
}
|
|
|
|
pub fn borrowed<'a>(&'a self) -> SyntaxNode<RefRoot<'a>> {
|
|
|
|
SyntaxNode(self.0.borrowed())
|
|
|
|
}
|
|
|
|
pub fn owned(&self) -> SyntaxNode<OwnedRoot> {
|
|
|
|
SyntaxNode(self.0.owned())
|
|
|
|
}
|
|
|
|
pub fn kind(&self) -> SyntaxKind {
|
|
|
|
self.0.kind()
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
2018-10-02 14:07:12 +00:00
|
|
|
pub fn range(&self) -> TextRange {
|
|
|
|
self.0.range()
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
2018-10-02 14:07:12 +00:00
|
|
|
pub fn text(&self) -> SyntaxText {
|
|
|
|
SyntaxText::new(self.borrowed())
|
|
|
|
}
|
|
|
|
pub fn is_leaf(&self) -> bool {
|
|
|
|
self.0.is_leaf()
|
|
|
|
}
|
|
|
|
pub fn parent(&self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.parent().map(SyntaxNode)
|
|
|
|
}
|
|
|
|
pub fn first_child(&self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.first_child().map(SyntaxNode)
|
|
|
|
}
|
|
|
|
pub fn last_child(&self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.last_child().map(SyntaxNode)
|
|
|
|
}
|
|
|
|
pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.next_sibling().map(SyntaxNode)
|
|
|
|
}
|
|
|
|
pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.prev_sibling().map(SyntaxNode)
|
|
|
|
}
|
|
|
|
pub fn children(&self) -> SyntaxNodeChildren<R> {
|
|
|
|
SyntaxNodeChildren(self.0.children())
|
2018-08-17 18:10:55 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-10 14:49:45 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
|
|
|
|
if has_short_text(self.kind()) {
|
|
|
|
write!(fmt, " \"{}\"", self.text())?;
|
2018-08-10 14:49:45 +00:00
|
|
|
}
|
2018-10-02 14:07:12 +00:00
|
|
|
Ok(())
|
2018-08-10 14:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
#[derive(Debug)]
|
2018-10-15 21:44:23 +00:00
|
|
|
pub struct SyntaxNodeChildren<R: TreeRoot<RaTypes>>(::rowan::SyntaxNodeChildren<RaTypes, R>);
|
2018-08-10 14:49:45 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
impl<R: TreeRoot<RaTypes>> Iterator for SyntaxNodeChildren<R> {
|
|
|
|
type Item = SyntaxNode<R>;
|
2018-08-10 14:49:45 +00:00
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
fn next(&mut self) -> Option<SyntaxNode<R>> {
|
|
|
|
self.0.next().map(SyntaxNode)
|
2018-08-10 14:49:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-02 14:07:12 +00:00
|
|
|
fn has_short_text(kind: SyntaxKind) -> bool {
|
2018-10-15 16:55:32 +00:00
|
|
|
use crate::SyntaxKind::*;
|
2018-10-02 14:07:12 +00:00
|
|
|
match kind {
|
|
|
|
IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
2018-08-10 14:49:45 +00:00
|
|
|
}
|