Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose sorbus as green tree impl #69

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 nice feature name!

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