aboutsummaryrefslogblamecommitdiff
path: root/compiler/test/dotty/tools/dotc/vulpix/ChildMain.scala
blob: fdd602379df472e106386050fa90f3105a74320c (plain) (tree)


















































































                                                                            
package dotty.tools.dotc
package vulpix

import java.io.{
  File => JFile,
  InputStream, ObjectInputStream,
  OutputStream, ObjectOutputStream,
  ByteArrayOutputStream, PrintStream
}
import java.lang.reflect.InvocationTargetException

import dotty.tools.dotc.vulpix.Statuses._

object ChildMain {
  val realStdin = System.in
  val realStderr = System.err
  val realStdout = System.out

  private def runMain(dir: JFile): Status = {
    def renderStackTrace(ex: Throwable): String =
      ex.getStackTrace
        .takeWhile(_.getMethodName != "invoke0")
        .mkString("    ", "\n    ", "")

    def resetOutDescriptors(): Unit = {
      System.setOut(realStdout)
      System.setErr(realStderr)
    }

    import java.net.{ URL, URLClassLoader }

    val printStream = new ByteArrayOutputStream

    try {
      // Do classloading magic and running here:
      val ucl = new URLClassLoader(Array(dir.toURI.toURL))
      val cls = ucl.loadClass("Test")
      val meth = cls.getMethod("main", classOf[Array[String]])

      try {
        val ps = new PrintStream(printStream)
        System.setOut(ps)
        System.setErr(ps)
        Console.withOut(printStream) {
          Console.withErr(printStream) {
            // invoke main with "jvm" as arg
            meth.invoke(null, Array("jvm"))
          }
        }
        resetOutDescriptors()
      } catch {
        case t: Throwable =>
          resetOutDescriptors()
          throw t
      }
      new Success(printStream.toString("utf-8"))
    }
    catch {
      case ex: NoSuchMethodException =>
        val msg = s"test in '$dir' did not contain method: ${ex.getMessage}"
        new Failure(msg, renderStackTrace(ex.getCause))

      case ex: ClassNotFoundException =>
        val msg = s"test in '$dir' did not contain class: ${ex.getMessage}"
        new Failure(msg, renderStackTrace(ex.getCause))

      case ex: InvocationTargetException =>
        val msg = s"An exception ocurred when running main: ${ex.getCause}"
        new Failure(msg, renderStackTrace(ex.getCause))
    }
  }

  def main(args: Array[String]): Unit = {
    val stdin = new ObjectInputStream(System.in);
    val stdout = new ObjectOutputStream(System.out);

    while (true) {
      val dir = stdin.readObject().asInstanceOf[JFile]
      stdout.writeObject(runMain(dir))
      stdout.flush()
    }
  }
}