compilemanager.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 204 行

SCALA
204
字号
/* NEST (New Scala Test) * Copyright 2007-2008 LAMP/EPFL * @author Philipp Haller */// $Id: CompileManager.scala 14415 2008-03-19 00:53:09Z mihaylov $package scala.tools.partest.nestimport scala.tools.nsc.{Global, Settings}import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}import java.io.{File, BufferedReader, PrintWriter, FileWriter, StringWriter}class ExtConsoleReporter(override val settings: Settings, reader: BufferedReader, var writer: PrintWriter) extends ConsoleReporter(settings, reader, writer) {  def this(settings: Settings) = {    this(settings, Console.in, new PrintWriter(new FileWriter("/dev/null")))  }  def hasWarnings: Boolean = WARNING.count != 0}abstract class SimpleCompiler {  def compile(file: File, kind: String): Boolean  def compile(file: File, kind: String, log: File): Boolean}class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {  def newGlobal(settings: Settings, reporter: Reporter): Global =    new Global(settings, reporter)  def newGlobal(settings: Settings, logWriter: FileWriter): Global = {    val rep = new ExtConsoleReporter(new Settings(x => ()),                                     Console.in,                                     new PrintWriter(logWriter))    rep.shortname = true    newGlobal(settings, rep)  }  def newSettings = {    val settings = new Settings(x => ())    settings.deprecation.value = true    settings.nowarnings.value = false    settings.encoding.value = "iso-8859-1"    settings  }  def newReporter(sett: Settings) = new ExtConsoleReporter(sett,                                                           Console.in,                                                           new PrintWriter(new StringWriter))  def compile(file: File, kind: String, log: File): Boolean = {    val testSettings = newSettings    val logWriter = new FileWriter(log)    val global = newGlobal(testSettings, logWriter)    val testRep: ExtConsoleReporter = global.reporter.asInstanceOf[ExtConsoleReporter]    val test: TestFile = kind match {      case "pos"      => PosTestFile(file, fileManager)      case "neg"      => NegTestFile(file, fileManager)      case "run"      => RunTestFile(file, fileManager)      case "jvm"      => JvmTestFile(file, fileManager)      case "jvm5"     => Jvm5TestFile(file, fileManager)      case "shootout" => ShootoutTestFile(file, fileManager)    }    test.defineSettings(testSettings)    val toCompile = List(file.getPath)    try {      (new global.Run) compile toCompile      testRep.printSummary      testRep.writer.flush      testRep.writer.close    } catch {      case e: Exception =>        e.printStackTrace()        false    } finally {      logWriter.close()    }    !testRep.hasErrors  }  def compile(file: File, kind: String): Boolean = {    val testSettings = newSettings    val testRep = newReporter(testSettings)    val global = newGlobal(testSettings, testRep)    val test: TestFile = kind match {      case "pos"      => PosTestFile(file, fileManager)      case "neg"      => NegTestFile(file, fileManager)      case "run"      => RunTestFile(file, fileManager)      case "jvm"      => JvmTestFile(file, fileManager)      case "jvm5"     => Jvm5TestFile(file, fileManager)      case "shootout" => ShootoutTestFile(file, fileManager)    }    test.defineSettings(testSettings)    val toCompile = List(file.getPath)    try {      (new global.Run) compile toCompile      testRep.printSummary      testRep.writer.flush      testRep.writer.close    } catch {      case e: Exception =>        e.printStackTrace()        false    }    !testRep.hasErrors  }}class ReflectiveCompiler(val fileManager: ConsoleFileManager) extends SimpleCompiler {  import fileManager.{latestCompFile, latestPartestFile, latestFjbgFile}  val sepUrls = Array(latestCompFile.toURL, latestPartestFile.toURL,                      latestFjbgFile.toURL)  //NestUI.verbose("constructing URLClassLoader from URLs "+latestCompFile+" and "+latestPartestFile)  val sepLoader = new java.net.URLClassLoader(sepUrls, null)  val sepCompilerClass =    sepLoader.loadClass("scala.tools.partest.nest.DirectCompiler")  val sepCompiler = sepCompilerClass.newInstance()  // needed for reflective invocation  val fileClass = Class.forName("java.io.File")  val stringClass = Class.forName("java.lang.String")  val sepCompileMethod =    sepCompilerClass.getMethod("compile", Array(fileClass, stringClass))  val sepCompileMethod2 =    sepCompilerClass.getMethod("compile", Array(fileClass, stringClass, fileClass))  /* This method throws java.lang.reflect.InvocationTargetException   * if the compiler crashes.   * This exception is handled in the shouldCompile and shouldFailCompile   * methods of class CompileManager.   */  def compile(file: File, kind: String): Boolean = {    val fileArgs: Array[AnyRef] = Array(file, kind)    val res = sepCompileMethod.invoke(sepCompiler, fileArgs).asInstanceOf[java.lang.Boolean]    res.booleanValue()  }  /* This method throws java.lang.reflect.InvocationTargetException   * if the compiler crashes.   * This exception is handled in the shouldCompile and shouldFailCompile   * methods of class CompileManager.   */  def compile(file: File, kind: String, log: File): Boolean = {    val fileArgs: Array[AnyRef] = Array(file, kind, log)    val res = sepCompileMethod2.invoke(sepCompiler, fileArgs).asInstanceOf[java.lang.Boolean]    res.booleanValue()  }}class CompileManager(val fileManager: FileManager) {  var compiler: SimpleCompiler = new /*ReflectiveCompiler*/ DirectCompiler(fileManager)  var numSeparateCompilers = 1  def createSeparateCompiler() = {    numSeparateCompilers += 1    compiler = new /*ReflectiveCompiler*/ DirectCompiler(fileManager)  }  /* This method returns true iff compilation succeeds.   */  def shouldCompile(file: File, kind: String, log: File): Boolean = {    createSeparateCompiler()    try {      compiler.compile(file, kind, log)    } catch {      case t: Throwable =>        NestUI.verbose("while invoking compiler ("+file+"):")        NestUI.verbose("caught "+t)        t.printStackTrace        t.getCause.printStackTrace        false    }  }  /* This method returns true iff compilation fails   * _and_ the compiler does _not_ crash.   *   * If the compiler crashes, this method returns false.   */  def shouldFailCompile(file: File, kind: String, log: File): Boolean = {    // always create new separate compiler    createSeparateCompiler()    try {      !compiler.compile(file, kind, log)    } catch {      case t: Throwable =>        NestUI.verbose("while invoking compiler ("+file+"):")        NestUI.verbose("caught "+t)        t.printStackTrace        t.getCause.printStackTrace        false    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?