Skip to content

Add/resident compiler #662

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 6 commits into from
Jun 29, 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
34 changes: 9 additions & 25 deletions src/dotty/tools/dotc/Bench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,7 @@ package dotc
import core.Contexts.Context
import reporting.Reporter

/* To do:
* - simplify hk types
* - have a second look at normalization (leave at method types if pt is method type?)
* - Don't open package objects from class files if they are present in source
* - Revise the way classes are inherited - when not followed by [...] or (...),
* assume the unparameterized type and forward type parameters as we do now for the synthetic head class.
*/
object Bench extends Driver {
def resident(compiler: Compiler): Reporter = unsupported("resident") /*loop { line =>
val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError))
compiler.reporter.reset()
new compiler.Run() compile command.files
}*/

private var numRuns = 1

Expand All @@ -29,29 +17,25 @@ 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], 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, reporter)
ctx.println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
r
}
override def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
ntimes(numRuns) {
val start = System.nanoTime()
val r = super.doCompile(compiler, fileNames)
println(s"time elapsed: ${(System.nanoTime - start) / 1000000}ms")
r
}

def extractNumArg(args: Array[String], name: String, default: Int = 1): (Int, Array[String]) = {
val pos = args indexOf name
if (pos < 0) (default, args)
else (args(pos + 1).toInt, (args take pos) ++ (args drop (pos + 2)))
}

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

