summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-27 22:47:36 +0300
committerEugene Burmako <xeno.by@gmail.com>2014-02-14 13:24:48 +0100
commitad7983b70a43ba9033a491c00ad22691e7a0a7b4 (patch)
treefded601a5fa3c4d7cea23d742e30e15f1ace7404
parent3293d60531615f4accdee886fba52ddda0929b31 (diff)
downloadscala-ad7983b70a43ba9033a491c00ad22691e7a0a7b4.tar.gz
scala-ad7983b70a43ba9033a491c00ad22691e7a0a7b4.tar.bz2
scala-ad7983b70a43ba9033a491c00ad22691e7a0a7b4.zip
additional class tags for reflection API
Introduces a test that iterates all abstract types in reflection API and makes sure that every one of them has an associated class tag. After being introduced, the test has immediately failed exposing the lack of tags for TreeCopier, Mirror and RuntimeClass, which has been subsequently fixed in this commit.
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala5
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ReflectGlobal.scala8
-rw-r--r--src/reflect/scala/reflect/api/ImplicitTags.scala5
-rw-r--r--src/reflect/scala/reflect/api/JavaMirrors.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala5
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverse.scala1
-rw-r--r--test/files/run/reflection-tags.check1
-rw-r--r--test/files/run/reflection-tags.scala17
-rw-r--r--test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala6
10 files changed, 48 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 1617db7517..1098766a07 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -15,6 +15,7 @@ import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString }
+import scala.reflect.ClassTag
import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile }
import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat }
import scala.reflect.io.VirtualFile
@@ -49,11 +50,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
override def isCompilerUniverse = true
override val useOffsetPositions = !currentSettings.Yrangepos
+ type RuntimeClass = java.lang.Class[_]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
+
class GlobalMirror extends Roots(NoSymbol) {
val universe: self.type = self
def rootLoader: LazyType = new loaders.PackageLoader(classPath)
override def toString = "compiler mirror"
}
+ implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[GlobalMirror])
lazy val rootMirror: Mirror = {
val rm = new GlobalMirror
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 7a7d4ac0b2..d33ea5bb5c 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc
package ast
+import scala.reflect.ClassTag
import scala.reflect.internal.Flags.BYNAMEPARAM
import scala.reflect.internal.Flags.DEFAULTPARAM
import scala.reflect.internal.Flags.IMPLICIT
@@ -102,6 +103,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue
def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
}
+ implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
index 6f369212ad..ac63232967 100644
--- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
@@ -37,5 +37,13 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val
// (each mirror has its own set package symbols, because of the peculiarities of symbol loading in scala),
// that `Predef` symbol only has a single owner, and this messes up visibility, which is calculated based on owners, not scopes.
override def runtimeMirror(cl: ClassLoader): Mirror = rootMirror
+
+ // Mirror and RuntimeClass come from both Global and reflect.runtime.SymbolTable
+ // so here the compiler needs an extra push to help decide between those (in favor of the latter)
+ import scala.reflect.ClassTag
+ override type Mirror = JavaMirror
+ override implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[Mirror])
+ override type RuntimeClass = java.lang.Class[_]
+ override implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
}
diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala
index 1b654a4a8d..4fd7709089 100644
--- a/src/reflect/scala/reflect/api/ImplicitTags.scala
+++ b/src/reflect/scala/reflect/api/ImplicitTags.scala
@@ -114,4 +114,9 @@ trait ImplicitTags {
implicit val UnApplyTag: ClassTag[UnApply]
implicit val ValDefTag: ClassTag[ValDef]
implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
+
+ // Miscellaneous
+ implicit val TreeCopierTag: ClassTag[TreeCopier]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass]
+ implicit val MirrorTag: ClassTag[Mirror]
}
diff --git a/src/reflect/scala/reflect/api/JavaMirrors.scala b/src/reflect/scala/reflect/api/JavaMirrors.scala
index 23abc23eb9..05a4a61d2e 100644
--- a/src/reflect/scala/reflect/api/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/api/JavaMirrors.scala
@@ -24,6 +24,7 @@ trait JavaMirrors { self: JavaUniverse =>
* @group JavaMirrors
*/
type RuntimeClass = java.lang.Class[_]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
/** In runtime reflection universes, mirrors are `JavaMirrors`.
* @group JavaMirrors
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index bc95b839b7..bf8a3f0ae2 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -22,7 +22,7 @@ import ReflectionUtils._
import scala.language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
-private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
+private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()
@@ -33,9 +33,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
jm
}
- override type RuntimeClass = java.lang.Class[_]
-
override type Mirror = JavaMirror
+ implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[JavaMirror])
override lazy val rootMirror: Mirror = createMirror(NoSymbol, rootClassLoader)
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
index f6556a442d..85c56bc4bb 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
@@ -20,6 +20,7 @@ class JavaUniverse extends internal.SymbolTable with JavaUniverseForce with Refl
def log(msg: => AnyRef): Unit = if (isLogging) Console.err.println("[reflect] " + msg)
type TreeCopier = InternalTreeCopierOps
+ implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
diff --git a/test/files/run/reflection-tags.check b/test/files/run/reflection-tags.check
new file mode 100644
index 0000000000..375518e921
--- /dev/null
+++ b/test/files/run/reflection-tags.check
@@ -0,0 +1 @@
+List()
diff --git a/test/files/run/reflection-tags.scala b/test/files/run/reflection-tags.scala
new file mode 100644
index 0000000000..fba90f61e9
--- /dev/null
+++ b/test/files/run/reflection-tags.scala
@@ -0,0 +1,17 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.ClassTag
+
+object Test extends App {
+ var typeMembers = typeOf[scala.reflect.api.Universe].members.filter(sym => sym.isType && !sym.isClass).toList
+ typeMembers = typeMembers.filter(_.name != TypeName("ModifiersCreator")) // type ModifiersCreator = ModifiersExtractor
+ val tags = typeOf[scala.reflect.api.Universe].members.filter(sym => sym.isImplicit).toList
+
+ typeMembers.foreach(_.typeSignature)
+ tags.foreach(_.typeSignature)
+
+ val outliers = typeMembers.filter(tm => !tags.exists(tag => tag.typeSignature match {
+ case NullaryMethodType(TypeRef(_, sym, targ :: Nil)) => sym == typeOf[ClassTag[_]].typeSymbol && targ.typeSymbol == tm
+ case _ => false
+ }))
+ println(outliers)
+} \ No newline at end of file
diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
index b42e9a07cb..25d8c4667f 100644
--- a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
+++ b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala
@@ -1,6 +1,7 @@
package scala.tools.nsc
package symtab
+import scala.reflect.ClassTag
import scala.reflect.internal.{Phase, NoPhase, SomePhase}
import scala.tools.util.PathResolver
import util.ClassPath
@@ -89,4 +90,9 @@ class SymbolTableForUnitTesting extends SymbolTable {
val currentFreshNameCreator = new reflect.internal.util.FreshNameCreator
phase = SomePhase
+
+ type RuntimeClass = java.lang.Class[_]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
+ implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[GlobalMirror])
+ implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
}