Skip to content

Commit e142f43

Browse files
committed
fix inline instance abstract calls
this also includes a rework of abstractClassStatics they are now moved into the new PolymodImpl class
1 parent e5b7d8a commit e142f43

5 files changed

Lines changed: 181 additions & 182 deletions

File tree

polymod/hscript/_internal/Interp.hx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ class Interp
128128

129129
function assign(e1:Expr, e2:Expr):Dynamic
130130
{
131-
var v = expr(e2);
131+
return assignValue(e1, expr(e2));
132+
}
133+
134+
function assignValue(e1:Expr, v:Dynamic, _abstractInlineAssign:Bool = false):Dynamic
135+
{
132136
switch (Tools.expr(e1))
133137
{
134138
case EIdent(id):
@@ -152,7 +156,10 @@ class Interp
152156
}
153157

154158
default:
155-
error(EInvalidOp("="));
159+
if (!_abstractInlineAssign)
160+
{
161+
error(EInvalidOp("="));
162+
}
156163
}
157164
return v;
158165
}

polymod/hscript/_internal/PolymodClassDeclEx.hx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,16 @@ class PolymodStaticAbstractReference
155155
public var absImpl:Null<Class<Dynamic>>;
156156

157157
/**
158-
* The path of the implementation class.
159-
* Used for resolving static fields cached at macro time.
158+
* The class, generated by Polymod, that implements the abstract class's static fields as well as inline instance functions,
159+
* if it exists.
160160
*/
161-
public var absImplPath:String;
161+
public var polymodImpl:Null<Class<Dynamic>>;
162162

163-
public function new(absName:String, absImpl:Null<Class<Dynamic>>, absImplPath:String)
163+
public function new(absName:String, absImpl:Null<Class<Dynamic>>, polymodImpl:Null<Class<Dynamic>>)
164164
{
165165
this.absName = absName;
166166
this.absImpl = absImpl;
167-
this.absImplPath = absImplPath;
167+
this.polymodImpl = polymodImpl;
168168
}
169169

