diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-04-14 21:11:37 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-04-14 21:11:37 +0200 |
commit | 5e4c47f33b8e25feb59ab4599231b1b8d3150de8 (patch) | |
tree | ff2ded10d14c5a6e859ac216e60244029a17a505 /src/compiler/scala/reflect/reify/codegen/AnnotationInfos.scala | |
parent | 3a2901da406f2478b5634b0636e56de9c4cd676d (diff) | |
download | scala-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.scala | 56 |
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 |