aboutsummaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-02-01 18:21:58 +1100
committerGitHub <noreply@github.com>2017-02-01 18:21:58 +1100
commitaf7fdb32df34b352bf39f01a26653b169e0d55cf (patch)
tree4307381bb799db513dd07a0f40aec968ae99e877 /library
parentbb2e99cdfa9876561df912d26e9870526de3dd5d (diff)
parent678e8e47b630786df7548c1be5bee744342f826c (diff)
downloaddotty-af7fdb32df34b352bf39f01a26653b169e0d55cf.tar.gz
dotty-af7fdb32df34b352bf39f01a26653b169e0d55cf.tar.bz2
dotty-af7fdb32df34b352bf39f01a26653b169e0d55cf.zip
Merge pull request #1881 from dotty-staging/add-structural-select
Implement structural type member access
Diffstat (limited to 'library')
-rw-r--r--library/src/scala/Selectable.scala8
-rw-r--r--library/src/scala/reflect/Selectable.scala73
2 files changed, 81 insertions, 0 deletions
diff --git a/library/src/scala/Selectable.scala b/library/src/scala/Selectable.scala
new file mode 100644
index 000000000..c5c714ca9
--- /dev/null
+++ b/library/src/scala/Selectable.scala
@@ -0,0 +1,8 @@
+package scala
+import scala.reflect.ClassTag
+
+trait Selectable extends Any {
+ def selectDynamic(name: String): Any
+ def selectDynamicMethod(name: String, paramClasses: ClassTag[_]*): Any =
+ new UnsupportedOperationException("selectDynamicMethod")
+}
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)
+ }
+}