aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-03 11:59:38 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-03 11:59:38 +0100
commit8ac1b32ad3b190de82f5c4f1d1666f093ad8c20f (patch)
tree024b841641152deb5743d678885afae68ba8647b /src/dotty/tools
parentabc8f5e1c382b1ead761976227878c4c38ebfbf5 (diff)
downloaddotty-8ac1b32ad3b190de82f5c4f1d1666f093ad8c20f.tar.gz
dotty-8ac1b32ad3b190de82f5c4f1d1666f093ad8c20f.tar.bz2
dotty-8ac1b32ad3b190de82f5c4f1d1666f093ad8c20f.zip
Integration of settings, platform, pathresolver, etc.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/config/JavaPlatform.scala63
-rw-r--r--src/dotty/tools/dotc/config/PathResolver.scala38
-rw-r--r--src/dotty/tools/dotc/config/Platform.scala6
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala172
-rw-r--r--src/dotty/tools/dotc/config/Settings.scala238
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala31
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala4
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala4
9 files changed, 465 insertions, 93 deletions
diff --git a/src/dotty/tools/dotc/config/JavaPlatform.scala b/src/dotty/tools/dotc/config/JavaPlatform.scala
index 3c6ea3a8a..0c91ae2e7 100644
--- a/src/dotty/tools/dotc/config/JavaPlatform.scala
+++ b/src/dotty/tools/dotc/config/JavaPlatform.scala
@@ -4,72 +4,41 @@ package config
import io.{AbstractFile,ClassPath,JavaClassPath,MergedClassPath,DeltaClassPath}
import ClassPath.{ JavaContext, DefaultJavaContext }
+import core.Contexts._
+import core.SymDenotations._, core.Symbols._, core.SymbolLoader
-trait JavaPlatform /*extends Platform {
- import global._
- import definitions._
+class JavaPlatform(base: ContextBase) extends Platform(base) {
- type BinaryRepr = AbstractFile
+ private var currentClassPath: Option[MergedClassPath] = None
- private var currentClassPath: Option[MergedClassPath[BinaryRepr]] = None
-
- def classPath: ClassPath[BinaryRepr] = {
- if (currentClassPath.isEmpty) currentClassPath = Some(new PathResolver(settings).result)
+ def classPath(implicit ctx: Context): ClassPath = {
+ if (currentClassPath.isEmpty)
+ currentClassPath = Some(new PathResolver(ctx).result)
currentClassPath.get
}
/** Update classpath with a substituted subentry */
- def updateClassPath(subst: Map[ClassPath[BinaryRepr], ClassPath[BinaryRepr]]) =
+ def updateClassPath(subst: Map[ClassPath, ClassPath]) =
currentClassPath = Some(new DeltaClassPath(currentClassPath.get, subst))
- def rootLoader = new loaders.PackageLoader(classPath.asInstanceOf[ClassPath[platform.BinaryRepr]])
- // [Martin] Why do we need a cast here?
- // The problem is that we cannot specify at this point that global.platform should be of type JavaPlatform.
- // So we cannot infer that global.platform.BinaryRepr is AbstractFile.
- // Ideally, we should be able to write at the top of the JavaPlatform trait:
- // val global: Global { val platform: JavaPlatform }
- // import global._
- // Right now, this does nothing because the concrete definition of platform in Global
- // replaces the tighter abstract definition here. If we had DOT typing rules, the two
- // types would be conjoined and everything would work out. Yet another reason to push for DOT.
-
- private def depAnalysisPhase =
- if (settings.make.isDefault) Nil
- else List(dependencyAnalysis)
-
- private def classEmitPhase =
- if (settings.target.value == "jvm-1.5-fjbg") genJVM
- else genASM
-
- def platformPhases = List(
- flatten, // get rid of inner classes
- classEmitPhase // generate .class files
- ) ++ depAnalysisPhase
-
- lazy val externalEquals = getDecl(BoxesRunTimeClass, nme.equals_)
- lazy val externalEqualsNumNum = getDecl(BoxesRunTimeClass, nme.equalsNumNum)
- lazy val externalEqualsNumChar = getDecl(BoxesRunTimeClass, nme.equalsNumChar)
- lazy val externalEqualsNumObject = getDecl(BoxesRunTimeClass, nme.equalsNumObject)
+ def rootLoader: ClassCompleter = ??? // = new loaders.PackageLoader(classPath)
/** We could get away with excluding BoxedBooleanClass for the
* purpose of equality testing since it need not compare equal
* to anything but other booleans, but it should be present in
* case this is put to other uses.
*/
- def isMaybeBoxed(sym: Symbol) = {
+ def isMaybeBoxed(sym: Symbol)(implicit ctx: Context) = {
+ val d = defn
+ import d._
(sym == ObjectClass) ||
(sym == JavaSerializableClass) ||
(sym == ComparableClass) ||
(sym isNonBottomSubClass BoxedNumberClass) ||
- (sym isNonBottomSubClass BoxedCharacterClass) ||
+ (sym isNonBottomSubClass BoxedCharClass) ||
(sym isNonBottomSubClass BoxedBooleanClass)
}
- def newClassLoader(bin: AbstractFile): loaders.SymbolLoader =
- new loaders.ClassfileLoader(bin)
-
- def doLoad(cls: ClassPath[BinaryRepr]#ClassRep): Boolean = true
-
- def needCompile(bin: AbstractFile, src: AbstractFile) =
- src.lastModified >= bin.lastModified
-}*/
+ def newClassLoader(bin: AbstractFile): SymbolLoader = ???
+ // new loaders.ClassfileLoader(bin)
+}
diff --git a/src/dotty/tools/dotc/config/PathResolver.scala b/src/dotty/tools/dotc/config/PathResolver.scala
index 6771e1465..06bb7f04b 100644
--- a/src/dotty/tools/dotc/config/PathResolver.scala
+++ b/src/dotty/tools/dotc/config/PathResolver.scala
@@ -8,13 +8,14 @@ import io.{ ClassPath, JavaClassPath, File, Directory, Path, AbstractFile }
import ClassPath.{ JavaContext, DefaultJavaContext, join, split }
import PartialFunction.condOpt
import scala.language.postfixOps
+import core.Contexts._
+import Settings._
// Loosely based on the draft specification at:
// https://wiki.scala-lang.org/display/SW/Classpath
object PathResolver {
- /*
// Imports property/environment functions which suppress
// security exceptions.
import AccessControl._
@@ -132,11 +133,9 @@ object PathResolver {
)
}
- def fromPathString(path: String, context: JavaContext = DefaultJavaContext): JavaClassPath = {
- val s = new Settings() {
- classpath = path
- }
- new PathResolver(s, context) result
+ def fromPathString(path: String)(implicit ctx: Context): JavaClassPath = {
+ val settings = ctx.settings.classpath.update(path)
+ new PathResolver(ctx.fresh.withSettings(settings)).result
}
/** With no arguments, show the interesting values in Environment and Defaults.
@@ -149,9 +148,11 @@ object PathResolver {
println(Defaults)
}
else {
- val settings = new Settings()
- val rest = settings.processArguments(args.toList, false)._2
- val pr = new PathResolver(settings)
+ val ctx = (new ContextBase).initialCtx
+ val ArgsSummary(sstate, rest, errors) =
+ ctx.settings.processArguments(args.toList, true)(ctx)
+ errors.foreach(println)
+ val pr = new PathResolver(ctx.fresh.withSettings(sstate))
println(" COMMAND: 'scala %s'".format(args.mkString(" ")))
println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" ")))
pr.result.show
@@ -160,7 +161,9 @@ object PathResolver {
}
import PathResolver.{ Defaults, Environment, firstNonEmpty, ppcp }
-class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext) {
+class PathResolver(_ctx: Context) {
+ implicit val ctx = _ctx
+ val context = ClassPath.DefaultJavaContext
private def cmdLineOrElse(name: String, alt: String) = {
(commandLineFor(name) match {
@@ -184,7 +187,7 @@ class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext
*/
object Calculated {
def scalaHome = Defaults.scalaHome
- def useJavaClassPath = settings.usejavacp.value || Defaults.useJavaClassPath
+ def useJavaClassPath = ctx.settings.usejavacp.value || Defaults.useJavaClassPath
def javaBootClassPath = cmdLineOrElse("javabootclasspath", Defaults.javaBootClassPath)
def javaExtDirs = cmdLineOrElse("javaextdirs", Defaults.javaExtDirs)
def javaUserClassPath = if (useJavaClassPath) Defaults.javaUserClassPath else ""
@@ -198,7 +201,7 @@ class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext
* and then when typing relative names, instead of picking <root>.scala.relect, typedIdentifier will pick up the
* <root>.reflect package created by the bootstrapping. Thus, no bootstrapping for scaladoc!
* TODO: we should refactor this as a separate -bootstrap option to have a clean implementation, no? */
- def sourcePath = if (!settings.isScaladoc) cmdLineOrElse("sourcepath", Defaults.scalaSourcePath) else ""
+ def sourcePath = cmdLineOrElse("sourcepath", Defaults.scalaSourcePath)
/** Against my better judgment, giving in to martin here and allowing
* CLASSPATH to be used automatically. So for the user-specified part
@@ -209,8 +212,8 @@ class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext
* - If neither of those, then "." is used.
*/
def userClassPath = (
- if (!settings.classpath.isDefault)
- settings.classpath.value
+ if (!ctx.settings.classpath.isDefault)
+ ctx.settings.classpath.value
else sys.env.getOrElse("CLASSPATH", ".")
)
@@ -251,10 +254,10 @@ class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext
def containers = Calculated.containers
- lazy val result = {
+ lazy val result: JavaClassPath = {
val cp = new JavaClassPath(containers.toIndexedSeq, context)
- if (settings.Ylogcp.value) {
- Console.println("Classpath built from " + settings.toConciseString)
+ if (ctx.settings.Ylogcp.value) {
+ Console.println("Classpath built from " + ctx.settings.toConciseString(ctx.sstate))
Console.println("Defaults: " + PathResolver.Defaults)
Console.println("Calculated: " + Calculated)
@@ -267,5 +270,4 @@ class PathResolver(settings: Settings, context: JavaContext = DefaultJavaContext
def asURLs = result.asURLs
- */
}
diff --git a/src/dotty/tools/dotc/config/Platform.scala b/src/dotty/tools/dotc/config/Platform.scala
index 73d32f193..32f2139e7 100644
--- a/src/dotty/tools/dotc/config/Platform.scala
+++ b/src/dotty/tools/dotc/config/Platform.scala
@@ -8,7 +8,7 @@ package dotc
package config
import io.{ClassPath, AbstractFile}
-import core.Contexts._
+import core.Contexts._, core.Symbols._
import core.SymDenotations.ClassCompleter
import core.SymbolLoader
@@ -20,7 +20,7 @@ abstract class Platform(base: ContextBase) {
def rootLoader: ClassCompleter
/** The compiler classpath. */
- def classPath: ClassPath
+ def classPath(implicit ctx: Context): ClassPath
/** Update classpath with a substitution that maps entries to entries */
def updateClassPath(subst: Map[ClassPath, ClassPath])
@@ -29,7 +29,7 @@ abstract class Platform(base: ContextBase) {
//def platformPhases: List[SubComponent]
/** The various ways a boxed primitive might materialize at runtime. */
- def isMaybeBoxed(sym: Symbol): Boolean
+ def isMaybeBoxed(sym: Symbol)(implicit ctx: Context): Boolean
/** Create a new class loader to load class file `bin` */
def newClassLoader(bin: AbstractFile): SymbolLoader
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
new file mode 100644
index 000000000..f020ac8ec
--- /dev/null
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -0,0 +1,172 @@
+package dotty.tools.dotc.config
+
+import PathResolver.Defaults
+
+class ScalaSettings extends Settings.SettingGroup {
+
+ protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".")
+
+ /** Path related settings.
+ */
+ val bootclasspath = PathSetting("-bootclasspath", "Override location of bootstrap class files.", Defaults.scalaBootClassPath)
+ val extdirs = PathSetting("-extdirs", "Override location of installed extensions.", Defaults.scalaExtDirs)
+ val javabootclasspath = PathSetting("-javabootclasspath", "Override java boot classpath.", Defaults.javaBootClassPath)
+ val javaextdirs = PathSetting("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs)
+ val sourcepath = PathSetting("-sourcepath", "Specify location(s) of source files.", "") // Defaults.scalaSourcePath
+
+ /** Other settings.
+ */
+ val dependencyfile = StringSetting("-dependencyfile", "file", "Set dependency tracking file.", ".scala_dependencies")
+ val deprecation = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.")
+ val encoding = StringSetting("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding)
+ val explaintypes = BooleanSetting("-explaintypes", "Explain type errors in more detail.")
+ val feature = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.")
+ val g = ChoiceSetting("-g", "level", "Set level of generated debugging info.", List("none", "source", "line", "vars", "notailcalls"), "vars")
+ val help = BooleanSetting("-help", "Print a synopsis of standard options")
+ val nowarn = BooleanSetting("-nowarn", "Generate no warnings.")
+ val print = BooleanSetting("-print", "Print program with Scala-specific features removed.")
+ val target = ChoiceSetting("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
+ List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "msil"),
+ "jvm-1.6")
+ val unchecked = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
+ val uniqid = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.")
+ val usejavacp = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.")
+ val verbose = BooleanSetting("-verbose", "Output messages about what the compiler is doing.")
+ val version = BooleanSetting("-version", "Print product version and exit.")
+
+ val jvmargs = PrefixSetting("-J<flag>", "-J", "Pass <flag> directly to the runtime system.")
+ val defines = PrefixSetting("-Dproperty=value", "-D", "Pass -Dproperty=value directly to the runtime system.")
+ val toolcp = PathSetting("-toolcp", "Add to the runner classpath.", "")
+ val nobootcp = BooleanSetting("-nobootcp", "Do not use the boot classpath for the scala jars.")
+
+ val argfiles = BooleanSetting("@<file>", "A text file containing compiler arguments (options and source files)")
+ val classpath = PathSetting("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
+ // val d = OutputSetting (outputDirs, ".")
+ val nospecialization = BooleanSetting("-no-specialization", "Ignore @specialize annotations.")
+ val language = MultiStringSetting("-language", "feature", "Enable one or more language features.")
+
+ /** -X "Advanced" settings
+ */
+ val Xhelp = BooleanSetting("-X", "Print a synopsis of advanced options.")
+ val assemname = StringSetting("-Xassem-name", "file", "(Requires -target:msil) Name of the output assembly.", "").dependsOn(target, "msil")
+ val assemrefs = StringSetting("-Xassem-path", "path", "(Requires -target:msil) List of assemblies referenced by the program.", ".").dependsOn(target, "msil")
+ val assemextdirs = StringSetting("-Xassem-extdirs", "dirs", "(Requires -target:msil) List of directories containing assemblies. default:lib", Defaults.scalaLibDir.path).dependsOn(target, "msil")
+ val sourcedir = StringSetting("-Xsourcedir", "directory", "(Requires -target:msil) Mirror source folder structure in output directory.", ".").dependsOn(target, "msil")
+ val checkInit = BooleanSetting("-Xcheckinit", "Wrap field accessors to throw an exception on uninitialized access.")
+ val noassertions = BooleanSetting("-Xdisable-assertions", "Generate no assertions or assumptions.")
+// val elidebelow = IntSetting("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument",
+// elidable.MINIMUM, None, elidable.byName get _)
+ val noForwarders = BooleanSetting("-Xno-forwarders", "Do not generate static forwarders in mirror classes.")
+ val genPhaseGraph = StringSetting("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
+ val XlogImplicits = BooleanSetting("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
+ val logImplicitConv = BooleanSetting("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.")
+ val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated")
+ val logFreeTerms = BooleanSetting("-Xlog-free-terms", "Print a message when reification creates a free term.")
+ val logFreeTypes = BooleanSetting("-Xlog-free-types", "Print a message when reification resorts to generating a free type.")
+ val maxClassfileName = IntSetting("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, 72 to 255)
+ val Xmigration28 = BooleanSetting("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.")
+ val nouescape = BooleanSetting("-Xno-uescape", "Disable handling of \\u unicode escapes.")
+ val Xnojline = BooleanSetting("-Xnojline", "Do not use JLine for editing.")
+ val Xverify = BooleanSetting("-Xverify", "Verify generic signatures in generated bytecode (asm backend only.)")
+ val plugin = MultiStringSetting("-Xplugin", "file", "Load one or more plugins from files.")
+ val disable = MultiStringSetting("-Xplugin-disable", "plugin", "Disable the given plugin(s).")
+ val showPlugins = BooleanSetting("-Xplugin-list", "Print a synopsis of loaded plugins.")
+ val require = MultiStringSetting("-Xplugin-require", "plugin", "Abort unless the given plugin(s) are available.")
+ val pluginsDir = StringSetting("-Xpluginsdir", "path", "Path to search compiler plugins.", Defaults.scalaPluginPath)
+ val Xprint = PhasesSetting("-Xprint", "Print out program after")
+ val writeICode = PhasesSetting("-Xprint-icode", "Log internal icode to *.icode files after", "icode")
+ 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.", "")
+ val Xshowobj = StringSetting("-Xshow-object", "object", "Show internal representation of object.", "")
+ val showPhases = BooleanSetting("-Xshow-phases", "Print a synopsis of compiler phases.")
+ val sourceReader = StringSetting("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "")
+
+ val XoldPatmat = BooleanSetting("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.")
+ val XnoPatmatAnalysis = BooleanSetting("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.")
+ val XfullLubs = BooleanSetting("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.")
+
+ /** -Y "Private" settings
+ */
+ val overrideObjects = BooleanSetting("-Yoverride-objects", "Allow member objects to be overridden.")
+ val overrideVars = BooleanSetting("-Yoverride-vars", "Allow vars to be overridden.")
+ val Yhelp = BooleanSetting("-Y", "Print a synopsis of private options.")
+ val browse = PhasesSetting("-Ybrowse", "Browse the abstract syntax tree after")
+ val check = PhasesSetting("-Ycheck", "Check the tree at the end of")
+ val Yshow = PhasesSetting("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after")
+ val Xcloselim = BooleanSetting("-Yclosure-elim", "Perform closure elimination.")
+ val Ycompacttrees = BooleanSetting("-Ycompact-trees", "Use compact tree printer when displaying trees.")
+ val noCompletion = BooleanSetting("-Yno-completion", "Disable tab-completion in the REPL.")
+ val Xdce = BooleanSetting("-Ydead-code", "Perform dead code elimination.")
+ val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
+ //val doc = BooleanSetting ("-Ydoc", "Generate documentation")
+ val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
+ val inline = BooleanSetting("-Yinline", "Perform inlining when possible.")
+ val inlineHandlers = BooleanSetting("-Yinline-handlers", "Perform exception handler inlining when possible.")
+ val YinlinerWarnings = BooleanSetting("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)")
+ val Xlinearizer = ChoiceSetting("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
+ val log = PhasesSetting("-Ylog", "Log operations during")
+ val Ylogcp = BooleanSetting("-Ylog-classpath", "Output information about what classpath is being applied.")
+ val Ynogenericsig = BooleanSetting("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
+ val noimports = BooleanSetting("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.")
+ val nopredef = BooleanSetting("-Yno-predef", "Compile without importing Predef.")
+ val noAdaptedArgs = BooleanSetting("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.")
+ val selfInAnnots = BooleanSetting("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.")
+ val Xshowtrees = BooleanSetting("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs in formatted form.")
+ val XshowtreesCompact = BooleanSetting("-Yshow-trees-compact", "(Requires -Xprint:) Print detailed ASTs in compact form.")
+ val XshowtreesStringified = BooleanSetting("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.")
+ val Yshowsyms = BooleanSetting("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
+ val Yshowsymkinds = BooleanSetting("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.")
+ val skip = PhasesSetting("-Yskip", "Skip")
+ val Ygenjavap = StringSetting("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
+ val Ydumpclasses = StringSetting("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
+ val Ynosqueeze = BooleanSetting("-Yno-squeeze", "Disable creation of compact code in matching.")
+ val stopAfter = PhasesSetting("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
+ val stopBefore = PhasesSetting("-Ystop-before", "Stop before")
+ val refinementMethodDispatch = ChoiceSetting("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache")
+ val Yrangepos = BooleanSetting("-Yrangepos", "Use range positions for syntax trees.")
+ val Ybuilderdebug = ChoiceSetting("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none")
+ val Yreifycopypaste = BooleanSetting("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
+ val Yreplsync = BooleanSetting("-Yrepl-sync", "Do not use asynchronous code for repl startup")
+ val Ynotnull = BooleanSetting("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.")
+ val YmethodInfer = BooleanSetting("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
+ val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.")
+ val Yinvalidate = StringSetting("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "")
+ val noSelfCheck = BooleanSetting("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.")
+ val YvirtClasses = false // too embryonic to even expose as a -Y //BooleanSetting ("-Yvirtual-classes", "Support virtual classes")
+
+ def stop = stopAfter
+
+ /** Area-specific debug output.
+ */
+ val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
+ val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.")
+ val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.")
+ val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
+ val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.")
+ val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.")
+ val YmacrodebugLite = BooleanSetting("-Ymacro-debug-lite", "Trace essential macro-related activities.")
+ val YmacrodebugVerbose = BooleanSetting("-Ymacro-debug-verbose", "Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.")
+ val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.")
+ val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.")
+ val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.")
+ val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.")
+ val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.")
+ val Ypatmatdebug = BooleanSetting("-Ypatmat-debug", "Trace pattern matching translation.")
+
+ val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize"
+
+ /** IDE-specific settings
+ */
+ val YpresentationVerbose = BooleanSetting("-Ypresentation-verbose", "Print information about presentation compiler tasks.")
+ val YpresentationDebug = BooleanSetting("-Ypresentation-debug", "Enable debugging output for the presentation compiler.")
+ val YpresentationStrict = BooleanSetting("-Ypresentation-strict", "Do not report type errors in sources with syntax errors.")
+
+ val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "")
+ val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "")
+ val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999)
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala
index 83c7a747f..eff9c245f 100644
--- a/src/dotty/tools/dotc/config/Settings.scala
+++ b/src/dotty/tools/dotc/config/Settings.scala
@@ -1,26 +1,240 @@
package dotty.tools.dotc
package config
+import collection.mutable.{ ArrayBuffer }
+import scala.util.{ Try, Success, Failure }
+import scala.reflect.internal.util.StringOps
+import reflect.ClassTag
+import core.Contexts._
-class Settings {
+object Settings {
- protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".")
+ val BooleanTag = ClassTag.Boolean
+ val IntTag = ClassTag.Int
+ val StringTag = ClassTag(classOf[String])
+ val ListTag = ClassTag(classOf[List[_]])
- protected implicit def mkSetting[T](x: T): Setting[T] = new Setting(x)
+ class SettingsState(initialValues: Seq[Any]) {
+ private var values = ArrayBuffer(initialValues: _*)
+ private var _wasRead: Boolean = false
- var default: Settings = this
+ def value(idx: Int) = {
+ _wasRead = true
+ values
+ }
- var classpath: Setting[String] = defaultClasspath
- var debug: Setting[Boolean] = false
- var verbose: Setting[Boolean] = false
+ def update(idx: Int, x: Any): SettingsState =
+ if (_wasRead)
+ new SettingsState(values).update(idx, x)
+ else {
+ values(idx) = x
+ this
+ }
+ }
- var XmaxClassfileName: Setting[Int] = 255
+ case class ArgsSummary(
+ sstate: SettingsState,
+ arguments: List[String],
+ errors: List[String]) {
- var YtermConflict: Setting[String] = "error"
+ def fail(msg: String) =
+ ArgsSummary(sstate, arguments, errors :+ msg)
+ }
- def processArguments(arguments: List[String], processAll: Boolean): (Boolean, List[String]) = ???
+ case class Setting[T: ClassTag] private[Settings] (
+ name: String,
+ description: String,
+ default: T,
+ helpArg: String = "",
+ choices: Seq[T] = Nil,
+ prefix: String = "",
+ aliases: List[String] = Nil,
+ depends: List[(Setting[_], Any)] = Nil)(private[Settings] val idx: Int) {
+ def withAbbreviation(abbrv: String): Setting[T] =
+ copy(aliases = aliases :+ abbrv)(idx)
-}
+ def dependsOn[U](setting: Setting[U], value: U): Setting[T] =
+ copy(depends = depends :+ (setting, value))(idx)
-case class Setting[T](value: T) \ No newline at end of file
+ def valueIn(state: SettingsState): T =
+ state.value(idx).asInstanceOf[T]
+
+ def updateIn(state: SettingsState, x: Any): SettingsState = x match {
+ case _: T => state.update(idx, x)
+ case _ => throw new ClassCastException("illegal argument")
+ }
+
+ def isDefaultIn(state: SettingsState) = valueIn(state) == default
+
+ def legalChoices: String =
+ if (choices.isEmpty) ""
+ else choices match {
+ case r: Range => r.head + ".." + r.last
+ case xs: List[_] => xs.mkString(", ")
+ }
+
+ def isLegal(arg: Any): Boolean =
+ if (choices.isEmpty)
+ arg match {
+ case _: T => true
+ case _ => false
+ }
+ else choices match {
+ case r: Range =>
+ arg match {
+ case x: Int => r.head <= x && x <= r.last
+ case _ => false
+ }
+ case xs: List[_] =>
+ xs contains arg
+ }
+
+ def tryToSet(state: ArgsSummary): ArgsSummary = {
+ val ArgsSummary(sstate, arg :: args, errors) = state
+ def update(value: Any, args: List[String]) =
+ ArgsSummary(updateIn(sstate, value), args, errors)
+ def fail(msg: String, args: List[String]) =
+ ArgsSummary(sstate, args, errors :+ msg)
+ def missingArg =
+ fail(s"missing argument for option $name", args)
+ def doSet(argRest: String) = (implicitly[ClassTag[T]], args) match {
+ case (BooleanTag, _) =>
+ update(true, args)
+ case (ListTag, _) =>
+ if (argRest.isEmpty) missingArg
+ else update((argRest split ",").toList, args)
+ case (StringTag, arg2 :: args2) =>
+ if (choices.nonEmpty && !(choices contains arg2))
+ fail(s"$arg2 is not a valid choice for $name", args2)
+ else
+ update(arg2, args2)
+ case (IntTag, arg2 :: args2) =>
+ try {
+ val x = arg.toInt
+ choices match {
+ case r: Range if x < r.head || r.last < x =>
+ fail(s"$arg2 is out of legal range $legalChoices for $name", args2)
+ case _ =>
+ update(x, args2)
+ }
+ } catch {
+ case _: NumberFormatException =>
+ fail(s"$arg2 is not an integer argument for $name", args2)
+ }
+ case (_, Nil) =>
+ missingArg
+ }
+
+ if (prefix != "" && arg.startsWith(prefix))
+ doSet(arg drop prefix.length)
+ else if (prefix == "" && name == arg.takeWhile(_ != ':'))
+ doSet(arg.dropWhile(_ != ':').drop(1))
+ else
+ state
+ }
+ }
+
+ object Setting {
+ implicit class SettingDecorator[T](val setting: Setting[T]) extends AnyVal {
+ def value(implicit ctx: Context): T = setting.valueIn(ctx.sstate)
+ def update(x: T)(implicit ctx: Context): SettingsState = setting.updateIn(ctx.sstate, x)
+ def isDefault(implicit ctx: Context): Boolean = setting.isDefaultIn(ctx.sstate)
+ }
+ }
+
+ class SettingGroup {
+
+ val _allSettings = new ArrayBuffer[Setting[_]]
+ def allSettings: Seq[Setting[_]] = _allSettings
+
+ def defaultState = new SettingsState(allSettings map (_.default))
+
+ def userSetSettings(state: SettingsState) =
+ allSettings filterNot (_.isDefaultIn(state))
+
+ def toConciseString(state: SettingsState) =
+ userSetSettings(state).mkString("(", " ", ")")
+
+ private def checkDependencies(state: ArgsSummary): ArgsSummary =
+ (state /: userSetSettings(state.sstate))(checkDependenciesOfSetting)
+
+ private def checkDependenciesOfSetting(state: ArgsSummary, setting: Setting[_]) =
+ (state /: setting.depends) { (s, dep) =>
+ val (depSetting, reqValue) = dep
+ if (depSetting.valueIn(state.sstate) == reqValue) s
+ else s.fail(s"incomplete option ${setting.name} (requires ${depSetting.name})")
+ }
+
+ /** Iterates over the arguments applying them to settings where applicable.
+ * Then verifies setting dependencies are met.
+ *
+ * This temporarily takes a boolean indicating whether to keep
+ * processing if an argument is seen which is not a command line option.
+ * This is an expedience for the moment so that you can say
+ *
+ * scalac -d /tmp foo.scala -optimise
+ *
+ * while also allowing
+ *
+ * scala Program opt opt
+ *
+ * to get their arguments.
+ */
+ protected def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
+ def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors)
+ state.arguments match {
+ case Nil =>
+ checkDependencies(stateWithArgs(skipped))
+ case "--" :: args =>
+ checkDependencies(stateWithArgs(skipped ++ args))
+ case x :: _ if x startsWith "-" =>
+ def loop(settings: List[Setting[_]]): ArgsSummary = settings match {
+ case setting :: settings1 =>
+ val state1 = setting.tryToSet(state)
+ if (state1 ne state) processArguments(state1, processAll, skipped)
+ else loop(settings1)
+ case Nil =>
+ state.fail(s"bad option: '$x'")
+ }
+ loop(allSettings.toList)
+ case arg :: args =>
+ if (processAll) processArguments(stateWithArgs(args), processAll, skipped :+ arg)
+ else state
+ }
+ }
+
+ def processArguments(arguments: List[String], processAll: Boolean)(implicit ctx: Context): ArgsSummary =
+ processArguments(ArgsSummary(ctx.sstate, arguments, Nil), processAll, Nil)
+
+ def publish[T](settingf: Int => Setting[T]): Setting[T] = {
+ val setting = settingf(_allSettings.length)
+ _allSettings += setting
+ setting
+ }
+
+ def BooleanSetting(name: String, descr: String): Setting[Boolean] =
+ publish(Setting(name, descr, false))
+
+ def StringSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] =
+ publish(Setting(name, descr, default, helpArg))
+
+ def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): Setting[String] =
+ publish(Setting(name, descr, default, helpArg, choices))
+
+ def IntSetting(name: String, descr: String, default: Int, range: Seq[Int]): Setting[Int] =
+ publish(Setting(name, descr, default, choices = range))
+
+ def MultiStringSetting(name: String, helpArg: String, descr: String): Setting[List[String]] =
+ publish(Setting(name, descr, Nil, helpArg))
+
+ def PathSetting(name: String, descr: String, default: String): Setting[String] =
+ publish(Setting(name, descr, default))
+
+ def PhasesSetting(name: String, descr: String, default: String = ""): Setting[List[String]] =
+ publish(Setting(name, descr, if (default.isEmpty) Nil else List(default)))
+
+ def PrefixSetting(name: String, pre: String, descr: String): Setting[List[String]] =
+ publish(Setting(name, descr, Nil, prefix = pre))
+ }
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index d7c8609f1..bbc134d7d 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -8,9 +8,11 @@ import Phases._
import Types._
import Symbols._
import TypeComparers._, Printers._, NameOps._, SymDenotations._
+import config.Settings._
+import config.ScalaSettings
import collection.mutable
import collection.immutable.BitSet
-import config.{Settings, Platform}
+import config.{Settings, Platform, JavaPlatform}
object Contexts {
@@ -54,9 +56,9 @@ object Contexts {
protected def owner_=(owner: Symbol) = _owner = owner
def owner: Symbol = _owner
- private[this] var _settings: Settings = _
- protected def settings_=(settings: Settings) = _settings = settings
- def settings: Settings = _settings
+ private[this] var _sstate: SettingsState = _
+ protected def sstate_=(sstate: SettingsState) = _sstate = sstate
+ def sstate: SettingsState = _sstate
def phase: Phase = ??? // phase(period.phaseId)
def enclClass: Context = ???
@@ -79,6 +81,7 @@ object Contexts {
def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this }
def withPrinter(printer: Context => Printer): this.type = { this.printer = printer; this }
def withOwner(owner: Symbol): this.type = { this.owner = owner; this }
+ def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
}
@@ -94,18 +97,26 @@ object Contexts {
val base = unsupported("base")
}
- class ContextBase extends Transformers.TransformerBase
+ class ContextBase extends ContextState with Transformers.TransformerBase
with Printers.PrinterBase {
- val initialCtx: Context = new InitialContext(this)
+ val settings = new ScalaSettings
- lazy val rootLoader: ClassCompleter = ???
+ val initialCtx: Context = new InitialContext(this).fresh
+ .withSettings(settings.defaultState)
- lazy val definitions = new Definitions()(initialCtx)
+ val loaders = new SymbolLoaders
- lazy val loaders = new SymbolLoaders
+ val platform: Platform = new JavaPlatform(this)
- lazy val platform: Platform = ???
+ val rootLoader: ClassCompleter = platform.rootLoader
+
+ val definitions = new Definitions()(initialCtx)
+
+ }
+
+ /** Mutable state of a context base, collected into a common class */
+ class ContextState {
// Symbols state
/** A map from a superclass id to the class that has it */
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 2b725c8b4..73c874422 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -76,6 +76,10 @@ class Definitions(implicit ctx: Context) {
lazy val NothingType = NothingClass.typeConstructor
lazy val NullType = NullClass.typeConstructor
+ lazy val BoxedNumberClass = requiredClass("java.lang.Number")
+ lazy val JavaSerializableClass = requiredClass("java.lang.Serializable")
+ lazy val ComparableClass = requiredClass("java.lang.Comparable")
+
// ----- Class sets ---------------------------------------------------
/** Modules whose members are in the default namespace */
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 5aa7e2e25..334d3a908 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -27,7 +27,7 @@ object NameOps {
*/
def apply(s: String)(implicit ctx: Context): String = {
val marker = "$$$$"
- val limit: Int = ctx.settings.XmaxClassfileName.value
+ val limit: Int = ctx.settings.maxClassfileName.value
val MaxNameLength = (limit - 6) min 2 * (limit - 6 - 2 * marker.length - 32)
def toMD5(s: String, edge: Int): String = {
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 41bd0fdeb..6aa959887 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -51,11 +51,11 @@ class SymbolLoaders {
// offer a setting to resolve the conflict one way or the other.
// This was motivated by the desire to use YourKit probes, which
// require yjp.jar at runtime. See SI-2089.
- if (ctx.settings.YtermConflict == ctx.settings.default.YtermConflict)
+ if (ctx.settings.termConflict.isDefault)
throw new TypeError(
s"""$owner contains object and package with same name: $name
|one of them needs to be removed from classpath""".stripMargin)
- else if (ctx.settings.YtermConflict.value == "package") {
+ else if (ctx.settings.termConflict.value == "package") {
ctx.warning(
s"Resolving package/object name conflict in favor of package ${preExisting.fullName}. The object will be inaccessible.")
owner.info.decls.unlink(preExisting)