-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Promote WhileDo
loops to typed trees.
#5113
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
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.
Hello, and thank you for opening this PR! 🎉
All contributors have signed the CLA, thank you! ❤️
Commit Messages
We want to keep history, but for that to actually be useful we have
some rules on how to format our commit messages (relevant xkcd).
Please stick to these guidelines for commit messages:
- Separate subject from body with a blank line
- When fixing an issue, start your commit message with
Fix #<ISSUE-NBR>:
- Limit the subject line to 72 characters
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line ("Add" instead of "Added")
- Wrap the body at 80 characters
- Use the body to explain what and why vs. how
adapted from https://chris.beams.io/posts/git-commit
Have an awesome day! ☀️
Everything seems to work fine, except the source display. One command that reproduces the issue:
Apparently the typer (or some other early phase) collapses nested @nicolasstucki Any idea to fix this? |
There is some logic taking care of the collapsed |
Hum, I don't think that's going to help me. I wonder if maybe the best thing to do would simply be to remove |
// while ({ { body }; { cond } }) { () } | ||
// the inner blocks are there to protect the scopes of body and cond from each other | ||
val protectedBody = Block(Nil, body).withPos(body) | ||
val protectedCond = Block(Nil, cond).withPos(cond) |
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 block for cond
needed?
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 am not 100% sure. I can't really come up with a problematic source code, but at the same time I cannot convince myself that there are no problematic source code. It is definitely possible to come up with a problematic AST (with cond
being a ValDef
for example), but the source syntax doesn't allow that, AFAICT. IMO it's better to play it safe.
labelDefAndCall(nme.DO_WHILE_PREFIX, rhs, call) | ||
// while ({ { body }; { cond } }) { () } | ||
// the inner blocks are there to protect the scopes of body and cond from each other | ||
val protectedBody = Block(Nil, body).withPos(body) |
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 withPos calls should be unnecessary: a tree position is the union of the positions of its children.
We can remove the do while from tasty reflect. We would then simply do a best effort in the decompiler to recover do while. |
I'm already doing the best-effort to recover the The only approach I can see involves deep inspection: if the
If it doesn't, we can display a |
I was also considering the deep inspection. I would say we should just decompile it as a while loop. If someone actually cares about them in the future, at that moment we would implement the best effort decompilation of do while loops. Let's not waste time more time now and keep it simple. |
c59877a
to
26c7fdc
Compare
So, turns out I was wrong: |
It's green now :) Ready for a full review. |
case Trees.Block((ddef: tpd.DefDef) :: Nil, expr) if expr.symbol.is(Flags.Label) && expr.symbol.name == nme.WHILE_PREFIX => | ||
val Trees.If(cond, Trees.Block(bodyStats, _), _) = ddef.rhs | ||
Some((cond, loopBody(bodyStats))) | ||
case x: tpd.WhileDo => Some((x.cond, x.body)) |
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.
Before this case we should check that this is not a do while
.
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.
Or maybe it would be better to remove the do while
extractor and place that condition in the decompiler.
case Term.While(cond, body) => | ||
this += "while " | ||
inParens(printTree(cond)) += " " | ||
printTree(body) | ||
|
||
case Term.DoWhile(body, cond) => |
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 should not be changed. The order should not matter.
@nicolasstucki I have added a commit that removes |
Submodule reference can be updated now that lampepfl/scala#38 is merged. |
f900fe0
to
58f0dda
Compare
Done. |
@sjrd you may need to rebase |
Hum, I ... did rebase, without conflict, but apparently there was a semantic conflict. I'll fix it later today, or tomorrow. |
They remain as such, without desugaring, until the back-end. We also use them to desugar `DoWhile` loops, instead of label-defs: do { body } while (cond) is now desugared as while { { body }; { cond } } () the inner blocks protecting the respective scopes of `body` and `cond` from each other. This is the second step towards getting rid of label-defs.
This avoids the awkward situation where `WhileDo` needs to be tested before `While` for it to meaningful, or suffering some more performance hit by rejecting `do-while`-like stuff in the `While` deconstructor. It will probably also simplify most usage patterns of the tasty-reflect API, since users will only have to worry about one kind of loop. The decompiler takes it upon itself to deconstruct `While` loops that look like the product of `do..while` to print a nice decompilation output.
58f0dda
to
2acfbf8
Compare
Back to green. |
They remain as such, without desugaring, until the back-end. We also use them to desugar
DoWhile
loops, instead of label-defs.This is the second step towards getting rid of label-defs.