aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-03 20:44:27 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-03 20:45:09 +0200
commit168e4f18f0b2f8ac0e3d7ef5128797303dec6a44 (patch)
treed07dbc2cd645e56784cf5c2b830508724761fc8c /src/dotty/tools/dotc
parent2020938a77590f8c461041707716eca228f647d2 (diff)
downloaddotty-168e4f18f0b2f8ac0e3d7ef5128797303dec6a44.tar.gz
dotty-168e4f18f0b2f8ac0e3d7ef5128797303dec6a44.tar.bz2
dotty-168e4f18f0b2f8ac0e3d7ef5128797303dec6a44.zip
Added version settings -migration, -source
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala3
-rw-r--r--src/dotty/tools/dotc/config/ScalaVersion.scala183
-rw-r--r--src/dotty/tools/dotc/config/Settings.scala9
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala5
4 files changed, 199 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
index aab2942bd..af2e42b77 100644
--- a/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -66,7 +66,8 @@ class ScalaSettings extends Settings.SettingGroup {
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 Xmigration = VersionSetting("-Xmigration", "Warn about constructs whose behavior may have changed since version.")
+ val Xsource = VersionSetting("-Xsource", "Treat compiler input as Scala source for the specified version.")
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.")
diff --git a/src/dotty/tools/dotc/config/ScalaVersion.scala b/src/dotty/tools/dotc/config/ScalaVersion.scala
new file mode 100644
index 000000000..7d4585441
--- /dev/null
+++ b/src/dotty/tools/dotc/config/ScalaVersion.scala
@@ -0,0 +1,183 @@
+/* @author James Iry
+ */
+package dotty.tools.dotc.config
+
+import scala.util.{Try, Success, Failure}
+
+/**
+ * Represents a single Scala version in a manner that
+ * supports easy comparison and sorting.
+ */
+sealed abstract class ScalaVersion extends Ordered[ScalaVersion] {
+ def unparse: String
+}
+
+/**
+ * A scala version that sorts higher than all actual versions
+ */
+case object NoScalaVersion extends ScalaVersion {
+ def unparse = "none"
+
+ def compare(that: ScalaVersion): Int = that match {
+ case NoScalaVersion => 0
+ case _ => 1
+ }
+}
+
+/**
+ * A specific Scala version, not one of the magic min/max versions. An SpecificScalaVersion
+ * may or may not be a released version - i.e. this same class is used to represent
+ * final, release candidate, milestone, and development builds. The build argument is used
+ * to segregate builds
+ */
+case class SpecificScalaVersion(major: Int, minor: Int, rev: Int, build: ScalaBuild) extends ScalaVersion {
+ def unparse = s"${major}.${minor}.${rev}.${build.unparse}"
+
+ def compare(that: ScalaVersion): Int = that match {
+ case SpecificScalaVersion(thatMajor, thatMinor, thatRev, thatBuild) =>
+ // this could be done more cleanly by importing scala.math.Ordering.Implicits, but we have to do these
+ // comparisons a lot so I'm using brute force direct style code
+ if (major < thatMajor) -1
+ else if (major > thatMajor) 1
+ else if (minor < thatMinor) -1
+ else if (minor > thatMinor) 1
+ else if (rev < thatRev) -1
+ else if (rev > thatRev) 1
+ else build compare thatBuild
+ case AnyScalaVersion => 1
+ case NoScalaVersion => -1
+ }
+}
+
+/**
+ * A Scala version that sorts lower than all actual versions
+ */
+case object AnyScalaVersion extends ScalaVersion {
+ def unparse = "any"
+
+ def compare(that: ScalaVersion): Int = that match {
+ case AnyScalaVersion => 0
+ case _ => -1
+ }
+}
+
+/**
+ * Methods for parsing ScalaVersions
+ */
+object ScalaVersion {
+ private val dot = "\\."
+ private val dash = "\\-"
+ private def not(s:String) = s"[^${s}]"
+ private val R = s"((${not(dot)}*)(${dot}(${not(dot)}*)(${dot}(${not(dash)}*)(${dash}(.*))?)?)?)".r
+
+ def parse(versionString : String): Try[ScalaVersion] = {
+ def failure = Failure(new NumberFormatException(
+ s"There was a problem parsing ${versionString}. " +
+ "Versions should be in the form major[.minor[.revision]] " +
+ "where each part is a positive number, as in 2.10.1. " +
+ "The minor and revision parts are optional."
+ ))
+
+ def toInt(s: String) = s match {
+ case null | "" => 0
+ case _ => s.toInt
+ }
+
+ def isInt(s: String) = Try(toInt(s)).isSuccess
+
+ import ScalaBuild._
+
+ def toBuild(s: String) = s match {
+ case null | "FINAL" => Final
+ case s if (s.toUpperCase.startsWith("RC") && isInt(s.substring(2))) => RC(toInt(s.substring(2)))
+ case s if (s.toUpperCase.startsWith("M") && isInt(s.substring(1))) => Milestone(toInt(s.substring(1)))
+ case _ => Development(s)
+ }
+
+ try versionString match {
+ case "" | "any" => Success(AnyScalaVersion)
+ case "none" => Success(NoScalaVersion)
+ case R(_, majorS, _, minorS, _, revS, _, buildS) =>
+ Success(SpecificScalaVersion(toInt(majorS), toInt(minorS), toInt(revS), toBuild(buildS)))
+ case _ => failure
+ } catch {
+ case e: NumberFormatException => failure
+ }
+ }
+
+ /**
+ * The version of the compiler running now
+ */
+ val current = parse(util.Properties.versionNumberString).get
+}
+
+/**
+ * Represents the data after the dash in major.minor.rev-build
+ */
+abstract class ScalaBuild extends Ordered[ScalaBuild] {
+ /**
+ * Return a version of this build information that can be parsed back into the
+ * same ScalaBuild
+ */
+ def unparse: String
+}
+
+object ScalaBuild {
+
+ /** A development, test, nightly, snapshot or other "unofficial" build
+ */
+ case class Development(id: String) extends ScalaBuild {
+ def unparse = s"-${id}"
+
+ def compare(that: ScalaBuild) = that match {
+ // sorting two development builds based on id is reasonably valid for two versions created with the same schema
+ // otherwise it's not correct, but since it's impossible to put a total ordering on development build versions
+ // this is a pragmatic compromise
+ case Development(thatId) => id compare thatId
+ // assume a development build is newer than anything else, that's not really true, but good luck
+ // mapping development build versions to other build types
+ case _ => 1
+ }
+ }
+
+ /** A final build
+ */
+ case object Final extends ScalaBuild {
+ def unparse = ""
+
+ def compare(that: ScalaBuild) = that match {
+ case Final => 0
+ // a final is newer than anything other than a development build or another final
+ case Development(_) => -1
+ case _ => 1
+ }
+ }
+
+ /** A candidate for final release
+ */
+ case class RC(n: Int) extends ScalaBuild {
+ def unparse = s"-RC${n}"
+
+ def compare(that: ScalaBuild) = that match {
+ // compare two rcs based on their RC numbers
+ case RC(thatN) => n - thatN
+ // an rc is older than anything other than a milestone or another rc
+ case Milestone(_) => 1
+ case _ => -1
+ }
+ }
+
+ /** An intermediate release
+ */
+ case class Milestone(n: Int) extends ScalaBuild {
+ def unparse = s"-M${n}"
+
+ def compare(that: ScalaBuild) = that match {
+ // compare two milestones based on their milestone numbers
+ case Milestone(thatN) => n - thatN
+ // a milestone is older than anything other than another milestone
+ case _ => -1
+
+ }
+ }
+}
diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala
index 17d4d6712..531c49bfb 100644
--- a/src/dotty/tools/dotc/config/Settings.scala
+++ b/src/dotty/tools/dotc/config/Settings.scala
@@ -18,6 +18,7 @@ object Settings {
val IntTag = ClassTag.Int
val StringTag = ClassTag(classOf[String])
val ListTag = ClassTag(classOf[List[_]])
+ val VersionTag = ClassTag(classOf[ScalaVersion])
class SettingsState(initialValues: Seq[Any]) {
private var values = ArrayBuffer(initialValues: _*)
@@ -132,6 +133,11 @@ object Settings {
case _: NumberFormatException =>
fail(s"$arg2 is not an integer argument for $name", args2)
}
+ case (VersionTag, _) =>
+ ScalaVersion.parse(argRest) match {
+ case Success(v) => update(v, args)
+ case Failure(ex) => fail(ex.getMessage, args)
+ }
case (_, Nil) =>
missingArg
}
@@ -246,5 +252,8 @@ object Settings {
def PrefixSetting(name: String, pre: String, descr: String): Setting[List[String]] =
publish(Setting(name, descr, Nil, prefix = pre))
+
+ def VersionSetting(name: String, descr: String, default: ScalaVersion = NoScalaVersion): Setting[ScalaVersion] =
+ publish(Setting(name, descr, default))
}
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 286d1437f..f20882ce4 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -107,6 +107,10 @@ class Definitions {
lazy val JavaPackageVal = ctx.requiredPackage("java")
lazy val JavaLangPackageVal = ctx.requiredPackage("java.lang")
+ // fundamental modules
+ lazy val SysPackage = ctx.requiredModule("scala.sys.package")
+ def Sys_error = ctx.requiredMethod(SysPackage.moduleClass.asClass, nme.error)
+
/** Note: We cannot have same named methods defined in Object and Any (and AnyVal, for that matter)
* because after erasure the Any and AnyVal references get remapped to the Object methods
* which would result in a double binding assertion failure.
@@ -292,6 +296,7 @@ class Definitions {
lazy val ScalaSignatureAnnot = ctx.requiredClass("scala.reflect.ScalaSignature")
lazy val ScalaLongSignatureAnnot = ctx.requiredClass("scala.reflect.ScalaLongSignature")
lazy val DeprecatedAnnot = ctx.requiredClass("scala.deprecated")
+ lazy val MigrationAnnot = ctx.requiredClass("scala.migration")
lazy val AnnotationDefaultAnnot = ctx.requiredClass("dotty.annotation.internal.AnnotationDefault")
lazy val ThrowsAnnot = ctx.requiredClass("scala.throws")
lazy val UncheckedAnnot = ctx.requiredClass("scala.unchecked")