Context.getBuildFields() not getting inherited fields

81 views
Skip to first unread message

Leonid Darovskikh

unread,
Feb 26, 2017, 5:16:51 PM2/26/17
to Haxe
Is this expected behaviour? 
What I'm trying to do is to generate constructors for subclasses(HpGroup) of a certain class(Group). To do that I need to add all fields to params of the constructor, but for some reason the inherited fields don't show up in the results of Context.getBuildFields(). Sure, right now I have only one property, that I can add manually, but what if I change Group?
Here's my code:
Group:
@:autoBuild(Macro.buildGroup())
class Group{
 
public var owner: Entity;

 
public function new(owner: Entity){
 
 this.owner=owner;
 
}
}

HpGroup:
class HpGroup extends Group{
 
public var hp: IntWrapper;
 
public var maxHp: IntWrapper;
}

Macro.buildGroup():
macro public static function buildGroup(): Array<Field>{
 
var fields: Array<Field>=Context.getBuildFields();

 
//if user has not defined a constructor
 
if(!fields.exists(function(field){return field.name=="new";})){

   
var constrArgs: Array<FunctionArg>=[];
   
var exprs: Array<Expr>=[macro super(owner)]; //add super constructor call

   
//for every field: if its a var, add it to arguments and add an assignment to constructor
   
for(field in fields){

     trace
(field);

     
switch(field.kind){
       
case(FVar(type, _)):
         constrArgs
.push({ //create constructor arg
           name
: field.name,
           type
: type,
           opt
: false
         
});
         
if(field.name!="owner"){ //create assignment
           exprs
.push(macro $p{["this", field.name]}=$i{field.name});
         
}
       
default:
     
}
   
}

   
//add constructor to fields
   fields
.push({
     name
: "new",
     pos
: Context.currentPos(),
     access
: [APublic],
     kind
: FFun({
       args
: constrArgs,
       expr
: macro $b{exprs},
       
params: [],
       ret
: null
     
})
   
});
 
}

 
return fields;
 
}

Juraj Kirchheim

unread,
Feb 27, 2017, 4:20:29 AM2/27/17
to haxe...@googlegroups.com
When a build macro is called on class B which extends class A, then class A has already been fully built and typed (the parsed representation has been converted into a properly type checked one). B on the other hand is in the process of being built and therefore not typed at all. Basically, you can only get the build fields (i.e. Array<haxe.macro.Expr.Field>) on classes that are currently being built. For all other classes, you can get the typed result (i.e. Array<haxe.macro.Type.ClassField>). In this case you would want to call `haxe.macro.Context.getLocalClass().getLocalClass().get().superClass.t.get().fields`. Note though that if you call this while building a class that doesn't have a super class, then `.superClass` will be `null` and accessing `.t` on it will give you an exception.

Best,
Juraj

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

Leonid Darovskikh

unread,
Feb 27, 2017, 6:06:16 AM2/27/17
to Haxe
Thanks!
Reply all
Reply to author
Forward
0 new messages