diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-12 16:24:43 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-12 16:24:43 +0200 |
commit | 34317c162e9d79729e57d22bb167f420e948da8f (patch) | |
tree | 6a3ff884020f14e7507f45de9d88240cf687ea2d /src/dotty | |
parent | 775b2a1857290f5e83036148dbbfcdc3a29a12d2 (diff) | |
download | dotty-34317c162e9d79729e57d22bb167f420e948da8f.tar.gz dotty-34317c162e9d79729e57d22bb167f420e948da8f.tar.bz2 dotty-34317c162e9d79729e57d22bb167f420e948da8f.zip |
Added main runner and driver.
Left dummies for Compiler and Run.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Driver.scala | 44 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Main.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Run.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/CompilerCommand.scala | 127 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/Properties.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 |
7 files changed, 221 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala new file mode 100644 index 000000000..f5bf1fb9b --- /dev/null +++ b/src/dotty/tools/dotc/Compiler.scala @@ -0,0 +1,11 @@ +package dotty.tools +package dotc + +import core._ +import Contexts._ + +class Compiler { + + def newRun(implicit ctx: Context): Run = new Run(this) + +}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala new file mode 100644 index 000000000..a175b8bc4 --- /dev/null +++ b/src/dotty/tools/dotc/Driver.scala @@ -0,0 +1,44 @@ +package dotty.tools.dotc + +import config.CompilerCommand +import core.Contexts.{Context, ContextBase} +import core.DotClass + +abstract class Driver extends DotClass { + + val prompt = "\ndotc>" + + protected def newCompiler(): Compiler + + protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context) = + if (fileNames.nonEmpty) { + val run = compiler.newRun + run.compile(fileNames) + ctx.reporter.printSummary + } + + protected def initCtx = (new ContextBase).initialCtx + + def process(args: Array[String]): Boolean = { + val summary = CompilerCommand.distill(args)(initCtx) + implicit val ctx = initCtx.fresh.withSettings(summary.sstate) + val fileNames = CompilerCommand.checkUsage(summary) + try { + doCompile(newCompiler(), fileNames) + !ctx.reporter.hasErrors + } catch { + case ex: Throwable => + ctx.error(ex.getMessage) + ex match { + case ex: FatalError => false // signals that we should fail compilation. + case _ => throw ex // unexpected error, tell the outside world. + } + } + } + + def main(args: Array[String]): Unit = + sys.exit(if (process(args)) 1 else 0) +} + +class FatalError(msg: String) extends Exception + diff --git a/src/dotty/tools/dotc/Main.scala b/src/dotty/tools/dotc/Main.scala new file mode 100644 index 000000000..3ba05dfee --- /dev/null +++ b/src/dotty/tools/dotc/Main.scala @@ -0,0 +1,23 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2013 LAMP/EPFL + * @author Martin Odersky + */ +package dotty.tools +package dotc + +import core.Contexts.Context + +object Main extends Driver { + def resident(compiler: Compiler): Unit = 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])(implicit ctx: Context) { + if (ctx.settings.resident.value) resident(compiler) + else super.doCompile(compiler, fileNames) + } +} diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala new file mode 100644 index 000000000..8358cdbca --- /dev/null +++ b/src/dotty/tools/dotc/Run.scala @@ -0,0 +1,12 @@ +package dotty.tools +package dotc + +import core._ +import Contexts._ + +class Run(comp: Compiler)(implicit ctx: Context) { + + def compile(fileNames: List[String]): Unit = + for (name <- fileNames) println(s"<compiling $name>") + +}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/config/CompilerCommand.scala b/src/dotty/tools/dotc/config/CompilerCommand.scala new file mode 100644 index 000000000..f4c6ea014 --- /dev/null +++ b/src/dotty/tools/dotc/config/CompilerCommand.scala @@ -0,0 +1,127 @@ + +package dotty.tools.dotc +package config + +import java.io.File +import Settings._ +import core.Contexts._ +import core.DotClass +import Properties._ + +object CompilerCommand extends DotClass { + + /** The name of the command */ + def cmdName = "scalac" + + private def explainAdvanced = "\n" + """ + |-- Notes on option parsing -- + |Boolean settings are always false unless set. + |Where multiple values are accepted, they should be comma-separated. + | example: -Xplugin:plugin1,plugin2 + |<phases> means one or a comma-separated list of: + | (partial) phase names, phase ids, phase id ranges, or the string "all". + | example: -Xprint:all prints all phases. + | example: -Xprint:expl,24-26 prints phases explicitouter, closelim, dce, jvm. + | example: -Xprint:-4 prints only the phases up to typer. + | + """.stripMargin.trim + "\n" + + def shortUsage = s"Usage: $cmdName <options> <source files>" + + def versionMsg = s"Dotty compiler $versionString -- $copyrightString" + + /** Distill arguments into summary detailing settings, errors and files to compiler */ + def distill(args: Array[String])(implicit ctx: Context): ArgsSummary = { + /** + * Expands all arguments starting with @ to the contents of the + * file named like each argument. + */ + def expandArg(arg: String): List[String] = unsupported("expandArg")/*{ + def stripComment(s: String) = s takeWhile (_ != '#') + val file = File(arg stripPrefix "@") + if (!file.exists) + throw new java.io.FileNotFoundException("argument file %s could not be found" format file.name) + + settings splitParams (file.lines() map stripComment mkString " ") + }*/ + + // expand out @filename to the contents of that filename + def expandedArguments = args.toList flatMap { + case x if x startsWith "@" => expandArg(x) + case x => List(x) + } + + ctx.settings.processArguments(expandedArguments, processAll = true) + } + + /** Provide usage feedback on argument summary, assuming that all settings + * are already applied in context. + * @return The list of files to compile. + */ + def checkUsage(summary: ArgsSummary)(implicit ctx: Context): List[String] = { + val settings = ctx.settings + + /** Creates a help message for a subset of options based on cond */ + def availableOptionsMsg(cond: Setting[_] => Boolean): String = { + val ss = (ctx.settings.allSettings filter cond).toList sortBy (_.name) + val width = (ss map (_.name.length)).max + def format(s: String) = ("%-" + width + "s") format s + def helpStr(s: Setting[_]) = s"${format(s.name)} ${s.description}" + ss map helpStr mkString "\n" + } + + def createUsageMsg(label: String, shouldExplain: Boolean, cond: Setting[_] => Boolean): String = { + val prefix = List( + Some(shortUsage), + Some(explainAdvanced) filter (_ => shouldExplain), + Some(label + " options include:") + ).flatten mkString "\n" + + prefix + "\n" + availableOptionsMsg(cond) + } + + def isStandard(s: Setting[_]): Boolean = !isAdvanced(s) && !isPrivate(s) + def isAdvanced(s: Setting[_]): Boolean = s.name startsWith "-X" + def isPrivate(s: Setting[_]) : Boolean = s.name startsWith "-Y" + + /** Messages explaining usage and options */ + def usageMessage = createUsageMsg("where possible standard", shouldExplain = false, isStandard) + def xusageMessage = createUsageMsg("Possible advanced", shouldExplain = true, isAdvanced) + def yusageMessage = createUsageMsg("Possible private", shouldExplain = true, isPrivate) + + def shouldStopWithInfo = { + import settings._ + Set(help, Xhelp, Yhelp, showPlugins, showPhases) exists (_.value) + } + + def infoMessage: String = { + import settings._ + if (help.value) usageMessage + else if (Xhelp.value) xusageMessage + else if (Yhelp.value) yusageMessage +// else if (showPlugins.value) global.pluginDescriptions +// else if (showPhases.value) global.phaseDescriptions + ( +// if (debug.value) "\n" + global.phaseFlagDescriptions else "" +// ) + else "" + } + + if (summary.errors.nonEmpty) { + summary.errors foreach (ctx.error(_)) + ctx.echo(" dotc -help gives more information") + Nil + } + else if (settings.version.value) { + ctx.echo(versionMsg) + Nil + } + else if (shouldStopWithInfo) { + ctx.echo(infoMessage) + Nil + } else { + if (summary.arguments.isEmpty && !settings.resident.value) + ctx.echo(usageMessage) + summary.arguments + } + } +} diff --git a/src/dotty/tools/dotc/config/Properties.scala b/src/dotty/tools/dotc/config/Properties.scala index 4507568e4..47572e087 100644 --- a/src/dotty/tools/dotc/config/Properties.scala +++ b/src/dotty/tools/dotc/config/Properties.scala @@ -94,8 +94,8 @@ trait PropertiesTrait { /** The version number of the jar this was loaded from plus "version " prefix, * or "version (unknown)" if it cannot be determined. */ - val versionString = "version " + scalaPropOrElse("version.number", "(unknown)") - val copyrightString = scalaPropOrElse("copyright.string", "(c) 2002-2011 LAMP/EPFL") + val versionString = "version " + "0.01" //scalaPropOrElse("version.number", "(unknown)")" + + val copyrightString = "(c) 2013 LAMP/EPFL" // scalaPropOrElse("copyright.string", "(c) 2002-2011 LAMP/EPFL") /** This is the encoding to use reading in source files, overridden with -encoding * Note that it uses "prop" i.e. looks in the scala jar, not the system properties. diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 9bdfea871..219f8045b 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -70,6 +70,8 @@ class Typer extends Namer with Applications with Implicits { /** A temporary data item valid for a single typed ident: * The set of all root import symbols that have been * encountered as a qualifier of an import so far. + * Note: It would be more proper to move importedFromRoot into typedIdent. + * We should check that this has no performance degradation, however. */ private var importedFromRoot: Set[Symbol] = Set() |