summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Context.scala3
-rw-r--r--src/compiler/scala/reflect/makro/runtime/ContextReifiers.scala26
-rw-r--r--src/compiler/scala/reflect/makro/runtime/Mirrors.scala43
-rw-r--r--src/compiler/scala/reflect/reify/Taggers.scala32
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala36
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTypes.scala3
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala4
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala2
-rw-r--r--src/compiler/scala/tools/reflect/FastTrack.scala3
-rw-r--r--src/compiler/scala/tools/reflect/MacroImplementations.scala9
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala61
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala2
-rw-r--r--src/library/scala/reflect/base/Base.scala3
-rw-r--r--src/library/scala/reflect/base/MirrorOf.scala65
-rw-r--r--src/partest/scala/tools/partest/CompilerTest.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala163
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/makro/Context.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala12
22 files changed, 284 insertions, 195 deletions
diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala
index c7563e7b67..68964b7abb 100644
--- a/src/compiler/scala/reflect/makro/runtime/Context.scala
+++ b/src/compiler/scala/reflect/makro/runtime/Context.scala
@@ -8,7 +8,6 @@ abstract class Context extends scala.reflect.makro.Context
with CapturedVariables
with Infrastructure
with Enclosures
- with Mirrors
with Names
with Reifiers
with FrontEnds
@@ -23,7 +22,7 @@ abstract class Context extends scala.reflect.makro.Context
val universe: Global
- val mirror: MirrorOf[universe.type] = new ContextMirror
+ val mirror: MirrorOf[universe.type] = universe.rootMirror
val callsiteTyper: universe.analyzer.Typer
diff --git a/src/compiler/scala/reflect/makro/runtime/ContextReifiers.scala b/src/compiler/scala/reflect/makro/runtime/ContextReifiers.scala
deleted file mode 100644
index 564148fe6c..0000000000
--- a/src/compiler/scala/reflect/makro/runtime/ContextReifiers.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-package scala.reflect.makro
-package runtime
-
-abstract class ContextReifiers { self =>
- val c: Context
-
- import c.universe._
- import definitions._
- import treeBuild._
-
- import scala.reflect.reify.Taggers
- import language.implicitConversions
- private implicit def context2taggers(c0: Context) : Taggers { val c: c0.type } = new { val c: c0.type = c0 } with Taggers
-
- private def forMacroContext[T](prefix: Tree)(op: (Tree, Tree) => T): T = {
- val universe = gen.mkAttributedSelect(prefix.duplicate, MacroContextUniverse) setType SingleType(prefix.tpe, MacroContextUniverse)
- val mirror = TypeApply(Select(Select(prefix.duplicate, nme.mirror), nme.asInstanceOf_), List(Select(Ident(nme.UNIVERSE_SHORT), tpnme.Mirror)))
- op(universe, mirror)
- }
-
- def materializeExprForMacroContext(prefix: Tree, expr: Tree): Tree =
- forMacroContext(prefix)((universe, mirror) => c.materializeExpr(universe, mirror, expr))
-
- def materializeTypeTagForMacroContext(prefix: Tree, tpe: Type, concrete: Boolean): Tree =
- forMacroContext(prefix)((universe, mirror) => c.materializeTypeTag(universe, mirror, tpe, concrete))
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/makro/runtime/Mirrors.scala b/src/compiler/scala/reflect/makro/runtime/Mirrors.scala
deleted file mode 100644
index ec970ee696..0000000000
--- a/src/compiler/scala/reflect/makro/runtime/Mirrors.scala
+++ /dev/null
@@ -1,43 +0,0 @@
-package scala.reflect.makro
-package runtime
-
-import scala.tools.nsc.util.ScalaClassLoader
-
-trait Mirrors {
- self: Context =>
-
- import universe._
- import definitions._
-
- class ContextMirror extends RootsBase(NoSymbol) {
- val universe: self.universe.type = self.universe
- def rootLoader: LazyType = rootMirror.rootLoader
-
- val RootPackage = rootMirror.RootPackage
- val RootClass = rootMirror.RootClass
- val EmptyPackage = rootMirror.EmptyPackage
- val EmptyPackageClass = rootMirror.EmptyPackageClass
-
- // [Eugene++] this still doesn't solve the problem of invoking `c.typeCheck` on the code that refers to packageless symbols
- override protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = {
- if (owner.isRoot && isJavaClass(name.toString)) EmptyPackageClass.info decl name
- else NoSymbol
- }
-
- private lazy val libraryClasspathLoader: ClassLoader = {
- val classpath = platform.classPath.asURLs
- ScalaClassLoader.fromURLs(classpath)
- }
-
- private def isJavaClass(path: String): Boolean =
- try {
- Class.forName(path, true, libraryClasspathLoader)
- true
- } catch {
- case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) =>
- false
- }
-
- override def toString = "macro context mirror"
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala
index e09f13a052..4e30d0acf8 100644
--- a/src/compiler/scala/reflect/reify/Taggers.scala
+++ b/src/compiler/scala/reflect/reify/Taggers.scala
@@ -37,23 +37,21 @@ abstract class Taggers {
}
def materializeTypeTag(universe: Tree, mirror: Tree, tpe: Type, concrete: Boolean): Tree = {
- if (universe.symbol == MacroContextUniverse && mirror == EmptyTree) {
- import scala.reflect.makro.runtime.ContextReifiers
- import language.implicitConversions
- implicit def context2contextreifiers(c0: Context) : ContextReifiers { val c: c0.type } = new { val c: c0.type = c0 } with ContextReifiers
- val Select(prefix, _) = universe
- c.materializeTypeTagForMacroContext(prefix, tpe, concrete)
- } else {
- val tagType = if (concrete) TypeTagClass else AbsTypeTagClass
- val unaffiliatedTagTpe = TypeRef(BaseUniverseClass.asTypeConstructor, tagType, List(tpe))
- val unaffiliatedTag = c.inferImplicitValue(unaffiliatedTagTpe, silent = true, withMacrosDisabled = true)
- unaffiliatedTag match {
- case success if !success.isEmpty =>
- Apply(Select(success, nme.in), List(mirror orElse mkDefaultMirrorRef(c.universe)(universe, c.callsiteTyper)))
- case _ =>
- val tagModule = if (concrete) TypeTagModule else AbsTypeTagModule
- materializeTag(universe, tpe, tagModule, c.reifyType(universe, mirror, tpe, concrete = concrete))
- }
+ val tagType = if (concrete) TypeTagClass else AbsTypeTagClass
+ // what we need here is to compose a type BaseUniverse # TypeTag[$tpe]
+ // to look for an implicit that conforms to this type
+ // that's why neither appliedType(tagType, List(tpe)) aka TypeRef(TypeTagsClass.thisType, tagType, List(tpe))
+ // nor TypeRef(BaseUniverseClass.thisType, tagType, List(tpe)) won't fit here
+ // scala> :type -v def foo: scala.reflect.base.Universe#TypeTag[Int] = ???
+ // NullaryMethodType(TypeRef(pre = TypeRef(TypeSymbol(Universe)), TypeSymbol(TypeTag), args = List($tpe))))
+ val unaffiliatedTagTpe = TypeRef(BaseUniverseClass.typeConstructor, tagType, List(tpe))
+ val unaffiliatedTag = c.inferImplicitValue(unaffiliatedTagTpe, silent = true, withMacrosDisabled = true)
+ unaffiliatedTag match {
+ case success if !success.isEmpty =>
+ Apply(Select(success, nme.in), List(mirror orElse mkDefaultMirrorRef(c.universe)(universe, c.callsiteTyper)))
+ case _ =>
+ val tagModule = if (concrete) TypeTagModule else AbsTypeTagModule
+ materializeTag(universe, tpe, tagModule, c.reifyType(universe, mirror, tpe, concrete = concrete))
}
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 9b0777580b..38c8fedac5 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -37,10 +37,40 @@ trait GenSymbols {
mirrorMirrorSelect(nme.EmptyPackageClass)
else if (sym.isModuleClass)
Select(Select(reify(sym.sourceModule), nme.asModuleSymbol), nme.moduleClass)
+ else if (sym.isPackage)
+ mirrorMirrorCall(nme.staticPackage, reify(sym.fullName))
else if (sym.isLocatable) {
- // [Eugene] am I doing this right?
-// if (sym.isStaticOwner) { // no good for us, because it returns false for packages
- if (sym.isStatic && (sym.isClass || sym.isModule)) {
+ /** This is a fancy conundrum that stems from the fact that Scala allows
+ * packageless packages and packageless objects with the same names in the same program.
+ *
+ * For more details read the docs to staticModule and staticPackage.
+ * Here I'll just provide the examples of how reify works for different kinds of symbols.
+ *
+ * // 1) packageless
+ * // packageless classes are non-ambiguous, but modules vs packages might be
+ * // that's why we have separate methods to reify those
+ * // note that staticModule will never resolve to a package if an object is missing and an homonymous package is present and vice versa
+ * // otherwise reification would be unsound
+ * class C => staticClass("C")
+ * object B => staticModule("B")
+ * package B => staticPackage("B")
+ *
+ * // 2) classes and modules enclosed in a package
+ * // staticXXX methods always look into parent packages and ignores parent modules, so for fully qualified names they are non-ambiguous
+ * // namely even if there's an object B { class C } next to package B { class C }, then staticClass("B.C") will resolve to a packageful class
+ * // this closely mirrors Scala's behavior, read up the docs to staticModule/staticPackage for more information
+ * package B { class C } => staticClass("B.C")
+ * package B { object B } => staticModule("B.B")
+ * package B { package B } => staticPackage("B.B")
+ *
+ * // 3) classes and modules enclosed in a packageless module
+ * // staticClass/staticModule won't look into EmptyPackageClass, so we reify such symbols in a roundabout way
+ * object B { class C } => selectType(staticModule("B"), "C")
+ * object B { object B } => selectType(staticModule("B"), "B")
+ * object B { package B } => impossible
+ */
+ val hasPackagelessParent = sym.ownerChain.tail.tail exists (_.isEmptyPackageClass)
+ if (sym.isStatic && (sym.isClass || sym.isModule) && !hasPackagelessParent) {
val resolver = if (sym.isType) nme.staticClass else nme.staticModule
mirrorMirrorCall(resolver, reify(sym.fullName))
} else {
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
index 82951a2434..c49e5b3342 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
@@ -41,8 +41,7 @@ trait GenTypes {
case tpe @ ThisType(empty) if empty.isEmptyPackageClass =>
mirrorBuildCall(nme.thisPrefix, mirrorMirrorSelect(nme.EmptyPackageClass))
case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic =>
- // [Eugene++ to Martin] makes sense?
- val module = mirrorMirrorCall(nme.staticModule, reify(clazz.fullName))
+ val module = reify(clazz.sourceModule)
val moduleClass = Select(Select(module, nme.asModuleSymbol), nme.moduleClass)
mirrorFactoryCall(nme.ThisType, moduleClass)
case tpe @ ThisType(_) =>
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index 52e4ff08c1..86265ec77a 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -27,7 +27,7 @@ trait Extractors {
// def applyImpl[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- // $u.Apply($u.Select($u.Select($u.build.This($m.staticModule("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
+ // $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
// }
// };
// new $treecreator1()
@@ -40,7 +40,7 @@ trait Extractors {
// def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Type = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- // $u.TypeRef($u.ThisType($m.staticModule("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").asTypeConstructor))
+ // $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").asTypeConstructor))
// }
// };
// new $typecreator1()
diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index 29f1baaa0c..415940b3fd 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -8,7 +8,7 @@ package cmd
import nsc.io.{ Path, File, Directory }
import scala.reflect.runtime.{universe => ru}
-import scala.tools.reflect.StdTags._
+import scala.tools.reflect.StdRuntimeTags._
/** A general mechanism for defining how a command line argument
* (always a String) is transformed into an arbitrary type. A few
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index e5e7d7081d..b567293a3f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -25,7 +25,7 @@ import ScalaClassLoader._
import scala.tools.util._
import language.{implicitConversions, existentials}
import scala.reflect.{ClassTag, classTag}
-import scala.tools.reflect.StdTags._
+import scala.tools.reflect.StdRuntimeTags._
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index b385787cce..7bdbff8627 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -28,7 +28,7 @@ import typechecker.Analyzer
import language.implicitConversions
import scala.reflect.runtime.{ universe => ru }
import scala.reflect.{ ClassTag, classTag }
-import scala.tools.reflect.StdTags._
+import scala.tools.reflect.StdRuntimeTags._
/** directory to save .class files to */
private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) {
diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala
index 63ecfa32b2..237ef813c7 100644
--- a/src/compiler/scala/tools/reflect/FastTrack.scala
+++ b/src/compiler/scala/tools/reflect/FastTrack.scala
@@ -1,7 +1,6 @@
package scala.tools
package reflect
-import scala.reflect.makro.runtime.ContextReifiers
import scala.reflect.reify.Taggers
import scala.tools.nsc.typechecker.{Analyzer, Macros}
@@ -16,7 +15,6 @@ trait FastTrack {
import language.implicitConversions
private implicit def context2taggers(c0: MacroContext): Taggers { val c: c0.type } = new { val c: c0.type = c0 } with Taggers
- private implicit def context2contextreifiers(c0: MacroContext): ContextReifiers { val c: c0.type } = new { val c: c0.type = c0 } with ContextReifiers
private implicit def context2macroimplementations(c0: MacroContext): MacroImplementations { val c: c0.type } = new { val c: c0.type = c0 } with MacroImplementations
implicit def fastTrackEntry2MacroRuntime(entry: FastTrackEntry): MacroRuntime = args => entry.run(args)
@@ -41,7 +39,6 @@ trait FastTrack {
MacroInternal_materializeAbsTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = false) }
MacroInternal_materializeTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = true) }
ApiUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }
- MacroContextReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExprForMacroContext(c.prefix.tree, expr) }
ReflectRuntimeCurrentMirror bindTo { case (c, _) => scala.reflect.runtime.Macros.currentMirror(c).tree }
StringContext_f bindTo { case (c, app@Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args, app.pos) }
registry
diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala
index 604bd7cd1a..e1b959cefa 100644
--- a/src/compiler/scala/tools/reflect/MacroImplementations.scala
+++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala
@@ -57,6 +57,9 @@ abstract class MacroImplementations {
)
}
+ val stdContextTags = new { val tc: c.type = c } with StdContextTags
+ import stdContextTags._
+
def conversionType(ch: Char, arg: Tree): Option[Type] = {
ch match {
case 'b' | 'B' =>
@@ -68,11 +71,11 @@ abstract class MacroImplementations {
case 'c' | 'C' =>
checkType(arg, CharTpe, ByteTpe, ShortTpe, IntTpe)
case 'd' | 'o' | 'x' | 'X' =>
- checkType(arg, IntTpe, LongTpe, ByteTpe, ShortTpe, typeOf[BigInt])
+ checkType(arg, IntTpe, LongTpe, ByteTpe, ShortTpe, tagOfBigInt.tpe)
case 'e' | 'E' | 'g' | 'G' | 'f' | 'a' | 'A' =>
- checkType(arg, DoubleTpe, FloatTpe, typeOf[BigDecimal])
+ checkType(arg, DoubleTpe, FloatTpe, tagOfBigDecimal.tpe)
case 't' | 'T' =>
- checkType(arg, LongTpe, typeOf[java.util.Calendar], typeOf[java.util.Date])
+ checkType(arg, LongTpe, tagOfCalendar.tpe, tagOfDate.tpe)
case _ => None
}
}
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index 18cbf9c4b7..25a42a82cd 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -4,46 +4,55 @@ package reflect
import java.lang.{Class => jClass}
import scala.reflect.{ClassTag, classTag}
import scala.reflect.base.{MirrorOf, TypeCreator, Universe => BaseUniverse}
-import scala.reflect.runtime.{universe => ru}
// [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 {
- // root mirror is fine for these guys, since scala-library.jar is guaranteed to be reachable from the root mirror
- lazy val tagOfString = ru.TypeTag[String](
- ru.rootMirror,
- new TypeCreator {
- def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = {
- val u = m.universe
- u.definitions.StringClass.asTypeConstructor
- }
- })
- lazy val tagOfListOfString = ru.TypeTag[List[String]](
- ru.rootMirror,
- new TypeCreator {
- def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = {
- val u = m.universe
- val pre = u.ThisType(m.staticModule("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
- u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.asTypeConstructor))
- }
- })
+trait StdTags {
+ val u: BaseUniverse with Singleton
+ val m: MirrorOf[u.type]
- // root mirror is NOT fine for these guys, hence we use the `currentMirror` trick
- private val ourClassloader = getClass.getClassLoader
- private def tagOfStaticClass[T: ClassTag] =
- ru.TypeTag[T](
- ru.runtimeMirror(ourClassloader),
+ lazy val tagOfListOfString: u.TypeTag[List[String]] =
+ u.TypeTag[List[String]](
+ m,
+ new TypeCreator {
+ def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = {
+ val u = m.universe
+ val pre = u.ThisType(m.staticPackage("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
+ u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.asTypeConstructor))
+ }
+ })
+
+ private def tagOfStaticClass[T: ClassTag]: u.TypeTag[T] =
+ u.TypeTag[T](
+ m,
new TypeCreator {
def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type =
m.staticClass(classTag[T].runtimeClass.getName).asTypeConstructor.asInstanceOf[U # Type]
})
- lazy val tagOfInt = ru.TypeTag.Int
+ lazy val tagOfInt = u.TypeTag.Int
+ lazy val tagOfString = tagOfStaticClass[String]
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]
+ lazy val tagOfBigInt = tagOfStaticClass[BigInt]
+ lazy val tagOfBigDecimal = tagOfStaticClass[BigDecimal]
+ lazy val tagOfCalendar = tagOfStaticClass[java.util.Calendar]
+ lazy val tagOfDate = tagOfStaticClass[java.util.Date]
+}
+
+object StdRuntimeTags extends StdTags {
+ val u: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
+ val m = u.runtimeMirror(getClass.getClassLoader)
+ // we need getClass.getClassLoader to support the stuff from scala-compiler.jar
+}
+
+abstract class StdContextTags extends StdTags {
+ val tc: scala.reflect.makro.Context
+ val u: tc.universe.type = tc.universe
+ val m = tc.mirror
}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index 3a1dc87a6a..46c644bcd6 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
@@ -36,7 +36,7 @@ trait CPSUtils {
lazy val MarkerCPSAdaptMinus = rootMirror.getRequiredClass("scala.util.continuations.cpsMinus")
lazy val Context = rootMirror.getRequiredClass("scala.util.continuations.ControlContext")
- lazy val ModCPS = rootMirror.getRequiredModule("scala.util.continuations")
+ lazy val ModCPS = rootMirror.getRequiredPackage("scala.util.continuations")
lazy val MethShiftUnit = definitions.getMember(ModCPS, cpsNames.shiftUnit)
lazy val MethShiftUnit0 = definitions.getMember(ModCPS, cpsNames.shiftUnit0)
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
index a4e6256f4d..4457a6cf14 100644
--- a/src/library/scala/reflect/base/Base.scala
+++ b/src/library/scala/reflect/base/Base.scala
@@ -357,6 +357,9 @@ class Base extends Universe { self =>
def staticModule(fullName: String): ModuleSymbol =
mkStatic[ModuleSymbol](fullName)
+ def staticPackage(fullName: String): ModuleSymbol =
+ staticModule(fullName) // this toy universe doesn't care about the distinction between packages and modules
+
private def mkStatic[S <: Symbol : ClassTag](fullName: String): S =
cached(fullName) {
val point = fullName lastIndexOf '.'
diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala
index 03e035cd81..6dc8090eee 100644
--- a/src/library/scala/reflect/base/MirrorOf.scala
+++ b/src/library/scala/reflect/base/MirrorOf.scala
@@ -15,11 +15,76 @@ abstract class MirrorOf[U <: base.Universe with Singleton] {
/** The symbol corresponding to the globally accessible class with the
* given fully qualified name `fullName`.
+ *
+ * If the name points to a type alias, it's recursively dealiased and its target is returned.
+ * If you need a symbol that corresponds to the type alias itself, load it directly from the package class:
+ *
+ * scala> cm.staticClass("scala.List")
+ * res0: reflect.runtime.universe.ClassSymbol = class List
+ *
+ * scala> res0.fullName
+ * res1: String = scala.collection.immutable.List
+ *
+ * scala> cm.staticPackage("scala")
+ * res2: reflect.runtime.universe.ModuleSymbol = package scala
+ *
+ * scala> res2.moduleClass.typeSignature member newTypeName("List")
+ * res3: reflect.runtime.universe.Symbol = type List
+ *
+ * scala> res3.fullName
+ * res4: String = scala.List
+ *
+ * To be consistent with Scala name resolution rules, in case of ambiguity between
+ * a package and an object, the object is never been considered.
+ *
+ * For example for the following code:
+ *
+ * package foo {
+ * class B
+ * }
+ *
+ * object foo {
+ * class A
+ * class B
+ * }
+ *
+ * staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and
+ * staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
+ * fully qualified class name is written inside any package in a Scala program).
+ *
+ * In the example above, to load a symbol that corresponds to the class B declared in the object foo,
+ * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
*/
def staticClass(fullName: String): U#ClassSymbol
/** The symbol corresponding to the globally accessible object with the
* given fully qualified name `fullName`.
+ *
+ * To be consistent with Scala name resolution rules, in case of ambiguity between
+ * a package and an object, the object is never been considered.
+ *
+ * For example for the following code:
+ *
+ * package foo {
+ * object B
+ * }
+ *
+ * object foo {
+ * object A
+ * object B
+ * }
+ *
+ * staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and
+ * staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
+ * fully qualified class name is written inside any package in a Scala program).
+ *
+ * In the example above, to load a symbol that corresponds to the object B declared in the object foo,
+ * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
*/
def staticModule(fullName: String): U#ModuleSymbol
+
+ /** The symbol corresponding to a package with the
+ * given fully qualified name `fullName`.
+ */
+ def staticPackage(fullName: String): U#ModuleSymbol
}
diff --git a/src/partest/scala/tools/partest/CompilerTest.scala b/src/partest/scala/tools/partest/CompilerTest.scala
index 89c1a9c2ca..fec9893099 100644
--- a/src/partest/scala/tools/partest/CompilerTest.scala
+++ b/src/partest/scala/tools/partest/CompilerTest.scala
@@ -50,7 +50,7 @@ abstract class CompilerTest extends DirectTest {
}
class SymsInPackage(pkgName: String) {
- def pkg = rootMirror.getRequiredModule(pkgName)
+ def pkg = rootMirror.getRequiredPackage(pkgName)
def classes = allMembers(pkg) filter (_.isClass)
def modules = allMembers(pkg) filter (_.isModule)
def symbols = classes ++ terms filterNot (_ eq NoSymbol)
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index cd243b9df0..7284a199b7 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -490,7 +490,6 @@ trait Definitions extends api.StandardDefinitions {
def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getMemberType(MacroContextClass, tpnme.PrefixType) else NoSymbol
def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol
def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol
- def MacroContextReify = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.reify) else NoSymbol
lazy val MacroImplAnnotation = requiredClass[scala.reflect.makro.internal.macroImpl]
lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal")
def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag)
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 761b993539..f7561ae274 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -36,7 +36,7 @@ trait Mirrors extends api.Mirrors {
if (point > 0) getModuleOrClass(path.toTermName, point)
else RootClass
val name = path subName (point + 1, len)
- val sym = owner.info member name
+ var sym = owner.info member name
val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
if (result != NoSymbol) result
else {
@@ -47,23 +47,39 @@ trait Mirrors extends api.Mirrors {
}
}
- protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = NoSymbol
-
- protected def symbolTableMissingHook(owner: Symbol, name: Name): Symbol = self.missingHook(owner, name)
-
- private[scala] def missingHook(owner: Symbol, name: Name): Symbol = mirrorMissingHook(owner, name) orElse symbolTableMissingHook(owner, name)
+ /** If you're looking for a class, pass a type name.
+ * If a module, a term name.
+ *
+ * Unlike `getModuleOrClass`, this function
+ * loads unqualified names from the root package.
+ */
+ private def getModuleOrClass(path: Name): Symbol =
+ getModuleOrClass(path, path.length)
/** If you're looking for a class, pass a type name.
* If a module, a term name.
+ *
+ * Unlike `getModuleOrClass`, this function
+ * loads unqualified names from the empty package.
*/
- private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)
+ private def staticModuleOrClass(path: Name): Symbol = {
+ val isPackageless = path.pos('.') == path.length
+ if (isPackageless) EmptyPackageClass.info decl path
+ else getModuleOrClass(path)
+ }
+
+ protected def mirrorMissingHook(owner: Symbol, name: Name): Symbol = NoSymbol
+
+ protected def universeMissingHook(owner: Symbol, name: Name): Symbol = self.missingHook(owner, name)
- override def staticClass(fullName: String): ClassSymbol = getRequiredClass(fullName)
+ private[scala] def missingHook(owner: Symbol, name: Name): Symbol = mirrorMissingHook(owner, name) orElse universeMissingHook(owner, name)
- // todo: get rid of most creation methods and keep just staticClass/Module/Package
+ // todo: get rid of most the methods here and keep just staticClass/Module/Package
- def getClassByName(fullname: Name): ClassSymbol = {
- var result = getModuleOrClass(fullname.toTypeName)
+ /************************ loaders of class symbols ************************/
+
+ private def ensureClassSymbol(fullname: String, sym: Symbol): ClassSymbol = {
+ var result = sym
while (result.isAliasType) result = result.info.typeSymbol
result match {
case x: ClassSymbol => x
@@ -71,45 +87,50 @@ trait Mirrors extends api.Mirrors {
}
}
- override def staticModule(fullName: String): ModuleSymbol = getRequiredModule(fullName)
+ @deprecated("Use getClassByName", "2.10.0")
+ def getClass(fullname: Name): ClassSymbol =
+ getClassByName(fullname)
- def getModule(fullname: Name): ModuleSymbol =
- // [Eugene++] should be a ClassCastException instead?
- getModuleOrClass(fullname.toTermName) match {
- case x: ModuleSymbol => x
- case _ => MissingRequirementError.notFound("object " + fullname)
- }
+ def getClassByName(fullname: Name): ClassSymbol =
+ ensureClassSymbol(fullname.toString, getModuleOrClass(fullname.toTypeName))
- def getPackage(fullname: Name): ModuleSymbol = getModule(fullname)
+ def getRequiredClass(fullname: String): ClassSymbol =
+ getClassByName(newTypeNameCached(fullname))
- def getRequiredPackage(fullname: String): ModuleSymbol =
- getPackage(newTermNameCached(fullname))
+ def requiredClass[T: ClassTag] : ClassSymbol =
+ getRequiredClass(erasureName[T])
- @deprecated("Use getClassByName", "2.10.0")
- def getClass(fullname: Name): ClassSymbol = getClassByName(fullname)
+ def getClassIfDefined(fullname: String): Symbol =
+ getClassIfDefined(newTypeNameCached(fullname))
- def getRequiredClass(fullname: String): ClassSymbol =
- getClassByName(newTypeNameCached(fullname)) match {
- case x: ClassSymbol => x
- case _ => MissingRequirementError.notFound("class " + fullname)
- }
+ def getClassIfDefined(fullname: Name): Symbol =
+ wrapMissing(getClassByName(fullname.toTypeName))
- def getRequiredModule(fullname: String): ModuleSymbol =
- getModule(newTermNameCached(fullname))
+ /** @inheritdoc
+ *
+ * Unlike getClassByName/getRequiredClass this function can also load packageless symbols.
+ * Compiler might ignore them, but they should be loadable with macros.
+ */
+ override def staticClass(fullname: String): ClassSymbol =
+ ensureClassSymbol(fullname, staticModuleOrClass(newTypeNameCached(fullname)))
- def erasureName[T: ClassTag] : String = {
- /** We'd like the String representation to be a valid
- * scala type, so we have to decode the jvm's secret language.
- */
- def erasureString(clazz: Class[_]): String = {
- if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]"
- else clazz.getName
+ /************************ loaders of module symbols ************************/
+
+ private def ensureModuleSymbol(fullname: String, sym: Symbol, allowPackages: Boolean): ModuleSymbol =
+ sym match {
+ case x: ModuleSymbol if allowPackages || !x.isPackage => x
+ case _ => MissingRequirementError.notFound("object " + fullname)
}
- erasureString(classTag[T].runtimeClass)
- }
- def requiredClass[T: ClassTag] : ClassSymbol =
- getRequiredClass(erasureName[T])
+ @deprecated("Use getModuleByName", "2.10.0")
+ def getModule(fullname: Name): ModuleSymbol =
+ getModuleByName(fullname)
+
+ def getModuleByName(fullname: Name): ModuleSymbol =
+ ensureModuleSymbol(fullname.toString, getModuleOrClass(fullname.toTermName), allowPackages = true)
+
+ def getRequiredModule(fullname: String): ModuleSymbol =
+ getModule(newTermNameCached(fullname))
// TODO: What syntax do we think should work here? Say you have an object
// like scala.Predef. You can't say requiredModule[scala.Predef] since there's
@@ -121,34 +142,60 @@ trait Mirrors extends api.Mirrors {
def requiredModule[T: ClassTag] : ModuleSymbol =
getRequiredModule(erasureName[T] stripSuffix "$")
- def getClassIfDefined(fullname: String): Symbol =
- getClassIfDefined(newTypeName(fullname))
-
- def getClassIfDefined(fullname: Name): Symbol =
- wrapMissing(getClassByName(fullname.toTypeName))
-
def getModuleIfDefined(fullname: String): Symbol =
- getModuleIfDefined(newTermName(fullname))
+ getModuleIfDefined(newTermNameCached(fullname))
def getModuleIfDefined(fullname: Name): Symbol =
wrapMissing(getModule(fullname.toTermName))
+ /** @inheritdoc
+ *
+ * Unlike getModule/getRequiredModule this function can also load packageless symbols.
+ * Compiler might ignore them, but they should be loadable with macros.
+ */
+ override def staticModule(fullname: String): ModuleSymbol =
+ ensureModuleSymbol(fullname, staticModuleOrClass(newTermNameCached(fullname)), allowPackages = false)
+
+ /************************ loaders of package symbols ************************/
+
+ private def ensurePackageSymbol(fullname: String, sym: Symbol, allowModules: Boolean): ModuleSymbol =
+ sym match {
+ case x: ModuleSymbol if allowModules || x.isPackage => x
+ case _ => MissingRequirementError.notFound("package " + fullname)
+ }
+
+ def getPackage(fullname: Name): ModuleSymbol =
+ ensurePackageSymbol(fullname.toString, getModuleOrClass(fullname), allowModules = true)
+
+ def getRequiredPackage(fullname: String): ModuleSymbol =
+ getPackage(newTermNameCached(fullname))
+
def getPackageObject(fullname: String): ModuleSymbol =
- (getModule(newTermName(fullname)).info member nme.PACKAGE) match {
+ (getPackage(newTermName(fullname)).info member nme.PACKAGE) match {
case x: ModuleSymbol => x
case _ => MissingRequirementError.notFound("package object " + fullname)
}
- def getPackageObjectIfDefined(fullname: String): Symbol = {
- val module = getModuleIfDefined(newTermName(fullname))
- if (module == NoSymbol) NoSymbol
- else {
- val packageObject = module.info member nme.PACKAGE
- packageObject match {
- case x: ModuleSymbol => x
- case _ => NoSymbol
- }
+ def getPackageObjectIfDefined(fullname: String): Symbol =
+ getPackageObjectIfDefined(newTermNameCached(fullname))
+
+ def getPackageObjectIfDefined(fullname: Name): Symbol =
+ wrapMissing(getPackageObject(fullname.toTermName))
+
+ override def staticPackage(fullname: String): ModuleSymbol =
+ ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
+
+ /************************ helpers ************************/
+
+ def erasureName[T: ClassTag] : String = {
+ /** We'd like the String representation to be a valid
+ * scala type, so we have to decode the jvm's secret language.
+ */
+ def erasureString(clazz: Class[_]): String = {
+ if (clazz.isArray) "Array[" + erasureString(clazz.getComponentType) + "]"
+ else clazz.getName
}
+ erasureString(classTag[T].runtimeClass)
}
@inline private def wrapMissing(body: => Symbol): Symbol =
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index c8a2424118..e5d0e96d9c 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -754,6 +754,7 @@ trait StdNames {
val splice: NameType = "splice"
val staticClass : NameType = "staticClass"
val staticModule : NameType = "staticModule"
+ val staticPackage : NameType = "staticPackage"
val synchronized_ : NameType = "synchronized"
val tail: NameType = "tail"
val `then` : NameType = "then"
diff --git a/src/reflect/scala/reflect/makro/Context.scala b/src/reflect/scala/reflect/makro/Context.scala
index f9858a063c..f093016a38 100644
--- a/src/reflect/scala/reflect/makro/Context.scala
+++ b/src/reflect/scala/reflect/makro/Context.scala
@@ -33,8 +33,4 @@ trait Context extends Aliases
/** The prefix tree from which the macro is selected */
val prefix: Expr[PrefixType]
-
- /** Alias to the underlying mirror's reify */
- // implementation is magically hardwired to `scala.reflect.makro.runtime.ContextReifiers`
- def reify[T](expr: T): Expr[T] = macro ???
}
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 9f9f79058d..0878801715 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -72,6 +72,18 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
override def complete(sym: Symbol) = sym setInfo new LazyPackageType
}
+ // reflective mirrors can't know the exhaustive list of available packages
+ // (that's because compiler mirrors are based on directories and reflective mirrors are based on classloaders,
+ // and unlike directories classloaders might make up stuff on the fly)
+ // hence we need to be optimistic and create packages out of thin air
+ // the same thing is done by the `missingHook` below
+ override def staticPackage(fullname: String): ModuleSymbol =
+ try super.staticPackage(fullname)
+ catch {
+ case _: MissingRequirementError =>
+ makeScalaPackage(fullname)
+ }
+
// ----------- Caching ------------------------------------------------------------------
// [Eugene++ to Martin] not weak? why?