diff options
author | odersky <odersky@gmail.com> | 2016-09-16 19:51:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-16 19:51:44 +0300 |
commit | 9ae9a20e6c1b349728d8b0ecd2144ed613cd0ef2 (patch) | |
tree | 18fcd1a7eeb5f3ad61bf8dae52daba45cdab8272 /tests/run | |
parent | 5d8f132b98ca10e47773275c7048ce132f5f197c (diff) | |
parent | 0ee74cc0f8252caa189f0a7aaf8a274df486f971 (diff) | |
download | dotty-9ae9a20e6c1b349728d8b0ecd2144ed613cd0ef2.tar.gz dotty-9ae9a20e6c1b349728d8b0ecd2144ed613cd0ef2.tar.bz2 dotty-9ae9a20e6c1b349728d8b0ecd2144ed613cd0ef2.zip |
Merge pull request #1469 from dotty-staging/fix-scala.Dynamic
Fixes for scala.Dynamic
Diffstat (limited to 'tests/run')
-rw-r--r-- | tests/run/applydynamic_sip.check | 29 | ||||
-rw-r--r-- | tests/run/applydynamic_sip.flags | 2 | ||||
-rw-r--r-- | tests/run/applydynamic_sip.scala | 67 | ||||
-rw-r--r-- | tests/run/dynamic-anyval.check | 4 | ||||
-rw-r--r-- | tests/run/dynamic-anyval.scala | 22 | ||||
-rw-r--r-- | tests/run/dynamicDynamicTests.scala | 41 | ||||
-rw-r--r-- | tests/run/t4536.check | 8 | ||||
-rw-r--r-- | tests/run/t4536.flags | 1 | ||||
-rw-r--r-- | tests/run/t4536.scala | 42 | ||||
-rw-r--r-- | tests/run/t5040.check | 1 | ||||
-rw-r--r-- | tests/run/t5040.flags | 1 | ||||
-rw-r--r-- | tests/run/t5040.scala | 12 | ||||
-rw-r--r-- | tests/run/t5733.check | 2 | ||||
-rw-r--r-- | tests/run/t5733.scala | 53 | ||||
-rw-r--r-- | tests/run/t6353.check | 1 | ||||
-rw-r--r-- | tests/run/t6353.scala | 12 | ||||
-rw-r--r-- | tests/run/t6355.check | 2 | ||||
-rw-r--r-- | tests/run/t6355.scala | 17 | ||||
-rw-r--r-- | tests/run/t6663.check | 1 | ||||
-rw-r--r-- | tests/run/t6663.flags | 1 | ||||
-rw-r--r-- | tests/run/t6663.scala | 17 |
21 files changed, 336 insertions, 0 deletions
diff --git a/tests/run/applydynamic_sip.check b/tests/run/applydynamic_sip.check new file mode 100644 index 000000000..6d04dc452 --- /dev/null +++ b/tests/run/applydynamic_sip.check @@ -0,0 +1,29 @@ +qual.applyDynamic(sel)() +qual.applyDynamic(sel)(a) +qual.applyDynamic(sel)(a) +.apply(a2) +qual.applyDynamic(sel)(a) +qual.applyDynamic(sel)(a) +.apply(a2) +qual.applyDynamicNamed(sel)((arg,a)) +qual.applyDynamicNamed(sel)((arg,a)) +qual.applyDynamicNamed(sel)((,a), (arg2,a2)) +qual.updateDynamic(sel)(expr) +qual.selectDynamic(sel) +qual.selectDynamic(sel) +qual.selectDynamic(sel) +.update(1, expr) +qual.selectDynamic(sel) +.update(expr) +qual.selectDynamic(sel) +.apply(1) +qual.selectDynamic(sel) +.apply +.update(1, 1) +qual.applyDynamic(apply)(a) +qual.applyDynamic(apply)(a) +qual.applyDynamic(apply)(a) +qual.applyDynamic(apply)(a) +qual.applyDynamicNamed(apply)((arg,a)) +qual.applyDynamicNamed(apply)((,a), (arg2,a2)) +qual.applyDynamic(update)(a, a2) diff --git a/tests/run/applydynamic_sip.flags b/tests/run/applydynamic_sip.flags new file mode 100644 index 000000000..ba6d37305 --- /dev/null +++ b/tests/run/applydynamic_sip.flags @@ -0,0 +1,2 @@ +-Yrangepos:false +-language:dynamics diff --git a/tests/run/applydynamic_sip.scala b/tests/run/applydynamic_sip.scala new file mode 100644 index 000000000..7f81a644a --- /dev/null +++ b/tests/run/applydynamic_sip.scala @@ -0,0 +1,67 @@ +import scala.language.dynamics +object Test extends dotty.runtime.LegacyApp { + object stubUpdate { + def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")")) + } + + object stub { + def apply = {println(".apply"); stubUpdate} + def apply(as: Any*) = println(".apply"+as.toList.mkString("(",", ", ")")) + def update(as: Any*) = println(".update"+as.toList.mkString("(",", ", ")")) + } + class MyDynamic extends Dynamic { + def applyDynamic[T](n: String)(as: Any*) = {println("qual.applyDynamic("+ n +")"+ as.toList.mkString("(",", ", ")")); stub} + def applyDynamicNamed[T](n: String)(as: (String, Any)*) = {println("qual.applyDynamicNamed("+ n +")"+ as.toList.mkString("(",", ", ")")); stub} + def selectDynamic[T](n: String) = {println("qual.selectDynamic("+ n +")"); stub} + def updateDynamic(n: String)(x: Any): Unit = {println("qual.updateDynamic("+ n +")("+ x +")")} + } + val qual = new MyDynamic + val expr = "expr" + val a = "a" + val a2 = "a2" + type T = String + + // If qual.sel is followed by a potential type argument list [Ts] and an argument list (arg1, …, argn) where none of the arguments argi are named: + // qual.applyDynamic(“sel”)(arg1, …, argn) + qual.sel() + qual.sel(a) + // qual.sel(a, a2: _*) -- should not accept varargs? + qual.sel(a)(a2) + qual.sel[T](a) + qual.sel[T](a)(a2) + + // If qual.sel is followed by a potential type argument list [Ts] + // and a non-empty named argument list (x1 = arg1, …, xn = argn) where some name prefixes xi = might be missing: + // qual.applyDynamicNamed(“sel”)(xs1 -> arg1, …, xsn -> argn) + qual.sel(arg = a) + qual.sel[T](arg = a) + qual.sel(a, arg2 = "a2") + // qual.sel(a)(a2, arg2 = "a2") + // qual.sel[T](a)(a2, arg2 = "a2") + // qual.sel(arg = a, a2: _*) + // qual.sel(arg, arg2 = "a2", a2: _*) + + // If qual.sel appears immediately on the left-hand side of an assigment + // qual.updateDynamic(“sel”)(expr) + qual.sel = expr + + // If qual.sel, possibly applied to type arguments, but is + // not applied to explicit value arguments, + // nor immediately followed by an assignment operator: + // qual.selectDynamic[Ts](“sel”) + qual.sel + qual.sel[T] + + qual.sel(1) = expr // parser turns this into qual.sel.update(1, expr) + qual.sel() = expr // parser turns this into qual.sel.update(expr) + qual.sel.apply(1) + qual.sel.apply(1) = 1 + + qual.apply(a) + qual.apply[String](a) + qual(a) + qual[String](a) + qual[T](arg = a) + qual(a, arg2 = "a2") + qual(a) = a2 +} diff --git a/tests/run/dynamic-anyval.check b/tests/run/dynamic-anyval.check new file mode 100644 index 000000000..dee7bef8e --- /dev/null +++ b/tests/run/dynamic-anyval.check @@ -0,0 +1,4 @@ +().dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) +().dingo(bippy, 5) +List(1, 2, 3).dingo(bippy, 5) diff --git a/tests/run/dynamic-anyval.scala b/tests/run/dynamic-anyval.scala new file mode 100644 index 000000000..605503d37 --- /dev/null +++ b/tests/run/dynamic-anyval.scala @@ -0,0 +1,22 @@ +import scala.language.dynamics + +object Test { + implicit class DynamicValue[T](val value: T) extends AnyVal with Dynamic { + def applyDynamic(name: String)(args: Any*) = println(s"""$this.$name(${args mkString ", "})""") + override def toString = "" + value + } + implicit class DynamicValue2[T](val value: T) extends Dynamic { + def applyDynamic(name: String)(args: Any*) = println(s"""$this.$name(${args mkString ", "})""") + override def toString = "" + value + } + + def f[T](x: DynamicValue[T]) = x.dingo("bippy", 5) + def g[T](x: DynamicValue2[T]) = x.dingo("bippy", 5) + + def main(args: Array[String]): Unit = { + f(()) + f(List(1, 2, 3)) + g(()) + g(List(1, 2, 3)) + } +} diff --git a/tests/run/dynamicDynamicTests.scala b/tests/run/dynamicDynamicTests.scala index 3f8da8298..05b878f1c 100644 --- a/tests/run/dynamicDynamicTests.scala +++ b/tests/run/dynamicDynamicTests.scala @@ -23,7 +23,16 @@ class Baz extends scala.Dynamic { def updateDynamic(name: String)(value: String): String = "updateDynamic(" + name + ")(" + value + ")" } +class Qux extends scala.Dynamic { + def selectDynamic[T](name: String): String = "selectDynamic(" + name + ")" + def applyDynamic[T](name: String)(args: String*): String = "applyDynamic(" + name + ")" + args.mkString("(", ", ", ")") + def applyDynamicNamed[T](name: String)(args: (String, Any)*): String = "applyDynamicNamed(" + name + ")" + args.mkString("(", ", ", ")") + def updateDynamic[T](name: String)(value: T): String = "updateDynamic(" + name + ")(" + value + ")" +} + object Test { + val qux = new Qux + implicit class StringUpdater(str: String) { def update(name: String, v: String) = s"$str.update(" + name + ", " + v + ")" } @@ -42,6 +51,7 @@ object Test { runFooTests2() runBarTests() runBazTests() + runQuxTests() assert(!failed) } @@ -161,4 +171,35 @@ object Test { assertEquals("selectDynamic(bazSelectUpdate).update(7, value)", baz.bazSelectUpdate(7) = "value") assertEquals("selectDynamic(bazSelectUpdate).update(7, 10)", baz.bazSelectUpdate(7) = 10) } + + /** Test correct lifting of type parameters */ + def runQuxTests() = { + implicit def intToString(n: Int): String = n.toString + + val qux = new Qux + + assertEquals("selectDynamic(quxSelect)", qux.quxSelect) + assertEquals("selectDynamic(quxSelect)", qux.quxSelect[Int]) + + assertEquals("applyDynamic(quxApply)()", qux.quxApply()) + assertEquals("applyDynamic(quxApply)()", qux.quxApply[Int]()) + assertEquals("applyDynamic(quxApply)(1)", qux.quxApply(1)) + assertEquals("applyDynamic(quxApply)(1)", qux.quxApply[Int](1)) + assertEquals("applyDynamic(quxApply)(1, 2, 3)", qux.quxApply(1, 2, 3)) + assertEquals("applyDynamic(quxApply)(1, 2, 3)", qux.quxApply[Int](1, 2, 3)) + assertEquals("applyDynamic(quxApply)(1, 2, a)", qux.quxApply(1, 2, "a")) + assertEquals("applyDynamic(quxApply)(1, 2, a)", qux.quxApply[Int](1, 2, "a")) + + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1))", qux.quxApplyNamed(a = 1)) + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1))", qux.quxApplyNamed[Int](a = 1)) + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1), (b,2))", qux.quxApplyNamed(a = 1, b = "2")) + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1), (b,2))", qux.quxApplyNamed[Int](a = 1, b = "2")) + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1), (,abc))", qux.quxApplyNamed(a = 1, "abc")) + assertEquals("applyDynamicNamed(quxApplyNamed)((a,1), (,abc))", qux.quxApplyNamed[Int](a = 1, "abc")) + + assertEquals("updateDynamic(quxUpdate)(abc)", qux.quxUpdate = "abc") + + assertEquals("selectDynamic(quxSelectUpdate).update(key, value)", qux.quxSelectUpdate("key") = "value") + assertEquals("selectDynamic(quxSelectUpdate).update(key, value)", qux.quxSelectUpdate[Int]("key") = "value") + } } diff --git a/tests/run/t4536.check b/tests/run/t4536.check new file mode 100644 index 000000000..0c5a72ada --- /dev/null +++ b/tests/run/t4536.check @@ -0,0 +1,8 @@ +cls: bar +obj: foo +obj: bar +cls: bar +obj: bar +trait: pili +trait: mili +trait: foo
\ No newline at end of file diff --git a/tests/run/t4536.flags b/tests/run/t4536.flags new file mode 100644 index 000000000..1141f9750 --- /dev/null +++ b/tests/run/t4536.flags @@ -0,0 +1 @@ +-language:dynamics diff --git a/tests/run/t4536.scala b/tests/run/t4536.scala new file mode 100644 index 000000000..89a93a5e0 --- /dev/null +++ b/tests/run/t4536.scala @@ -0,0 +1,42 @@ +import scala.language.dynamics + +object dynamicObject extends Dynamic { + def applyDynamic(m: String)() = println("obj: " + m); + this.foo() +} + + +class dynamicClass extends Dynamic { + def applyDynamic(m: String)() = println("cls: " + m); + this.bar() + dynamicObject.bar() +} + + +abstract class dynamicAbstractClass extends Dynamic { + def applyDynamic(m: String)(args: Any*): Unit + this.pili(1, new dynamicClass, "hello"); +} + + +trait dynamicTrait extends Dynamic { + def applyDynamic(m: String)(args: Any*) = println("trait: " + m); + def two = 2 + this.mili(1,2,3) + two +} + + +object dynamicMixin extends dynamicAbstractClass with dynamicTrait { + this.foo(None) +} + + +object Test { + + def main(args: Array[String]) = { + val cls = new dynamicClass + dynamicMixin + } + +} diff --git a/tests/run/t5040.check b/tests/run/t5040.check new file mode 100644 index 000000000..3f7b5908a --- /dev/null +++ b/tests/run/t5040.check @@ -0,0 +1 @@ +applyDynamic diff --git a/tests/run/t5040.flags b/tests/run/t5040.flags new file mode 100644 index 000000000..1141f9750 --- /dev/null +++ b/tests/run/t5040.flags @@ -0,0 +1 @@ +-language:dynamics diff --git a/tests/run/t5040.scala b/tests/run/t5040.scala new file mode 100644 index 000000000..58d054412 --- /dev/null +++ b/tests/run/t5040.scala @@ -0,0 +1,12 @@ +import scala.language.dynamics // originaly used the flag -language:dynamics in t5040.flags, .flags are currently ignored +abstract class Prova2 extends Dynamic { + def applyDynamic(m: String)(): Unit + private def privateMethod() = println("private method") +} + +object Test extends dotty.runtime.LegacyApp { + val prova= new Prova2 { + def applyDynamic(m: String)() = println("applyDynamic") + } + prova.privateMethod() +} diff --git a/tests/run/t5733.check b/tests/run/t5733.check new file mode 100644 index 000000000..e697046a9 --- /dev/null +++ b/tests/run/t5733.check @@ -0,0 +1,2 @@ +Running ABTest asserts +Done diff --git a/tests/run/t5733.scala b/tests/run/t5733.scala new file mode 100644 index 000000000..a9e58d77e --- /dev/null +++ b/tests/run/t5733.scala @@ -0,0 +1,53 @@ +import scala.language.dynamics + +object A extends Dynamic { + var a = "a" + + def selectDynamic(method:String): String = a + + def updateDynamic(method:String)(v:String): Unit = { a = v } +} + +class B extends Dynamic { + var b = "b" + + def selectDynamic(method:String): String = b + + def updateDynamic(method:String)(v:String): Unit = { b = v } +} + +object Test extends dotty.runtime.LegacyApp { + assert( A.foo == "a" ) + assert( A.bar == "a" ) + A.aaa = "aaa" + assert( A.bar == "aaa" ) + + val b = new B + assert( b.foo == "b" ) + assert( b.bar == "b" ) + b.bbb = "bbb" + assert( b.bar == "bbb" ) + + { + println("Running ABTest asserts") + A.a = "a" + (new ABTest).test() + } + + println("Done") +} + +class ABTest { + def test(): Unit = { + assert( A.foo == "a" ) + assert( A.bar == "a" ) + A.aaa = "aaa" + assert( A.bar == "aaa" ) + + val b = new B + assert( b.foo == "b" ) + assert( b.bar == "b" ) + b.bbb = "bbb" + assert( b.bar == "bbb" ) + } +} diff --git a/tests/run/t6353.check b/tests/run/t6353.check new file mode 100644 index 000000000..5676bed24 --- /dev/null +++ b/tests/run/t6353.check @@ -0,0 +1 @@ +applyDynamic(apply)(9) diff --git a/tests/run/t6353.scala b/tests/run/t6353.scala new file mode 100644 index 000000000..7077eaeda --- /dev/null +++ b/tests/run/t6353.scala @@ -0,0 +1,12 @@ +import language.dynamics + +object Test extends dotty.runtime.LegacyApp { + val x = new X(3) + val y = x(9) + class X(i: Int) extends Dynamic { + def applyDynamic(name: String)(in: Int): Int = { + println(s"applyDynamic($name)($in)") + i + in + } + } +} diff --git a/tests/run/t6355.check b/tests/run/t6355.check new file mode 100644 index 000000000..ce74ab38a --- /dev/null +++ b/tests/run/t6355.check @@ -0,0 +1,2 @@ +bippy(x: Int) called with x = 42 +bippy(x: String) called with x = "42" diff --git a/tests/run/t6355.scala b/tests/run/t6355.scala new file mode 100644 index 000000000..f1921391a --- /dev/null +++ b/tests/run/t6355.scala @@ -0,0 +1,17 @@ +import scala.language.dynamics + +class A extends Dynamic { + def applyDynamic(method: String): B = new B(method) +} +class B(method: String) { + def apply(x: Int) = s"$method(x: Int) called with x = $x" + def apply(x: String) = s"""$method(x: String) called with x = "$x"""" +} + +object Test { + def main(args: Array[String]): Unit = { + val x = new A + println(x.bippy(42)) + println(x.bippy("42")) + } +} diff --git a/tests/run/t6663.check b/tests/run/t6663.check new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/tests/run/t6663.check @@ -0,0 +1 @@ +42 diff --git a/tests/run/t6663.flags b/tests/run/t6663.flags new file mode 100644 index 000000000..ea7fc37e1 --- /dev/null +++ b/tests/run/t6663.flags @@ -0,0 +1 @@ +-Yrangepos:false diff --git a/tests/run/t6663.scala b/tests/run/t6663.scala new file mode 100644 index 000000000..bfe464ad6 --- /dev/null +++ b/tests/run/t6663.scala @@ -0,0 +1,17 @@ +import language.dynamics + +class C(v: Any) extends Dynamic { + def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T]) + def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T]) +} + +object Test extends dotty.runtime.LegacyApp { + // this should be converted to + // C(42).selectDynamic[Int]("foo").get + // but, before fixing SI-6663, became + // C(42).selectDynamic[Nothing]("foo").get + // leading to a ClassCastException + var v = new C(42).foo[Int].get + println(v) +} + |