diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-04-30 21:14:06 +0200 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-07-02 14:22:00 +0200 |
commit | 0c5dd9e02f03143372237018c55e12a07c13f8c1 (patch) | |
tree | e1295c82ff27e3191c17f090b135903103b05f2a /test/files/run/t5923c/Macros_1.scala | |
parent | 300db2a1e3eefc2a6ed379c870bc7da42a26e69a (diff) | |
download | scala-0c5dd9e02f03143372237018c55e12a07c13f8c1.tar.gz scala-0c5dd9e02f03143372237018c55e12a07c13f8c1.tar.bz2 scala-0c5dd9e02f03143372237018c55e12a07c13f8c1.zip |
[backport] SI-7470 implements fundep materialization
Backports 21a8c6c from the 2.11.x branch under -Xfundep-materialization
as per Miles Sabin's request. Thanks Miles!
Diffstat (limited to 'test/files/run/t5923c/Macros_1.scala')
-rw-r--r-- | test/files/run/t5923c/Macros_1.scala | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/files/run/t5923c/Macros_1.scala b/test/files/run/t5923c/Macros_1.scala new file mode 100644 index 0000000000..0b7a3399e2 --- /dev/null +++ b/test/files/run/t5923c/Macros_1.scala @@ -0,0 +1,39 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +trait Iso[T, U] { + def to(t : T) : U + // def from(u : U) : T +} + +object Iso { + implicit def materializeIso[T, U]: Iso[T, U] = macro impl[T, U] + def impl[T: c.WeakTypeTag, U: c.WeakTypeTag](c: Context): c.Expr[Iso[T, U]] = { + import c.universe._ + import definitions._ + import Flag._ + + 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.typeSignature.declarations.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.typeSignature))) + } + + 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("Iso")), List(Ident(sym), mkTpt()))), + emptyValDef, + List( + DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))), + DefDef(Modifiers(), newTermName("to"), List(), List(List(ValDef(Modifiers(PARAM), newTermName("f"), Ident(sym), EmptyTree))), TypeTree(), mkFrom())))) + c.Expr[Iso[T, U]](Block(List(evidenceClass), Apply(Select(New(Ident(newTypeName("$anon"))), nme.CONSTRUCTOR), List()))) + } +} |