Skip to content

Simplify Source Positions #5713

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

Merged
merged 102 commits into from
Jan 18, 2019
Merged

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jan 15, 2019

Based on #5644, this PR simplifies and clarifies the handling of source positions.

  • The source file of a tree is always given explicitly when we construct the tree.

  • The initial span of the tree is computed from all children that have the
    same source as the tree.

  • Computing the initial span of a tree or setting it using withSpan also fills in children's spans where possible. A filled-in child span is one of

    • the end position of the sibling tree to its left, if one exists
    • otherwise, the start position of the parent span, if it exists
    • otherwise the start position of the sibling tree to its right, if it exists
    • otherwise the span is left absent, to be filled in when parents further up are defined.

With these changes, there were now various trees that got rejected since they do not have a position (typically since all children come from different sources). This required various fixes, mostly in Inliner and Stager.

Copy link
Member

@dottybot dottybot left a 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:

  1. Separate subject from body with a blank line
  2. When fixing an issue, start your commit message with Fix #<ISSUE-NBR>:
  3. Limit the subject line to 72 characters
  4. Capitalize the subject line
  5. Do not end the subject line with a period
  6. Use the imperative mood in the subject line ("Add" instead of "Added")
  7. Wrap the body at 80 characters
  8. Use the body to explain what and why vs. how

adapted from https://chris.beams.io/posts/git-commit

Have an awesome day! ☀️

@odersky odersky force-pushed the refactor-sourcepos branch from d5dfe16 to c816b6e Compare January 15, 2019 13:04
@odersky
Copy link
Contributor Author

odersky commented Jan 15, 2019

test performance please

@dottybot
Copy link
Member

performance test scheduled: 3 job(s) in queue, 1 running.

@odersky
Copy link
Contributor Author

odersky commented Jan 15, 2019

Unfortunately, but not unexpectedly, there's again a bunch of REPL tests that break. REPL seems to build trees with multiple source files that are really all different objects standing for the same file. That's a bad idea now, since it will result in missing positions.

@odersky
Copy link
Contributor Author

odersky commented Jan 15, 2019

test performance please

@dottybot
Copy link
Member

performance test scheduled: 3 job(s) in queue, 1 running.

@dottybot
Copy link
Member

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/5713/ to see the changes.

Benchmarks is based on merging with master (615fdc9)

@odersky
Copy link
Contributor Author

odersky commented Jan 15, 2019

Performance looks OK. So maybe we finally reach the end of the tunnel?

@odersky odersky force-pushed the refactor-sourcepos branch from 36c1314 to f494bd1 Compare January 15, 2019 19:20
@odersky
Copy link
Contributor Author

odersky commented Jan 15, 2019

@nicolasstucki Could you give this another round for getting the repl tests to pass? Thanks!

@nicolasstucki
Copy link
Contributor

I will have a look at the repl failures.

@nicolasstucki
Copy link
Contributor

Rebased

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Jan 16, 2019

There is still an issue with SuperAccessors. It can be reproduced with
testOnly dotty.tools.repl.DocTests -- dotty.tools.repl.DocTests.docOfObject.

[error]     at dotty.tools.dotc.transform.SuperAccessors.wrapTemplate(SuperAccessors.scala:188)

is called twice with the same object.

@nicolasstucki
Copy link
Contributor

Not anymore. Now it only happens when calling withSpan explicitly.

@smarter
Copy link
Member

smarter commented Jan 16, 2019

Are you sure ? The initial span in Positioned is computed using span = envelope(src) and envelope does look at the span of children to compute the span of the current element.

@nicolasstucki
Copy link
Contributor

I missed that one.

@nicolasstucki
Copy link
Contributor

The issue is that they come from two different files <console> and rs$line$1. That is why it is not assigned. Though in theory, those come from the same line.

@allanrenucci
Copy link
Contributor

The issue is that they come from two different files <console> and rs$line$1. That is why it is not assigned. Though in theory, those come from the same line.

Then let's use the same filename 😄. I am wondering if we could use <console> everywhere. For instance, here: https://github.com/lampepfl/dotty/blob/4ecbb60119008febec99c153025ecd03da428c12/compiler/src/dotty/tools/repl/ReplCompiler.scala#L144
and here: https://github.com/lampepfl/dotty/blob/4ecbb60119008febec99c153025ecd03da428c12/compiler/src/dotty/tools/repl/ReplDriver.scala#L168
Or if the file name needs to match the name of the wrapper object for some reason

