Skip to content

Partest output redirection over context.reporter #691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 26, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/dotty/tools/dotc/Bench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ object Bench extends Driver {
private def ntimes(n: Int)(op: => Reporter): Reporter =
(emptyReporter /: (0 until n)) ((_, _) => op)

override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
override def doCompile(compiler: Compiler, fileNames: List[String], reporter: Option[Reporter] = None)
(implicit ctx: Context): Reporter =
if (new config.Settings.Setting.SettingDecorator[Boolean](ctx.base.settings.resident).value(ctx))
resident(compiler)
else
ntimes(numRuns) {
val start = System.nanoTime()
val r = super.doCompile(compiler, fileNames)
println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
val r = super.doCompile(compiler, fileNames, reporter)
ctx.println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
r
}

Expand All @@ -46,11 +47,11 @@ object Bench extends Driver {
else (args(pos + 1).toInt, (args take pos) ++ (args drop (pos + 2)))
}

override def process(args: Array[String], rootCtx: Context): Reporter = {
override def process(args: Array[String], rootCtx: Context, reporter: Option[Reporter] = None): Reporter = {
val (numCompilers, args1) = extractNumArg(args, "#compilers")
val (numRuns, args2) = extractNumArg(args1, "#runs")
this.numRuns = numRuns
ntimes(numCompilers)(super.process(args2, rootCtx))
ntimes(numCompilers)(super.process(args2, rootCtx, reporter))
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Periods._
import Symbols._
import Scopes._
import typer.{FrontEnd, Typer, Mode, ImportInfo, RefChecks}
import reporting.ConsoleReporter
import reporting.{ConsoleReporter, Reporter}
import Phases.Phase
import dotty.tools.dotc.transform._
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransform, TreeTransformer}
Expand Down Expand Up @@ -93,7 +93,7 @@ class Compiler {
* for type checking.
* imports For each element of RootImports, an import context
*/
def rootContext(implicit ctx: Context): Context = {
def rootContext(implicit ctx: Context, r: Option[Reporter] = None): Context = {
ctx.definitions.init(ctx)
ctx.setPhasePlan(phases)
val rootScope = new MutableScope
Expand All @@ -105,7 +105,7 @@ class Compiler {
.setOwner(defn.RootClass)
.setTyper(new Typer)
.setMode(Mode.ImplicitsEnabled)
.setTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
.setTyperState(new MutableTyperState(ctx.typerState, r.getOrElse(new ConsoleReporter()(ctx)), isCommittable = true))
ctx.definitions.init(start) // set context of definitions to start
def addImport(ctx: Context, symf: () => Symbol) =
ctx.fresh.setImportInfo(ImportInfo.rootImport(symf)(ctx))
Expand All @@ -117,8 +117,8 @@ class Compiler {
ctx.runInfo.clear()
}

def newRun(implicit ctx: Context): Run = {
def newRun(implicit ctx: Context, r: Option[Reporter] = None): Run = {
reset()
new Run(this)(rootContext)
new Run(this)(rootContext(ctx, r))
}
}
9 changes: 5 additions & 4 deletions src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@ abstract class Driver extends DotClass {

protected def emptyReporter: Reporter = new StoreReporter

protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
protected def doCompile(compiler: Compiler, fileNames: List[String], reporter: Option[Reporter] = None)
(implicit ctx: Context): Reporter =
if (fileNames.nonEmpty) {
val run = compiler.newRun
val run = compiler.newRun(ctx, reporter)
run.compile(fileNames)
run.printSummary()
} else emptyReporter

protected def initCtx = (new ContextBase).initialCtx

def process(args: Array[String], rootCtx: Context): Reporter = {
def process(args: Array[String], rootCtx: Context, reporter: Option[Reporter] = None): Reporter = {
val summary = CompilerCommand.distill(args)(rootCtx)
implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
val fileNames = CompilerCommand.checkUsage(summary)
try {
doCompile(newCompiler(), fileNames)
doCompile(newCompiler(), fileNames, reporter)
} catch {
case ex: FatalError =>
ctx.error(ex.getMessage) // signals that we should fail compilation.
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/FromTasty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SymDenotations._
import typer.FrontEnd
import Phases.Phase
import util._
import reporting.Reporter
import Decorators._
import dotty.tools.dotc.transform.Pickler
import tasty.DottyUnpickler
Expand Down Expand Up @@ -41,7 +42,7 @@ object FromTasty extends Driver {
List(new ReadTastyTreesFromClasses) :: backendPhases
}

override def newRun(implicit ctx: Context): Run = {
override def newRun(implicit ctx: Context, reporter: Option[Reporter] = None): Run = {
reset()
new TASTYRun(this)(rootContext)
}
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ object Main extends Driver {

override def newCompiler(): Compiler = new Compiler

override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter = {
override def doCompile(compiler: Compiler, fileNames: List[String], reporter: Option[Reporter] = None)(implicit ctx: Context): Reporter = {
if (new config.Settings.Setting.SettingDecorator[Boolean](ctx.base.settings.resident).value(ctx))
resident(compiler)
else
super.doCompile(compiler, fileNames)
super.doCompile(compiler, fileNames, reporter)
}
}
8 changes: 4 additions & 4 deletions src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
compileSources(sources)
} catch {
case NonFatal(ex) =>
println(i"exception occurred while compiling $units%, %")
ctx.println(i"exception occurred while compiling $units%, %")
throw ex
}

Expand All @@ -55,7 +55,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
ctx.usePhases(phases)
for (phase <- ctx.allPhases)
if (!ctx.reporter.hasErrors) {
if (ctx.settings.verbose.value) println(s"[$phase]")
if (ctx.settings.verbose.value) ctx.println(s"[$phase]")
units = phase.runOn(units)
def foreachUnit(op: Context => Unit)(implicit ctx: Context): Unit =
for (unit <- units) op(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
Expand All @@ -69,8 +69,8 @@ class Run(comp: Compiler)(implicit ctx: Context) {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squashedPhase = ctx.squashed(prevPhase)

println(s"result of $unit after ${squashedPhase}:")
println(unit.tpdTree.show(ctx))
ctx.println(s"result of $unit after ${squashedPhase}:")
ctx.println(unit.tpdTree.show(ctx))
}

def compile(sourceCode: String): Unit = {
Expand Down
12 changes: 6 additions & 6 deletions src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class TreeChecker extends Phase with SymTransformer {
private val seenClasses = collection.mutable.HashMap[String, Symbol]()
private val seenModuleVals = collection.mutable.HashMap[String, Symbol]()

def printError(str: String) = {
println(Console.RED + "[error] " + Console.WHITE + str)
def printError(str: String)(implicit ctx: Context) = {
ctx.println(Console.RED + "[error] " + Console.WHITE + str)
}

val NoSuperClass = Trait | Package
Expand Down Expand Up @@ -109,15 +109,15 @@ class TreeChecker extends Phase with SymTransformer {
def check(phasesToRun: Seq[Phase], ctx: Context) = {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squahsedPhase = ctx.squashed(prevPhase)
println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
val checkingCtx = ctx.fresh
.setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter)))
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
catch {
case NonFatal(ex) =>
implicit val ctx: Context = checkingCtx
println(i"*** error while checking after phase ${checkingCtx.phase.prev} ***")
ctx.println(i"*** error while checking after phase ${checkingCtx.phase.prev} ***")
throw ex
}
}
Expand Down Expand Up @@ -151,10 +151,10 @@ class TreeChecker extends Phase with SymTransformer {
}

nowDefinedSyms += tree.symbol
//println(i"defined: ${tree.symbol}")
//ctx.println(i"defined: ${tree.symbol}")
val res = op
nowDefinedSyms -= tree.symbol
//println(i"undefined: ${tree.symbol}")
//ctx.println(i"undefined: ${tree.symbol}")
res
case _ => op
}
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/FrontEnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FrontEnd extends Phase {
try body
catch {
case NonFatal(ex) =>
println(s"exception occurred while $doing ${ctx.compilationUnit}")
ctx.println(s"exception occurred while $doing ${ctx.compilationUnit}")
throw ex
}

Expand Down
7 changes: 5 additions & 2 deletions test/dotty/partest/DPConfig.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package dotty.partest

import java.io.File
import scala.collection.JavaConversions._
import scala.reflect.io.Path
import java.io.File


/** Dotty Partest runs all tests in the provided testDirs located under
Expand All @@ -14,7 +15,9 @@ import scala.collection.JavaConversions._
* otherwise pos/__defaultFlags.flags are used if the file exists).
*/
object DPConfig {
val testRoot = "./tests/partest-generated"
val testRoot = (Path(".") / Path("tests") / Path("partest-generated")).toString
val genLog = Path(testRoot) / Path("gen.log")

lazy val testDirs = {
val root = new File(testRoot)
val dirs = if (!root.exists) Array.empty[String] else root.listFiles.filter(_.isDirectory).map(_.getName)
Expand Down
29 changes: 11 additions & 18 deletions test/dotty/partest/DPConsoleRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import scala.tools.partest._
import scala.tools.partest.nest._
import scala.util.matching.Regex
import tools.nsc.io.{ File => NSCFile }
import java.io.{ File, PrintStream, FileOutputStream }
import java.io.{ File, PrintStream, FileOutputStream, PrintWriter, FileWriter }
import java.net.URLClassLoader

/** Runs dotty partest from the Console, discovering test sources in
Expand Down Expand Up @@ -91,23 +91,11 @@ extends SuiteRunner(testSourcePath, fileManager, updateCheck, failed, javaCmdPat

val state =
try {
// IO redirection is messy, there are no concurrency guarantees.
// Parts of test output might end up in the wrong file or get lost.
Console.out.flush
Console.err.flush
val clog = runner.cLogFile
val stream = new PrintStream(new FileOutputStream(clog.jfile), true)
val result = Console.withOut(stream)({ Console.withErr(stream)({
val res = runner.run()
Console.err.flush
Console.out.flush
res
})})
result match {
runner.run match {
// Append compiler output to transcript if compilation failed,
// printed with --verbose option
case TestState.Fail(f, r@"compilation failed", transcript) =>
TestState.Fail(f, r, transcript ++ clog.fileLines.dropWhile(_ == ""))
TestState.Fail(f, r, transcript ++ runner.cLogFile.fileLines.dropWhile(_ == ""))
case res => res
}
} catch {
Expand Down Expand Up @@ -261,11 +249,16 @@ class DPTestRunner(testFile: File, suiteRunner: DPSuiteRunner) extends nest.Runn
override def groupedFiles(sources: List[File]): List[List[File]] = {
val grouped = sources groupBy (_.group)
val flatGroup = List(grouped.keys.toList.sorted.map({ k => grouped(k) sortBy (_.getName) }).flatten)
try { // try/catch because of bug in partest
try { // try/catch because of bug in partest that throws exception
if (flatGroup != super.groupedFiles(sources))
NestUI.echoWarning("Warning: Overriding compilation groups for tests: " + sources)
throw new java.lang.UnsupportedOperationException()
} catch {
case e: java.lang.UnsupportedOperationException => NestUI.echoWarning("Warning: Overriding compilation groups for tests: " + sources)
case e: java.lang.UnsupportedOperationException =>
val genlogFWriter = new FileWriter(DPConfig.genLog.jfile, true)
val genlogWriter = new PrintWriter(genlogFWriter, true)
genlogWriter.println("Warning: Overriding compilation groups for tests: " + sources)
genlogWriter.close
genlogFWriter.close
}
flatGroup
}
Expand Down
19 changes: 13 additions & 6 deletions test/dotty/partest/DPDirectCompiler.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package dotty.partest

import dotty.tools.dotc.reporting.ConsoleReporter
import scala.tools.partest.{ TestState, nest }
import java.io.File
import java.io.{ File, PrintWriter, FileWriter }


/* NOTE: Adapted from partest.DirectCompiler and DottyTest */
class DPDirectCompiler(runner: nest.Runner) extends nest.DirectCompiler(runner) {
class DPDirectCompiler(runner: DPTestRunner) extends nest.DirectCompiler(runner) {

override def compile(opts0: List[String], sources: List[File]): TestState = {
println("\ncompiling " + sources.mkString(" ") + "\noptions: " + opts0.mkString(" "))
val clogFWriter = new FileWriter(runner.cLogFile.jfile, true)
val clogWriter = new PrintWriter(clogFWriter, true)
clogWriter.println("\ncompiling " + sources.mkString(" ") + "\noptions: " + opts0.mkString(" "))

implicit var ctx: dotty.tools.dotc.core.Contexts.Context = {
val base = new dotty.tools.dotc.core.Contexts.ContextBase
Expand All @@ -18,17 +21,21 @@ class DPDirectCompiler(runner: nest.Runner) extends nest.DirectCompiler(runner)
base.definitions.init(ctx)
ctx
}

try {
val processor = if (opts0.exists(_.startsWith("#"))) dotty.tools.dotc.Bench else dotty.tools.dotc.Main
val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, ctx)
val clogger = new ConsoleReporter(writer = clogWriter)(ctx)
val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, ctx, Some(clogger))
if (!reporter.hasErrors) runner.genPass()
else {
reporter.printSummary(ctx)
runner.genFail(s"compilation failed with ${reporter.errorCount} errors")
}
} catch {
} catch {
case t: Throwable => runner.genCrash(t)
} finally {
clogFWriter.close
clogWriter.close
}
}
}
2 changes: 1 addition & 1 deletion test/test/CompilerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ object CompilerTest extends App {
lazy val init: SFile = {
scala.reflect.io.Directory(DPConfig.testRoot).deleteRecursively
new JFile(DPConfig.testRoot).mkdirs
val log = (Path(DPConfig.testRoot) / Path("gen.log")).createFile(true)
val log = DPConfig.genLog.createFile(true)
println(s"CompilerTest is generating tests for partest, log: $log")
log
}
Expand Down