-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rewrite algo::diff to support insertion and deletion #6310
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
Conversation
| r#" | ||
| fn {a:42, b: ()} {} | ||
| fn some(, b: ()} {} | ||
| fn items() {} |
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.
Thanks to this macro text expecting already broken output you can see the result of these changes in that the diff became smaller here 😄
crates/syntax/src/algo.rs
Outdated
| deletions: Vec<SyntaxElement>, | ||
| // the vec as well as the indexmap are both here to preserve order | ||
| insertions: | ||
| IndexMap<SyntaxElement, Vec<SyntaxElement>, BuildHasherDefault<rustc_hash::FxHasher>>, |
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.
Insertion order is important as insertions might be chained after each other. The IndexMap could be replace by Vec<(SyntaxElement, Vec<SyntaxElement>) with binary_search insertion on the first tuple part as the key but I'm uncertain what would be better.
| (Some(lhs_ele), Some(rhs_ele)) => go(diff, lhs_ele, rhs_ele), | ||
| } | ||
| last_lhs = lhs_child.or(last_lhs); |
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.
Hm, would this work corretly if the go ends up replacing the whole lhs_child, and then, on the next iteration, we use it as an anchor in inserts?
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.
Ah, it seems it will work, cool!
| // first iteration, this means we got no anchor element to insert after | ||
| // therefor replace the parent node instead |
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.
An alternative is to key insertion not by SyntaxElement, but by (SyntaxElement, bool), where bool should choose between prev sibling and parent. But this is also ok
|
Nifty, didn't realize that we can improve tree diffing this way! r=me wiith FxIndexMap nit fixed If you feel like ii though, adding some unit-tests for tree diff based on |
ef08d2f to
32fc764
Compare
32fc764 to
0059188
Compare
|
bors r+ |
This in turn also makes
algo::diffgenerate finer diffs(maybe even minimal diffs?) as insertions and deletions aren't always represented as as replacements of parent nodes now.Required for #6287 to go on.