summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2017-01-10 16:33:37 -0800
committerGitHub <noreply@github.com>2017-01-10 16:33:37 -0800
commita5d38ea33430e144d05e7486791f70e144c5b602 (patch)
tree18b1458795b529dd1331b84231e8a8add0946fa3 /test
parent36967321c7a8a99cab2f9f1c4c0c46f09d3d34a6 (diff)
parent359b0bce8ec9bced0ca6fbb3865e9b3a6bcb30b4 (diff)
downloadscala-a5d38ea33430e144d05e7486791f70e144c5b602.tar.gz
scala-a5d38ea33430e144d05e7486791f70e144c5b602.tar.bz2
scala-a5d38ea33430e144d05e7486791f70e144c5b602.zip
Merge pull request #5630 from adriaanm/rebase-5557
[backport] SI-10071 SI-8786 varargs methods
Diffstat (limited to 'test')
-rw-r--r--test/files/jvm/t8786-sig.scala126
-rw-r--r--test/files/jvm/t8786/A_1.scala3
-rw-r--r--test/files/jvm/t8786/B_2.java22
-rw-r--r--test/files/jvm/t8786/Test_2.scala3
-rw-r--r--test/files/jvm/varargs-separate-bytecode.check1
-rw-r--r--test/files/jvm/varargs-separate-bytecode/AbstractProps_1.scala8
-rw-r--r--test/files/jvm/varargs-separate-bytecode/Props_2.scala3
-rw-r--r--test/files/jvm/varargs-separate-bytecode/Test.scala15
-rw-r--r--test/files/jvm/varargs/JavaClass.java26
-rw-r--r--test/files/jvm/varargs/VaClass.scala9
-rw-r--r--test/files/jvm/varargs/varargs.scala16
-rw-r--r--test/files/run/reflection-mem-typecheck.scala26
-rw-r--r--test/files/run/t5125b.check3
-rw-r--r--test/files/run/t5125b.scala12
14 files changed, 208 insertions, 65 deletions
diff --git a/test/files/jvm/t8786-sig.scala b/test/files/jvm/t8786-sig.scala
new file mode 100644
index 0000000000..f22e400528
--- /dev/null
+++ b/test/files/jvm/t8786-sig.scala
@@ -0,0 +1,126 @@
+class A[U] {
+ @annotation.varargs def m1[T] (a: T*): T = a.head
+ @annotation.varargs def m2[T <: AnyRef](a: T*): T = a.head
+ @annotation.varargs def m3[T <: AnyVal](a: T*): T = a.head
+ @annotation.varargs def m4[T <: Int] (a: T*): T = a.head
+ @annotation.varargs def m5[T <: String](a: T*): T = a.head
+ @annotation.varargs def m6 (a: String*): String = a.head
+ @annotation.varargs def m7 (a: Int*): Int = a.head
+ @annotation.varargs def m8 (a: U*): U = a.head
+
+ def n1[T] (a: Array[T]): T = a(0)
+ def n2[T <: AnyRef](a: Array[T]): T = a(0)
+ def n3[T <: AnyVal](a: Array[T]): T = a(0)
+ def n4[T <: Int] (a: Array[T]): T = a(0)
+ def n5[T <: String](a: Array[T]): T = a(0)
+ def n6 (a: Array[String]): String = a(0)
+ def n7 (a: Array[Int]): Int = a(0)
+ def n8 (a: Array[U]): U = a(0)
+}
+
+object Test extends App {
+ val a = classOf[A[_]]
+
+ def sig (method: String, tp: Class[_]) = a.getDeclaredMethod(method, tp).toString
+ def genSig(method: String, tp: Class[_]) = a.getDeclaredMethod(method, tp).toGenericString
+ def isVarArgs(method: String, tp: Class[_]) = a.getDeclaredMethod(method, tp).isVarArgs
+ def bound (method: String, tp: Class[_]) = {
+ val m = a.getDeclaredMethod(method, tp)
+ m.getGenericParameterTypes.apply(0) match {
+ case _: Class[_] => ""
+ case gat: java.lang.reflect.GenericArrayType =>
+ val compTp = gat.getGenericComponentType.asInstanceOf[java.lang.reflect.TypeVariable[_]]
+ compTp.getBounds.apply(0).toString
+ }
+ }
+
+ def check(found: String, expected: String): Unit =
+ assert(found == expected, s"found: $found\nexpected: $expected")
+
+ def checkVarArgs(method: String, tp: Class[_])(expected: String): Unit = {
+ assert(isVarArgs(method, tp), s"expected varargs for $method")
+ val found = genSig(method, tp)
+
+ def varArgsToBraces(sig: String) = sig.replaceAll("""\.\.\.""","[]")
+ // Normalize sigs so that the tests works on Java 6 (where varargs are printed as [])
+ // and above (where vargs are pretty printed using ...)
+ assert(varArgsToBraces(found) == varArgsToBraces(expected), s"found: $found\nexpected: $expected (modulo `...` or `[]` as varargs suffix)")
+ }
+
+ val sq = classOf[Seq[_]]
+ val ob = classOf[Object]
+ val ao = classOf[Array[Object]]
+ val as = classOf[Array[String]]
+ val ai = classOf[Array[Int]]
+
+ check(sig("m1", sq) , "public java.lang.Object A.m1(scala.collection.Seq)")
+ check(sig("m2", sq) , "public java.lang.Object A.m2(scala.collection.Seq)")
+ check(sig("m3", sq) , "public java.lang.Object A.m3(scala.collection.Seq)")
+ check(sig("m4", sq) , "public int A.m4(scala.collection.Seq)")
+ check(sig("m5", sq) , "public java.lang.String A.m5(scala.collection.Seq)")
+ check(sig("m6", sq) , "public java.lang.String A.m6(scala.collection.Seq)")
+ check(sig("m7", sq) , "public int A.m7(scala.collection.Seq)")
+ check(sig("m8", sq) , "public java.lang.Object A.m8(scala.collection.Seq)")
+
+ check(genSig("m1", sq), "public <T> T A.m1(scala.collection.Seq<T>)")
+ check(genSig("m2", sq), "public <T> T A.m2(scala.collection.Seq<T>)")
+ check(genSig("m3", sq), "public <T> T A.m3(scala.collection.Seq<T>)")
+ // TODO: the signature for is wrong for T <: Int, SI-9846. The signature should be
+ // `public int A.m4(scala.collection.Seq<java.lang.Object>)`. This is testing the status quo.
+ check(genSig("m4", sq), "public <T> T A.m4(scala.collection.Seq<T>)")
+ check(genSig("m5", sq), "public <T> T A.m5(scala.collection.Seq<T>)")
+ check(genSig("m6", sq), "public java.lang.String A.m6(scala.collection.Seq<java.lang.String>)")
+ check(genSig("m7", sq), "public int A.m7(scala.collection.Seq<java.lang.Object>)")
+ check(genSig("m8", sq), "public U A.m8(scala.collection.Seq<U>)")
+
+
+ // varargs forwarder
+
+ check(sig("m1", ao) , "public java.lang.Object A.m1(java.lang.Object[])")
+ check(sig("m2", ao) , "public java.lang.Object A.m2(java.lang.Object[])")
+ check(sig("m3", ao) , "public java.lang.Object A.m3(java.lang.Object[])")
+ check(sig("m4", ao) , "public int A.m4(java.lang.Object[])")
+ check(sig("m5", as) , "public java.lang.String A.m5(java.lang.String[])")
+ check(sig("m6", as) , "public java.lang.String A.m6(java.lang.String[])")
+ check(sig("m7", ai) , "public int A.m7(int[])")
+ check(sig("m8", ao) , "public java.lang.Object A.m8(java.lang.Object[])")
+
+ checkVarArgs("m1", ao)("public <T> T A.m1(T...)")
+ checkVarArgs("m2", ao)("public <T> T A.m2(T...)")
+ checkVarArgs("m3", ao)("public <T> T A.m3(T...)")
+ // testing status quo: signature is wrong for T <: Int, SI-9846
+ checkVarArgs("m4", ao)("public <T> T A.m4(T...)")
+ checkVarArgs("m5", as)("public <T> T A.m5(T...)")
+ checkVarArgs("m6", as)("public java.lang.String A.m6(java.lang.String...)")
+ checkVarArgs("m7", ai)("public int A.m7(int...)")
+ checkVarArgs("m8", ao)("public U A.m8(U...)")
+
+ check(bound("m1", ao) , "class java.lang.Object")
+ check(bound("m2", ao) , "class java.lang.Object")
+ check(bound("m3", ao) , "class java.lang.Object")
+ check(bound("m4", ao) , "class java.lang.Object")
+ check(bound("m5", as) , "class java.lang.String")
+ check(bound("m6", as) , "")
+ check(bound("m7", ai) , "")
+ check(bound("m8", ao) , "class java.lang.Object")
+
+
+ check(sig("n1", ob) , "public java.lang.Object A.n1(java.lang.Object)")
+ check(sig("n2", ao) , "public java.lang.Object A.n2(java.lang.Object[])")
+ check(sig("n3", ob) , "public java.lang.Object A.n3(java.lang.Object)")
+ check(sig("n4", ob) , "public int A.n4(java.lang.Object)")
+ check(sig("n5", as) , "public java.lang.String A.n5(java.lang.String[])")
+ check(sig("n6", as) , "public java.lang.String A.n6(java.lang.String[])")
+ check(sig("n7", ai) , "public int A.n7(int[])")
+ check(sig("n8", ob) , "public java.lang.Object A.n8(java.lang.Object)")
+
+ check(genSig("n1", ob), "public <T> T A.n1(java.lang.Object)")
+ check(genSig("n2", ao), "public <T> T A.n2(T[])")
+ check(genSig("n3", ob), "public <T> T A.n3(java.lang.Object)")
+ // testing status quo: signature is wrong for T <: Int, SI-9846
+ check(genSig("n4", ob), "public <T> T A.n4(java.lang.Object)")
+ check(genSig("n5", as), "public <T> T A.n5(T[])")
+ check(genSig("n6", as), "public java.lang.String A.n6(java.lang.String[])")
+ check(genSig("n7", ai), "public int A.n7(int[])")
+ check(genSig("n8", ob), "public U A.n8(java.lang.Object)")
+}
diff --git a/test/files/jvm/t8786/A_1.scala b/test/files/jvm/t8786/A_1.scala
new file mode 100644
index 0000000000..13c0ad191d
--- /dev/null
+++ b/test/files/jvm/t8786/A_1.scala
@@ -0,0 +1,3 @@
+class A {
+ @annotation.varargs def foo[T](a: Int, b: T*): T = b.head
+}
diff --git a/test/files/jvm/t8786/B_2.java b/test/files/jvm/t8786/B_2.java
new file mode 100644
index 0000000000..dc155a290f
--- /dev/null
+++ b/test/files/jvm/t8786/B_2.java
@@ -0,0 +1,22 @@
+public class B_2 {
+ private static int res = 0;
+
+ public static void m(char a[]) { res += 10; }
+ public static void m(String a) { res += 100; }
+ public static void m(Object a) { res += 1000; }
+
+ public static <T> T foo(int a, T... b) { return b[0]; }
+
+ public static <T> T bar(T b[]) { return b[0]; }
+
+ public static void main(String[] args) {
+ m(foo(15, "a", "b", "c"));
+ if (res != 100)
+ throw new Error("bad: "+ res);
+
+ A a = new A();
+ m(a.foo(16, "a", "b", "c"));
+ if (res != 200)
+ throw new Error("bad: " + res);
+ }
+}
diff --git a/test/files/jvm/t8786/Test_2.scala b/test/files/jvm/t8786/Test_2.scala
new file mode 100644
index 0000000000..76ccb4c3ed
--- /dev/null
+++ b/test/files/jvm/t8786/Test_2.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ B_2.main(null)
+}
diff --git a/test/files/jvm/varargs-separate-bytecode.check b/test/files/jvm/varargs-separate-bytecode.check
new file mode 100644
index 0000000000..1507cd48c5
--- /dev/null
+++ b/test/files/jvm/varargs-separate-bytecode.check
@@ -0,0 +1 @@
+Found vararg overload for method create \ No newline at end of file
diff --git a/test/files/jvm/varargs-separate-bytecode/AbstractProps_1.scala b/test/files/jvm/varargs-separate-bytecode/AbstractProps_1.scala
new file mode 100644
index 0000000000..5dfb8d1a9e
--- /dev/null
+++ b/test/files/jvm/varargs-separate-bytecode/AbstractProps_1.scala
@@ -0,0 +1,8 @@
+package foo
+
+import scala.annotation.varargs
+
+trait AbstractProps {
+ @varargs
+ def create(x: String, y: Int*): AbstractProps = null
+}
diff --git a/test/files/jvm/varargs-separate-bytecode/Props_2.scala b/test/files/jvm/varargs-separate-bytecode/Props_2.scala
new file mode 100644
index 0000000000..3fc09586fc
--- /dev/null
+++ b/test/files/jvm/varargs-separate-bytecode/Props_2.scala
@@ -0,0 +1,3 @@
+import foo.AbstractProps
+
+class Props extends AbstractProps \ No newline at end of file
diff --git a/test/files/jvm/varargs-separate-bytecode/Test.scala b/test/files/jvm/varargs-separate-bytecode/Test.scala
new file mode 100644
index 0000000000..a666de7f39
--- /dev/null
+++ b/test/files/jvm/varargs-separate-bytecode/Test.scala
@@ -0,0 +1,15 @@
+import scala.collection.JavaConverters._
+import scala.tools.asm
+import scala.tools.asm.Opcodes
+import scala.tools.partest.BytecodeTest
+
+object Test extends BytecodeTest {
+ def show: Unit = {
+ val classNode = loadClassNode("Props")
+ val methods = classNode.methods.iterator().asScala.filter( m => m.name == "create")
+
+ for (m <- methods if (m.access & Opcodes.ACC_VARARGS) > 0) {
+ println(s"Found vararg overload for method ${m.name}")
+ }
+ }
+}
diff --git a/test/files/jvm/varargs/JavaClass.java b/test/files/jvm/varargs/JavaClass.java
index 6928ee5adc..0cc3587c5e 100644
--- a/test/files/jvm/varargs/JavaClass.java
+++ b/test/files/jvm/varargs/JavaClass.java
@@ -1,16 +1,12 @@
-
-
-
public class JavaClass {
- public static <T> void varargz(int i, T... v) {
- }
-
- public static void callSomeAnnotations() {
- VaClass va = new VaClass();
- va.vs(4, "", "", "");
- va.vi(1, 2, 3, 4);
- varargz(5, 1.0, 2.0, 3.0);
- va.vt(16, "", "", "");
- System.out.println(va.vt1(16, "a", "b", "c"));
- }
-} \ No newline at end of file
+ public static <T> void varargz(int i, T... v) { }
+
+ public static void callSomeAnnotations() {
+ VaClass va = new VaClass();
+ va.vs(4, "", "", "");
+ va.vi(1, 2, 3, 4);
+ varargz(5, 1.0, 2.0, 3.0);
+ va.vt(16, "", "", "");
+ System.out.println(va.vt1(16, "a", "b", "c"));
+ }
+}
diff --git a/test/files/jvm/varargs/VaClass.scala b/test/files/jvm/varargs/VaClass.scala
index d83e63ace1..ee8c288a16 100644
--- a/test/files/jvm/varargs/VaClass.scala
+++ b/test/files/jvm/varargs/VaClass.scala
@@ -1,15 +1,8 @@
-
-
import annotation.varargs
-
-
class VaClass {
-
@varargs def vs(a: Int, b: String*) = println(a + b.length)
@varargs def vi(a: Int, b: Int*) = println(a + b.sum)
@varargs def vt[T](a: Int, b: T*) = println(a + b.length)
-
- // TODO remove type bound after fixing SI-8786, see also https://github.com/scala/scala/pull/3961
- @varargs def vt1[T <: String](a: Int, b: T*): T = b.head
+ @varargs def vt1[T](a: Int, b: T*): T = b.head
}
diff --git a/test/files/jvm/varargs/varargs.scala b/test/files/jvm/varargs/varargs.scala
index 6d2e707bdf..b09818f46f 100644
--- a/test/files/jvm/varargs/varargs.scala
+++ b/test/files/jvm/varargs/varargs.scala
@@ -1,21 +1,5 @@
-
-
-
-
-
-
object Test {
def main(args: Array[String]) {
JavaClass.callSomeAnnotations
}
}
-
-
-
-
-
-
-
-
-
-
diff --git a/test/files/run/reflection-mem-typecheck.scala b/test/files/run/reflection-mem-typecheck.scala
deleted file mode 100644
index f1fe983ede..0000000000
--- a/test/files/run/reflection-mem-typecheck.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-import scala.tools.partest.MemoryTest
-
-trait A { type T <: A }
-trait B { type T <: B }
-
-object Test extends MemoryTest {
- lazy val tb = {
- import scala.reflect.runtime.universe._
- import scala.reflect.runtime.{currentMirror => cm}
- import scala.tools.reflect.ToolBox
- cm.mkToolBox()
- }
-
- override def maxDelta = 12
- override def calcsPerIter = 8
- override def calc() {
- var snippet = """
- trait A { type T <: A }
- trait B { type T <: B }
- def foo[T](x: List[T]) = x
- foo(List(new A {}, new B {}))
- """.trim
- snippet = snippet + "\n" + (List.fill(50)(snippet.split("\n").last) mkString "\n")
- tb.typecheck(tb.parse(snippet))
- }
-} \ No newline at end of file
diff --git a/test/files/run/t5125b.check b/test/files/run/t5125b.check
index ddbf908f04..29b438a2d6 100644
--- a/test/files/run/t5125b.check
+++ b/test/files/run/t5125b.check
@@ -5,3 +5,6 @@ public void C2.f(scala.collection.Seq)
public void C2$C3.f(java.lang.String[])
public void C2$C3.f(scala.collection.Seq)
public void C4.f(scala.collection.Seq)
+private void C5.f(int,int[])
+private void C5.f(int,scala.collection.Seq)
+public void C5.f(scala.collection.Seq)
diff --git a/test/files/run/t5125b.scala b/test/files/run/t5125b.scala
index 149c49e213..60ab1d9792 100644
--- a/test/files/run/t5125b.scala
+++ b/test/files/run/t5125b.scala
@@ -23,6 +23,17 @@ class C4 {
}
}
+class C5 {
+ def f(values: String*) = println("Calling C5.f(): " + values)
+ @scala.annotation.varargs
+ private def f(v: Int, values: Int*) = println("Calling C5.f(): " + values)
+
+ def method(): Unit = {
+ @scala.annotation.varargs
+ def f(values: String*) = println("Calling C5.<locally>.f(): " + values)
+ }
+}
+
object Test extends App {
def check(c: Class[_]) {
val methodName = "f"
@@ -34,4 +45,5 @@ object Test extends App {
check(classOf[C2])
check(classOf[C2#C3])
check(classOf[C4])
+ check(classOf[C5])
}