Skip to content

Commit

Permalink
Throw some wrappingPos on the result of dyna.mkInvoke.
Browse files Browse the repository at this point in the history
The result is more accurate positions for some dynamics,
as can be seen in the diffs for `run/dynamic-*.scala`,
and less crashy positions for others, as can be seen in
the attached new test case.

Fixes scala/bug#10203.
  • Loading branch information
hrhino committed Mar 19, 2018
1 parent 6385c2b commit d8a3740
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 9 deletions.
10 changes: 8 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4272,12 +4272,18 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ => t.children.flatMap(findSelection).headOption
}
findSelection(cxTree) map { case (opName, treeInfo.Applied(_, targs, _)) =>
val fun = gen.mkTypeApply(Select(qual, opName), targs)
val fun = atPos(wrappingPos(qual :: targs)) {
gen.mkTypeApply(Select(qual, opName) setPos qual.pos, targs)
}
if (opName == nme.updateDynamic) suppressMacroExpansion(fun) // scala/bug#7617
val nameStringLit = atPos(treeSelection.pos.withStart(treeSelection.pos.point).makeTransparent) {
Literal(Constant(name.decode))
}
markDynamicRewrite(atPos(qual.pos)(Apply(fun, List(nameStringLit))))
markDynamicRewrite {
atPos(wrappingPos(qual :: fun :: nameStringLit :: Nil)) {
Apply(fun, List(nameStringLit))
}
}
} getOrElse {
// While there may be an error in the found tree itself, it should not be possible to *not find* it at all.
devWarning(s"Tree $tree not found in the context $cxTree while trying to do a dynamic application")
Expand Down
4 changes: 2 additions & 2 deletions test/files/run/dynamic-applyDynamic.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
};
[17:30]private[this] val d: [21]D = [25:30][25:30][25:30]new [29:30]D();
[21]<stable> <accessor> def d: [21]D = [21][21]X.this.d;
[37:49][37:38][37:38][37]X.this.d.applyDynamic(<39:45>"method")([46:48]10);
[56:61]<56:57><56:57>[56]X.this.d.applyDynamic(<56:57>"apply")([58:60]10)
[37:49][37:45][37:38][37]X.this.d.applyDynamic(<39:45>"method")([46:48]10);
[56:61][56:57]<56:57>[56]X.this.d.applyDynamic(<56:57>"apply")([58:60]10)
}
}

4 changes: 2 additions & 2 deletions test/files/run/dynamic-applyDynamicNamed.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
};
[17:30]private[this] val d: [21]D = [25:30][25:30][25:30]new [29:30]D();
[21]<stable> <accessor> def d: [21]D = [21][21]X.this.d;
[37:70][37:38][37:38][37]X.this.d.applyDynamicNamed(<39:43>"meth")([44:55][44][44]scala.Tuple2.apply[[44]String, [44]Int]([44:50]"value1", [53:55]10), [57:69][57][57]scala.Tuple2.apply[[57]String, [57]Int]([57:63]"value2", [66:69]100));
[77:91]<77:78><77:78>[77]X.this.d.applyDynamicNamed(<77:78>"apply")([79:90][79][79]scala.Tuple2.apply[[79]String, [79]Int]([79:85]"value1", [88:90]10))
[37:70][37:43][37:38][37]X.this.d.applyDynamicNamed(<39:43>"meth")([44:55][44][44]scala.Tuple2.apply[[44]String, [44]Int]([44:50]"value1", [53:55]10), [57:69][57][57]scala.Tuple2.apply[[57]String, [57]Int]([57:63]"value2", [66:69]100));
[77:91][77:78]<77:78>[77]X.this.d.applyDynamicNamed(<77:78>"apply")([79:90][79][79]scala.Tuple2.apply[[79]String, [79]Int]([79:85]"value1", [88:90]10))
}
}

2 changes: 1 addition & 1 deletion test/files/run/dynamic-selectDynamic.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
};
[17:30]private[this] val d: [21]D = [25:30][25:30][25:30]new [29:30]D();
[21]<stable> <accessor> def d: [21]D = [21][21]X.this.d;
[37:38][37:38][37]X.this.d.selectDynamic(<39:44>"field")
[37:44][37:38][37]X.this.d.selectDynamic(<39:44>"field")
}
}

4 changes: 2 additions & 2 deletions test/files/run/dynamic-updateDynamic.check
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
};
[17:30]private[this] val d: [21]D = [25:30][25:30][25:30]new [29:30]D();
[21]<stable> <accessor> def d: [21]D = [21][21]X.this.d;
[37:49][37:38][37:38][37]X.this.d.updateDynamic(<39:44>"field")([47:49]10);
[56:57][56:57][56]X.this.d.selectDynamic(<58:63>"field")
[37:49][37:44][37:38][37]X.this.d.updateDynamic(<39:44>"field")([47:49]10);
[56:63][56:57][56]X.this.d.selectDynamic(<58:63>"field")
}
}

14 changes: 14 additions & 0 deletions test/files/run/t10203.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[[syntax trees at end of typer]] // newSource1.scala
[0:88]package [0:0]<empty> {
[0:88]object X extends [9:88][88]scala.AnyRef {
[88]def <init>(): [9]X.type = [88]{
[88][88][88]X.super.<init>();
[9]()
};
[17:24][17:18][17:18]D.selectDynamic[[17]Nothing](<19:24>"aaaaa");
[31:42][31:42][31:32]D.selectDynamic[[39:42]<type: [39:42]scala.Int>](<33:38>"sssss");
[50:60][50:57][50:51][50:51]D.applyDynamic[[50]Int](<52:57>"ddddd")([58:59]1);
[67:82][67:78][67:78][67:68]D.applyDynamic[[75:78]<type: [75:78]scala.Int>](<69:74>"fffff")([80:81]1)
}
}

28 changes: 28 additions & 0 deletions test/files/run/t10203.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import scala.tools.partest.DirectTest

object Test extends DirectTest {

override def extraSettings: String =
s"-usejavacp -Xprint-pos -Xprint:typer -Yrangepos -Ystop-after:typer -d ${testOutput.path}"

override def code = """
object X {
D.aaaaa
D.sssss[Int]
D.ddddd(1)
D.fffff[Int](1)
}
""".trim

override def show(): Unit = {
Console.withErr(System.out) {
compile()
}
}
}

import language.dynamics
object D extends Dynamic {
def selectDynamic[T](nme: String): String = ???
def applyDynamic[T](name: String)(value: T) = ???
}

0 comments on commit d8a3740

Please sign in to comment.