Skip to content

Instantly share code, notes, and snippets.

@nadako
Created February 14, 2014 11:06
Show Gist options
  • Save nadako/8999329 to your computer and use it in GitHub Desktop.
Save nadako/8999329 to your computer and use it in GitHub Desktop.
@:genericBuild read-only type builder
@:genericBuild(ConstMacro.build())
class Const<T> {}
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
using haxe.macro.Tools;
class ConstMacro
{
public static function build():Type
{
var type = Context.getLocalType();
switch (type.follow())
{
case TInst(ref, params):
switch (ref.get())
{
case {pack: [], name: "Const"}:
return createReadType(params[0]);
default:
throw false;
}
default:
throw false;
}
return type;
}
static function createReadType(type:Type):Type
{
switch (type)
{
case TType(ref, []):
var td = ref.get();
switch (td.type)
{
case TAnonymous(ref):
var readFields:Array<Field> = [];
for (field in ref.get().fields)
{
var fieldType = field.type.toComplexType();
readFields.push({
name: field.name,
kind: FProp("default", "null", fieldType),
pos: field.pos,
});
}
Context.defineType({
pack: td.pack,
name: td.name + "_Read",
pos: td.pos,
kind: TDStructure,
fields: readFields
});
return ComplexType.TPath({pack: [], name: td.name + "_Read", params: []}).toType();
default:
throw false;
}
default:
throw false;
}
}
}
typedef MapItem =
{
var itemId:Int;
var typeId:String;
}
class Main
{
static function main()
{
var a:Const<MapItem> = {itemId: 1, typeId: "house"};
a.itemId = 10; // Cannot access field or identifier itemId for writing
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment