summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-04-14 21:11:37 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-04-14 21:11:37 +0200
commit5e4c47f33b8e25feb59ab4599231b1b8d3150de8 (patch)
treeff2ded10d14c5a6e859ac216e60244029a17a505 /src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
parent3a2901da406f2478b5634b0636e56de9c4cd676d (diff)
downloadscala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.tar.gz
scala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.tar.bz2
scala-5e4c47f33b8e25feb59ab4599231b1b8d3150de8.zip
implements reification of tough types
Diffstat (limited to 'src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala')
-rw-r--r--src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
new file mode 100644
index 0000000000..1d218317dc
--- /dev/null
+++ b/src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala
@@ -0,0 +1,56 @@
+package scala.reflect.reify
+package codegen
+
+trait AnnotationInfos {
+ self: Reifier =>
+
+ import mirror._
+ import definitions._
+ import treeInfo._
+
+ // usually annotations are reified as their originals from Modifiers
+ // however, when reifying free and tough types, we're forced to reify annotation infos as is
+ // why is that bad? take a look inside
+ def reifyAnnotationInfo(ann: AnnotationInfo): Tree = {
+ val reifiedArgs = ann.args map { arg =>
+ val saved1 = reifyTreeSymbols
+ val saved2 = reifyTreeTypes
+
+ try {
+ // one more quirk of reifying annotations
+ //
+ // when reifying AnnotatedTypes we need to reify all the types and symbols of inner ASTs
+ // that's because a lot of logic expects post-typer trees to have non-null tpes
+ //
+ // Q: reified trees are pre-typer, so there's shouldn't be a problem.
+ // reflective typechecker will fill in missing symbols and types, right?
+ // A: actually, no. annotation ASTs live inside AnnotatedTypes,
+ // and insides of the types is the place where typechecker doesn't look.
+ reifyTreeSymbols = true
+ reifyTreeTypes = true
+
+ // todo. every AnnotationInfo is an island, entire of itself
+ // no regular Traverser or Transformer can reach it
+ // hence we need to run its contents through the entire reification pipeline
+ // e.g. to apply reshaping or to check metalevels
+ reify(arg)
+ } finally {
+ reifyTreeSymbols = saved1
+ reifyTreeTypes = saved2
+ }
+ }
+
+ def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match {
+ case LiteralAnnotArg(const) =>
+ mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const))
+ case ArrayAnnotArg(args) =>
+ mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*))
+ case NestedAnnotArg(ann) =>
+ mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann))
+ }
+
+ // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
+ val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2)))
+ mirrorFactoryCall(nme.AnnotationInfo, reify(ann.atp), mkList(reifiedArgs), mkList(reifiedAssocs))
+ }
+} \ No newline at end of file