Skip to content

Add -print-lines #3523

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 4 commits into from
Nov 23, 2017
Merged

Add -print-lines #3523

merged 4 commits into from
Nov 23, 2017

Conversation

nicolasstucki
Copy link
Contributor

This can be used with dotc -decompiler -print-lines ... or dotc -Xprint.

@nicolasstucki
Copy link
Contributor Author

Example output for

class Foo {

  def foo = {
    3 + 6 +
     7 + 8 +
      9
    "asdfdsfdsfdsgfsg" +
    "asdfdsfdsfdsgfsg" +
    "asdfdsf654765dsfdsgfsg" +
    "asdfdsfdsfdsgfsg" +
    "asdfdsfd7645767sfdsgfsg" +
    "dfdsgfgdfhtrtyuu6" +
    "asdfdsfdsfdsgfsg" +
    "asdf53453dsfdsfdsgfsg"

  }
  def bar =
    foo

  println(
    "2"
  )
 List(1, 2, 3).
   max
}
    1|package <empty> {
    1|  @scala.annotation.internal.SourceFile("Foo.scala") class Foo() extends 
     |    Object
     |  () { 
    3|    def foo: String = 
     |      {
  4-6|        3.+(6).+(7).+(8).+(9)
  7-8|        "asdfdsfdsfdsgfsg".+("asdfdsfdsfdsgfsg").+(
    9|          "asdfdsf654765dsfdsgfsg"
 9-11|        ).+("asdfdsfdsfdsgfsg").+("asdfdsfd7645767sfdsgfsg").+(
   12|          "dfdsgfgdfhtrtyuu6"
12-14|        ).+("asdfdsfdsfdsgfsg").+("asdf53453dsfdsfdsgfsg")
     |      }
17-18|    def bar: String = this.foo
20-21|    println("2")
23-24|    List.apply[Int]([1,2,3 : Int]: Int*).max[Int](scala.math.Ordering.Int)
     |  }
     |}

We use line ranges to ensure all lines from the source are accounted in each line of type checked code.

@smarter
Copy link
Member

smarter commented Nov 22, 2017

This is interesting, but why not tweak the pretty-printer so that it uses the source line number to decide where to put newlines instead of the -pagewidth setting? Then the output line numbers and source line numbers would be exactly the same.

@nicolasstucki
Copy link
Contributor Author

That was my initial approach. But while implementing it I stumbled upon several issues.

The first is that it was hard to maintain a pleasing formatting while adding the new lines on each new source line. Making this work correctly would require a fair amount of work and possibly and possibly some major changes in the pretty printer.

The second and most important reason is that there is no linear correspondence between the source lines and the code in the trees. For example, the synthetic apply of a case class has the same position as the definition of the class but it will be placed inside and potentially after some other code that is in the sources. Furthermore, for expressions such as

1 ::
2 ::
Nil

The positions will be reversed which would make it impossible to print source line by source line. We could try to reverse engineer all desugared tree just to try to keep line numbers, but I feel that it would be a can of worms and that we would lose useful information about how the code is desugared/typed.

We still can combine this with -Yprint-pos to show precise positions. We could try to make a more user-friendly version of it in case this line scheme is not precise enough for their use case.

@@ -155,7 +171,7 @@ object Texts {
def lines(xs: Traversable[Text]) = Vertical(xs.toList.reverse)
}

case class Str(s: String) extends Text {
case class Str(s: String, startLine: Int = Int.MaxValue, endLine: Int = -1) extends Text {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would create a special purpose class Lines with a special instance NoLine. I think it is weird to use Int.MaxValue and -1 as special values. You can even make it a value class that wraps a Long like Position if performance matters here.

@@ -694,4 +705,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}

override def plain = new PlainPrinter(_ctx)

def withPos(txt: Text, pos: SourcePosition): Text = {
Copy link
Contributor

Choose a reason for hiding this comment

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

private?

@nicolasstucki nicolasstucki merged commit 1d79ae2 into scala:master Nov 23, 2017
@allanrenucci allanrenucci deleted the print-lines branch December 14, 2017 19:24
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.

3 participants