En utilisant des macros, je souhaite obtenir une solution générale pour faire référence à Symbol
de champs et de sous-champs d'un arbre de données de classe de cas.
Inspiré par ce gist J'ai créé le squelette suivant :
import language.experimental.macros
import reflect.runtime.universe._
import reflect.macros.Context
object SubRef {
case class SubRef[ SourceT, TargetT ]( symbol : Symbol )
implicit def functionToSubRef
[ SourceT, TargetT ]
( f : SourceT => TargetT )
: SubRef[ SourceT, TargetT ]
= macro functionToSubRefMacro[ SourceT, TargetT ]
def functionToSubRefMacro
[ SourceT : c.WeakTypeTag, TargetT : c.WeakTypeTag ]
( c : Context )
( f : c.Expr[ SourceT => TargetT ] )
: c.Expr[ SubRef[ SourceT, TargetT ] ]
= ???
}
Je m'attends à ce que cette solution fonctionne de la manière suivante :
case class A( b : B )
case class B( c : Int )
val ref : SubRef[ A, Int ] = _.b.c
La conversion de la macro doit échouer si la fonction transmise :
- N'est pas une expression unique
- Ne renvoie pas la valeur d'un symbole qui est un sous-champ du symbole source, c'est-à-dire le symbole
targetSymbol.owner[.owner...] == sourceSymbol
Quelle devrait être l'implémentation de la macro manquante ?