1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
import scala.language.reflectiveCalls
trait A {
trait Concrete { def conco: Int = 1 }
type Foo <: { def bippy: Int }
type Bar <: { def barry: Int }
implicit def barTag: scala.reflect.ClassTag[Bar]
def f1(x: Any) = x match {
case x: Foo with Concrete => x.bippy + x.conco
case _ => -1
}
def f2(x: Any) = x match {
case x: Concrete with Foo => x.bippy + x.conco
case _ => -1
}
def f3(x: Any) = x match {
case x: Foo with Bar => x.bippy + x.barry
case _ => -1
}
def f4(x: Any) = x match {
case x: (Foo @unchecked) => x.bippy // warns, suppressed
case _ => -1
}
def f5(x: Any) = x match {
case x: (Bar @unchecked) => x.barry // warns (but about the "outer reference"), suppressed
case _ => -1
}
}
trait B extends A {
type Foo <: { def bippy: Int ; def dingo: Int }
type Bar <: { def barry: Int ; def bongo: Int }
override implicit def barTag: scala.reflect.ClassTag[Bar]
override def f1(x: Any) = x match {
case x: Foo with Concrete => x.bippy + x.dingo + x.conco
case _ => -1
}
override def f2(x: Any) = x match {
case x: Concrete with Foo => x.bippy + x.dingo + x.conco
case _ => -1
}
override def f3(x: Any) = x match {
case x: Foo with Bar with Concrete => x.bippy + x.barry + x.dingo + x.conco + x.bongo
case _ => -1
}
override def f4(x: Any) = x match {
case x: (Foo @unchecked) => x.bippy + x.dingo // warns, suppressed
case _ => -1
}
override def f5(x: Any) = x match {
case x: (Bar @unchecked) => x.barry + x.bongo // warns (but about the "outer reference"), suppressed
case _ => -1
}
}
object Test {
abstract class Base extends A {
trait Foo {
def bippy = 2
def dingo = 3
}
trait Bar {
def barry = 2
def bongo = 3
}
implicit def barTag: scala.reflect.ClassTag[Bar] = scala.reflect.ClassTag(classOf[Bar])
def run() {
println("f1")
wrap(f1(new Concrete {}))
wrap(f1(new Foo {}))
wrap(f1(new Bar {}))
wrap(f1(new Foo with Concrete {}))
wrap(f1(new Concrete with Foo {}))
println("\nf2")
wrap(f2(new Concrete {}))
wrap(f2(new Foo {}))
wrap(f2(new Bar {}))
wrap(f2(new Foo with Concrete {}))
wrap(f2(new Concrete with Foo {}))
wrap(f2(new Bar with Concrete {}))
wrap(f2(new Concrete with Bar {}))
wrap(f2(new Concrete with Foo with Bar {}))
wrap(f2(new Foo with Bar with Concrete {}))
println("\nf3")
wrap(f3(new Concrete {}))
wrap(f3(new Foo {}))
wrap(f3(new Bar {}))
wrap(f3(new Foo with Concrete {}))
wrap(f3(new Concrete with Foo {}))
wrap(f3(new Bar with Concrete {}))
wrap(f3(new Concrete with Bar {}))
wrap(f3(new Concrete with Foo with Bar {}))
wrap(f3(new Foo with Bar with Concrete {}))
println("\nf4")
wrap(f4(new Concrete {}))
wrap(f4(new Foo {}))
wrap(f4(new Bar {}))
wrap(f4(new Foo with Concrete {}))
wrap(f4(new Concrete with Foo {}))
wrap(f4(new Bar with Concrete {}))
wrap(f4(new Concrete with Bar {}))
wrap(f4(new Concrete with Foo with Bar {}))
wrap(f4(new Foo with Bar with Concrete {}))
println("\nf5")
wrap(f5(new Concrete {}))
wrap(f5(new Foo {}))
wrap(f5(new Bar {}))
wrap(f5(new Foo with Concrete {}))
wrap(f5(new Concrete with Foo {}))
wrap(f5(new Bar with Concrete {}))
wrap(f5(new Concrete with Bar {}))
wrap(f5(new Concrete with Foo with Bar {}))
wrap(f5(new Foo with Bar with Concrete {}))
}
}
object ao extends Base
object bo extends Base with B
private def wrap(body: => Any) {
try println(body)
catch { case ex: NoSuchMethodException => println(ex) }
}
def main(args: Array[String]) {
ao.run()
bo.run()
}
}
// java.lang.NoSuchMethodException: Test$$anon$1.bippy()
|