I am migrating some code from Scala 2.10-M5 to Scala 2.10-M7. I have found that the Type API in the macro context has been notably reduced. In particular, I am wondering how to get the underlying and typeArgs defs.
—
UPDATED
As requested by @EugeneBurmako, I am going to show the whole picture. Suppose we have this state:
class Attribute[C[_], E]
class Id[E]
trait Entity {
val att1: List[Int]
val att2: Int
}
object Entity {
val att1reif = new Attribute[List, Int]
val att2reif = new Attribute[Id, Int]
}
def Let[T <: Entity, C[_], E](en: T, att: Attribute[C, E], ce: C[E]): T =
/* Updates the whole attribute */
def Let[T <: Entity, C[_], E](en: Entity, att: Attribute[C, E], e: E, mode: Boolean): T =
/* Adds or removes (mode) an item */
where we have an Entity hosting some attributes. The entity companion object contains meta-information (reifications) about those attributes. The Let family allows updating the entities (by creating new copies).
So far, so good. We can use the Let methods as follows:
val ent = new Entity { val att1 = List(); val att2 = 3 }
Let(ent, Entity.att1reif, List(1, 2, 3)) // att1 = List(1, 2, 3)
Let(ent, Entity.att1reif, 4, true) // att1 = List(1, 2, 3, 4)
Let(ent, Entity.att1reif, 1, false) // att1 = List(2, 3, 4)
The reification attribute is redundant, so we’d like our users to have a simpler API. In particular, the next one:
// Same code as DSL
ent.att1 := List(1, 2, 3)
ent.att1 :+ 4
ent.att1 :- 1
Notice that there isn’t information about the reification anywhere. So, we need some Helpers and a macro view to reach our goal.
trait AttributeHelper {
type T <: Entity
type C[_]
type E
val ent: T
val att: Attribute[C, E]
def :=(ce: C[E]): T = Let(ent, att, ce)
def :+(e: E): T = Let(ent, att, e, true)
def :-(e: E): T = Let(ent, att, e, false)
}
def toAttributeHelperImpl[V: c.AbsTypeTag](c: Context)(expr: c.Expr[V]): c.Expr[AttributeHelper] =
/* A looong macro (currently broken), since I can't split V into C[_] and E,
* which are needed to generate the expression that instantiates an *AttributeHelper*.
* The macro is responsible of finding the attribute reification.
*/
Our macro definition is, in fact, a view, and it does the magic to allow the DSL expression:
implicit def toAttributeHelper[V](expr: V): AttributeHelper = macro toAttributeHelperImpl[V]
I have been trying to go on with a macro which uses two type params, but while doing so, the implicit view is not applied (because the compiler can’t infer both types).
So, as I mentioned at the beginning, the lack of typeArgs which was available in M5, but does not in M7, has broken the previous macro. How can I generate the AttributeHelper construction without having that def?
Finally, I must say that the previous code is just a simplification. There are some other involved evidences, that’s why I need to use the underlying.
The general idea behind the reflection API cleanup, which happened somewhen around M5, was to remove extremely specialized methods.
For example,
typeArgsis only applicable toTypeReftypes, so it doesn’t make much sense to keep it in the base typeType. The replacement is a simple pattern match:tpe match { case TypeRef(_, _, args) => arg; case _ => Nil }.underlyingis different, though, since it’s an internal implementation concept that means a lot of things depending on a concrete flavor of the type. If you elaborate on your use case, I might help with finding an alternative forunderlying.