1/*  Title:      Pure/General/untyped.scala
2    Author:     Makarius
3
4Untyped, unscoped, unchecked access to JVM objects.
5*/
6
7package isabelle
8
9
10import java.lang.reflect.{Method, Field}
11
12
13object Untyped
14{
15  def method(c: Class[_], name: String, arg_types: Class[_]*): Method =
16  {
17    val m = c.getDeclaredMethod(name, arg_types: _*)
18    m.setAccessible(true)
19    m
20  }
21
22  def classes(obj: AnyRef): Iterator[Class[_ <: AnyRef]] = new Iterator[Class[_ <: AnyRef]] {
23    private var next_elem: Class[_ <: AnyRef] = obj.getClass
24    def hasNext(): Boolean = next_elem != null
25    def next(): Class[_ <: AnyRef] = {
26      val c = next_elem
27      next_elem = c.getSuperclass.asInstanceOf[Class[_ <: AnyRef]]
28      c
29    }
30  }
31
32  def field(obj: AnyRef, x: String): Field =
33  {
34    val iterator =
35      for {
36        c <- classes(obj)
37        field <- c.getDeclaredFields.iterator
38        if field.getName == x
39      } yield {
40        field.setAccessible(true)
41        field
42      }
43    if (iterator.hasNext) iterator.next
44    else error("No field " + quote(x) + " for " + obj)
45  }
46
47  def get[A](obj: AnyRef, x: String): A =
48    if (obj == null) null.asInstanceOf[A]
49    else field(obj, x).get(obj).asInstanceOf[A]
50
51  def set[A](obj: AnyRef, x: String, y: A): Unit =
52    field(obj, x).set(obj, y)
53}
54