alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (UniversalFn.scala)

This example Scala source code file (UniversalFn.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

anyref, anyref, argument, illegalargumentexception, invocationtargetexception, invocationtargetexception, manifest, method, reflection, seq, seq, t, type, universalfn, universalfn

The Scala UniversalFn.scala source code

/* NSC -- new Scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author Paul Phillips
 */
 
package scala.tools
package reflect

import java.lang.reflect.{ Method, InvocationTargetException }
import java.{ lang => jl }

/** For certain reflection tasks it is convenient to treat all methods
 *  as having the same signature: (Seq[AnyRef]) => AnyRef
 *   
 *  That is the "universal signature" and UniversalFn exists to provide
 *  it without abandoning the information we had before we needed it.
 *  One place this is used: closures can pose as arbitrary interfaces,
 *  and this is how we route the arguments from the actual method
 *  invocation (which targets a proxy object) to the original closure.
 */
class UniversalFn private (val closure: AnyRef, val method: Method) extends (Seq[AnyRef] => AnyRef) {
  universal =>

  /** Given an interface type argument, creates a proxy object of the
   *  type of the interface which implements all its methods by routing
   *  them to this universal function.  Will throw an exception in the
   *  face of any bad data.
   */
  def as[T: Manifest] : T = {
    val clazz = manifest[T].erasure
    require(clazz.isInterface, "Type argument must be an interface.")

    val interfaceMethods = clazz.getDeclaredMethods.toSet
    val proxy = Mock.fromInterfaces(clazz) {
      case Invoked(_, m, args) if interfaceMethods(m) => universal(args)
    }
    proxy.asInstanceOf[T]
  }

  def apply(xs: Seq[AnyRef]): AnyRef = 
    try method.invoke(closure, xs: _*)
    catch { case x: InvocationTargetException => throw x.getCause() }
}

object UniversalFn { 
  /** We use a private constructor so we can enforce some rules: we don't want
   *  universal functions to stack up, and right now we will only allow objects
   *  which appear to be closures (there's no reason not to eventually lift
   *  this restriction, but it should be harder to shoot your foot first.)
   */
  def apply(closure: AnyRef): UniversalFn = closure match {
    case x: UniversalFn => x
    case _              =>
      val m = uniqueApply(closure) getOrElse {
        throw new IllegalArgumentException("Argument must have exactly one non-bridge apply method.")
      }
      new UniversalFn(closure, m)
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala UniversalFn.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.