一部のコードを Scala 2.10-M5から Scala 2.10-M7に移行しています。マクロ コンテキストの Type API が大幅に削減されていることがわかりました。特に、基になる定義と typeArgs 定義を取得する方法を考えています。
--
更新しました
@EugeneBurmako のリクエストに応じて、全体像を表示します。次の状態があるとします。
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 */
いくつかの属性をホストするエンティティがあります。エンティティ コンパニオン オブジェクトには、これらの属性に関するメタ情報 (具体化) が含まれています。Letファミリでは、(新しいコピーを作成することによって) エンティティを更新できます。
ここまでは順調ですね。Let メソッドは次のように使用できます。
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)
具体化属性は冗長であるため、ユーザーにはよりシンプルな API を使用してもらいたいと考えています。特に、次のもの:
// Same code as DSL
ent.att1 := List(1, 2, 3)
ent.att1 :+ 4
ent.att1 :- 1
具体化に関する情報はどこにもないことに注意してください。したがって、目標を達成するには、いくつかのヘルパーとマクロ ビューが必要です。
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.
*/
私たちのマクロ定義は、実際にはビューであり、DSL 式を許可する魔法を行います。
implicit def toAttributeHelper[V](expr: V): AttributeHelper = macro toAttributeHelperImpl[V]
2 つの型パラメーターを使用するマクロを実行しようとしましたが、その間、暗黙的なビューは適用されません (コンパイラーは両方の型を推測できないため)。
そのため、最初に述べたように、M5 では利用可能でしたが M7 では利用できなかったtypeArgsの欠如が、以前のマクロを壊してしまいました。その定義を持たずに AttributeHelper 構造を生成するにはどうすればよいですか?
最後に、前のコードは簡略化したものに過ぎないと言わなければなりません。他にも関連する証拠がいくつかあります。そのため、基礎となるを使用する必要があります。