-
Notifications
You must be signed in to change notification settings - Fork 1k
/
Selectable.scala
52 lines (45 loc) · 1.97 KB
/
Selectable.scala
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
package scala.reflect
/** A class that implements structural selections using Java reflection.
*
* It can be used as a supertrait of a class or be made available
* as an implicit conversion via `reflectiveSelectable`.
*
* In Scala.js, it is implemented using a separate Scala.js-specific
* mechanism, since Java reflection is not available.
*/
trait Selectable extends scala.Selectable:
/** The value from which structural members are selected.
* By default this is the Selectable instance itself, but it can
* be overridden.
*/
protected def selectedValue: Any = this
// The Scala.js codegen relies on this method being final for correctness
/** Select member with given name */
final def selectDynamic(name: String): Any =
val rcls = selectedValue.getClass
try
val fld = rcls.getField(NameTransformer.encode(name)).nn
ensureAccessible(fld)
fld.get(selectedValue)
catch case ex: NoSuchFieldException =>
applyDynamic(name)()
// The Scala.js codegen relies on this method being final for correctness
/** Select method and apply to arguments.
* @param name The name of the selected method
* @param paramTypes The class tags of the selected method's formal parameter types
* @param args The arguments to pass to the selected method
*/
final def applyDynamic(name: String, paramTypes: Class[?]*)(args: Any*): Any =
val rcls = selectedValue.getClass
val mth = rcls.getMethod(NameTransformer.encode(name), paramTypes*).nn
ensureAccessible(mth)
mth.invoke(selectedValue, args.asInstanceOf[Seq[AnyRef]]*)
object Selectable:
/** An implicit conversion that turns a value into a Selectable
* such that structural selections are performed on that value.
*/
implicit def reflectiveSelectable(x: Any): Selectable =
new DefaultSelectable(x)
@inline // important for Scala.js
private final class DefaultSelectable(override protected val selectedValue: Any) extends Selectable
end Selectable