summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2013-06-03 11:08:50 -0700
committerEugene Burmako <xeno.by@gmail.com>2013-06-03 11:08:50 -0700
commit69887ddd682057c4787e2e4377830390faf8ecf1 (patch)
tree1158f24dd50dac397e867a6d2d861171e7335c4f /src/reflect
parentc1cd65bb5276b715141df6d09fc95b0c44d2b4c2 (diff)
parent82f0925b69db8b5f9a3b10f58926c574433ca423 (diff)
downloadscala-69887ddd682057c4787e2e4377830390faf8ecf1.tar.gz
scala-69887ddd682057c4787e2e4377830390faf8ecf1.tar.bz2
scala-69887ddd682057c4787e2e4377830390faf8ecf1.zip
Merge pull request #2577 from scalamacros/pullrequest/paradise
Backport from paradise/macros
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala14
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala2
-rw-r--r--src/reflect/scala/reflect/api/package.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala62
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala664
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala5
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala13
-rw-r--r--src/reflect/scala/reflect/macros/Macro.scala39
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala2
11 files changed, 466 insertions, 356 deletions
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index f4ada814af..f7a6a68946 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -296,6 +296,20 @@ trait Trees { self: Universe =>
def name: Name
}
+ /** The constructor/extractor for `RefTree` instances.
+ * @group Extractors
+ */
+ val RefTree: RefTreeExtractor
+
+ /** An extractor class to create and pattern match with syntax `RefTree(qual, name)`.
+ * This AST node corresponds to either Ident, Select or SelectFromTypeTree.
+ * @group Extractors
+ */
+ abstract class RefTreeExtractor {
+ def apply(qualifier: Tree, name: Name): RefTree
+ def unapply(refTree: RefTree): Option[(Tree, Name)]
+ }
+
/** A tree which defines a symbol-carrying entity.
* @group Trees
* @template
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index 799fbd0dfb..cb629f9c5a 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -94,5 +94,5 @@ abstract class Universe extends Symbols
*/
// implementation is hardwired to `scala.reflect.reify.Taggers`
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
- def reify[T](expr: T): Expr[T] = ??? // macro
+ def reify[T](expr: T): Expr[T] = macro ???
}
diff --git a/src/reflect/scala/reflect/api/package.scala b/src/reflect/scala/reflect/api/package.scala
index 14dcc9247f..a8f409e123 100644
--- a/src/reflect/scala/reflect/api/package.scala
+++ b/src/reflect/scala/reflect/api/package.scala
@@ -43,6 +43,6 @@ package object api {
// implementation is hardwired into `scala.reflect.reify.Taggers`
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
// todo. once we have implicit macros for tag generation, we can remove these anchors
- private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = ??? // macro
- private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = ??? // macro
+ private[scala] def materializeWeakTypeTag[T](u: ApiUniverse): u.WeakTypeTag[T] = macro ???
+ private[scala] def materializeTypeTag[T](u: ApiUniverse): u.TypeTag[T] = macro ???
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 5cd86b7eed..1b46d9e00b 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -491,8 +491,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val ReflectPackage = requiredModule[scala.reflect.`package`.type]
lazy val ReflectApiPackage = getPackageObjectIfDefined("scala.reflect.api") // defined in scala-reflect.jar, so we need to be careful
lazy val ReflectRuntimePackage = getPackageObjectIfDefined("scala.reflect.runtime") // defined in scala-reflect.jar, so we need to be careful
- def ReflectRuntimeUniverse = if (ReflectRuntimePackage != NoSymbol) getMemberValue(ReflectRuntimePackage, nme.universe) else NoSymbol
- def ReflectRuntimeCurrentMirror = if (ReflectRuntimePackage != NoSymbol) getMemberMethod(ReflectRuntimePackage, nme.currentMirror) else NoSymbol
+ def ReflectRuntimeUniverse = ReflectRuntimePackage.map(sym => getMemberValue(sym, nme.universe))
+ def ReflectRuntimeCurrentMirror = ReflectRuntimePackage.map(sym => getMemberMethod(sym, nme.currentMirror))
lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest)
lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifestFactory.type]
@@ -501,24 +501,38 @@ trait Definitions extends api.StandardDefinitions {
lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]]
lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type]
+ lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful
+ lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree))
+ object TreeType {
+ def unapply(tpe: Type): Boolean = unapply(tpe.typeSymbol)
+ def unapply(sym: Symbol): Boolean = sym.overrideChain contains TreesTreeType
+ }
+
lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful
- lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol
- def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol
- def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol
+ lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr))
+ def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice))
+ def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value))
+ object ExprClassOf {
+ def unapply(tpe: Type): Option[Type] = tpe.dealias match {
+ case ExistentialType(_, underlying) => unapply(underlying)
+ case TypeRef(_, ExprClass, t :: Nil) => Some(t)
+ case _ => None
+ }
+ }
lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
lazy val TypeTagsClass = getClassIfDefined("scala.reflect.api.TypeTags") // defined in scala-reflect.jar, so we need to be careful
- lazy val WeakTypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.WeakTypeTag) else NoSymbol
- lazy val WeakTypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.WeakTypeTag) else NoSymbol
- lazy val TypeTagClass = if (TypeTagsClass != NoSymbol) getMemberClass(TypeTagsClass, tpnme.TypeTag) else NoSymbol
- lazy val TypeTagModule = if (TypeTagsClass != NoSymbol) getMemberModule(TypeTagsClass, nme.TypeTag) else NoSymbol
+ lazy val WeakTypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag))
+ lazy val WeakTypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag))
+ lazy val TypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag))
+ lazy val TypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.TypeTag))
def materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag)
- def materializeWeakTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeWeakTypeTag) else NoSymbol
- def materializeTypeTag = if (ReflectApiPackage != NoSymbol) getMemberMethod(ReflectApiPackage, nme.materializeTypeTag) else NoSymbol
+ def materializeWeakTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag))
+ def materializeTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag))
lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful
- def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
+ def ApiUniverseReify = ApiUniverseClass.map(sym => getMemberMethod(sym, nme.reify))
lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful
@@ -526,14 +540,18 @@ trait Definitions extends api.StandardDefinitions {
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
- lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful
- def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol
- def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getTypeMember(MacroContextClass, tpnme.PrefixType) else NoSymbol
- def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol
- lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl]
+ lazy val MacroClass = getClassIfDefined("scala.reflect.macros.Macro") // defined in scala-reflect.jar, so we need to be careful
+ lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful
+ def MacroContextPrefix = MacroContextClass.map(sym => getMemberMethod(sym, nme.prefix))
+ def MacroContextPrefixType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType))
+ def MacroContextUniverse = MacroContextClass.map(sym => getMemberMethod(sym, nme.universe))
+ def MacroContextExprClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Expr))
+ def MacroContextWeakTypeTagClass = MacroContextClass.map(sym => getTypeMember(sym, tpnme.WeakTypeTag))
+ def MacroContextTreeType = MacroContextClass.map(sym => getTypeMember(sym, tpnme.Tree))
+ lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl]
- lazy val StringContextClass = requiredClass[scala.StringContext]
- def StringContext_f = getMemberMethod(StringContextClass, nme.f)
+ lazy val StringContextClass = requiredClass[scala.StringContext]
+ def StringContext_f = getMemberMethod(StringContextClass, nme.f)
lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature]
lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature]
@@ -640,6 +658,12 @@ trait Definitions extends api.StandardDefinitions {
}
def isTupleType(tp: Type) = isTupleTypeDirect(tp.dealiasWiden)
+ def isMacroBundleType(tp: Type) = {
+ val isNonTrivial = tp != ErrorType && tp != NothingTpe && tp != NullTpe
+ val isMacroCompatible = MacroClass != NoSymbol && tp <:< MacroClass.tpe
+ isNonTrivial && isMacroCompatible
+ }
+
lazy val ProductRootClass: ClassSymbol = requiredClass[scala.Product]
def Product_productArity = getMemberMethod(ProductRootClass, nme.productArity)
def Product_productElement = getMemberMethod(ProductRootClass, nme.productElement)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index b0d3cda629..f8584ac9b0 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -6,17 +6,17 @@ import scala.collection.mutable.WeakHashMap
import scala.ref.WeakReference
// SI-6241: move importers to a mirror
-trait Importers extends api.Importers { self: SymbolTable =>
+trait Importers extends api.Importers { to: SymbolTable =>
def mkImporter(from0: api.Universe): Importer { val from: from0.type } = (
- if (self eq from0) {
+ if (to eq from0) {
new Importer {
val from = from0
- val reverse = this.asInstanceOf[from.Importer{ val from: self.type }]
- def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol]
- def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type]
- def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree]
- def importPosition(pos: from.Position) = pos.asInstanceOf[self.Position]
+ val reverse = this.asInstanceOf[from.Importer{ val from: to.type }]
+ def importSymbol(their: from.Symbol) = their.asInstanceOf[to.Symbol]
+ def importType(their: from.Type) = their.asInstanceOf[to.Type]
+ def importTree(their: from.Tree) = their.asInstanceOf[to.Tree]
+ def importPosition(their: from.Position) = their.asInstanceOf[to.Position]
}
} else {
// todo. fix this loophole
@@ -29,8 +29,8 @@ trait Importers extends api.Importers { self: SymbolTable =>
val from: SymbolTable
- protected lazy val symMap = new Cache[from.Symbol, Symbol]()
- protected lazy val tpeMap = new Cache[from.Type, Type]()
+ protected lazy val symMap = new Cache[from.Symbol, to.Symbol]()
+ protected lazy val tpeMap = new Cache[from.Type, to.Type]()
protected class Cache[K <: AnyRef, V <: AnyRef] extends WeakHashMap[K, WeakReference[V]] {
def weakGet(key: K): Option[V] = this get key flatMap WeakReference.unapply
def weakUpdate(key: K, value: V) = this.update(key, WeakReference(value))
@@ -50,158 +50,162 @@ trait Importers extends api.Importers { self: SymbolTable =>
}
object reverse extends from.StandardImporter {
- val from: self.type = self
+ val from: to.type = to
// FIXME this and reverse should be constantly kept in sync
// not just synced once upon the first usage of reverse
- for ((fromsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(fromsym)))
- for ((fromtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(fromtpe)))
+ for ((theirsym, WeakReference(mysym)) <- StandardImporter.this.symMap) symMap += ((mysym, WeakReference(theirsym)))
+ for ((theirtpe, WeakReference(mytpe)) <- StandardImporter.this.tpeMap) tpeMap += ((mytpe, WeakReference(theirtpe)))
}
- // todo. careful import of positions
- def importPosition(pos: from.Position): Position =
- pos.asInstanceOf[Position]
+ // ============== SYMBOLS ==============
+
+ protected def recreatedSymbolCompleter(my: to.Symbol, their: from.Symbol) = {
+ // we lock the symbol that is imported for a very short period of time
+ // i.e. only for when type parameters of the symbol are being imported
+ // the lock is used to communicate to the recursive importSymbol calls
+ // that type parameters need to be created from scratch
+ // because otherwise type parameters are imported by looking into owner.typeParams
+ // which is obviously unavailable while the completer is being created
+ try {
+ my setFlag Flags.LOCKED
+ val mytypeParams = their.typeParams map importSymbol
+ new LazyPolyType(mytypeParams) with FlagAgnosticCompleter {
+ override def complete(my: to.Symbol): Unit = {
+ val theirCore = their.info match {
+ case from.PolyType(_, core) => core
+ case core => core
+ }
+ my setInfo GenPolyType(mytypeParams, importType(theirCore))
+ my setAnnotations (their.annotations map importAnnotationInfo)
+ }
+ }
+ } finally {
+ my resetFlag Flags.LOCKED
+ }
+ }
+
+ protected def recreateSymbol(their: from.Symbol): to.Symbol = {
+ val myowner = importSymbol(their.owner)
+ val mypos = importPosition(their.pos)
+ val myname = importName(their.name)
+ val myflags = their.flags
+ def linkReferenced(my: TermSymbol, their: from.TermSymbol, op: from.Symbol => Symbol): Symbol = {
+ symMap.weakUpdate(their, my)
+ my.referenced = op(their.referenced)
+ my
+ }
+ val my = their match {
+ case their: from.MethodSymbol =>
+ linkReferenced(myowner.newMethod(myname.toTermName, mypos, myflags), their, importSymbol)
+ case their: from.ModuleSymbol =>
+ val ret = linkReferenced(myowner.newModuleSymbol(myname.toTermName, mypos, myflags), their, importSymbol)
+ ret.associatedFile = their.associatedFile
+ ret
+ case their: from.FreeTermSymbol =>
+ newFreeTermSymbol(myname.toTermName, their.value, their.flags, their.origin) setInfo importType(their.info)
+ case their: from.FreeTypeSymbol =>
+ newFreeTypeSymbol(myname.toTypeName, their.flags, their.origin)
+ case their: from.TermSymbol =>
+ linkReferenced(myowner.newValue(myname.toTermName, mypos, myflags), their, importSymbol)
+ case their: from.TypeSkolem =>
+ val origin = their.unpackLocation match {
+ case null => null
+ case theirloc: from.Tree => importTree(theirloc)
+ case theirloc: from.Symbol => importSymbol(theirloc)
+ }
+ myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags)
+ case their: from.ModuleClassSymbol =>
+ val my = myowner.newModuleClass(myname.toTypeName, mypos, myflags)
+ symMap.weakUpdate(their, my)
+ my.sourceModule = importSymbol(their.sourceModule)
+ my
+ case their: from.ClassSymbol =>
+ val my = myowner.newClassSymbol(myname.toTypeName, mypos, myflags)
+ symMap.weakUpdate(their, my)
+ if (their.thisSym != their) {
+ my.typeOfThis = importType(their.typeOfThis)
+ my.thisSym setName importName(their.thisSym.name)
+ }
+ my.associatedFile = their.associatedFile
+ my
+ case their: from.TypeSymbol =>
+ myowner.newTypeSymbol(myname.toTypeName, mypos, myflags)
+ }
+ symMap.weakUpdate(their, my)
+ my setInfo recreatedSymbolCompleter(my, their)
+ }
- def importSymbol(sym0: from.Symbol): Symbol = {
- def doImport(sym: from.Symbol): Symbol =
- symMap weakGet sym match {
+ def importSymbol(their0: from.Symbol): Symbol = {
+ def cachedRecreateSymbol(their: from.Symbol): Symbol =
+ symMap weakGet their match {
case Some(result) => result
- case _ =>
- val myowner = importSymbol(sym.owner)
- val mypos = importPosition(sym.pos)
- val myname = importName(sym.name).toTermName
- val myflags = sym.flags
- def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = {
- symMap.weakUpdate(x, mysym)
- mysym.referenced = op(x.referenced)
- mysym
- }
- val mysym = sym match {
- case x: from.MethodSymbol =>
- linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol)
- case x: from.ModuleSymbol =>
- linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol)
- case x: from.FreeTermSymbol =>
- newFreeTermSymbol(importName(x.name).toTermName, x.value, x.flags, x.origin) setInfo importType(x.info)
- case x: from.FreeTypeSymbol =>
- newFreeTypeSymbol(importName(x.name).toTypeName, x.flags, x.origin)
- case x: from.TermSymbol =>
- linkReferenced(myowner.newValue(myname, mypos, myflags), x, importSymbol)
- case x: from.TypeSkolem =>
- val origin = x.unpackLocation match {
- case null => null
- case y: from.Tree => importTree(y)
- case y: from.Symbol => importSymbol(y)
- }
- myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags)
- case x: from.ModuleClassSymbol =>
- val mysym = myowner.newModuleClass(myname.toTypeName, mypos, myflags)
- symMap.weakUpdate(x, mysym)
- mysym.sourceModule = importSymbol(x.sourceModule)
- mysym
- case x: from.ClassSymbol =>
- val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags)
- symMap.weakUpdate(x, mysym)
- if (sym.thisSym != sym) {
- mysym.typeOfThis = importType(sym.typeOfThis)
- mysym.thisSym setName importName(sym.thisSym.name)
- }
- mysym
- case x: from.TypeSymbol =>
- myowner.newTypeSymbol(myname.toTypeName, mypos, myflags)
- }
- symMap.weakUpdate(sym, mysym)
- mysym setFlag Flags.LOCKED
- mysym setInfo {
- val mytypeParams = sym.typeParams map importSymbol
- new LazyPolyType(mytypeParams) with FlagAgnosticCompleter {
- override def complete(s: Symbol) {
- val result = sym.info match {
- case from.PolyType(_, res) => res
- case result => result
- }
- s setInfo GenPolyType(mytypeParams, importType(result))
- s setAnnotations (sym.annotations map importAnnotationInfo)
- }
- }
- }
- mysym resetFlag Flags.LOCKED
- } // end doImport
+ case _ => recreateSymbol(their)
+ }
- def importOrRelink: Symbol = {
- val sym = sym0 // makes sym visible in the debugger
- if (sym == null)
+ def recreateOrRelink: Symbol = {
+ val their = their0 // makes their visible in the debugger
+ if (their == null)
null
- else if (sym == from.NoSymbol)
+ else if (their == from.NoSymbol)
NoSymbol
- else if (sym.isRoot)
+ else if (their.isRoot)
rootMirror.RootClass // !!! replace with actual mirror when we move importers to the mirror
else {
- val name = sym.name
- val owner = sym.owner
- var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType
- var existing = scope.decl(name)
- if (sym.isModuleClass)
- existing = existing.moduleClass
-
- if (!existing.exists) scope = from.NoType
-
- val myname = importName(name)
- val myowner = importSymbol(owner)
- val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType
- var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods
- if (sym.isModuleClass)
- myexisting = importSymbol(sym.sourceModule).moduleClass
-
- if (!sym.isOverloaded && myexisting.isOverloaded) {
- myexisting =
- if (sym.isMethod) {
- val localCopy = doImport(sym)
- myexisting filter (_.tpe matches localCopy.tpe)
- } else {
- myexisting filter (!_.isMethod)
+ val isModuleClass = their.isModuleClass
+ val isTparam = their.isTypeParameter && their.paramPos >= 0
+ val isOverloaded = their.isOverloaded
+
+ var theirscope = if (their.owner.isClass && !their.owner.isRefinementClass) their.owner.info else from.NoType
+ val theirexisting = if (isModuleClass) theirscope.decl(their.name).moduleClass else theirscope.decl(their.name)
+ if (!theirexisting.exists) theirscope = from.NoType
+
+ val myname = importName(their.name)
+ val myowner = importSymbol(their.owner)
+ val myscope = if (theirscope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType
+ val myexisting = {
+ if (isModuleClass) importSymbol(their.sourceModule).moduleClass
+ else if (isTparam) (if (myowner hasFlag Flags.LOCKED) NoSymbol else myowner.typeParams(their.paramPos))
+ else if (isOverloaded) myowner.newOverloaded(myowner.thisType, their.alternatives map importSymbol)
+ else {
+ def disambiguate(my: Symbol) = {
+ val result =
+ if (their.isMethod) {
+ val localCopy = cachedRecreateSymbol(their)
+ my filter (_.tpe matches localCopy.tpe)
+ } else {
+ my filter (!_.isMethod)
+ }
+ assert(!result.isOverloaded,
+ "import failure: cannot determine unique overloaded method alternative from\n "+
+ (result.alternatives map (_.defString) mkString "\n")+"\n that matches "+their+":"+their.tpe)
+ result
}
- assert(!myexisting.isOverloaded,
- "import failure: cannot determine unique overloaded method alternative from\n "+
- (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe)
- }
- val mysym = {
- if (sym.isOverloaded) {
- myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol)
- } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) {
- assert(myowner.typeParams.length > sym.paramPos,
- "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+
- myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+
- sym.owner+from.typeParamsString(sym.owner.info))
- myowner.typeParams(sym.paramPos)
- } else {
- if (myexisting != NoSymbol) {
- myexisting
- } else {
- val mysym = doImport(sym)
-
- if (myscope != NoType) {
- assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+myexisting)
- myowner.info.decls enter mysym
- }
-
- mysym
- }
+ val myexisting = if (myscope != NoType) myscope.decl(myname) else NoSymbol
+ if (myexisting.isOverloaded) disambiguate(myexisting)
+ else myexisting
}
}
- mysym
+ myexisting.orElse {
+ val my = cachedRecreateSymbol(their)
+ if (myscope != NoType) {
+ assert(myscope.decls.lookup(myname) == NoSymbol, myname+" "+myscope.decl(myname)+" "+myexisting)
+ myscope.decls enter my
+ }
+ my
+ }
}
- } // end importOrRelink
+ } // end recreateOrRelink
- val sym = sym0
- symMap.weakGet(sym) match {
+ val their = their0
+ symMap.weakGet(their) match {
case Some(result) => result
case None =>
pendingSyms += 1
try {
- val result = importOrRelink
- symMap.weakUpdate(sym, result)
+ val result = recreateOrRelink
+ symMap.weakUpdate(their, result)
result
} finally {
pendingSyms -= 1
@@ -210,69 +214,70 @@ trait Importers extends api.Importers { self: SymbolTable =>
}
}
- def importType(tpe: from.Type): Type = {
- def doImport(tpe: from.Type): Type = tpe match {
- case from.TypeRef(pre, sym, args) =>
- TypeRef(importType(pre), importSymbol(sym), args map importType)
- case from.ThisType(clazz) =>
- ThisType(importSymbol(clazz))
- case from.SingleType(pre, sym) =>
- SingleType(importType(pre), importSymbol(sym))
- case from.MethodType(params, restpe) =>
- MethodType(params map importSymbol, importType(restpe))
- case from.PolyType(tparams, restpe) =>
- PolyType(tparams map importSymbol, importType(restpe))
- case from.NullaryMethodType(restpe) =>
- NullaryMethodType(importType(restpe))
- case from.ConstantType(constant @ from.Constant(_)) =>
- ConstantType(importConstant(constant))
- case from.SuperType(thistpe, supertpe) =>
- SuperType(importType(thistpe), importType(supertpe))
- case from.TypeBounds(lo, hi) =>
- TypeBounds(importType(lo), importType(hi))
- case from.BoundedWildcardType(bounds) =>
- BoundedWildcardType(importTypeBounds(bounds))
- case from.ClassInfoType(parents, decls, clazz) =>
- val myclazz = importSymbol(clazz)
- val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope
- val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz)
- myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope
- decls foreach importSymbol // will enter itself into myclazz
- myclazzTpe
- case from.RefinedType(parents, decls) =>
- RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol))
- case from.ExistentialType(tparams, restpe) =>
- newExistentialType(tparams map importSymbol, importType(restpe))
- case from.OverloadedType(pre, alts) =>
- OverloadedType(importType(pre), alts map importSymbol)
- case from.AntiPolyType(pre, targs) =>
- AntiPolyType(importType(pre), targs map importType)
- case x: from.TypeVar =>
- TypeVar(importType(x.origin), importTypeConstraint(x.constr), x.typeArgs map importType, x.params map importSymbol)
- case from.AnnotatedType(annots, tpe, selfsym) =>
- AnnotatedType(annots map importAnnotationInfo, importType(tpe), importSymbol(selfsym))
- case from.ErrorType =>
- ErrorType
- case from.WildcardType =>
- WildcardType
- case from.NoType =>
- NoType
- case from.NoPrefix =>
- NoPrefix
- case null =>
- null
- } // end doImport
-
- def importOrRelink: Type =
- doImport(tpe)
+ // ============== TYPES ==============
+
+ def recreateType(their: from.Type): Type = their match {
+ case from.TypeRef(pre, sym, args) =>
+ TypeRef(importType(pre), importSymbol(sym), args map importType)
+ case from.ThisType(clazz) =>
+ ThisType(importSymbol(clazz))
+ case from.SingleType(pre, sym) =>
+ SingleType(importType(pre), importSymbol(sym))
+ case from.MethodType(params, result) =>
+ MethodType(params map importSymbol, importType(result))
+ case from.PolyType(tparams, result) =>
+ PolyType(tparams map importSymbol, importType(result))
+ case from.NullaryMethodType(result) =>
+ NullaryMethodType(importType(result))
+ case from.ConstantType(constant @ from.Constant(_)) =>
+ ConstantType(importConstant(constant))
+ case from.SuperType(thistpe, supertpe) =>
+ SuperType(importType(thistpe), importType(supertpe))
+ case from.TypeBounds(lo, hi) =>
+ TypeBounds(importType(lo), importType(hi))
+ case from.BoundedWildcardType(bounds) =>
+ BoundedWildcardType(importType(bounds).asInstanceOf[TypeBounds])
+ case from.ClassInfoType(parents, decls, clazz) =>
+ val myclazz = importSymbol(clazz)
+ val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope
+ val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz)
+ myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope
+ decls foreach importSymbol // will enter itself into myclazz
+ myclazzTpe
+ case from.RefinedType(parents, decls) =>
+ RefinedType(parents map importType, importScope(decls), importSymbol(their.typeSymbol))
+ case from.ExistentialType(tparams, result) =>
+ newExistentialType(tparams map importSymbol, importType(result))
+ case from.OverloadedType(pre, alts) =>
+ OverloadedType(importType(pre), alts map importSymbol)
+ case from.AntiPolyType(pre, targs) =>
+ AntiPolyType(importType(pre), targs map importType)
+ case their: from.TypeVar =>
+ val myconstr = new TypeConstraint(their.constr.loBounds map importType, their.constr.hiBounds map importType)
+ myconstr.inst = importType(their.constr.inst)
+ TypeVar(importType(their.origin), myconstr, their.typeArgs map importType, their.params map importSymbol)
+ case from.AnnotatedType(annots, result, selfsym) =>
+ AnnotatedType(annots map importAnnotationInfo, importType(result), importSymbol(selfsym))
+ case from.ErrorType =>
+ ErrorType
+ case from.WildcardType =>
+ WildcardType
+ case from.NoType =>
+ NoType
+ case from.NoPrefix =>
+ NoPrefix
+ case null =>
+ null
+ }
- tpeMap.weakGet(tpe) match {
+ def importType(their: from.Type): Type = {
+ tpeMap.weakGet(their) match {
case Some(result) => result
case None =>
pendingTpes += 1
try {
- val result = importOrRelink
- tpeMap.weakUpdate(tpe, result)
+ val result = recreateType(their)
+ tpeMap.weakUpdate(their, result)
result
} finally {
pendingTpes -= 1
@@ -281,7 +286,136 @@ trait Importers extends api.Importers { self: SymbolTable =>
}
}
- def importTypeBounds(bounds: from.TypeBounds) = importType(bounds).asInstanceOf[TypeBounds]
+ // ============== TREES ==============
+
+ def recreatedTreeCompleter(their: from.Tree, my: to.Tree): Unit = {
+ if (their.canHaveAttrs) {
+ if (my.hasSymbolField) my.symbol = importSymbol(their.symbol)
+ my.pos = importPosition(their.pos)
+ (their, my) match {
+ case (their: from.TypeTree, my: to.TypeTree) =>
+ if (their.wasEmpty) my.defineType(importType(their.tpe)) else my.setType(importType(their.tpe))
+ case (_, _) =>
+ my.tpe = importType(their.tpe)
+ }
+ }
+ }
+
+ def recreateTree(their: from.Tree): to.Tree = their match {
+ case from.ClassDef(mods, name, tparams, impl) =>
+ new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl))
+ case from.PackageDef(pid, stats) =>
+ new PackageDef(importRefTree(pid), stats map importTree)
+ case from.ModuleDef(mods, name, impl) =>
+ new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl))
+ case from.emptyValDef =>
+ emptyValDef
+ case from.pendingSuperCall =>
+ pendingSuperCall
+ case from.ValDef(mods, name, tpt, rhs) =>
+ new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
+ case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs))
+ case from.TypeDef(mods, name, tparams, rhs) =>
+ new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs))
+ case from.LabelDef(name, params, rhs) =>
+ new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs))
+ case from.Import(expr, selectors) =>
+ new Import(importTree(expr), selectors map importImportSelector)
+ case from.Template(parents, self, body) =>
+ new Template(parents map importTree, importValDef(self), body map importTree)
+ case from.Block(stats, expr) =>
+ new Block(stats map importTree, importTree(expr))
+ case from.CaseDef(pat, guard, body) =>
+ new CaseDef(importTree(pat), importTree(guard), importTree(body))
+ case from.Alternative(trees) =>
+ new Alternative(trees map importTree)
+ case from.Star(elem) =>
+ new Star(importTree(elem))
+ case from.Bind(name, body) =>
+ new Bind(importName(name), importTree(body))
+ case from.UnApply(fun, args) =>
+ new UnApply(importTree(fun), args map importTree)
+ case from.ArrayValue(elemtpt ,elems) =>
+ new ArrayValue(importTree(elemtpt), elems map importTree)
+ case from.Function(vparams, body) =>
+ new Function(vparams map importValDef, importTree(body))
+ case from.Assign(lhs, rhs) =>
+ new Assign(importTree(lhs), importTree(rhs))
+ case from.AssignOrNamedArg(lhs, rhs) =>
+ new AssignOrNamedArg(importTree(lhs), importTree(rhs))
+ case from.If(cond, thenp, elsep) =>
+ new If(importTree(cond), importTree(thenp), importTree(elsep))
+ case from.Match(selector, cases) =>
+ new Match(importTree(selector), cases map importCaseDef)
+ case from.Return(expr) =>
+ new Return(importTree(expr))
+ case from.Try(block, catches, finalizer) =>
+ new Try(importTree(block), catches map importCaseDef, importTree(finalizer))
+ case from.Throw(expr) =>
+ new Throw(importTree(expr))
+ case from.New(tpt) =>
+ new New(importTree(tpt))
+ case from.Typed(expr, tpt) =>
+ new Typed(importTree(expr), importTree(tpt))
+ case from.TypeApply(fun, args) =>
+ new TypeApply(importTree(fun), args map importTree)
+ case from.Apply(fun, args) => their match {
+ case _: from.ApplyToImplicitArgs =>
+ new ApplyToImplicitArgs(importTree(fun), args map importTree)
+ case _: from.ApplyImplicitView =>
+ new ApplyImplicitView(importTree(fun), args map importTree)
+ case _ =>
+ new Apply(importTree(fun), args map importTree)
+ }
+ case from.ApplyDynamic(qual, args) =>
+ new ApplyDynamic(importTree(qual), args map importTree)
+ case from.Super(qual, mix) =>
+ new Super(importTree(qual), importName(mix).toTypeName)
+ case from.This(qual) =>
+ new This(importName(qual).toTypeName)
+ case from.Select(qual, name) =>
+ new Select(importTree(qual), importName(name))
+ case from.Ident(name) =>
+ new Ident(importName(name))
+ case from.ReferenceToBoxed(ident) =>
+ new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident })
+ case from.Literal(constant @ from.Constant(_)) =>
+ new Literal(importConstant(constant))
+ case theirtt @ from.TypeTree() =>
+ val mytt = TypeTree()
+ if (theirtt.original != null) mytt.setOriginal(importTree(theirtt.original))
+ mytt
+ case from.Annotated(annot, arg) =>
+ new Annotated(importTree(annot), importTree(arg))
+ case from.SingletonTypeTree(ref) =>
+ new SingletonTypeTree(importTree(ref))
+ case from.SelectFromTypeTree(qual, name) =>
+ new SelectFromTypeTree(importTree(qual), importName(name).toTypeName)
+ case from.CompoundTypeTree(templ) =>
+ new CompoundTypeTree(importTemplate(templ))
+ case from.AppliedTypeTree(tpt, args) =>
+ new AppliedTypeTree(importTree(tpt), args map importTree)
+ case from.TypeBoundsTree(lo, hi) =>
+ new TypeBoundsTree(importTree(lo), importTree(hi))
+ case from.ExistentialTypeTree(tpt, whereClauses) =>
+ new ExistentialTypeTree(importTree(tpt), whereClauses map importTree)
+ case from.EmptyTree =>
+ EmptyTree
+ case null =>
+ null
+ }
+
+ def importTree(their: from.Tree): Tree = {
+ val my = recreateTree(their)
+ if (my != null) {
+ addFixup(recreatedTreeCompleter(their, my))
+ tryFixup()
+ }
+ my
+ }
+
+ // ============== MISCELLANEOUS ==============
def importAnnotationInfo(ann: from.AnnotationInfo): AnnotationInfo = {
val atp1 = importType(ann.atp)
@@ -302,11 +436,9 @@ trait Importers extends api.Importers { self: SymbolTable =>
NestedAnnotArg(importAnnotationInfo(annInfo))
}
- def importTypeConstraint(constr: from.TypeConstraint): TypeConstraint = {
- val result = new TypeConstraint(constr.loBounds map importType, constr.hiBounds map importType)
- result.inst = importType(constr.inst)
- result
- }
+ // todo. careful import of positions
+ def importPosition(their: from.Position): to.Position =
+ their.asInstanceOf[Position]
// !!! todo: override to cater for PackageScopes
def importScope(decls: from.Scope): Scope =
@@ -314,138 +446,12 @@ trait Importers extends api.Importers { self: SymbolTable =>
def importName(name: from.Name): Name =
if (name.isTypeName) newTypeName(name.toString) else newTermName(name.toString)
- def importTypeName(name: from.TypeName): TypeName = importName(name).toTypeName
def importModifiers(mods: from.Modifiers): Modifiers =
new Modifiers(mods.flags, importName(mods.privateWithin), mods.annotations map importTree)
def importImportSelector(sel: from.ImportSelector): ImportSelector =
new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos)
-
- def importTree(tree: from.Tree): Tree = {
- val mytree = tree match {
- case from.ClassDef(mods, name, tparams, impl) =>
- new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl))
- case from.PackageDef(pid, stats) =>
- new PackageDef(importRefTree(pid), stats map importTree)
- case from.ModuleDef(mods, name, impl) =>
- new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl))
- case from.emptyValDef =>
- emptyValDef
- case from.pendingSuperCall =>
- pendingSuperCall
- case from.ValDef(mods, name, tpt, rhs) =>
- new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
- case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs))
- case from.TypeDef(mods, name, tparams, rhs) =>
- new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs))
- case from.LabelDef(name, params, rhs) =>
- new LabelDef(importName(name).toTermName, params map importIdent, importTree(rhs))
- case from.Import(expr, selectors) =>
- new Import(importTree(expr), selectors map importImportSelector)
- case from.Template(parents, self, body) =>
- new Template(parents map importTree, importValDef(self), body map importTree)
- case from.Block(stats, expr) =>
- new Block(stats map importTree, importTree(expr))
- case from.CaseDef(pat, guard, body) =>
- new CaseDef(importTree(pat), importTree(guard), importTree(body))
- case from.Alternative(trees) =>
- new Alternative(trees map importTree)
- case from.Star(elem) =>
- new Star(importTree(elem))
- case from.Bind(name, body) =>
- new Bind(importName(name), importTree(body))
- case from.UnApply(fun, args) =>
- new UnApply(importTree(fun), args map importTree)
- case from.ArrayValue(elemtpt ,elems) =>
- new ArrayValue(importTree(elemtpt), elems map importTree)
- case from.Function(vparams, body) =>
- new Function(vparams map importValDef, importTree(body))
- case from.Assign(lhs, rhs) =>
- new Assign(importTree(lhs), importTree(rhs))
- case from.AssignOrNamedArg(lhs, rhs) =>
- new AssignOrNamedArg(importTree(lhs), importTree(rhs))
- case from.If(cond, thenp, elsep) =>
- new If(importTree(cond), importTree(thenp), importTree(elsep))
- case from.Match(selector, cases) =>
- new Match(importTree(selector), cases map importCaseDef)
- case from.Return(expr) =>
- new Return(importTree(expr))
- case from.Try(block, catches, finalizer) =>
- new Try(importTree(block), catches map importCaseDef, importTree(finalizer))
- case from.Throw(expr) =>
- new Throw(importTree(expr))
- case from.New(tpt) =>
- new New(importTree(tpt))
- case from.Typed(expr, tpt) =>
- new Typed(importTree(expr), importTree(tpt))
- case from.TypeApply(fun, args) =>
- new TypeApply(importTree(fun), args map importTree)
- case from.Apply(fun, args) => tree match {
- case _: from.ApplyToImplicitArgs =>
- new ApplyToImplicitArgs(importTree(fun), args map importTree)
- case _: from.ApplyImplicitView =>
- new ApplyImplicitView(importTree(fun), args map importTree)
- case _ =>
- new Apply(importTree(fun), args map importTree)
- }
- case from.ApplyDynamic(qual, args) =>
- new ApplyDynamic(importTree(qual), args map importTree)
- case from.Super(qual, mix) =>
- new Super(importTree(qual), importTypeName(mix))
- case from.This(qual) =>
- new This(importName(qual).toTypeName)
- case from.Select(qual, name) =>
- new Select(importTree(qual), importName(name))
- case from.Ident(name) =>
- new Ident(importName(name))
- case from.ReferenceToBoxed(ident) =>
- new ReferenceToBoxed(importTree(ident) match { case ident: Ident => ident })
- case from.Literal(constant @ from.Constant(_)) =>
- new Literal(importConstant(constant))
- case from.TypeTree() =>
- new TypeTree()
- case from.Annotated(annot, arg) =>
- new Annotated(importTree(annot), importTree(arg))
- case from.SingletonTypeTree(ref) =>
- new SingletonTypeTree(importTree(ref))
- case from.SelectFromTypeTree(qual, name) =>
- new SelectFromTypeTree(importTree(qual), importName(name).toTypeName)
- case from.CompoundTypeTree(templ) =>
- new CompoundTypeTree(importTemplate(templ))
- case from.AppliedTypeTree(tpt, args) =>
- new AppliedTypeTree(importTree(tpt), args map importTree)
- case from.TypeBoundsTree(lo, hi) =>
- new TypeBoundsTree(importTree(lo), importTree(hi))
- case from.ExistentialTypeTree(tpt, whereClauses) =>
- new ExistentialTypeTree(importTree(tpt), whereClauses map importTree)
- case from.EmptyTree =>
- EmptyTree
- case null =>
- null
- }
- addFixup({
- if (mytree != null) {
- val mysym = if (tree.hasSymbolField) importSymbol(tree.symbol) else NoSymbol
- val mytpe = importType(tree.tpe)
-
- mytree match {
- case mytt: TypeTree =>
- val tt = tree.asInstanceOf[from.TypeTree]
- if (mytree.hasSymbolField) mytt.symbol = mysym
- if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe)
- if (tt.original != null) mytt.setOriginal(importTree(tt.original))
- case _ =>
- if (mytree.hasSymbolField) mytree.symbol = importSymbol(tree.symbol)
- mytree setType importType(tree.tpe)
- }
- }
- })
- tryFixup()
- mytree
- }
-
def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef]
def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef]
def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template]
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index a20307882d..81fffc833c 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -8,6 +8,7 @@ package reflect
package internal
import java.security.MessageDigest
+import java.util.UUID.randomUUID
import Chars.isOperatorPart
import scala.annotation.switch
import scala.language.implicitConversions
@@ -290,6 +291,9 @@ trait StdNames {
val FAKE_LOCAL_THIS: NameType = "this$"
val LAZY_LOCAL: NameType = "$lzy"
val LAZY_SLOW_SUFFIX: NameType = "$lzycompute"
+ val MACRO_INVOKER_PACKAGE: NameType = "scala.reflect.macros.synthetic"
+ // TODO: if I use dollars in MACRO_INVOKER_SUFFIX, as in "$Invoker$", then Scala reflection fails to load implementations
+ val MACRO_INVOKER_SUFFIX: NameType = "Invoker"
val UNIVERSE_BUILD_PREFIX: NameType = "$u.build."
val UNIVERSE_PREFIX: NameType = "$u."
val UNIVERSE_SHORT: NameType = "$u"
@@ -584,6 +588,7 @@ trait StdNames {
val box: NameType = "box"
val build : NameType = "build"
val bytes: NameType = "bytes"
+ val c: NameType = "c"
val canEqual_ : NameType = "canEqual"
val checkInitialized: NameType = "checkInitialized"
val classOf: NameType = "classOf"
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index e9ef9c7945..d1e8a04553 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -836,8 +836,17 @@ abstract class TreeInfo {
}
def unapply(tree: Tree) = refPart(tree) match {
- case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, dissectApplied(tree).targs))
- case _ => None
+ case ref: RefTree => {
+ val isBundle = definitions.isMacroBundleType(ref.qualifier.tpe)
+ val owner =
+ if (isBundle) ref.qualifier.tpe.typeSymbol
+ else {
+ val sym = ref.qualifier.symbol
+ if (sym.isModule) sym.moduleClass else sym
+ }
+ Some((isBundle, owner, ref.symbol, dissectApplied(tree).targs))
+ }
+ case _ => None
}
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 833adb99c7..8781423a6d 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -253,6 +253,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
def name: Name
}
+ object RefTree extends RefTreeExtractor {
+ def apply(qualifier: Tree, name: Name): RefTree = qualifier match {
+ case EmptyTree =>
+ Ident(name)
+ case qual if qual.isTerm =>
+ Select(qual, name)
+ case qual if qual.isType =>
+ assert(name.isTypeName, s"qual = $qual, name = $name")
+ SelectFromTypeTree(qual, name.toTypeName)
+ }
+ def unapply(refTree: RefTree): Option[(Tree, Name)] = Some((refTree.qualifier, refTree.name))
+ }
+
abstract class DefTree extends SymTree with NameTree with DefTreeApi {
def name: Name
override def isDef = true
diff --git a/src/reflect/scala/reflect/macros/Macro.scala b/src/reflect/scala/reflect/macros/Macro.scala
new file mode 100644
index 0000000000..44bedf483d
--- /dev/null
+++ b/src/reflect/scala/reflect/macros/Macro.scala
@@ -0,0 +1,39 @@
+package scala.reflect
+package macros
+
+/**
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ *
+ * Traditionally macro implementations are defined as methods,
+ * but this trait provides an alternative way of encoding macro impls as
+ * bundles, traits which extend `scala.reflect.macros.Macro`.
+ *
+ * Instead of:
+ *
+ * def impl[T: c.WeakTypeTag](c: Context)(x: c.Expr[Int]) = ...
+ *
+ * One can write:
+ *
+ * trait Impl extends Macro {
+ * def apply[T: c.WeakTypeTag](x: c.Expr[Int]) = ...
+ * }
+ *
+ * Without changing anything else at all.
+ *
+ * This language feature is useful in itself in cases when macro implementations
+ * are complex and need to be modularized. State of the art technique of addressing this need is quite heavyweight:
+ * http://docs.scala-lang.org/overviews/macros/overview.html#writing_bigger_macros.
+ *
+ * However utility of this approach to writing macros isn't limited to just convenience.
+ * When a macro implementation becomes not just a function, but a full-fledged module,
+ * it can define callbacks that will be called by the compiler upon interesting events.
+ * In subsequent commits I will add support for programmable type inference
+ */
+trait Macro {
+ /** The context to be used by the macro implementation.
+ *
+ * Vanilla macro implementations have to carry it in their signatures, however when a macro is a full-fledged module,
+ * it can define the context next to the implementation, makes implementation signature more lightweight.
+ */
+ val c: Context
+}
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index adee155db0..a3684f602f 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -972,8 +972,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
javaTypeToValueClass(jclazz) orElse lookupClass
assert (cls.isType,
- sm"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"}
- | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""")
+ (if (cls != NoSymbol) s"not a type: symbol $cls" else "no symbol could be") +
+ s" loaded from $jclazz in $owner with name $simpleName and classloader $classLoader")
cls.asClass
}
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index 0354b424d2..41c1310e17 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -21,7 +21,7 @@ package object runtime {
*/
// implementation hardwired to the `currentMirror` method below
// using the mechanism implemented in `scala.tools.reflect.FastTrack`
- def currentMirror: universe.Mirror = ??? // macro
+ def currentMirror: universe.Mirror = macro ???
}
package runtime {