Scala Programming Language
  1. Scala Programming Language
  2. SI-4287

Range positions for default arguments are incorrect

    Details

      Description

      === What steps will reproduce the problem (please be specific and use wikiformatting)? ===

      Compile the following code with Scaladoc:

      class A(val a: Int = 4) {
         def k1(x:Int = (new B).t ):Int= x
      }
      class B {
         val t: Int = 0
      }
      

      The generated Scaladoc, which uses range positions to extract default arguments from source, has the following signatures for A:

      class A(val a: Int) {
         def k1(x:Int = new B).t ):Int
      }
      

      Notice:

      • The default argument for the constructor parameter disappeared because a non-ranged position is generated for it (so that its `startOrPoint` and `endOrPoint` indices are equal).
      • The default argument for method parameter x has lost its first `(` because its `startOrPoint` index is one too much.

      === Additional information ===

      Ranged positions are not generated in a normal compiler run. Scaladoc is a way to demonstrate this issue because it forces the compiler to generate ranged positions, and outputs an artefact based upon them. Running the compiler in interactive mode for an IDE should have the same issue, but I do not know how to visualise the issue in the IDE.

      To debug directly on position rather than indirectly through the resulting documentation, a possible entry point is at the beginning of method `makeTree` in class `scala.tools.nsc.doc.model.TreeFactory`.

      Tested in 2.9 trunk r24334.

        Activity

        Hide
        Mirco Dotta added a comment - - edited

        I just ran the compiler based on this commit on the code example in the ticket linked by Iulian. Below is the tree printed after typer, with -Yrangepos flag

        [[syntax trees at end of                     typer]] // Foo.scala
        [0:63]package [0:0]<empty> {
          [0:37]class Baz extends [9:37][39]scala.AnyRef {
            [10:31]<paramaccessor> private[this] val f: [14]Int = _;
            [14]<stable> <accessor> <paramaccessor> def f: [14]Int = [14][14]Baz.this.f;
            [39]def <init>([14]f: [17]<type: [17]scala.Int> = [30]B.a): [9]Baz = [39]{
              [39][39][39]Baz.super.<init>();
              [9]()
            }
          };
          [6]<synthetic> object Baz extends [6][6]AnyRef {
            [6]def <init>(): [9]Baz.type = [6]{
              [6][6][6]Baz.super.<init>();
              [9]()
            };
            [14]<synthetic> def <init>$default$1: [14]Int = [30]B.a
          };
          [39:63]object B extends [48:63][63]scala.AnyRef {
            [63]def <init>(): [48]B.type = [63]{
              [63][63][63]B.super.<init>();
              [48]()
            };
            [52:61]private[this] val a: [56]Int = [60:61]2;
            [56]<stable> <accessor> def a: [56]Int = [56][56]B.this.a
          }
        }
        

        Looks like offset position are assigned to the `B.a` tree, which is why hyperlinking fails.

        Show
        Mirco Dotta added a comment - - edited I just ran the compiler based on this commit on the code example in the ticket linked by Iulian. Below is the tree printed after typer, with -Yrangepos flag [[syntax trees at end of typer]] // Foo.scala [0:63]package [0:0]<empty> { [0:37]class Baz extends [9:37][39]scala.AnyRef { [10:31]<paramaccessor> private[this] val f: [14]Int = _; [14]<stable> <accessor> <paramaccessor> def f: [14]Int = [14][14]Baz.this.f; [39]def <init>([14]f: [17]<type: [17]scala.Int> = [30]B.a): [9]Baz = [39]{ [39][39][39]Baz.super.<init>(); [9]() } }; [6]<synthetic> object Baz extends [6][6]AnyRef { [6]def <init>(): [9]Baz.type = [6]{ [6][6][6]Baz.super.<init>(); [9]() }; [14]<synthetic> def <init>$default$1: [14]Int = [30]B.a }; [39:63]object B extends [48:63][63]scala.AnyRef { [63]def <init>(): [48]B.type = [63]{ [63][63][63]B.super.<init>(); [48]() }; [52:61]private[this] val a: [56]Int = [60:61]2; [56]<stable> <accessor> def a: [56]Int = [56][56]B.this.a } } Looks like offset position are assigned to the `B.a` tree, which is why hyperlinking fails.
        Hide
        Mirco Dotta added a comment -

        @Paul Are you currently working on this? I think I should be able to fix it...

        Show
        Mirco Dotta added a comment - @Paul Are you currently working on this? I think I should be able to fix it...
        Hide
        Mirco Dotta added a comment -

        I'm assigning this to me, as I would like it to be fixed in time for 2.11.0-M8 (possibly even 2.10.4-RC1, but it may be a bit short). Paul let me know if you want me to pass the ball back.

        Show
        Mirco Dotta added a comment - I'm assigning this to me, as I would like it to be fixed in time for 2.11.0-M8 (possibly even 2.10.4-RC1, but it may be a bit short). Paul let me know if you want me to pass the ball back.
        Hide
        Paul Phillips added a comment -

        Please enjoy it. My struggles with positions have become ineffectual.

        Show
        Paul Phillips added a comment - Please enjoy it. My struggles with positions have become ineffectual.
        Hide
        Mirco Dotta added a comment - - edited

        PR opened 3210 I've closed the former, and opened a new one https://github.com/scala/scala/pull/3269

        Show
        Mirco Dotta added a comment - - edited PR opened 3210 I've closed the former, and opened a new one https://github.com/scala/scala/pull/3269

          People

          • Assignee:
            Mirco Dotta
            Reporter:
            Gilles Dubochet
            TracCC:
            Mirko Stocker
          • Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development