summaryrefslogtreecommitdiff
path: root/test/files/run/macro-bundle-whitebox-use-refined
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-02-21 21:40:12 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-02-21 22:38:28 +0100
commitfb0c25c7fd004ee5de1a910bdcccc4fd503da3ce (patch)
treea30cdf647eaa282644c7f0b50e1e06d5205e78f6 /test/files/run/macro-bundle-whitebox-use-refined
parent64edb44fc6a4db0ba3ecee0555212d8112a17f1a (diff)
downloadscala-fb0c25c7fd004ee5de1a910bdcccc4fd503da3ce.tar.gz
scala-fb0c25c7fd004ee5de1a910bdcccc4fd503da3ce.tar.bz2
scala-fb0c25c7fd004ee5de1a910bdcccc4fd503da3ce.zip
more tests for macro bundles
Given the recent glaring oversight in macro bundles, I have to have more tests in order to make sure that things are going to work as they should.
Diffstat (limited to 'test/files/run/macro-bundle-whitebox-use-refined')
-rw-r--r--test/files/run/macro-bundle-whitebox-use-refined/Macros_1.scala108
-rw-r--r--test/files/run/macro-bundle-whitebox-use-refined/Test_2.scala19
2 files changed, 127 insertions, 0 deletions
diff --git a/test/files/run/macro-bundle-whitebox-use-refined/Macros_1.scala b/test/files/run/macro-bundle-whitebox-use-refined/Macros_1.scala
new file mode 100644
index 0000000000..de1863418e
--- /dev/null
+++ b/test/files/run/macro-bundle-whitebox-use-refined/Macros_1.scala
@@ -0,0 +1,108 @@
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+// whitebox use case #1: return type refinement
+
+class ReturnTypeRefinementBundle(val c: Context) {
+ import c.universe._
+ def impl = {
+ q"""
+ trait Foo {
+ def x = 2
+ }
+ new Foo {}
+ """
+ }
+}
+
+object ReturnTypeRefinement {
+ def foo: Any = macro ReturnTypeRefinementBundle.impl
+}
+
+// whitebox use case #2: fundep materialization
+
+trait FundepMaterialization[T, U] {
+ def to(t : T) : U
+ // def from(u : U) : T
+}
+
+class FundepMaterializationBundle(val c: Context) {
+ import c.universe._
+ import definitions._
+ import Flag._
+
+ def impl[T: c.WeakTypeTag, U: c.WeakTypeTag]: c.Expr[FundepMaterialization[T, U]] = {
+ val sym = c.weakTypeOf[T].typeSymbol
+ if (!sym.isClass || !sym.asClass.isCaseClass) c.abort(c.enclosingPosition, s"$sym is not a case class")
+ val fields = sym.info.decls.toList.collect{ case x: TermSymbol if x.isVal && x.isCaseAccessor => x }
+
+ def mkTpt() = {
+ val core = Ident(TupleClass(fields.length) orElse UnitClass)
+ if (fields.length == 0) core
+ else AppliedTypeTree(core, fields map (f => TypeTree(f.info)))
+ }
+
+ def mkFrom() = {
+ if (fields.length == 0) Literal(Constant(Unit))
+ else Apply(Ident(newTermName("Tuple" + fields.length)), fields map (f => Select(Ident(newTermName("f")), newTermName(f.name.toString.trim))))
+ }
+
+ val evidenceClass = ClassDef(Modifiers(FINAL), newTypeName("$anon"), List(), Template(
+ List(AppliedTypeTree(Ident(newTypeName("FundepMaterialization")), List(Ident(sym), mkTpt()))),
+ emptyValDef,
+ List(
+ DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(typeNames.EMPTY), typeNames.EMPTY), termNames.CONSTRUCTOR), List())), Literal(Constant(())))),
+ DefDef(Modifiers(), newTermName("to"), List(), List(List(ValDef(Modifiers(PARAM), newTermName("f"), Ident(sym), EmptyTree))), TypeTree(), mkFrom()))))
+ c.Expr[FundepMaterialization[T, U]](Block(List(evidenceClass), Apply(Select(New(Ident(newTypeName("$anon"))), termNames.CONSTRUCTOR), List())))
+ }
+}
+
+object FundepMaterialization {
+ implicit def materializeIso[T, U]: FundepMaterialization[T, U] = macro FundepMaterializationBundle.impl[T, U]
+}
+
+// whitebox use case #3: dynamic materialization
+
+trait DynamicMaterialization[T]
+
+class C1(val x: Int)
+class C2(val x: String)
+
+trait LowPriority {
+ implicit def lessSpecific[T]: DynamicMaterialization[T] = null
+}
+
+object DynamicMaterialization extends LowPriority {
+ implicit def moreSpecific[T]: DynamicMaterialization[T] = macro DynamicMaterializationBundle.impl[T]
+}
+
+class DynamicMaterializationBundle(val c: Context) {
+ import c.universe._
+ def impl[T: c.WeakTypeTag] = {
+ val tpe = weakTypeOf[T]
+ if (tpe.members.exists(_.info =:= typeOf[Int]))
+ c.abort(c.enclosingPosition, "I don't like classes that contain integers")
+ q"new DynamicMaterialization[$tpe]{ override def toString = ${tpe.toString} }"
+ }
+}
+
+// whitebox use case #4: extractor macros
+
+object ExtractorMacro {
+ def unapply(x: Int): Any = macro ExtractorBundle.unapplyImpl
+}
+
+class ExtractorBundle(val c: Context) {
+ import c.universe._
+ def unapplyImpl(x: Tree) = {
+ q"""
+ new {
+ class Match(x: Int) {
+ def isEmpty = false
+ def get = x
+ }
+ def unapply(x: Int) = new Match(x)
+ }.unapply($x)
+ """
+ }
+}
diff --git a/test/files/run/macro-bundle-whitebox-use-refined/Test_2.scala b/test/files/run/macro-bundle-whitebox-use-refined/Test_2.scala
new file mode 100644
index 0000000000..3a81700251
--- /dev/null
+++ b/test/files/run/macro-bundle-whitebox-use-refined/Test_2.scala
@@ -0,0 +1,19 @@
+object Test extends App {
+ println(ReturnTypeRefinement.foo.x)
+
+ case class Foo(i: Int, s: String, b: Boolean)
+ def foo[C, L](c: C)(implicit iso: FundepMaterialization[C, L]): L = iso.to(c)
+ locally {
+ val equiv = foo(Foo(23, "foo", true))
+ def typed[T](t: => T) {}
+ typed[(Int, String, Boolean)](equiv)
+ println(equiv)
+ }
+
+ println(implicitly[DynamicMaterialization[C1]])
+ println(implicitly[DynamicMaterialization[C2]])
+
+ 42 match {
+ case ExtractorMacro(x) => println(x)
+ }
+}