So, I’m not sure if this is a compiler issue or if this is a problem that I have generated for myself.
I have a local assigns
variable which is capturing haxe.macro.Expr
in this array which I later use $a{assigns};
for. This is so that I can capture the necessary expressions within the respective context.
I iterate over each field
within a class marked with the @:build
meta tag, and detect which fields are functions, taking into account that those fields are marked with @sllCapture
meta data.
The code I use for this is as follows:
class Capture
{
public static macro function build():Array<Field>
{
var fields = Context.getBuildFields();
var cls = Context.getLocalClass().get();
var assigns:Array<Expr> = [];
for (field in fields)
{
var isCapture = false;
if (field.meta != null)
{
for (m in field.meta)
{
if (m.name == "sllCapture")
{
isCapture = true;
break;
}
}
}
if (isCapture)
{
switch (field.kind)
{
case FFun(body):
{
var fullName = "";
for (pack in cls.pack)
{
fullName += pack + "_";
}
fullName += cls.name + "_" + field.name;
var argTypesIdentifier = fullName + "_types";
assigns.push(macro { var $argTypesIdentifier : Array<sll.Token.ArgumentType> = []; });
for (arg in body.args)
{
if (arg.type == macro :String)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_STRING); });
}
else if (arg.type == macro :sll.Token.Byte)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_BYTE); });
}
else if (arg.type == macro :sll.Token.Short)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_SHORT); });
}
else if (arg.type == macro :sll.Token.Byte)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_BYTE); });
}
else if (arg.type == macro :Int)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_INT); });
}
else if (arg.type == macro :sll.Token.SByte)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_SBYTE); });
}
else if (arg.type == macro :sll.Token.UShort)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_USHORT); });
}
else if (arg.type == macro :UInt)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_UINT); });
}
else if (arg.type == macro :Float)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_FLOAT); });
}
else if (arg.type == macro :Bool)
{
assigns.push(macro { $i{argTypesIdentifier}.push(sll.Token.ArgumentType.ARG_TYPE_BOOL); });
}
}
assigns.push(macro { sll.Parser.functionTypes.set($v{field.name}, $i{argTypesIdentifier}); });
}
default:
{
// ignore everything not a function
}
}
}
}
// build `initSLL()` function
{
var exprBody = macro {
if (sll.Parser.tokens == null)
sll.Parser.tokens = [];
if (sll.Parser.typeMap == null)
sll.Parser.typeMap = new Map<String, haxe.Constraints.Function>();
if (sll.Parser.interpretedTypes == null)
sll.Parser.interpretedTypes = new Map<String, Any>();
if (sll.Parser.functionTypes == null)
sll.Parser.functionTypes = new Map<String, Array<sll.Token.ArgumentType>>();
$a{assigns};
};
var func:Function = {
expr: exprBody,
args: [],
ret: macro :Void
};
var initField:Field = {
name: "initSLL",
access: [APublic, AStatic],
pos: Context.currentPos(),
kind: FFun(func)
};
fields.push(initField);
}
return fields;
}
}
I’ve been bashing my head against a wall (metaphorically) trying to understand why the Haxe compiler is producing a nonsensical error:
e:\StoryDev\Websites\StoryDev\Sources/sll/Capture.hx:90: characters 75-95 : Unknown identifier : SLLUI_title_types
e:\StoryDev\Websites\StoryDev\Sources/sll/Capture.hx:90: characters 75-95 : For function argument 'value'
e:\StoryDev\Websites\StoryDev\Sources/SLLUI.hx:10: lines 10-29 : Defined in this class
The identifier SLLUI_title_types
Haxe is trying to find is declared here: var argTypesIdentifier = fullName + "_types";
and right below it I add it to the assigns
value as an expression like so:
assigns.push(macro { var $argTypesIdentifier : Array<sll.Token.ArgumentType> = []; });
Why would Haxe think it cannot identify $argTypesIdentifier
even though that very code very clearly shows it’s being defined.
In the error above, line 90 is referring to: assigns.push(macro { sll.Parser.functionTypes.set($v{field.name}, $i{argTypesIdentifier}); });
For me, this just doesn’t make any sense, unless the reification I’m using is wrong. Any suggestions?
For the record, the variable being assigned to is of type Map<String, Array<sll.Token.ArgumentType>>
.