aboutsummaryrefslogtreecommitdiff
path: root/compiler/test/dotty/tools/dotc/vulpix/ChildMain.scala
blob: fdd602379df472e106386050fa90f3105a74320c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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()
    }
  }
}