Expand Down
12 changes: 7 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, Reporter}
import reporting.{Reporter, ConsoleReporter}
import Phases.Phase
import dotty.tools.dotc.transform._
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransform, TreeTransformer}
Expand Down Expand Up @@ -94,7 +94,7 @@ class Compiler {
* for type checking.
* imports For each element of RootImports, an import context
*/
def rootContext(implicit ctx: Context, r: Option[Reporter] = None): Context = {
def rootContext(implicit ctx: Context): Context = {
ctx.definitions.init(ctx)
ctx.setPhasePlan(phases)
val rootScope = new MutableScope
Expand All @@ -106,20 +106,22 @@ class Compiler {
.setOwner(defn.RootClass)
.setTyper(new Typer)
.setMode(Mode.ImplicitsEnabled)
.setTyperState(new MutableTyperState(ctx.typerState, r.getOrElse(new ConsoleReporter()(ctx)), isCommittable = true))
.setTyperState(new MutableTyperState(ctx.typerState, rootReporter(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))
(start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)
}

protected def rootReporter(implicit ctx: Context): Reporter = new ConsoleReporter()(ctx)

def reset()(implicit ctx: Context): Unit = {
ctx.base.reset()
ctx.runInfo.clear()
}

def newRun(implicit ctx: Context, r: Option[Reporter] = None): Run = {
def newRun(implicit ctx: Context): Run = {
reset()
new Run(this)(rootContext(ctx, r))
new Run(this)(rootContext)
}
}
41 changes: 24 additions & 17 deletions src/dotty/tools/dotc/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,40 @@ import scala.util.control.NonFatal

abstract class Driver extends DotClass {

val prompt = "\ndotc>"
val prompt = "\ndotc> "

protected def newCompiler(): Compiler

protected def emptyReporter: Reporter = new StoreReporter

protected def doCompile(compiler: Compiler, fileNames: List[String], reporter: Option[Reporter] = None)
(implicit ctx: Context): Reporter =
if (fileNames.nonEmpty) {
val run = compiler.newRun(ctx, reporter)
run.compile(fileNames)
run.printSummary()
} else emptyReporter
protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
if (fileNames.nonEmpty)
try {
val run = compiler.newRun
run.compile(fileNames)
run.printSummary()
}
catch {
case ex: FatalError =>
ctx.error(ex.getMessage) // signals that we should fail compilation.
ctx.typerState.reporter
}
else emptyReporter

protected def initCtx = (new ContextBase).initialCtx

def process(args: Array[String], rootCtx: Context, reporter: Option[Reporter] = None): Reporter = {
protected def sourcesRequired = true

def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
val summary = CompilerCommand.distill(args)(rootCtx)
implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
val fileNames = CompilerCommand.checkUsage(summary)
try {
doCompile(newCompiler(), fileNames, reporter)
} catch {
case ex: FatalError =>
ctx.error(ex.getMessage) // signals that we should fail compilation.
ctx.typerState.reporter
}
val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)
(fileNames, ctx)
}

def process(args: Array[String], rootCtx: Context): Reporter = {
val (fileNames, ctx) = setup(args, rootCtx)
doCompile(newCompiler(), fileNames)(ctx)
}

def main(args: Array[String]): Unit =
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/FromTasty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ object FromTasty extends Driver {
List(new ReadTastyTreesFromClasses) :: backendPhases
}

override def newRun(implicit ctx: Context, reporter: Option[Reporter] = None): Run = {
override def newRun(implicit ctx: Context): Run = {
reset()
new TASTYRun(this)(rootContext)
}
Expand Down
17 changes: 0 additions & 17 deletions src/dotty/tools/dotc/Main.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/* NSC -- new Scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Martin Odersky
*/
package dotty.tools
package dotc

Expand All @@ -11,18 +7,5 @@ import reporting.Reporter
/* To do:
*/
object Main extends Driver {
def resident(compiler: Compiler): Reporter = unsupported("resident") /*loop { line =>
val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError))
compiler.reporter.reset()
new compiler.Run() compile command.files
}*/

override def newCompiler(): Compiler = new Compiler

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, reporter)
}
}
55 changes: 55 additions & 0 deletions src/dotty/tools/dotc/Resident.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package dotty.tools
package dotc

import core.Contexts.Context
import reporting.Reporter
import java.io.EOFException
import scala.annotation.tailrec

/** A compiler which stays resident between runs.
* Usage:
*
* > scala dotty.tools.dotc.Resident <options> <initial files>
*
* dotc> "more options and files to compile"
*
* ...
*
* dotc> :reset // reset all options to the ones passed on the command line
*
* ...
*
* dotc> :q // quit
*/
object Resident extends Driver {

object residentCompiler extends Compiler

override def newCompiler(): Compiler = ???

override def sourcesRequired = false

private val quit = ":q"
private val reset = ":reset"

private def getLine() = {
Console.print(prompt)
try scala.io.StdIn.readLine() catch { case _: EOFException => quit }
}

final override def process(args: Array[String], rootCtx: Context): Reporter = {
@tailrec def loop(args: Array[String], prevCtx: Context): Reporter = {
var (fileNames, ctx) = setup(args, prevCtx)
doCompile(residentCompiler, fileNames)(ctx)
var nextCtx = ctx
var line = getLine()
while (line == reset) {
nextCtx = rootCtx
line = getLine()
}
if (line.startsWith(quit)) ctx.typerState.reporter
else loop(line split "\\s+", nextCtx)
}
loop(args, rootCtx)
}
}
5 changes: 2 additions & 3 deletions src/dotty/tools/dotc/config/CompilerCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ object CompilerCommand extends DotClass {
* are already applied in context.
* @return The list of files to compile.
*/
def checkUsage(summary: ArgsSummary)(implicit ctx: Context): List[String] = {
def checkUsage(summary: ArgsSummary, sourcesRequired: Boolean)(implicit ctx: Context): List[String] = {
val settings = ctx.settings

/** Creates a help message for a subset of options based on cond */
Expand Down Expand Up @@ -121,8 +121,7 @@ object CompilerCommand extends DotClass {
ctx.println(infoMessage)
Nil
} else {
if (summary.arguments.isEmpty && !settings.resident.value)
ctx.println(usageMessage)
if (sourcesRequired && summary.arguments.isEmpty) ctx.println(usageMessage)
summary.arguments
}
}
Expand Down
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ class ScalaSettings extends Settings.SettingGroup {
val Xprintpos = BooleanSetting("-Xprint-pos", "Print tree positions, as offsets.")
val printtypes = BooleanSetting("-Xprint-types", "Print tree types (debugging option).")
val prompt = BooleanSetting("-Xprompt", "Display a prompt after each error (debugging option).")
val resident = BooleanSetting("-Xresident", "Compiler stays resident: read source filenames from standard input.")
val script = StringSetting("-Xscript", "object", "Treat the source file as a script and wrap it in a main method.", "")
val mainClass = StringSetting("-Xmain-class", "path", "Class for manifest's Main-Class entry (only useful with -d <jar>)", "")
val Xshowcls = StringSetting("-Xshow-class", "class", "Show internal representation of class.", "")
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/reporting/ThrowingReporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import collection.mutable
import Reporter._

/**
* This class implements a Reporter that stores all messages
* This class implements a Reporter that throws all errors and sends warnings and other
* info to the underlying reporter.
*/
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
Expand Down
6 changes: 4 additions & 2 deletions test/dotty/partest/DPDirectCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ class DPDirectCompiler(runner: DPTestRunner) extends nest.DirectCompiler(runner)
}

try {
val processor = if (opts0.exists(_.startsWith("#"))) dotty.tools.dotc.Bench else dotty.tools.dotc.Main
val processor =
if (opts0.exists(_.startsWith("#"))) dotty.tools.dotc.Bench else dotty.tools.dotc.Main
val clogger = new ConsoleReporter(writer = clogWriter)(ctx)
val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, ctx, Some(clogger))
val logCtx = ctx.fresh.setTyperState(ctx.typerState.withReporter(clogger))
val reporter = processor.process((sources.map(_.toString) ::: opts0).toArray, logCtx)
if (!reporter.hasErrors) runner.genPass()
else {
reporter.printSummary(ctx)
Expand Down