ATANG ATANG - 9 months ago 54
Scala Question

Scala Parse String Class and Compile in Run-Time

I want to implement a function in scala that can parse string of a source code (a class object) and compile it to an object in the run time.

For example, the function is what I have tried so far. My goal is that run it compiled in run-time environment, I can use it constructor or its function. This code has run-time error but I don't understand the how to fix the reflect class error. Thanks!

object test {
def main(args: Array[String]): Unit = {
val m = universe.runtimeMirror(getClass.getClassLoader)
val tb = m.mkToolBox()
val clazz = tb.compile(tb.parse("class insideclass {\n val model_field = 5\n def insideclass(model: Int) = {\n val model_field = model \n } \n\n def test() : Int = {\n model_field\n }\n\n}\nscala.reflect.classTag[insideclass].runtimeClass"))().asInstanceOf[Class[_]]
val classinside = universe.typeOf[Class[_]].typeSymbol.asClass
val ctor = universe.typeOf[Class[_]].declaration(universe.nme.CONSTRUCTOR).asMethod
val cm=m.reflectClass(classinside)
val ctorm=cm.reflectConstructor(ctor)

Answer Source

The problem is that the outside compiler does not know that "insideclass" exists as a class definition. One solution is to make inside class extend some other class that is know to both inside and outside compiler, for example Function[Int, Int]. You will need to rename your "test" method to "apply" in this case.

val clazz = tb.compile(tb.parse("class PersonData(x:Int) extends  Function[Int, Int] {\n val allen = x.toInt\n\n override def apply(x:Int):Int = allen}\n scala.reflect.classTag[PersonData].runtimeClass"))().asInstanceOf[Class[_]]

val ctor = clazz.getDeclaredConstructors()(0)

val instance = ctor.newInstance(new Integer(1))
// this cast can succeed because the outside knows what is Function[Int, Int]
println(instance.asInstanceOf[Function[Int, Int]].apply(1))