diff options
Diffstat (limited to 'src/compiler/scala/reflect/makro/runtime/Reifiers.scala')
-rw-r--r-- | src/compiler/scala/reflect/makro/runtime/Reifiers.scala | 123 |
1 files changed, 11 insertions, 112 deletions
diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala index d9a89d0e6d..1c5af4b752 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Reifiers.scala @@ -12,124 +12,23 @@ trait Reifiers { import mirror._ import definitions._ - private lazy val ClassTagModule = ClassTagClass.companionSymbol + lazy val reflectMirrorPrefix: Tree = ReflectMirrorPrefix - // [Eugene] imho this logic should be moved into `erasure` - private def calculateTagErasure(tpe: Type) = tpe match { - case tpe if tpe.typeSymbol.isDerivedValueClass => tpe // [Eugene to Martin] is this correct? - case ConstantType(value) => tpe.widen.erasure - case _ => - // [Eugene] magikz. needs review - // necessary to deal with erasures of HK types, typeConstructor won't work - tpe.erasure.normalize match { - // we don't want undets in the result - case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) - case result => result - } - } - private def classTagFromArgument(tpe: Type, arg: Tree) = { - gen.mkMethodCall(ClassTagModule, nme.apply, List(tpe), List(arg)) - // val factory = TypeApply(Select(Ident(ClassTagModule), nme.apply), List(TypeTree(tpe))) - // Apply(factory, List(typeArg)) - } - private def classTagFromErasure(tpe: Type) = { - val erasure = calculateTagErasure(tpe) - classTagFromArgument(tpe, gen.mkNullaryCall(Predef_classOf, List(erasure))) - // val targ = TypeApply(Select(Ident(PredefModule), nme.classOf), List(TypeTree(erasure))) - // classTagFromArgument(tpe, targ) - } - private def typetagIsSynthetic(tree: Tree) = tree match { - case Block(_, _) => true - case _ => tree exists (_ hasSymbolWhich Set(TypeTagModule, ConcreteTypeTagModule)) + def reifyTree(prefix: Tree, tree: Tree): Tree = { + val result = scala.reflect.reify.`package`.reifyTree(mirror)(callsiteTyper, prefix, tree) + logFreeVars(enclosingPosition, result) + result } - lazy val reflectMirrorPrefix: Tree = { - // [Eugene] how do I typecheck this without undergoing this tiresome (and, in general, incorrect) procedure? - val prefix: Tree = Select(Select(Ident(definitions.ScalaPackage), newTermName("reflect")), newTermName("mirror")) - val prefixTpe = typeCheck(TypeApply(Select(prefix, newTermName("asInstanceOf")), List(SingletonTypeTree(prefix)))).tpe - typeCheck(prefix) setType prefixTpe + def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, concrete: Boolean = false): Tree = { + val result = scala.reflect.reify.`package`.reifyType(mirror)(callsiteTyper, prefix, tpe, dontSpliceAtTopLevel, concrete) + logFreeVars(enclosingPosition, result) + result } - def reifyTree(prefix: Tree, tree: Tree): Tree = - reifyTopLevel(prefix, tree) - - def reifyType(prefix: Tree, tpe: Type, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = - reifyTopLevel(prefix, tpe, dontSpliceAtTopLevel, requireConcreteTypeTag) - - def reifyErasure(tpe: Type): Tree = { - val positionBearer = (enclosingMacros.find(_.macroApplication.pos != NoPosition) match { - case None => EmptyTree - case Some(m) => m.macroApplication - }).asInstanceOf[Tree] - - val typetagInScope = callsiteTyper.context.withMacrosDisabled( - callsiteTyper.resolveTypeTag( - positionBearer, - singleType(Reflect_mirror.owner.thisPrefix, Reflect_mirror), - tpe, - full = true - ) - ) - typetagInScope match { - case success if !success.isEmpty && !typetagIsSynthetic(success) => - classTagFromArgument(tpe, typetagInScope) - case _ => - if (tpe.typeSymbol == ArrayClass) { - val componentTpe = tpe.typeArguments(0) - val componentTag = callsiteTyper.resolveClassTag(positionBearer, componentTpe) - Select(componentTag, nme.wrap) - } - // [Eugene] what's the intended behavior? there's no spec on ClassManifests - // for example, should we ban Array[T] or should we tag them with Array[AnyRef]? - // if its the latter, what should be the result of tagging Array[T] where T <: Int? - else if (tpe.isSpliceable) { - throw new ReificationError(enclosingPosition, - "tpe %s is an unresolved spliceable type".format(tpe)) - } - else classTagFromErasure(tpe) - } - } + def reifyErasure(tpe: Type, concrete: Boolean = true): Tree = + scala.reflect.reify.`package`.reifyErasure(mirror)(callsiteTyper, tpe, concrete) def unreifyTree(tree: Tree): Tree = Select(tree, definitions.ExprEval) - - def reifyTopLevel(prefix: Tree, reifee: Any, dontSpliceAtTopLevel: Boolean = false, requireConcreteTypeTag: Boolean = false): Tree = { - // [Eugene] the plumbing is not very pretty, but anyways factoring out the reifier seems like a necessary step to me - import scala.reflect.reify._ - val reifier = mkReifier(mirror)(callsiteTyper, prefix, reifee, dontSpliceAtTopLevel, requireConcreteTypeTag) - - try { - val result = reifier.reified - logFreeVars(enclosingPosition, result) - result - } catch { - case ex: reifier.ReificationError => -// // this is a "soft" exception - it will normally be caught by the macro -// // consequently, we need to log the stack trace here, so that it doesn't get lost -// if (settings.Yreifydebug.value) { -// val message = new java.io.StringWriter() -// ex.printStackTrace(new java.io.PrintWriter(message)) -// println(scala.compat.Platform.EOL + message) -// } - val xlated = new ReificationError(ex.pos, ex.msg) - xlated.setStackTrace(ex.getStackTrace) - throw xlated - case ex: reifier.UnexpectedReificationError => - val xlated = new UnexpectedReificationError(ex.pos, ex.msg, ex.cause) - xlated.setStackTrace(ex.getStackTrace) - throw xlated - } - } - - class ReificationError(var pos: Position, val msg: String) extends Throwable(msg) - - object ReificationError extends ReificationErrorExtractor { - def unapply(error: ReificationError): Option[(Position, String)] = Some((error.pos, error.msg)) - } - - class UnexpectedReificationError(val pos: Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause) - - object UnexpectedReificationError extends UnexpectedReificationErrorExtractor { - def unapply(error: UnexpectedReificationError): Option[(Position, String, Throwable)] = Some((error.pos, error.msg, error.cause)) - } } |