| author | wenzelm | 
| Mon, 02 Jul 2018 16:43:06 +0200 | |
| changeset 68572 | c8bf6077a87d | 
| parent 64370 | 865b39487b5d | 
| child 72973 | fc69884a6e5a | 
| permissions | -rw-r--r-- | 
| 56905 | 1 | /* Title: Pure/General/untyped.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Untyped, unscoped, unchecked access to JVM objects. | |
| 5 | */ | |
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | ||
| 63419 | 10 | import java.lang.reflect.{Method, Field}
 | 
| 59080 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 11 | |
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 12 | |
| 56905 | 13 | object Untyped | 
| 14 | {
 | |
| 59080 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 15 | def method(c: Class[_], name: String, arg_types: Class[_]*): Method = | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 16 |   {
 | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 17 | val m = c.getDeclaredMethod(name, arg_types: _*) | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 18 | m.setAccessible(true) | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 19 | m | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 20 | } | 
| 
611914621edb
added Untyped.method convenience (for *this* class only);
 wenzelm parents: 
59079diff
changeset | 21 | |
| 58682 | 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 | |
| 56905 | 29 | } | 
| 30 | } | |
| 58682 | 31 | |
| 63419 | 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 | ||
| 59079 | 47 | def get[A](obj: AnyRef, x: String): A = | 
| 48 | if (obj == null) null.asInstanceOf[A] | |
| 63419 | 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) | |
| 56905 | 53 | } |