@smarter
Copy link
Member

smarter commented Jan 16, 2019

Then let's use the same filename

That used to work but one commit in this PR actually changed equality to not be based on filenames: 1a358c0 this is more correct in general but means we can't get away with just using the same name for the repl

@nicolasstucki
Copy link
Contributor

I'm already working on that. The solution is to have the same SourceFile instance. This requires a bit of refactoring.

@nicolasstucki
Copy link
Contributor

test performance please

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 1 running.

@dottybot
Copy link
Member

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/5713/ to see the changes.

Benchmarks is based on merging with master (5547a0b)

Copy link
Contributor

@nicolasstucki nicolasstucki left a comment

Choose a reason for hiding this comment

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

Commits for @odersky LGTM

if (f == null || f.isVirtual)
// don't trust virtual files for tree creation - replTest fails otherwise
ctx.source
if (f == null) ctx.source
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Relieved that we could remove this!


import scala.annotation.internal.sharable

/** A parsing result from string input */
sealed trait ParseResult

/** An error free parsing resulting in a list of untyped trees */
case class Parsed(sourceCode: String, trees: List[untpd.Tree]) extends ParseResult
Copy link
Contributor Author

Choose a reason for hiding this comment

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

That looks much better.

@odersky
Copy link
Contributor Author

odersky commented Jan 18, 2019

Commits for @nicolasstucki LGTM

@odersky
Copy link
Contributor Author

odersky commented Jan 18, 2019

I ran some stats to find out how many SimpleIdentityMaps of size > 4 we create, and of what size. Test inputs is everything in dotc/typer (about 10000 loc).

Here's what we have:

SimpleIdentityMap/5 -> 205
SimpleIdentityMap/6 -> 78
SimpleIdentityMap/7 -> 28
SimpleIdentityMap/8 -> 10
SimpleIdentityMap/9 -> 2

Nothing beyond that.

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

Great stuff !

This is more efficient, especially for small sizes where setup cost for Array.copy
is higher.
This makes the source change tracking in MacroTransform redundant.
@odersky
Copy link
Contributor Author

odersky commented Jan 18, 2019

@smarter All points addressed now, I think.

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

👍


def Ident(tree: Tree)(name: Name): Ident = tree match {
protected def srcCtx(tree: Tree)(implicit ctx: Context) = ctx.withSource(tree.source)
Copy link
Member

Choose a reason for hiding this comment

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

This method is never used.


/** Removes all Inlined trees, replacing them with blocks.
* Repositions all trees directly inside an inlined expansion of a non empty call to the position of the call.
* Any tree directly inside an empty call (inlined in the inlined code) retains their position.
*/
class Reposition extends TreeMap {
override def transform(tree: Tree)(implicit ctx: Context): Tree = {
tree match {
if (tree.source != ctx.source && tree.source.exists)
Copy link
Member

Choose a reason for hiding this comment

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

No longer needed since TreeMap does that now.

@@ -71,11 +71,11 @@ object Parsers {
/** Positions tree.
* If `t` does not have a position yet, set its position to the given one.
Copy link
Member

Choose a reason for hiding this comment

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

position -> span ?

// Nodes which have the same positions as their parents are omitted.
// offset_Deltas give difference of start/end offset wrt to the
// same offset in the previously recorded node (or 0 for the first recorded node)
Delta = Int // Difference between consecutive offsets,
SOURCE = 4 // Impossible as header, since addr_Delta = 0 implies that we refer to the
// same treeas the previous one, but then hasStartDiff = 1 implies that
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// same treeas the previous one, but then hasStartDiff = 1 implies that
// same tree as the previous one, but then hasStartDiff = 1 implies that

... and bump major Tasty version

Also: drop unused method
@odersky odersky force-pushed the refactor-sourcepos branch from 005ff4e to 652b570 Compare January 18, 2019 17:38
@odersky odersky merged commit e724058 into scala:master Jan 18, 2019
@Blaisorblade Blaisorblade deleted the refactor-sourcepos branch January 19, 2019 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants