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

Better typed api #105

Merged
merged 33 commits into from
Jul 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9f56e12
more types; add match_ast; literalkind
oberblastmeister Oct 1, 2021
61211a3
use rowan AstNode
oberblastmeister Jul 19, 2022
3743c07
transition AST type to Parse type
oberblastmeister Jul 19, 2022
6706b12
implement From for enum AstNodes
oberblastmeister Jul 19, 2022
6590dea
start literal node in string and add comment
oberblastmeister Jul 19, 2022
ae449c1
distinguish between keys and attrs
oberblastmeister Jul 19, 2022
acabaa3
use rowan AstChildren
oberblastmeister Jul 19, 2022
46148ba
fix macro indentation
oberblastmeister Jul 19, 2022
57bb3f1
api improvements
oberblastmeister Jul 19, 2022
8a3ad43
use Root::parse function
oberblastmeister Jul 19, 2022
f9d4281
update tests to make string a literal also
oberblastmeister Jul 19, 2022
91717e2
separate string related stuff from value.rs
oberblastmeister Jul 19, 2022
e2c669f
Update src/ast/expr_ext.rs
oberblastmeister Jul 19, 2022
dc58b01
Update src/ast/expr_ext.rs
oberblastmeister Jul 19, 2022
3f8bfb6
remove value.rs
oberblastmeister Jul 20, 2022
460b07e
delete types.rs
oberblastmeister Jul 20, 2022
ef22d2c
update examples
oberblastmeister Jul 20, 2022
62052fb
Update src/ast/str_util.rs
oberblastmeister Jul 21, 2022
3e6c10f
don't put NODE_STRING under NODE_LITERAL
oberblastmeister Jul 21, 2022
1ea3f7b
add catch all case for macro
oberblastmeister Jul 21, 2022
f0fda83
Better macro syntax
oberblastmeister Jul 21, 2022
9a1cee9
updae list-fns example
oberblastmeister Jul 21, 2022
fcaa745
change token macros
oberblastmeister Jul 21, 2022
4bb1ccd
Update examples/list-fns.rs
oberblastmeister Jul 21, 2022
141ea37
port some tests
oberblastmeister Jul 22, 2022
b0a5d72
port another test
oberblastmeister Jul 22, 2022
d87d171
ok
oberblastmeister Jul 22, 2022
63952e3
update match_ast documentation
oberblastmeister Jul 22, 2022
340fd89
delete stray file
oberblastmeister Jul 22, 2022
059206d
token getters for InheritFrom
oberblastmeister Jul 22, 2022
518df53
node improvments
oberblastmeister Jul 22, 2022
ecd0ca8
rename EntryHolder to HasEntry
oberblastmeister Jul 22, 2022
7ef4dd2
make children_tokens generic
oberblastmeister Jul 22, 2022
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
84 changes: 39 additions & 45 deletions examples/list-fns.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{env, error::Error, fs};

use rnix::ast::AstToken;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
use rnix::ast::AstToken;

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed.

use rnix::{
ast::{self, EntryHolder},
oberblastmeister marked this conversation as resolved.
Show resolved Hide resolved
NodeOrToken, SyntaxNode,
match_ast, NodeOrToken, SyntaxNode,
};
use rowan::ast::AstNode;

