Workaround HaxeFoundation/haxe #2272.

This commit is contained in:
back2dos
2013-10-21 22:26:54 +02:00
parent 687683e86a
commit 70f2c9ba40
3 changed files with 27 additions and 24 deletions

View File

@@ -16,7 +16,7 @@ class ClassBuilder {
var constructor:Null<Constructor>; var constructor:Null<Constructor>;
public var target(default, null):ClassType;//TODO: this could be lazy public var target(default, null):ClassType;//TODO: this could be lazy
var superFields:Map<String,Bool>; var superFields:Map<String,Bool>;
var keepers:Array<Expr>;//hack to force field generation
public function new() { public function new() {
this.memberMap = new Map(); this.memberMap = new Map();
this.memberList = []; this.memberList = [];
@@ -38,7 +38,7 @@ class ClassBuilder {
macros.set(field.name, field) macros.set(field.name, field)
else if (field.name == 'new') { else if (field.name == 'new') {
var m:Member = field; var m:Member = field;
this.constructor = new Constructor(m.getFunction().sure(), m.isPublic, m.pos); this.constructor = new Constructor(this, m.getFunction().sure(), m.isPublic, m.pos);
} }
else else
addMember(field); addMember(field);
@@ -47,7 +47,7 @@ class ClassBuilder {
public function getConstructor(?fallback:Function):Constructor { public function getConstructor(?fallback:Function):Constructor {
if (constructor == null) if (constructor == null)
if (fallback != null) if (fallback != null)
new Constructor(fallback); new Constructor(this, fallback);
else { else {
var sup = target.superClass; var sup = target.superClass;
while (sup != null) { while (sup != null) {
@@ -61,21 +61,21 @@ class ClassBuilder {
arg.type = null; arg.type = null;
func.expr = "super".resolve().call(func.getArgIdents()); func.expr = "super".resolve().call(func.getArgIdents());
constructor = new Constructor(func); constructor = new Constructor(this, func);
if (ctor.isPublic) if (ctor.isPublic)
constructor.publish(); constructor.publish();
} }
catch (e:Dynamic) {//fails for unknown reason catch (e:Dynamic) {//fails for unknown reason
if (e == 'assert') if (e == 'assert')
neko.Lib.rethrow(e); neko.Lib.rethrow(e);
constructor = new Constructor(null); constructor = new Constructor(this, null);
} }
break; break;
} }
else sup = cl.superClass; else sup = cl.superClass;
} }
if (constructor == null) if (constructor == null)
constructor = new Constructor(null); constructor = new Constructor(this, null);
} }
return constructor; return constructor;

View File

@@ -1,6 +1,7 @@
package tink.macro; package tink.macro;
import haxe.macro.Expr; import haxe.macro.Expr;
import haxe.macro.Context;
import tink.core.Pair; import tink.core.Pair;
using tink.MacroApi; using tink.MacroApi;
@@ -19,10 +20,13 @@ class Constructor {
var pos:Position; var pos:Position;
var onGenerateHooks:Array<Function->Void>; var onGenerateHooks:Array<Function->Void>;
var superCall:Expr; var superCall:Expr;
var owner:ClassBuilder;
var keepers:Array<Expr>;//hack to force field generation
public var isPublic:Null<Bool>; public var isPublic:Null<Bool>;
public function new(f:Function, ?isPublic:Null<Bool> = null, ?pos:Position, ?meta:Metadata) { public function new(owner:ClassBuilder, f:Function, ?isPublic:Null<Bool> = null, ?pos:Position, ?meta:Metadata) {
this.nuStatements = []; this.nuStatements = [];
this.owner = owner;
this.isPublic = isPublic; this.isPublic = isPublic;
this.pos = pos.sanitize(); this.pos = pos.sanitize();
@@ -30,6 +34,7 @@ class Constructor {
this.args = []; this.args = [];
this.beforeArgs = []; this.beforeArgs = [];
this.afterArgs = []; this.afterArgs = [];
this.keepers = [];
this.oldStatements = this.oldStatements =
if (f == null) []; if (f == null) [];
@@ -67,6 +72,9 @@ class Constructor {
args.push( { name : name, opt : opt || e != null, type : t, value: e } ); args.push( { name : name, opt : opt || e != null, type : t, value: e } );
public function init(name:String, pos:Position, with:FieldInit, ?options:{ ?prepend:Bool, ?bypass:Bool }) { public function init(name:String, pos:Position, with:FieldInit, ?options:{ ?prepend:Bool, ?bypass:Bool }) {
@:privateAccess
if (owner.memberMap.exists('name'))
owner.memberMap.get('name').addMeta(':isVar');
if (options == null) if (options == null)
options = {}; options = {};
var e = var e =
@@ -87,23 +95,13 @@ class Constructor {
var tmp = MacroApi.tempName(); var tmp = MacroApi.tempName();
if (options.bypass) { if (options.bypass) {
if (haxe.macro.Context.defined('java')) { if (Context.defined('dce') && Context.definedValue('dce') == 'full') {
addStatement( if (keepers.length == 0)
macro @:pos(pos) keepers.push(macro return);
if (Math.random() < .0) { keepers.push(macro this.$name = $e);
//if this is false, then it gets thrown out before reaching the backend which will then generate invalid code
var $tmp = this.$name;
$i{tmp} = $e;
this.$name = $i{tmp};
},
true
);
addStatement(macro @:pos(pos) (cast this).$name = $e, options.prepend);
}
else {
addStatement(macro @:pos(pos) if (false) { var $tmp = this.$name; $i{tmp} = $e; }, true);
addStatement(macro @:pos(pos) (cast this).$name = $e, options.prepend);
} }
addStatement(macro @:pos(pos) if (false) { var $tmp = this.$name; $i{tmp} = $e; }, true);
addStatement(macro @:pos(pos) (cast this).$name = $e, options.prepend);
} }
else else
addStatement(macro @:pos(pos) this.$name = $e, options.prepend); addStatement(macro @:pos(pos) this.$name = $e, options.prepend);
@@ -113,7 +111,11 @@ class Constructor {
isPublic = true; isPublic = true;
function toBlock() function toBlock()
return [superCall].concat(nuStatements).concat(oldStatements).toBlock(pos); return [superCall]
.concat(nuStatements)
.concat(oldStatements)
.concat(keepers)
.toBlock(pos);
public function onGenerate(hook) public function onGenerate(hook)
this.onGenerateHooks.push(hook); this.onGenerateHooks.push(hook);

View File

@@ -15,6 +15,7 @@ class Run {
#end #end
macro static function test() { macro static function test() {
var runner = new TestRunner(); var runner = new TestRunner();
tink.macro.ClassBuilder;
for (c in cases) for (c in cases)
runner.add(c); runner.add(c);
runner.run(); runner.run();