diff options
author | Martin Odersky <odersky@gmail.com> | 2017-01-07 14:47:18 +0700 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-01-07 14:47:18 +0700 |
commit | 69feaa89167ebeb708535dd4abf3a79a410130f0 (patch) | |
tree | ec93cdc0b05ccb22628ca9dee454e33e4df3e8ee /library/src/scala/reflect/Selectable.scala | |
parent | 7e3f69ace983adfbc9bbf44954f9a5845add3d43 (diff) | |
download | dotty-69feaa89167ebeb708535dd4abf3a79a410130f0.tar.gz dotty-69feaa89167ebeb708535dd4abf3a79a410130f0.tar.bz2 dotty-69feaa89167ebeb708535dd4abf3a79a410130f0.zip |
Change scheme to use Selectable
Use base types instead of implicits. This is more robust
in the presence of type abstraction.
Diffstat (limited to 'library/src/scala/reflect/Selectable.scala')
-rw-r--r-- | library/src/scala/reflect/Selectable.scala | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/library/src/scala/reflect/Selectable.scala b/library/src/scala/reflect/Selectable.scala new file mode 100644 index 000000000..0dbdbc293 --- /dev/null +++ b/library/src/scala/reflect/Selectable.scala @@ -0,0 +1,73 @@ +package scala.reflect + +class Selectable(val receiver: Any) extends AnyVal with scala.Selectable { + def selectDynamic(name: String): Any = { + val rcls = receiver.getClass + try { + val fld = rcls.getField(name) + fld.get(receiver) + } + catch { + case ex: NoSuchFieldError => + selectDynamicMethod(name).asInstanceOf[() => Any]() + } + } + + override def selectDynamicMethod(name: String, paramTypes: ClassTag[_]*): Any = { + val rcls = receiver.getClass + val paramClasses = paramTypes.map(_.runtimeClass) + val mth = rcls.getMethod(name, paramClasses: _*) + paramTypes.length match { + case 0 => () => + mth.invoke(receiver) + case 1 => (x0: Any) => + mth.invoke(receiver, x0.asInstanceOf[Object]) + case 2 => (x0: Any, x1: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object]) + case 3 => (x0: Any, x1: Any, x2: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object], + x2.asInstanceOf[Object]) + case 4 => (x0: Any, x1: Any, x2: Any, x3: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object], + x2.asInstanceOf[Object], + x3.asInstanceOf[Object]) + case 5 => (x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object], + x2.asInstanceOf[Object], + x3.asInstanceOf[Object], + x4.asInstanceOf[Object]) + case 6 => (x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object], + x2.asInstanceOf[Object], + x3.asInstanceOf[Object], + x4.asInstanceOf[Object], + x5.asInstanceOf[Object]) + case 7 => (x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) => + mth.invoke(receiver, + x0.asInstanceOf[Object], + x1.asInstanceOf[Object], + x2.asInstanceOf[Object], + x3.asInstanceOf[Object], + x4.asInstanceOf[Object], + x5.asInstanceOf[Object], + x6.asInstanceOf[Object]) + } + } +} + +object Selectable { + implicit def reflectiveSelectable(receiver: Any): scala.Selectable = receiver match { + case receiver: scala.Selectable => receiver + case _ => new Selectable(receiver) + } +} |