Je suis en train de migrer du code de Scala 2.10-M5 à Scala 2.10-M7 . J'ai constaté que l'API de type dans le contexte de la macro a été considérablement réduite. En particulier, je me demande comment obtenir la fonction sous-jacent y typeArgs défs.
--
MISE À JOUR
Comme demandé par @EugeneBurmako, je vais montrer l'ensemble du tableau. Supposons que nous ayons cet état :
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 */
où nous avons un Entité accueillant certains attributs. L'objet compagnon de l'entité contient des méta-informations (réifications) sur ces attributs. Le site Soit permet de mettre à jour les entités (en créant de nouvelles copies).
Jusqu'à présent, tout va bien. Nous pouvons utiliser les méthodes Let comme suit :
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)
L'attribut de réification est redondant, et nous souhaitons que nos utilisateurs disposent d'une API plus simple. En particulier, la suivante :
// Same code as DSL
ent.att1 := List(1, 2, 3)
ent.att1 :+ 4
ent.att1 :- 1
Remarquez qu'il n'y a aucune information sur la réification. Donc, nous avons besoin de Aides et une vue macro pour atteindre notre objectif.
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.
*/
Notre définition de macro est, en fait, une vue, et elle fait la magie pour permettre l'expression DSL :
implicit def toAttributeHelper[V](expr: V): AttributeHelper = macro toAttributeHelperImpl[V]
J'ai essayé de continuer avec une macro qui utilise deux types de paramètres, mais en le faisant, la vue implicite n'est pas appliquée (parce que le compilateur ne peut pas déduire les deux types).
Donc, comme je l'ai mentionné au début, le manque de typeArgs qui était disponible dans M5, mais ne l'est pas dans M7, a cassé la macro précédente. Comment puis-je générer la construction de l'AttributeHelper sans avoir cette défense ?
Enfin, je dois dire que le code précédent n'est qu'une simplification. Il y a d'autres évidences impliquées, c'est pourquoi j'ai besoin d'utiliser la fonction sous-jacent .