2017-07-10 1 views
4

Je voudrais pouvoir obtenir la classe d'un objet pour pouvoir accéder à la variable statique de cette classe.Récupère le type d'un objet dans haxe macro ou fonction (compile-time)

// autoBuild macro adds static field "id_ : Int" to all subclasses 
class Base { 

} 

class Child1 extends Base { 
    public function new() {} 
} 

class Child2 extends Base { 
    public function new() {} 
} 

class Container { 
    public function addChild(index: Int, object: Base) {} 

    macro function add(object: ???) { 
    // find out class of on object 
    // ??? 
    // var id = class.id_; 
    this.addChild(id, object); 
    } 
} 

// Use it like this: 
var c = new Container(); 
c.add(new Child1()); 
c.add(new Child2()); 

Remarque, je souhaite résoudre la classe d'un objet à la compilation.

Répondre

3

Vous pouvez utiliser Context.typeof() pour obtenir le type de l'expression - alors vous devez faire un peu de correspondance de modèle pour trouver le nom du type. Ce qui suit ne fonctionne qu'avec des classes, car il correspond seulement TInst, mais pourrait être étendue:

import haxe.macro.Context; 
import haxe.macro.Expr; 

class Container { 
    // [...] 

    public macro function add(self:Expr, object:Expr):Expr { 
     var name = switch (Context.typeof(object)) { 
      case TInst(_.get() => t, _): t.name; 
      case _: throw "object type not found"; 
     } 
     return macro $self.addChild($i{name}.id_, $object); 
    } 
} 

Cela va générer le code suivant:

var c = new Container(); 
c.addChild(Child1.id_, new Child1()); 
c.addChild(Child2.id_, new Child2()); 

Notez que l'accès _id via son nom non qualifié est sûr que si En réalité, vous devez utiliser t.pack en combinaison avec $p{} pour générer le chemin qualifié complet.

+0

Merci beaucoup - cela fonctionne comme vous le souhaitez! – montonero