Workaround HaxeFoundation/haxe #2272.
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user