Skip to content

Instantly share code, notes, and snippets.

@skial
Created August 16, 2016 16:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skial/39c70b2813ac04aa20d22bffb69bf338 to your computer and use it in GitHub Desktop.
Save skial/39c70b2813ac04aa20d22bffb69bf338 to your computer and use it in GitHub Desktop.
Example code for haxe mailing list question Macro question, want to find the "expected identifier" - https://groups.google.com/d/msg/haxelang/N1ysdWAVAEo/0wZZJyI2AwAJ
-cp src
-debug
-main Main
--macro Macro.init()
--each
-js bin/getExpectedIdent.js
// Generated by Haxe 3.3.0 (git build development @ 6163882)
(function () { "use strict";
var Macro = function() { };
var Main = function() {
console.log("myLongIdNameWithYummyFooBars");
console.log("foo");
};
Main.main = function() {
new Main();
};
Main.main();
})();
//# sourceMappingURL=getExpectedIdent.js.map
{
"version":3,
"file":"getExpectedIdent.js",
"sourceRoot":"file:///",
"sources":["C:/dev/macro_getExpectedIdent/src/Main.hx"],
"names":[],
"mappings":";;;WAQQ,WAAe;AAAA,CAErB,YAAO;CAIP,YAAO;;YAVM,WACb;AAAA;;;;;"
}
package ;
import haxe.macro.Type;
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Compiler;
using haxe.macro.ExprTools;
class Macro {
public static macro function init() {
Compiler.addGlobalMetadata('', '@:astSource', true, false, true);
return null;
}
public static macro function getExpectedIdent():ExprOf<String> {
var local:ClassType = switch Context.getLocalClass() {
case _.get() => cls: cls;
case _: throw 'Can not determine the local calling class.';
}
var method = Context.getLocalMethod();
if (method == null) throw 'Can not determine the local calling method.';
var position = Context.getPosInfos(Context.currentPos());
var field:ClassField = if (method == 'new') {
local.constructor.get();
} else {
var result = null;
for (list in [local.fields, local.statics]) for (field in list.get()) if (field.name == method) {
result = field;
break;
}
if (result == null) throw 'Can not find local calling method.';
result;
}
if (!field.meta.has(':astSource')) throw '${field.name} does not have @:astSource.';
var meta:MetadataEntry = field.meta.extract(':astSource')[0];
var exprs = meta.params;
if (exprs.length == 0) throw '${field.name} @:astSource is empty.';
//trace(exprs[0]);
var result = macro null;
function identify(e:Expr):String {
return switch e {
case _.expr => EVars(vars): vars[0].name;
case _.expr => EConst(CIdent(s)): s;
case _: '';
}
}
function find(e:Expr, parent:Expr) {
switch e {
case _.expr => EVars(vars):
for (v in vars) find(v.expr, {expr:EVars([v]), pos:e.pos});
case macro $ident = $expr:
find(expr, ident);
case macro Macro.getExpectedIdent():
var pos = Context.getPosInfos(e.pos);
trace( pos, position);
if (pos.file == position.file && pos.min == position.min && pos.max == position.max) {
trace( parent.toString(), parent );
result = macro $v{identify(parent)};
return;
}
case _:
e.iter( find.bind(_, parent ) );
}
}
trace( field.name );
find( exprs[0], exprs[0] );
return result;
}
}
package ;
class Main {
public static function main() {
new Main();
}
public function new() {
var myLongIdNameWithYummyFooBars:Array<String> = [Macro.getExpectedIdent()];
trace( myLongIdNameWithYummyFooBars[0] );
var foo = 'xx';
foo = Macro.getExpectedIdent();
trace( foo );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment