src/Pure/General/untyped.scala
changeset 58682 542fa5093ebf
parent 56905 fb38a767a78b
child 59079 12a689755c3d
     1.1 --- a/src/Pure/General/untyped.scala	Tue Oct 14 08:23:23 2014 +0200
     1.2 +++ b/src/Pure/General/untyped.scala	Tue Oct 14 19:38:41 2014 +0200
     1.3 @@ -10,14 +10,30 @@
     1.4  
     1.5  object Untyped
     1.6  {
     1.7 -  def get(obj: AnyRef, x: String): AnyRef =
     1.8 -  {
     1.9 -    obj.getClass.getDeclaredFields.find(_.getName == x) match {
    1.10 -      case Some(field) =>
    1.11 -        field.setAccessible(true)
    1.12 -        field.get(obj)
    1.13 -      case None => error("No field " + quote(x) + " for " + obj)
    1.14 +  def classes(obj: AnyRef): Iterator[Class[_ <: AnyRef]] = new Iterator[Class[_ <: AnyRef]] {
    1.15 +    private var next_elem: Class[_ <: AnyRef] = obj.getClass
    1.16 +    def hasNext(): Boolean = next_elem != null
    1.17 +    def next(): Class[_ <: AnyRef] = {
    1.18 +      val c = next_elem
    1.19 +      next_elem = c.getSuperclass.asInstanceOf[Class[_ <: AnyRef]]
    1.20 +      c
    1.21      }
    1.22    }
    1.23 +
    1.24 +  def get(obj: AnyRef, x: String): AnyRef =
    1.25 +    if (obj == null) null
    1.26 +    else {
    1.27 +      val iterator =
    1.28 +        for {
    1.29 +          c <- classes(obj)
    1.30 +          field <- c.getDeclaredFields.iterator
    1.31 +          if field.getName == x
    1.32 +        } yield {
    1.33 +          field.setAccessible(true)
    1.34 +          field.get(obj)
    1.35 +        }
    1.36 +      if (iterator.hasNext) iterator.next
    1.37 +      else error("No field " + quote(x) + " for " + obj)
    1.38 +    }
    1.39  }
    1.40