@@ -21,10 +21,15 @@ import java.util.concurrent.{ TimeoutException, Callable, FutureTask, TimeUnit }
2121
2222import scala .util .Try
2323import scala .util .control .NonFatal
24+ import scala .concurrent ._
2425import scala .concurrent .duration ._
26+ import scala .concurrent .ExecutionContext
2527import scala .language .reflectiveCalls
28+
2629import com .twitter .util .Eval
2730
31+ import monix .execution ._
32+
2833import scala .reflect .internal .util .{ BatchSourceFile , Position }
2934
3035sealed trait Severity
@@ -43,12 +48,14 @@ object EvalResult {
4348
4449 case object Timeout extends EvalResult [Nothing ]
4550 case class Success [T ](complilationInfos : CI , result : T , consoleOutput : String ) extends EvalResult [T ]
51+ case class Timeout [T ]() extends EvalResult [T ]
4652 case class EvalRuntimeError (complilationInfos : CI , runtimeError : Option [RuntimeError ]) extends EvalResult [Nothing ]
4753 case class CompilationError (complilationInfos : CI ) extends EvalResult [Nothing ]
4854 case class GeneralError (stack : Throwable ) extends EvalResult [Nothing ]
4955}
5056
51- class Evaluator (timeout : Duration = 20 .seconds) {
57+ class Evaluator (timeout : FiniteDuration = 20 .seconds) {
58+ implicit val scheduler : ExecutionContext = Scheduler .io(" evaluation-scheduler" )
5259
5360 def convert (errors : (Position , String , String )): (Severity , List [CompilationInfo ]) = {
5461 val (pos, msg, severity) = errors
@@ -60,11 +67,7 @@ class Evaluator(timeout: Duration = 20.seconds) {
6067 (sev, CompilationInfo (msg, Some (RangePosition (pos.start, pos.point, pos.end))) :: Nil )
6168 }
6269
63- def apply [T ](pre : String , code : String ): EvalResult [T ] = {
64- val allCode = s """
65- | $pre
66- | $code
67- """ .stripMargin
70+ def eval [T ](code : String ): EvalResult [T ] = {
6871 val eval = new Eval {
6972 @ volatile var errors : Map [Severity , List [CompilationInfo ]] = Map .empty
7073
@@ -82,8 +85,8 @@ class Evaluator(timeout: Duration = 20.seconds) {
8285 }
8386
8487 val result = for {
85- _ ← Try (eval.check(allCode ))
86- result ← Try (eval.apply[T ](allCode , resetState = true ))
88+ _ ← Try (eval.check(code ))
89+ result ← Try (eval.apply[T ](code , resetState = true ))
8790 } yield result
8891
8992 val errors : Map [Severity , List [CompilationInfo ]] = eval.errors.toMap
@@ -97,4 +100,15 @@ class Evaluator(timeout: Duration = 20.seconds) {
97100 }
98101 }
99102 }
103+
104+ def apply [T ](pre : String , code : String ): EvalResult [T ] = {
105+ val allCode = s """
106+ | $pre
107+ | $code
108+ """ .stripMargin
109+ val fut = Future ({ eval(allCode) })
110+ Try (
111+ Await .result(fut, timeout)
112+ ).getOrElse(EvalResult .Timeout ())
113+ }
100114}
0 commit comments