Closed
Description
We could generate these reflectively. Here's a sketch:
object Test {
def main(args: Array[String]): Unit = {
reflect
}
def reflect = {
import scala.tools.nsc._
import scala.tools.nsc._
val settings = new Settings
settings.processArgumentString("-usejavacp")
val compiler = new Global(settings)
new compiler.Run
import compiler._, definitions._
val pack = rootMirror.getPackageIfDefined("java.util.function")
println(pack.info.decls.toList.take(10).map(_.fullName).mkString("\n"))
def wrap(abstractMethod: Symbol): Tree = {
val name = abstractMethod.name.toTermName
val params = abstractMethod.info.params
val result = abstractMethod.info.resultType
val arity = params.length
val enclosingClass = abstractMethod.owner
val enclosingTparams = enclosingClass.typeParams
val wrapperName = TypeName(enclosingClass.name.encoded + "Wrapper")
val parent = gen.mkAttributedRef(FunctionClass(arity))
val wrapperTParams: List[TypeDef] = enclosingTparams.map(_.name.toTypeName).map(TypeDef(NoMods, _, Nil, EmptyTree))
val selfTargs: List[Tree] = wrapperTParams.map(_.name).map(Ident(_))
def mkRef(tp: Type): Tree = if (tp.typeSymbol.isTypeParameter) Ident(tp.typeSymbol.name.toTypeName) else tq"$tp"
val parentTargs: List[Tree] = params.map(_.info).map(mkRef) :+ mkRef(result)
val wrapperVParams = params.map(p =>
ValDef(NoMods, p.name.toTermName, if (p.info.typeSymbol.isTypeParameter) Ident(p.info.typeSymbol.name) else gen.mkAttributedRef(p.info.typeSymbol), EmptyTree)
)
val wrapperVParamRefs = wrapperVParams.map(_.name).map(Ident(_))
q"""class ${wrapperName}[..$wrapperTParams](self: ${gen.mkAttributedRef(enclosingClass)}[..$selfTargs]) extends $parent[..$parentTargs] {
def apply(..$wrapperVParams) = self.$name(..${wrapperVParamRefs})
}
"""
}
{
val longToIntFunction = pack.info.decl(TypeName("LongToIntFunction"))
val abstractMethod = longToIntFunction.info.decls.toList.find(_.isAbstract).get
println(abstractMethod.defString)
println(showCode(wrap(abstractMethod)))
}
{
val predicate = pack.info.decl(TypeName("Predicate"))
val abstractMethod = predicate.info.decls.toList.find(_.isAbstract).get
println(abstractMethod.defString)
println(showCode(wrap(abstractMethod)))
}
}
}
Outputs:
% scalac sandbox/reflect.scala && scala Test
warning: there was one deprecation warning; re-run with -deprecation for details
one warning found
java.util.function.ToDoubleBiFunction
java.util.function.ToDoubleFunction
java.util.function.LongToIntFunction
java.util.function.IntFunction
java.util.function.LongConsumer
java.util.function.LongFunction
java.util.function.BooleanSupplier
java.util.function.ObjDoubleConsumer
java.util.function.Supplier
java.util.function.IntSupplier
def applyAsInt(x$1: Long): Int
class LongToIntFunctionWrapper(self: java.util.function.LongToIntFunction) extends scala.Function1[Long, Int] {
def apply(x$1: scala.Long) = self.applyAsInt(x$1)
}
def test(x$1: T): Boolean
class PredicateWrapper[T](self: java.util.function.Predicate[T]) extends scala.Function1[T, Boolean] {
def apply(x$1: T) = self.test(x$1)
}