Skip to content

Instantly share code, notes, and snippets.

@hamaluik
Created April 9, 2015 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hamaluik/0fa7cd80b7d315296268 to your computer and use it in GitHub Desktop.
Save hamaluik/0fa7cd80b7d315296268 to your computer and use it in GitHub Desktop.
Showing how to use macros to get a list of all methods with a specific metadata at runtime. Very kludgey, my first attempt, but it works.
package dc;
import dc.DevConsoleInjector;
import haxe.macro.Context;
import haxe.macro.Expr;
typedef ConsoleCommand = {
var className:String;
var methodName:String;
}
class DevConsole
{
public static var commands:Array<ConsoleCommand>;
public function new()
{
throw "DevConsole is a static class only!";
}
public static function printCommands() {
for (command in commands) {
trace("Found command: " + command.className + "." + command.methodName + "()");
}
}
macro public static function build():Array<Field>
{
var fields:Array<Field> = Context.getBuildFields();
var newFields:Array<Field> = new Array<Field>();
var type = ComplexType.TPath({
pack: ["dc"],
params: null,
name: "DevConsoleInjector",
});
for (field in fields) {
var fieldMetas:Metadata = field.meta;
if (fieldMetas != null) {
for (fieldMeta in fieldMetas) {
if (fieldMeta.name == "console") {
//trace("Found console function: " + Context.getLocalClass().get().name + "." + field.name + "()");
var consoleCommand:ConsoleCommand = {
className: Context.getLocalClass().get().name,
methodName: field.name
}
var newField:Field = {
name: consoleCommand.className + "." + consoleCommand.methodName + "___injector",
doc: "A DevConsole injector for " + consoleCommand.methodName + "()",
meta: [],
access: [APublic, AStatic],
kind: FVar(type, macro new dc.DevConsoleInjector($v { consoleCommand } )),
pos: Context.currentPos()
};
newFields.push(newField);
}
}
}
}
return fields.concat(newFields);
}
}
package dc;
import dc.DevConsole.ConsoleCommand;
/**
* ...
* @author Kenton Hamaluik
*/
class DevConsoleInjector {
public function new(cmd:ConsoleCommand) {
if (DevConsole.commands == null) {
DevConsole.commands = new Array<ConsoleCommand>();
}
DevConsole.commands.push(cmd);
}
}
package ;
import dc.DevConsole;
import neko.Lib;
/**
* ...
* @author Kenton Hamaluik
*/
@:build(dc.DevConsole.build())
class Main
{
@console
public static function herp(args) {
Lib.println("herp!");
}
@console
public static function derp(args) {
Lib.println(42);
}
static function main()
{
herp(42);
DevConsole.printCommands();
derp(5);
}
}
herp!
DevConsole.hx:22: Found command: Main.herp()
DevConsole.hx:22: Found command: Main.derp()
42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment