-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
feat(fmt): WIP update to latest solang-parser #1612
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking good so far,
we can merge this once fmt
command module in the cli crate is reenabled and compiles
As discussed, let's go with the following plan:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good so far, some thoughts/nits..
what remains to get this over the line?
fmt/src/ast_eq.rs
Outdated
Pure(), | ||
View(), | ||
Constant(), | ||
Payable(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be Pure
instead of Pure()
? Given it's an enum with no internal value? @seanyoung maybe a Solang thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why they can't be Pure
rather than Pure()
.
In the solang parse tree, pure has a has a source file location value: Pure(Loc)
but I don't see how that is relevant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just related to the way I wrote the macro here. There's a hidden ..
that covers the Loc
in the enum. I'll pull it out to make it unhidden and more clear.
fmt/src/ast_eq.rs
Outdated
use itertools::Itertools; | ||
use solang_parser::pt::*; | ||
|
||
pub trait AstEq { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the reason why this trait exists because we cannot derive on the larpop code-gened files? https://github.com/hyperledger-labs/solang/blob/c63b552373f9660027568e0af4040a82d8821de7/solang-parser/src/solidity.lalrpop#L20
@seanyoung is there a way for us to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if a #[derive(Eq)]
or something like that can be done in the solang-parser, by all means.
However, I think here there is a specific type of equality is required here, with sorted function attributes for example. I'm not sure how else we could deal with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, agree. A derive macro would definitely make this more succinct, but we would have to cover the cases where order matters and cases where they don't which means making the proc_macro a little more complicated. In the end, because I just use this for writing tests to make sure the formatted parse tree matches, its not super critical I think. Its more just a convenience and double checking my work
fmt/src/formatter.rs
Outdated
@@ -2,11 +2,13 @@ | |||
|
|||
use std::fmt::Write; | |||
|
|||
// use crate::operators::Operator; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// use crate::operators::Operator; |
fmt/src/formatter.rs
Outdated
// let op = Operator::for_expr(expr); | ||
// let is_literal = |exp: &Expression| { | ||
// matches!( | ||
// exp, | ||
// Expression::AddressLiteral(..) | ||
// | Expression::ArrayLiteral(..) | ||
// | Expression::BoolLiteral(..) | ||
// | Expression::HexLiteral(..) | ||
// | Expression::HexNumberLiteral(..) | ||
// | Expression::NumberLiteral(..) | ||
// | Expression::RationalNumberLiteral(..) | ||
// | Expression::StringLiteral(..) | ||
// ) | ||
// }; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be removed? or do we need it elsewhere and still WIP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove it, I've decided to go with a different method for handling unary / binary operators and operator precedence anyways since
fmt/src/formatter.rs
Outdated
write!(self, "]")?; | ||
} | ||
// Expression::Assign(_, var_expr, value_expr) => { | ||
// // TODO handle with operators? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do we need to handle here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll get rid of this section as per my comment above for right now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are a lot of expressions we need to handle here, but they basically get split up into a few categories, binary operators, unary operators and literal expresions and a bunch of one off stuff like assigning, identifiers, member access, function calls etc. My plan was to start with binary operators and build up the correct parentheses management / operator precedence, indentation etc after I get comments working
if !event.doc.is_empty() { | ||
event.doc.visit(self)?; | ||
writeln!(self)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it OK to remove all these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc comments are no longer attached to individual elements and exist as their own nodes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We made that change because solc accepts doc comments anywhere in a file. This is valid solidity:
contract c {}
/** foo */
fmt/src/formatter.rs
Outdated
"(formatted Parse Tree == expected Parse Tree) in {}", | ||
filename | ||
); | ||
// panic!("(formatted Parse Tree == expected Parse Tree) in {}", filename) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// panic!("(formatted Parse Tree == expected Parse Tree) in {}", filename) |
fmt/src/formatter.rs
Outdated
test_directory! { EnumDefinition } | ||
test_directory! { ErrorDefinition } | ||
test_directory! { EventDefinition } | ||
// test_directory! { ExpressionPrecedence } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we re-enable this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was an experiment related to the operator precedence as mentioned above. i'll also remove
fmt/src/helpers.rs
Outdated
// TODO handle me | ||
todo!() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what needs to go here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll expand the todo message here and return false. it shouldn't panic either way
fmt/src/visit.rs
Outdated
// TODO implement me | ||
Ok(()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this log trace::warn!("Formatting not yet implemented for Using")
or something? Same for all our other unimplemented stuff?
Okay, I cleaned up the PR, sorry a lot of work in progress stuff got mixed in because I wasn't sure if this was just here as feedback or if it was going to be merged in before comments were done. I probably should have submitted it as a draft, but this at least fixes the update for solang_parser and doc comments, using statements and a few other small things. I'll hopefully have the comments done soon and I'll open that in a separate PR. And then started working on expressions which I think is the next hardest thing to tackle here. After that, there's the Yul stuff, and incremental improvements I think |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good stuff!
fmt/src/formatter.rs
Outdated
let mut lines = doc_comment | ||
.comment | ||
.lines() | ||
.map(|line| line.trim_start()) | ||
.peekable() | ||
.collect::<Vec<_>>(); | ||
if lines.last() == Some(&"") { | ||
lines.pop(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut lines = doc_comment | |
.comment | |
.lines() | |
.map(|line| line.trim_start()) | |
.peekable() | |
.collect::<Vec<_>>(); | |
if lines.last() == Some(&"") { | |
lines.pop(); | |
} | |
let mut lines = doc_comment | |
.comment | |
.trim_end() | |
.lines() | |
.map(|line| line.trim_start()) | |
.peekable() | |
.collect::<Vec<_>>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
much cleaner and correcter! thanks!
* Make AstEq more clear * Code reorganization * Handling easy todos * Remove useless comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pr updates the solang-parser crate in fmt, but cli still using an old version: https://github.com/jpopesculian/foundry/blob/fmt/cli/Cargo.toml#L29
This means the formattter could re-format something that the cli code then cannot parse.
Motivation
Build fails with the newest version of solang-parser if dependencies are not locked
Solution
Update to use the latest version of solang-parser and also lock the solang-parser version