Permalink
Browse files

preparations: always explicitly provide type tags

In our codebase we now explicitly provide type tags even if they can be materialized.
This is necessary to ease the upcoming reflection refactoring (or refactorings :)).
  • Loading branch information...
xeno-by committed Jun 6, 2012
1 parent 3a19897 commit 8ce47873f2207a72d902e01cc54eef26f28d1213
@@ -7,7 +7,7 @@ package scala.tools
package cmd
import nsc.io.{ Path, File, Directory }
-import scala.reflect.TypeTag
+import scala.tools.reflect.StdTags._
/** A general mechanism for defining how a command line argument
* (always a String) is transformed into an arbitrary type. A few
@@ -29,19 +29,19 @@ object FromString {
/** Path related stringifiers.
*/
- val ExistingFile: FromString[File] = new FromString[File] {
+ val ExistingFile: FromString[File] = new FromString[File]()(tagOfFile) {
override def isDefinedAt(s: String) = toFile(s).isFile
def apply(s: String): File =
if (isDefinedAt(s)) toFile(s)
else cmd.runAndExit(println("'%s' is not an existing file." format s))
}
- val ExistingDir: FromString[Directory] = new FromString[Directory] {
+ val ExistingDir: FromString[Directory] = new FromString[Directory]()(tagOfDirectory) {
override def isDefinedAt(s: String) = toDir(s).isDirectory
def apply(s: String): Directory =
if (isDefinedAt(s)) toDir(s)
else cmd.runAndExit(println("'%s' is not an existing directory." format s))
}
- def ExistingDirRelativeTo(root: Directory) = new FromString[Directory] {
+ def ExistingDirRelativeTo(root: Directory) = new FromString[Directory]()(tagOfDirectory) {
private def resolve(s: String) = toDir(s) toAbsoluteWithRoot root toDirectory
override def isDefinedAt(s: String) = resolve(s).isDirectory
def apply(s: String): Directory =
@@ -52,19 +52,19 @@ object FromString {
/** Argument expander, i.e. turns single argument "foo bar baz" into argument
* list "foo", "bar", "baz".
*/
- val ArgumentsFromString: FromString[List[String]] = new FromString[List[String]] {
+ val ArgumentsFromString: FromString[List[String]] = new FromString[List[String]]()(tagOfListOfString) {
def apply(s: String) = toArgs(s)
}
/** Identity.
*/
- implicit val StringFromString: FromString[String] = new FromString[String] {
+ implicit val StringFromString: FromString[String] = new FromString[String]()(tagOfString) {
def apply(s: String): String = s
}
/** Implicit as the most likely to be useful as-is.
*/
- implicit val IntFromString: FromString[Int] = new FromString[Int] {
+ implicit val IntFromString: FromString[Int] = new FromString[Int]()(tagOfInt) {
override def isDefinedAt(s: String) = safeToInt(s).isDefined
def apply(s: String) = safeToInt(s).get
def safeToInt(s: String): Option[Int] = try Some(java.lang.Integer.parseInt(s)) catch { case _: NumberFormatException => None }
@@ -24,6 +24,7 @@ import util.ScalaClassLoader
import ScalaClassLoader._
import scala.tools.util._
import language.{implicitConversions, existentials}
+import scala.tools.reflect.StdTags._
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
@@ -105,7 +106,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
def isAsync = !settings.Yreplsync.value
- lazy val power = new Power(intp, new StdReplVals(this))
+ lazy val power = new Power(intp, new StdReplVals(this))(tagOfStdReplVals)
def history = in.history
/** The context class loader at the time this object was created */
@@ -830,7 +831,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
// Bind intp somewhere out of the regular namespace where
// we can get at it in generated code.
- addThunk(intp.quietBind("$intp" -> intp))
+ addThunk(intp.quietBind(NamedParam[IMain]("$intp", intp)(tagOfIMain)))
addThunk({
import scala.tools.nsc.io._
import Properties.userHome
@@ -25,6 +25,7 @@ import IMain._
import java.util.concurrent.Future
import typechecker.Analyzer
import language.implicitConversions
+import scala.tools.reflect.StdTags._
/** directory to save .class files to */
private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) {
@@ -717,7 +718,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
val unwrapped = unwrap(t)
withLastExceptionLock[String]({
- directBind[Throwable]("lastException", unwrapped)
+ directBind[Throwable]("lastException", unwrapped)(classTag[Throwable])
util.stackTraceString(unwrapped)
}, util.stackTraceString(unwrapped))
}
@@ -0,0 +1,26 @@
+package scala.tools
+package reflect
+
+import java.lang.{Class => jClass}
+import scala.reflect.mirror._
+
+// [Eugene++] Before 2.10 is released, I suggest we don't rely on automated type tag generation
+// sure, it's convenient, but then refactoring reflection / reification becomes a pain
+// `ClassTag` tags are fine, because they don't need a reifier to be generated
+
+object StdTags {
+ lazy val tagOfString = TypeTag.String
+ lazy val tagOfListOfString = TypeTag[List[String]]({
+ val pre = ThisType(staticModule("scala.collection.immutable").moduleClass)
+ TypeRef(pre, definitions.ListClass, List(definitions.StringClass.asTypeConstructor))
+ }, classOf[List[String]])
+
+ private def tagOfStaticClass[T: ClassTag] = TypeTag[T](staticClass(classTag[T].erasure.getName).asTypeConstructor, classTag[T].erasure)
+ lazy val tagOfInt = TypeTag.Int
+ lazy val tagOfFile = tagOfStaticClass[scala.tools.nsc.io.File]
+ lazy val tagOfDirectory = tagOfStaticClass[scala.tools.nsc.io.Directory]
+ lazy val tagOfStdReplVals = tagOfStaticClass[scala.tools.nsc.interpreter.StdReplVals]
+ lazy val tagOfIMain = tagOfStaticClass[scala.tools.nsc.interpreter.IMain]
+ lazy val tagOfThrowable = tagOfStaticClass[java.lang.Throwable]
+ lazy val tagOfClassLoader = tagOfStaticClass[java.lang.ClassLoader]
+}

0 comments on commit 8ce4787

Please sign in to comment.