170170
/**
@@ -211,7 +211,17 @@ class PolymodStaticAbstractReference
211211
}
212212
}
213213

214-
return fetchAbstractClassStatic(fieldName);
214+
if (this.polymodImpl != null)
215+
{
216+
var getterName:String = 'get_$fieldName';
217+
if (Reflect.hasField(this.polymodImpl, getterName))
218+
{
219+
var getter = Reflect.field(this.polymodImpl, getterName);
220+
return Reflect.callMethod(this.polymodImpl, getter, []);
221+
}
222+
}
223+
224+
throw 'Could not resolve abstract class static field ${fieldName}';
215225
}
216226

217227
/**
@@ -259,21 +269,28 @@ class PolymodStaticAbstractReference
259269
throw 'Could not resolve abstract class static function ${funcName}';
260270
}
261271

262-
function fetchAbstractClassStatic(fieldName:String):Dynamic
272+
public function hasInlineFunction(funcName:String):Bool
263273
{
264-
var key:String = '${this.absImplPath}.${fieldName}';
265-
266-
if (PolymodScriptClass.abstractClassStatics.exists(key))
274+
if (this.polymodImpl != null)
267275
{
268-
var holder = PolymodScriptClass.abstractClassStatics.get(key);
269-
var property = key.replace('.', '_');
270-
271-
return Reflect.getProperty(holder, property);
276+
return Reflect.hasField(this.polymodImpl, funcName);
272277
}
273-
else
278+
279+
return false;
280+
}
281+
282+
public function callInlineFunction(interp:PolymodInterpEx, absInstanceExpr:Expr, funcName:String, args:Array<Dynamic>):Dynamic
283+
{
284+
if (this.polymodImpl != null)
274285
{
275-
throw 'Could not resolve abstract class static field ${fieldName}';
286+
var func = Reflect.field(this.polymodImpl, funcName);
287+
if (func != null)
288+
{
289+
return Reflect.callMethod(this.polymodImpl, func, ([interp, absInstanceExpr] : Array<Dynamic>).concat(args));
290+
}
276291
}
292+
293+
throw 'Could not resolve abstract class inline instance function ${funcName}';
277294
}
278295

279296
public function toString():String

polymod/hscript/_internal/PolymodInterpEx.hx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ class PolymodInterpEx extends Interp
410410
super.setVar(id, v);
411411
}
412412

413-
override function assign(e1:Expr, e2:Expr):Dynamic
413+
override function assignValue(e1:Expr, v:Dynamic, _abstractInlineAssign:Bool = false):Dynamic
414414
{
415415
switch (Tools.expr(e1))
416416
{
@@ -419,8 +419,6 @@ class PolymodInterpEx extends Interp
419419
// Also ensures property functions are accounted for.
420420
if (_proxy != null && _proxy.superHasField(id))
421421
{
422-
var v = expr(e2);
423-
424422
if (Std.isOfType(_proxy.superClass, PolymodScriptClass))
425423
{
426424
var superClass:PolymodAbstractScriptClass = cast(_proxy.superClass, PolymodScriptClass);
@@ -442,7 +440,6 @@ class PolymodInterpEx extends Interp
442440
final setName = 'set_$id';
443441
if (!_propTrack.exists(setName))
444442
{
445-
var v = expr(e2);
446443
_propTrack.set(setName, true);
447444
var out = _proxy.callFunction(setName, [v]);
448445
_propTrack.remove(setName);
@@ -471,8 +468,6 @@ class PolymodInterpEx extends Interp
471468
{
472469
if (_proxy != null && _proxy.superHasField(id))
473470
{
474-
var v = expr(e2);
475-
476471
if (Std.isOfType(_proxy.superClass, PolymodScriptClass))
477472
{
478473
var superClass:PolymodAbstractScriptClass = cast(_proxy.superClass, PolymodScriptClass);
@@ -510,7 +505,7 @@ class PolymodInterpEx extends Interp
510505
default:
511506
}
512507
// Fallback, which calls set()
513-
return super.assign(e1, e2);
508+
return super.assignValue(e1, v, _abstractInlineAssign);
514509
}
515510

516511
override function increment(e:Expr, prefix:Bool, delta:Int)
@@ -875,14 +870,28 @@ class PolymodInterpEx extends Interp
875870
{
876871
case EField(e, f):
877872
var name = getIdent(e);
878-
name = getClassDecl().imports.get(name)?.fullPath ?? name;
879-
if (name != null && _scriptEnumDescriptors.exists(name))
873+
if (name != null)
880874
{
881-
var args = new Array();
882-
for (p in params)
883-
args.push(expr(p));
875+
var imp = getClassDecl().imports.get(name);
876+
if (imp != null)
877+
{
878+
if (_scriptEnumDescriptors.exists(imp.fullPath))
879+
{
880+
var args = new Array();
881+
for (p in params)
882+
args.push(expr(p));
884883

885-
return new PolymodEnum(_scriptEnumDescriptors.get(name), f, args);
884+
return new PolymodEnum(_scriptEnumDescriptors.get(imp.fullPath), f, args);
885+
}
886+
else if (imp?.abs != null && imp.abs.hasInlineFunction(f))
887+
{
888+
var args = new Array();
889+
for (p in params)
890+
args.push(expr(p));
891+
892+
return imp.abs.callInlineFunction(this, params[0], f, args);
893+
}
894+
}
886895
}
887896
default:
888897
}

polymod/hscript/_internal/PolymodScriptClass.hx

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -105,45 +105,20 @@ class PolymodScriptClass
105105
var baseAbstractClassImpls:Map<String,
106106
{
107107
cls:Class<Dynamic>,
108-
clsName:String,
108+
polymodCls:Null<Class<Dynamic>>,
109109
}> = PolymodScriptClassMacro.listAbstractImpls();
110110

111111
for (key => value in baseAbstractClassImpls)
112112
{
113113
if (value == null) continue;
114114

115-
_abstractClassImpls.set(key, new PolymodStaticAbstractReference(key, value.cls, value.clsName));
115+
_abstractClassImpls.set(key, new PolymodStaticAbstractReference(key, value.cls, value.polymodCls));
116116
}
117117
}
118118

119119
return _abstractClassImpls;
120120
}
121121

122-
/**
123-
* Define a list of `fieldName -> Class` pointing to the generated class containing a reference
124-
* to each static field of each abstract.
125-
*/
126-
public static var abstractClassStatics(get, never):Map<String, Class<Dynamic>>;
127-
128-
static var _abstractClassStatics:Map<String, Class<Dynamic>> = null;
129-
130-
static function get_abstractClassStatics():Map<String, Class<Dynamic>>
131-
{
132-
if (_abstractClassStatics == null)
133-
{
134-
_abstractClassStatics = new Map<String, Class<Dynamic>>();
135-
136-
var baseAbstractClassStatics:Map<String, Class<Dynamic>> = PolymodScriptClassMacro.listAbstractStatics();
137-
138-
for (key => value in baseAbstractClassStatics)
139-
{
140-
_abstractClassStatics.set(key, value);
141-
}
142-
}
143-
144-
return _abstractClassStatics;
145-
}
146-
147122
/**
148123
* Define a list of `typeName -> Class` which provides a reference to each typedef,
149124
* since typedefs can't be normally resolved at runtime.

0 commit comments

Comments
 (0)