Skip to content

Commit

Permalink
Expose sorbus as green tree impl
Browse files Browse the repository at this point in the history
  • Loading branch information
CAD97 committed Jul 16, 2020
1 parent 5cf7c24 commit 58c994c
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 950 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ erasable = "1.2.1"
rustc-hash = "1.0.1"
serde = { version = "1.0.89", optional = true, default-features = false }
slice-dst = "1.4.1"
smol_str = "0.1.10"
text-size = "1.0.0"
sorbus = { path = "../sorbus" }

[dev-dependencies]
m_lexer = "0.0.4"
smol_str = "0.1.10"

[features]
serde1 = [ "serde", "text-size/serde" ]
serde1 = [ "serde", "sorbus/ser" ]
13 changes: 7 additions & 6 deletions examples/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
//! - "+" Token(Add)
//! - "4" Token(Number)

use rowan::{GreenNodeBuilder, NodeOrToken, SmolStr};
use rowan::GreenNodeBuilder;
use smol_str::SmolStr;
use std::iter::Peekable;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -57,10 +58,10 @@ type SyntaxNode = rowan::SyntaxNode<Lang>;
#[allow(unused)]
type SyntaxToken = rowan::SyntaxToken<Lang>;
#[allow(unused)]
type SyntaxElement = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;
type SyntaxElement = rowan::SyntaxElement<Lang>;

struct Parser<I: Iterator<Item = (SyntaxKind, SmolStr)>> {
builder: GreenNodeBuilder<'static>,
builder: GreenNodeBuilder,
iter: Peekable<I>,
}
impl<I: Iterator<Item = (SyntaxKind, SmolStr)>> Parser<I> {
Expand All @@ -72,7 +73,7 @@ impl<I: Iterator<Item = (SyntaxKind, SmolStr)>> Parser<I> {
}
fn bump(&mut self) {
if let Some((token, string)) = self.iter.next() {
self.builder.token(token.into(), string);
self.builder.token(token.into(), &string);
}
}
fn parse_val(&mut self) {
Expand Down Expand Up @@ -114,14 +115,14 @@ fn print(indent: usize, element: SyntaxElement) {
let kind: SyntaxKind = element.kind().into();
print!("{:indent$}", "", indent = indent);
match element {
NodeOrToken::Node(node) => {
SyntaxElement::Node(node) => {
println!("- {:?}", kind);
for child in node.children_with_tokens() {
print(indent + 2, child);
}
}

NodeOrToken::Token(token) => println!("- {:?} {:?}", token.text(), kind),
SyntaxElement::Token(token) => println!("- {:?} {:?}", token.text(), kind),
}
}

Expand Down
19 changes: 11 additions & 8 deletions examples/s_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
//! alongside this tutorial:
//! https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/syntax.md

use rowan::ArcBorrow;
use std::sync::Arc;

/// Currently, rowan doesn't have a hook to add your own interner,
/// but `SmolStr` should be a "good enough" type for representing
/// tokens.
/// Additionally, rowan uses `TextSize` and `TextRange` types to
/// represent utf8 offsets and ranges.
use rowan::SmolStr;
use smol_str::SmolStr;

/// Let's start with defining all kinds of tokens and
/// composite nodes.
Expand Down Expand Up @@ -74,7 +77,7 @@ use rowan::GreenNodeBuilder;
/// The parse results are stored as a "green tree".
/// We'll discuss working with the results later
struct Parse {
green_node: GreenNode,
green_node: Arc<GreenNode>,
#[allow(unused)]
errors: Vec<String>,
}
Expand All @@ -89,7 +92,7 @@ fn parse(text: &str) -> Parse {
/// in *reverse* order.
tokens: Vec<(SyntaxKind, SmolStr)>,
/// the in-progress tree.
builder: GreenNodeBuilder<'static>,
builder: GreenNodeBuilder,
/// the list of syntax errors we've accumulated
/// so far.
errors: Vec<String>,
Expand Down Expand Up @@ -176,7 +179,7 @@ fn parse(text: &str) -> Parse {
/// Advance one token, adding it to the current branch of the tree builder.
fn bump(&mut self) {
let (kind, text) = self.tokens.pop().unwrap();
self.builder.token(kind.into(), text);
self.builder.token(kind.into(), &text);
}
/// Peek at the first unprocessed token
fn current(&self) -> Option<SyntaxKind> {
Expand Down Expand Up @@ -323,7 +326,7 @@ impl Atom {
self.text().parse().ok()
}
fn as_op(&self) -> Option<Op> {
let op = match self.text().as_str() {
let op = match self.text() {
"+" => Op::Add,
"-" => Op::Sub,
"*" => Op::Mul,
Expand All @@ -332,9 +335,9 @@ impl Atom {
};
Some(op)
}
fn text(&self) -> &SmolStr {
match &self.0.green().children().next() {
Some(rowan::NodeOrToken::Token(token)) => token.text(),
fn text(&self) -> &str {
match self.0.green().children().next() {
Some(rowan::NodeOrToken::Token(token)) => ArcBorrow::downgrade(token).text(),
_ => unreachable!(),
}
}
Expand Down
85 changes: 44 additions & 41 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{fmt, marker::PhantomData};
use std::{fmt, marker::PhantomData, sync::Arc};

use crate::{
cursor, Direction, GreenNode, GreenToken, NodeOrToken, SmolStr, SyntaxKind, SyntaxText,
TextRange, TextSize, TokenAtOffset, WalkEvent,
cursor, Direction, GreenNode, GreenToken, SyntaxKind, SyntaxText, TextRange, TextSize,
TokenAtOffset, WalkEvent,
};

pub trait Language: Sized + Clone + Copy + fmt::Debug + Eq + Ord + std::hash::Hash {
Expand Down Expand Up @@ -41,8 +41,8 @@ impl<L: Language> fmt::Debug for SyntaxNode<L> {
write!(f, " ")?;
}
match element {
NodeOrToken::Node(node) => writeln!(f, "{:?}", node)?,
NodeOrToken::Token(token) => writeln!(f, "{:?}", token)?,
SyntaxElement::Node(node) => writeln!(f, "{:?}", node)?,
SyntaxElement::Token(token) => writeln!(f, "{:?}", token)?,
}
level += 1;
}
Expand Down Expand Up @@ -87,7 +87,7 @@ impl<L: Language> fmt::Debug for SyntaxToken<L> {
if self.text().len() < 25 {
return write!(f, " {:?}", self.text());
}
let text = self.text().as_str();
let text = self.text();
for idx in 21..25 {
if text.is_char_boundary(idx) {
let text = format!("{} ...", &text[..idx]);
Expand All @@ -104,52 +104,55 @@ impl<L: Language> fmt::Display for SyntaxToken<L> {
}
}

pub type SyntaxElement<L> = NodeOrToken<SyntaxNode<L>, SyntaxToken<L>>;
pub enum SyntaxElement<L: self::Language> {
Node(SyntaxNode<L>),
Token(SyntaxToken<L>),
}

impl<L: Language> From<cursor::SyntaxElement> for SyntaxElement<L> {
fn from(raw: cursor::SyntaxElement) -> SyntaxElement<L> {
match raw {
NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
cursor::SyntaxElement::Node(it) => SyntaxElement::Node(it.into()),
cursor::SyntaxElement::Token(it) => SyntaxElement::Token(it.into()),
}
}
}

impl<L: Language> From<SyntaxElement<L>> for cursor::SyntaxElement {
fn from(element: SyntaxElement<L>) -> cursor::SyntaxElement {
match element {
NodeOrToken::Node(it) => NodeOrToken::Node(it.into()),
NodeOrToken::Token(it) => NodeOrToken::Token(it.into()),
SyntaxElement::Node(it) => cursor::SyntaxElement::Node(it.into()),
SyntaxElement::Token(it) => cursor::SyntaxElement::Token(it.into()),
}
}
}

impl<L: Language> From<SyntaxNode<L>> for SyntaxElement<L> {
fn from(node: SyntaxNode<L>) -> SyntaxElement<L> {
NodeOrToken::Node(node)
SyntaxElement::Node(node)
}
}

impl<L: Language> From<SyntaxToken<L>> for SyntaxElement<L> {
fn from(token: SyntaxToken<L>) -> SyntaxElement<L> {
NodeOrToken::Token(token)
SyntaxElement::Token(token)
}
}

impl<L: Language> fmt::Display for SyntaxElement<L> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
NodeOrToken::Node(it) => fmt::Display::fmt(it, f),
NodeOrToken::Token(it) => fmt::Display::fmt(it, f),
SyntaxElement::Node(it) => fmt::Display::fmt(it, f),
SyntaxElement::Token(it) => fmt::Display::fmt(it, f),
}
}
}

impl<L: Language> SyntaxNode<L> {
pub fn new_root(green: GreenNode) -> SyntaxNode<L> {
pub fn new_root(green: Arc<GreenNode>) -> SyntaxNode<L> {
SyntaxNode::from(cursor::SyntaxNode::new_root(green))
}
pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
pub fn replace_with(&self, replacement: Arc<GreenNode>) -> Arc<GreenNode> {
self.raw.replace_with(replacement)
}

Expand Down Expand Up @@ -190,31 +193,31 @@ impl<L: Language> SyntaxNode<L> {
}

pub fn first_child_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.first_child_or_token().map(NodeOrToken::from)
self.raw.first_child_or_token().map(SyntaxElement::from)
}

pub fn last_child(&self) -> Option<SyntaxNode<L>> {
self.raw.last_child().map(Self::from)
}

pub fn last_child_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.last_child_or_token().map(NodeOrToken::from)
self.raw.last_child_or_token().map(SyntaxElement::from)
}

pub fn next_sibling(&self) -> Option<SyntaxNode<L>> {
self.raw.next_sibling().map(Self::from)
}

pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.next_sibling_or_token().map(NodeOrToken::from)
self.raw.next_sibling_or_token().map(SyntaxElement::from)
}

pub fn prev_sibling(&self) -> Option<SyntaxNode<L>> {
self.raw.prev_sibling().map(Self::from)
}

pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.prev_sibling_or_token().map(NodeOrToken::from)
self.raw.prev_sibling_or_token().map(SyntaxElement::from)
}

pub fn first_token(&self) -> Option<SyntaxToken<L>> {
Expand All @@ -241,28 +244,28 @@ impl<L: Language> SyntaxNode<L> {
}

pub fn descendants_with_tokens(&self) -> impl Iterator<Item = SyntaxElement<L>> {
self.raw.descendants_with_tokens().map(NodeOrToken::from)
self.raw.descendants_with_tokens().map(SyntaxElement::from)
}

pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode<L>>> {
self.raw.preorder().map(|event| event.map(SyntaxNode::from))
}

pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement<L>>> {
self.raw.preorder_with_tokens().map(|event| event.map(NodeOrToken::from))
self.raw.preorder_with_tokens().map(|event| event.map(SyntaxElement::from))
}

pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken<L>> {
self.raw.token_at_offset(offset).map(SyntaxToken::from)
}

pub fn covering_element(&self, range: TextRange) -> SyntaxElement<L> {
NodeOrToken::from(self.raw.covering_element(range))
SyntaxElement::from(self.raw.covering_element(range))
}
}

impl<L: Language> SyntaxToken<L> {
pub fn replace_with(&self, new_token: GreenToken) -> GreenNode {
pub fn replace_with(&self, new_token: Arc<GreenToken>) -> Arc<GreenNode> {
self.raw.replace_with(new_token)
}

Expand All @@ -274,7 +277,7 @@ impl<L: Language> SyntaxToken<L> {
self.raw.text_range()
}

pub fn text(&self) -> &SmolStr {
pub fn text(&self) -> &str {
self.raw.text()
}

Expand All @@ -291,11 +294,11 @@ impl<L: Language> SyntaxToken<L> {
}

pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.next_sibling_or_token().map(NodeOrToken::from)
self.raw.next_sibling_or_token().map(SyntaxElement::from)
}

pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
self.raw.prev_sibling_or_token().map(NodeOrToken::from)
self.raw.prev_sibling_or_token().map(SyntaxElement::from)
}

pub fn siblings_with_tokens(
Expand All @@ -317,43 +320,43 @@ impl<L: Language> SyntaxToken<L> {
impl<L: Language> SyntaxElement<L> {
pub fn text_range(&self) -> TextRange {
match self {
NodeOrToken::Node(it) => it.text_range(),
NodeOrToken::Token(it) => it.text_range(),
SyntaxElement::Node(it) => it.text_range(),
SyntaxElement::Token(it) => it.text_range(),
}
}

pub fn kind(&self) -> L::Kind {
match self {
NodeOrToken::Node(it) => it.kind(),
NodeOrToken::Token(it) => it.kind(),
SyntaxElement::Node(it) => it.kind(),
SyntaxElement::Token(it) => it.kind(),
}
}

pub fn parent(&self) -> Option<SyntaxNode<L>> {
match self {
NodeOrToken::Node(it) => it.parent(),
NodeOrToken::Token(it) => Some(it.parent()),
SyntaxElement::Node(it) => it.parent(),
SyntaxElement::Token(it) => Some(it.parent()),
}
}

pub fn ancestors(&self) -> impl Iterator<Item = SyntaxNode<L>> {
match self {
NodeOrToken::Node(it) => it.ancestors(),
NodeOrToken::Token(it) => it.parent().ancestors(),
SyntaxElement::Node(it) => it.ancestors(),
SyntaxElement::Token(it) => it.parent().ancestors(),
}
}

pub fn next_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
match self {
NodeOrToken::Node(it) => it.next_sibling_or_token(),
NodeOrToken::Token(it) => it.next_sibling_or_token(),
SyntaxElement::Node(it) => it.next_sibling_or_token(),
SyntaxElement::Token(it) => it.next_sibling_or_token(),
}
}

pub fn prev_sibling_or_token(&self) -> Option<SyntaxElement<L>> {
match self {
NodeOrToken::Node(it) => it.prev_sibling_or_token(),
NodeOrToken::Token(it) => it.prev_sibling_or_token(),
SyntaxElement::Node(it) => it.prev_sibling_or_token(),
SyntaxElement::Token(it) => it.prev_sibling_or_token(),
}
}
}
Expand All @@ -380,6 +383,6 @@ pub struct SyntaxElementChildren<L: Language> {
impl<L: Language> Iterator for SyntaxElementChildren<L> {
type Item = SyntaxElement<L>;
fn next(&mut self) -> Option<Self::Item> {
self.raw.next().map(NodeOrToken::from)
self.raw.next().map(SyntaxElement::from)
}
}
Loading

0 comments on commit 58c994c

Please sign in to comment.