what I need is simple but I’m not sure it’s even possible:
I have a couple of classes that extend a common class:
CommonClass {
}
ClassExtendingCommonClass extends CommonClass {
// some public fields here
public var id:Int;
public var name:String;
// ...
}
And I need to loop through all those classes that extends my “common class” in order to create a custom method for each one of them inside a “factory class” like so:
CommonClassFactory {
public function classExtendingCommonClass(id:Int, name:String):ClassExtendingCommonClass
{
var c:ClassExtendingCommonClass = new ClassExtendingCommonClass ();
c.id = id;
c.name = name;
return c;
}
}
Is this even possible ? How would you go about that ?
Basically I want a factory class that will auto populate itself based on all the classes that extend my CommonClass that exist.
As for as I know, the only way is to parse the files by myself as the callbacks at macro time that I can use to get a list of all the types won’t allow me to modify another type after the callback has been called.
Maybe the only way is to create a new type instead of modifying an existing one after the onAfterTyping callback ?
You want an interface that applies a build macro on the base class. The build macro will get run on the base class AND the extending classes. This will allow you to add a field to the extending classes:
thanks for your answer. I already have that part figured out.
I realize I wasn’t very clear. My main question actually is:
Inside a macro, how do I access all the types that extend a certain type (or that contain certain metadata, or anything that allows me to identify the types I want to target) and modify the current type/class the macro is running on with the information of the targeted types ?
Let’s say for example, I want to fill an array in a specific class/type with all the types I’m targeting using a macro. How would I go about that ?
The onAfterTyping callback seems to be the only thing I can use to get a list of all the types but it doesn’t allow me to modify a class. At the moment I feel the only solution is to create a new class/type in the onAfterTyping callback… just like back2dos is explaining here: Google Groups
I just hope there is a less hackish way of doing this.
Maybe you’ll find some useful pattern in @jasononeil’s CompileTime or @back2dos’s ctl – both are using Context.onGenerate to look over type information.
Another approach that will collect the classes at static init runtime: use your build macro to define a static var, who’s init function will push the class into the list, like so:
class MyClassName implements IBuildMacro
{
/* generate this field with the macro */
private static var __inserted:Bool = function() {
SomeHelperClass.my_class_list.push(MyClassName);
return true;
}();
}
class SomeHelperClass {
public static var my_class_list:Array<Class<IBuildMacro>> = [];
}
class Main {
public static function main() {
// my_class_list should be populated by the time I execute...
}
}
I think I understand better how it all works. It seems to me that the only way I can have a list of all the types is on the onAfterTyping callback. This is what CompileTime and ctl are doing. I understand why we can’t modify a type after that callback as it would mean to redo the entire typing thing.
Well, they could have allowed it, from another callback for example, but it seems a bit too much for just a small change.
I’ll have to go with the back2dos answer here: Google Groups
But when I think about it, replacing an existing type would also mean to recheck all its dependencies, etc…
Anyways, I don’t like it but I’ll go with it.