#[macro_export]
macro_rules! single_match {
($expression:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? => $captured:expr) => {
match $expression {
Expand All @@ -33,7 +33,7 @@ fn main() -> Result<(), Box<dyn Error>> {
};
for entry in set.entries() {
if let ast::Entry::KeyValue(key_value) = entry {
if let ast::Expr::Lambda(lambda) = key_value.value().unwrap() {
if let Some(ast::Expr::Lambda(lambda)) = key_value.value() {
let key = key_value.key().unwrap();
let ident = key.attrs().last().and_then(|attr| match attr {
ast::Attr::Ident(ident) => Some(ident),
Expand All @@ -44,22 +44,26 @@ fn main() -> Result<(), Box<dyn Error>> {
|ident| ident.ident_token().unwrap().text().to_string(),
);
println!("Function name: {}", s);
// if let Some(comment) = find_comment(key.syntax().clone()) {
// println!("-> Doc: {}", comment);
// }
{
let comments = comments_before(key_value.syntax());
if !comments.is_empty() {
println!("--> Doc: {comments}");
}
}

let mut value = Some(lambda);
while let Some(lambda) = value {
let s = ident.as_ref().map_or_else(
|| "error".to_string(),
|ident| ident.ident_token().unwrap().to_string(),
);
println!("-> Arg: {}", s);
// if let Some(comment) =
// lambda.param().map(|param| param.syntax()).and_then(find_comment)
// {
// println!("--> Doc: {}", comment);
// }
let s = lambda
.param()
.as_ref()
.map_or_else(|| "error".to_string(), |param| param.to_string());
println!("-> Param: {}", s);
{
let comments = comments_before(lambda.syntax());
if !comments.is_empty() {
println!("--> Doc: {comments}");
}
}
value =
single_match!(lambda.body().unwrap(), ast::Expr::Lambda(lambda) => lambda);
}
Expand All @@ -71,32 +75,22 @@ fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}

// fn find_comment(node: &SyntaxNode) -> Option<String> {
// let mut node = NodeOrToken::Node(node);
// let mut comments = Vec::new();
// loop {
// loop {
// if let Some(new) = node.prev_sibling_or_token() {
// node = new;
// break;
// } else {
// node = NodeOrToken::Node(node.parent()?);
// }
// }

// match node.kind() {
// TOKEN_COMMENT => match &node {
// NodeOrToken::Token(token) => comments.push(token.text().to_string()),
// NodeOrToken::Node(_) => unreachable!(),
// },
// t if t.is_trivia() => (),
// _ => break,
// }
// }
// let doc = comments
// .iter()
// .map(|it| it.trim_start_matches('#').trim())
// .collect::<Vec<_>>()
// .join("\n ");
// Some(doc).filter(|it| !it.is_empty())
// }
fn comments_before(node: &SyntaxNode) -> String {
node.siblings_with_tokens(rowan::Direction::Prev)
// rowan always returns the first node for some reason
.skip(1)
.map_while(|element| match element {
NodeOrToken::Token(token) => match_ast! {
match token {
ast::Comment(it) => Some(Some(it)),
ast::Whitespace(_) => Some(None),
_ => None,
}
},
_ => None,
})
.flatten()
.map(|s| s.text().trim().to_string())
.collect::<Vec<_>>()
.join(" ")
oberblastmeister marked this conversation as resolved.
Show resolved Hide resolved
}
4 changes: 0 additions & 4 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ mod support {
use super::{AstNode, AstToken};
use crate::{SyntaxElement, SyntaxKind, SyntaxToken};

pub(super) fn first<N: AstNode, NN: AstNode>(parent: &N) -> Option<NN> {
parent.syntax().children().find_map(|n| NN::cast(n))
}

pub(super) fn nth<N: AstNode, NN: AstNode>(parent: &N, n: usize) -> Option<NN> {
parent.syntax().children().flat_map(NN::cast).nth(n)
}
Expand Down
8 changes: 6 additions & 2 deletions src/ast/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,17 @@ macro_rules! ast_tokens {

ast_tokens! {
TOKEN_WHITESPACE => Whitespace,
TOKEN_COMMENT => Comment,
TOKEN_COMMENT => Comment: {
pub fn text(&self) -> &str {
self.syntax().text().strip_prefix('#').unwrap()
}
},
TOKEN_FLOAT => Float: {
pub fn value(&self) -> Result<f64, num::ParseFloatError> {
self.syntax().text().parse()
}
},
TOKEN_INTEGER => Integer: {
TOKEN_INTEGER => Integer: {
pub fn value(&self) -> Result<i64, num::ParseIntError> {
self.syntax().text().parse()
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use self::{kinds::SyntaxKind, tokenizer::tokenize};

use ast::AstNode;
use parser::ParseError;
use rowan::{ast::AstNode as OtherAstNode, GreenNode};
use rowan::GreenNode;
pub use rowan::{NodeOrToken, TextRange, TextSize, TokenAtOffset, WalkEvent};

use self::tokenizer::Tokenizer;
Expand Down Expand Up @@ -98,7 +98,7 @@ macro_rules! match_ast {
(match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };

(match ($node:expr) {
$( ast::$ast:ident($it:ident) => $res:expr, )*
$( ast::$ast:ident($it:pat) => $res:expr, )*
_ => $catch_all:expr $(,)?
}) => {{
$( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )*
Expand Down