diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2012-02-12 23:07:30 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2012-02-12 23:07:33 +0100 |
commit | 6548dcf12d83e327df2f90048140fb95346b7e95 (patch) | |
tree | e20b3b6ce697af665983c3cc510d763a926650c6 /test/files/neg | |
parent | 6b56405cb39b979dccbadd06110e283a254b6150 (diff) | |
download | scala-6548dcf12d83e327df2f90048140fb95346b7e95.tar.gz scala-6548dcf12d83e327df2f90048140fb95346b7e95.tar.bz2 scala-6548dcf12d83e327df2f90048140fb95346b7e95.zip |
reifyAnnotations
Annotations are now supported by the reifier:
* AnnotationInfos from symbols get transformed back into mods.
* AnnotatedTypes are retained and are reified along with AnnotationInfos.
Reification is no magic, and reification of annotations especially:
* Annotations cannot refer to symbols defined inside the quasiquote.
This restriction is due to the fact that we need to erase locally defined
symbols before reifying to make subsequent reflective compilations succeed.
However, while doing that, we also need to make sure that we don't make
resulting ASTs non-compilable by removing essential information.
This is tricky, and it more or less works for TypeTrees, but
not for annotations that can contain arbitrary ASTs.
For more details look into the comments to Reifiers.scala.
* Classfile annotations that contain array arguments and are applied to types,
i.e. the ones that generate AnnotatedTypes, cannot be reified.
This is because of limitations of manifest infrastructure.
Typechecking "Array(mirror.LiteralAnnotArg(...))" would require the compiler
to produce a manifest for a path-dependent type, which cannot be done now.
Review by @odersky.
Diffstat (limited to 'test/files/neg')
-rw-r--r-- | test/files/neg/reify_ann2a.check | 4 | ||||
-rw-r--r-- | test/files/neg/reify_ann2a.scala | 30 | ||||
-rw-r--r-- | test/files/neg/reify_ann2b.check | 7 | ||||
-rw-r--r-- | test/files/neg/reify_ann2b.scala | 30 |
4 files changed, 71 insertions, 0 deletions
diff --git a/test/files/neg/reify_ann2a.check b/test/files/neg/reify_ann2a.check new file mode 100644 index 0000000000..2afe37e1d8 --- /dev/null +++ b/test/files/neg/reify_ann2a.check @@ -0,0 +1,4 @@ +reify_ann2a.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(immutable.this.List.apply[String]("1a")) which involves a symbol declared inside the block being reified + val tree = scala.reflect.Code.lift{ + ^ +one error found diff --git a/test/files/neg/reify_ann2a.scala b/test/files/neg/reify_ann2a.scala new file mode 100644 index 0000000000..071919eb76 --- /dev/null +++ b/test/files/neg/reify_ann2a.scala @@ -0,0 +1,30 @@ +import scala.reflect._ +import scala.reflect.api._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + // test 1: reify + val tree = scala.reflect.Code.lift{ + class ann(bar: List[String]) extends StaticAnnotation + + @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { + @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { + @ann(bar=List("7a")) @ann(bar=List("7b")) val r = (x + 3): @ann(bar=List("8a")) @ann(bar=List("8b")) + val s = 4: Int @ann(bar=List("9a")) @ann(bar=List("9b")) + r + s + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(ttree) +}
\ No newline at end of file diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check new file mode 100644 index 0000000000..ceb70689f1 --- /dev/null +++ b/test/files/neg/reify_ann2b.check @@ -0,0 +1,7 @@ +reify_ann2b.scala:10: error: inner classes cannot be classfile annotations + class ann(bar: String) extends ClassfileAnnotation + ^ +reify_ann2b.scala:9: error: exception during macro expansion: implementation restriction: cannot reify annotation @ann(bar = "1a") which involves a symbol declared inside the block being reified + val tree = scala.reflect.Code.lift{ + ^ +two errors found diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala new file mode 100644 index 0000000000..74273ad6ec --- /dev/null +++ b/test/files/neg/reify_ann2b.scala @@ -0,0 +1,30 @@ +import scala.reflect._ +import scala.reflect.api._ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + // test 1: reify + val tree = scala.reflect.Code.lift{ + class ann(bar: String) extends ClassfileAnnotation + + @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { + @ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = { + @ann(bar="7a") @ann(bar="7b") val r = (x + 3): @ann(bar="8a") @ann(bar="8b") + val s = 4: Int @ann(bar="9a") @ann(bar="9b") + r + s + } + } + }.tree + println(tree.toString) + + // test 2: import and typecheck + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(tree) + println(ttree.toString) + + // test 3: import and compile + toolbox.runExpr(ttree) +}
\ No newline at end of file |