@@ -7,14 +7,67 @@ import scala.tools.nsc.ReflectGlobal
77import scala .tools .nsc .CompilerCommand
88import scala .tools .nsc .Global
99import scala .tools .nsc .typechecker .Modes
10+ import scala .tools .nsc .io .VirtualDirectory
11+ import scala .tools .nsc .interpreter .AbstractFileClassLoader
12+ import reflect .{mirror => rm }
13+ import scala .tools .nsc .util .FreshNameCreator
14+ import scala .reflect .internal .Flags
15+ import scala .tools .nsc .util .NoSourceFile
16+ import java .lang .{Class => jClass }
1017
1118trait ToolBoxes extends { self : Universe =>
1219
1320 class ToolBox (val reporter : Reporter = new StoreReporter , val options : String = " " ) {
1421
15- lazy val compiler : Global = {
22+ class ToolBoxGlobal (settings : scala.tools.nsc.Settings , reporter : scala.tools.nsc.reporters.Reporter )
23+ extends ReflectGlobal (settings, reporter) {
24+ import definitions ._
25+
26+ private final val wrapperMethodName = " wrapper"
27+
28+ private def isFree (t : Tree ) = t.isInstanceOf [Ident ] && t.symbol.isInstanceOf [FreeVar ]
29+
30+ def wrapInClass (expr : Tree , fvs : List [Symbol ]): ClassDef = {
31+ val clazz = EmptyPackageClass .newAnonymousClass(NoPosition )
32+ clazz setInfo ClassInfoType (List (ObjectClass .tpe), new Scope , clazz)
33+ val meth = clazz.newMethod(NoPosition , wrapperMethodName)
34+ meth setFlag Flags .STATIC
35+ meth setInfo MethodType (meth.owner.newSyntheticValueParams(fvs map (_.tpe)), expr.tpe)
36+ clazz.info.decls enter meth
37+ val methdef = DefDef (meth, expr)
38+ val clazzdef = ClassDef (clazz, NoMods , List (List ()), List (List ()), List (methdef), NoPosition )
39+ clazzdef
40+ }
41+
42+ def wrapInCompilationUnit (tree : Tree ): CompilationUnit = {
43+ val unit = new CompilationUnit (NoSourceFile )
44+ unit.body = tree
45+ unit
46+ }
47+
48+ def compileExpr (expr : Tree , fvs : List [Symbol ]): String = {
49+ val cdef = wrapInClass(expr, fvs)
50+ val unit = wrapInCompilationUnit(cdef)
51+ val run = new Run
52+ run.compileUnits(List (unit), run.namerPhase)
53+ cdef.name.toString
54+ }
55+
56+ def runExpr (expr : Tree ): Any = {
57+ val fvs = (expr filter isFree map (_.symbol)).distinct
58+ val className = compileExpr(expr, fvs)
59+ val jclazz = jClass.forName(className, true , classLoader)
60+ val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get
61+ jmeth.invoke(null , fvs map (sym => sym.asInstanceOf [FreeVar ].value.asInstanceOf [AnyRef ]): _* )
62+ }
63+ }
64+
65+ lazy val virtualDirectory = new VirtualDirectory (" (memory)" , None )
66+
67+ lazy val compiler : ToolBoxGlobal = {
1668 val command = new CompilerCommand (options.split(" " ).toList, reporter.error(scala.tools.nsc.util.NoPosition , _))
17- new ReflectGlobal (command.settings, reporter)
69+ command.settings.outputDirs setSingleOutput virtualDirectory
70+ new ToolBoxGlobal (command.settings, reporter)
1871 }
1972
2073 lazy val importer = new compiler.Importer {
@@ -23,20 +76,23 @@ trait ToolBoxes extends { self: Universe =>
2376
2477 lazy val exporter = importer.reverse
2578
26- def typeCheck (tree : reflect.mirror.Tree , expectedType : reflect.mirror.Type ): reflect.mirror.Tree = {
79+ lazy val classLoader = new AbstractFileClassLoader (virtualDirectory, getClass.getClassLoader)
80+
81+
82+ def typeCheck (tree : rm.Tree , expectedType : rm.Type ): rm.Tree = {
2783 if (compiler.settings.verbose.value) println(" typing " + tree+ " , pt = " + expectedType)
2884 val run = new compiler.Run
2985 compiler.phase = run.refchecksPhase
3086 val ctree : compiler.Tree = importer.importTree(tree.asInstanceOf [Tree ])
3187 val pt : compiler.Type = importer.importType(expectedType.asInstanceOf [Type ])
3288 val ttree : compiler.Tree = compiler.typer.typed(ctree, compiler.analyzer.EXPRmode , pt)
33- exporter.importTree(ttree).asInstanceOf [reflect.mirror .Tree ]
89+ exporter.importTree(ttree).asInstanceOf [rm .Tree ]
3490 }
3591
36- def typeCheck (tree : reflect.mirror. Tree ): reflect.mirror .Tree =
37- typeCheck(tree, WildcardType .asInstanceOf [reflect.mirror .Type ])
92+ def typeCheck (tree : rm. Tree ): rm .Tree =
93+ typeCheck(tree, WildcardType .asInstanceOf [rm .Type ])
3894
39- def showAttributed (tree : reflect.mirror .Tree ): String = {
95+ def showAttributed (tree : rm .Tree ): String = {
4096 val saved = compiler.settings.printtypes.value
4197 try {
4298 compiler.settings.printtypes.value = true
0 commit comments