Skip to content

Instantly share code, notes, and snippets.

@boozook
Created April 21, 2015 11:00
Show Gist options
  • Save boozook/941fbc4d55b5d9d89212 to your computer and use it in GitHub Desktop.
Save boozook/941fbc4d55b5d9d89212 to your computer and use it in GitHub Desktop.
Haxe possible issue about macro and creation @:to-methods for abstracts.
-main Main
-cp ./src
-D dump=pretty
-D analyzer
-dce std
# Defines for test (!)
# Cases:
# If both => "Duplicate class field declaration : toCloImpl"
# If comment `original_method` => "Abstract Clo has no @:to function that accepts _Main.IClo<Float -> Void>"
-D original_method
-D generate_method
-x Main.n
import haxe.unit.TestRunner;
import haxe.unit.TestCase;
import haxe.Constraints.Function;
import haxe.macro.Printer;
import haxe.macro.Context;
import haxe.macro.Expr;
class Main extends TestCase
{
static function main()
{
var runner = new TestRunner();
runner.add(new Main());
runner.run();
var result = runner.result;
#if sys
Sys.exit(result.success ? 0 : 1);
#end
}
public function new() super();
// ---- test ---- //
var instance:Clo<Float -> Void>;
public function testFieldTo():Void
{
function assert(value):Void
assertEquals(value, 111.0);
instance = new Clo();
instance.set(assert);
instance.call(111.0);
instance.call(111);
}
}
#if macro
class CloBuilder
{
public static function build():Array<Field>
{
var fields:Array<Field> = Context.getBuildFields();
var field:Field =
(
// this is a temp class - only for get field from it:
macro class Temp
{
// field what we need:
@:to function toCloImpl<T1>(closure:IClo<T1 -> Void>):CloImpl<T1>
return new CloImpl();
}
).fields[0];
field.access = [Access.AInline, Access.AStatic, Access.APublic];
// is dublicate?
var print = new Printer().printField;
for(existing in fields)
if(existing.name == field.name)// found
if(print(field) == print(existing))// yes
trace("fields are EQ!");
else
Sys.println('\nnew:\n${print(field)}\n\t!=\n${print(existing)}');
#if generate_method
fields.push(field);
#end
return fields;
}
}
#end
@:multiType
@:forward(set)
#if !macro @:build(Main.CloBuilder.build()) #end
abstract Clo<T:Method>(IClo<T>)
{
public var call(get, never):T;
public function new();
private inline function get_call():T
return this.call;
#if original_method
@:to public static inline function toCloImpl<T1>(closure:IClo<T1 -> Void>):CloImpl<T1> return new CloImpl();
#end
}
class CloImpl<T> implements IClo<T -> Void>
{
public var call(default, null):T -> Void;
private var method:T -> Void;
public function new()
{
call = _call;
}
private function _call(value:T):Void
{
if(method != null)
method(value);
}
public function set(method:T -> Void):Void
{
this.method = method;
}
}
private interface IClo<T:Method>
{
public var call(default, null):T;
public function set(listener:T):Void;
}
private typedef Method = haxe.Constraints.Function;
@lavraalex
Copy link

Delete all issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment