Skip to content

Commit d7c5963

Browse files
committed
Fix "using" classes calling their function on the wrong type
1 parent 15a476d commit d7c5963

File tree

4 files changed

+81
-13
lines changed

4 files changed

+81
-13
lines changed

include.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<haxelib name="thx.semver" />
55
<!-- <haxelib name="hscript" /> This library is now OPTIONAL. -->
66

7+
<haxeflag name="--macro" value="polymod.hscript._internal.UsingRttiMacro.addRtti()" />
78
<!--
89
<haxeflag name="- -macro" value="polymod.hscript._internal.PolymodFinalMacro.locateAllFinals()" />
910
-->

polymod/hscript/_internal/PolymodInterpEx.hx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,17 @@ class PolymodInterpEx extends Interp
153153
return proxy.callFunction(f, args);
154154
}
155155

156-
var func = get(o, f);
157-
158156
@:privateAccess
159157
{
160158
if (_proxy != null && _proxy._cachedUsingFunctions.exists(f))
161159
{
162-
return _proxy._cachedUsingFunctions[f]([o].concat(args));
160+
var func = _proxy._cachedUsingFunctions[f];
161+
if (func.type == null || Std.isOfType(o, func.type)) return func.func([o].concat(args));
163162
}
164163
}
165164

165+
var func = get(o, f);
166+
166167
// Workaround for an HTML5-specific issue.
167168
// https://github.com/HaxeFoundation/haxe/issues/11298
168169
if (func == null && f == "contains") {

polymod/hscript/_internal/PolymodScriptClass.hx

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package polymod.hscript._internal;
22

33
#if hscript
4+
import haxe.Constraints.Function;
5+
import haxe.rtti.Rtti;
46
import hscript.Expr.FieldDecl;
57
import hscript.Expr.FunctionDecl;
68
import hscript.Expr.VarDecl;
79
import hscript.Printer;
810
import polymod.hscript._internal.PolymodClassDeclEx;
911

12+
using haxe.rtti.CType.CTypeTools;
1013
using StringTools;
1114

1215
enum Param
@@ -885,7 +888,7 @@ class PolymodScriptClass
885888
private var _cachedSuperFunctionDecls:Map<String, Dynamic> = [];
886889
private var _cachedFunctionDecls:Map<String, FunctionDecl> = [];
887890
private var _cachedVarDecls:Map<String, VarDecl> = [];
888-
private var _cachedUsingFunctions:Map<String, Dynamic> = [];
891+
private var _cachedUsingFunctions:Map<String, {type:Null<Class<Dynamic>>, func:Dynamic}> = [];
889892

890893
private function buildCaches()
891894
{
@@ -895,20 +898,46 @@ class PolymodScriptClass
895898
_cachedVarDecls.clear();
896899
_cachedUsingFunctions.clear();
897900

898-
for (n => u in _c.usings)
901+
for (_ => u in _c.usings)
899902
{
900-
var fields = Type.getClassFields(u.cls);
901-
if (fields.length == 0) continue;
903+
if (Rtti.hasRtti(u.cls))
904+
{
905+
var fields = Rtti.getRtti(u.cls).statics;
906+
if (fields.length == 0) continue;
907+
908+
for (fld in fields)
909+
{
910+
var usingType:Null<Class<Dynamic>> = null;
911+
switch (fld.type)
912+
{
913+
case CFunction(args, _): usingType = Type.resolveClass(args[0].t.toString());
914+
default:
915+
}
916+
var func:Dynamic = function(params:Array<Dynamic>)
917+
{
918+
var prop:Dynamic = Reflect.getProperty(u.cls, fld.name);
919+
return Reflect.callMethod(u.cls, prop, params);
920+
}
902921

903-
for (fld in fields)
922+
_cachedUsingFunctions.set(fld.name, { type: usingType, func: func });
923+
}
924+
}
925+
else
904926
{
905-
var func:Dynamic = function(params:Array<Dynamic>)
927+
// We make fields for it anyway and pray they work on other targets
928+
var fields = Type.getClassFields(u.cls);
929+
if (fields.length == 0) continue;
930+
931+
for (fld in fields)
906932
{
907-
var prop:Dynamic = Reflect.getProperty(u.cls, fld);
908-
return Reflect.callMethod(u.cls, prop, params);
933+
var func:Dynamic = function(params:Array<Dynamic>)
934+
{
935+
var prop:Dynamic = Reflect.getProperty(u.cls, fld);
936+
return Reflect.callMethod(u.cls, prop, params);
937+
}
938+
939+
_cachedUsingFunctions.set(fld, { type: null, func: func });
909940
}
910-
911-
_cachedUsingFunctions.set(fld, func);
912941
}
913942
}
914943

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package polymod.hscript._internal;
2+
3+
import haxe.macro.Context;
4+
import haxe.macro.Type;
5+
import haxe.macro.Expr;
6+
7+
using haxe.macro.TypeTools;
8+
9+
/**
10+
* Automatically adds the @:rtti metadata to classes with "Tools" or "Util" in their name
11+
*/
12+
class UsingRttiMacro
13+
{
14+
public static macro function addRtti():Void
15+
{
16+
Context.onGenerate((types) ->
17+
{
18+
for (type in types)
19+
{
20+
if (shouldAddRtti(type))
21+
{
22+
switch (type)
23+
{
24+
case TInst(_.get() => cls, _):
25+
cls.meta.add(':rtti', [], cls.pos);
26+
case _:
27+
}
28+
}
29+
}
30+
});
31+
}
32+
33+
private static function shouldAddRtti(type:haxe.macro.Type):Bool {
34+
final name = type.toString();
35+
return name.indexOf("Tools") != -1 || name.indexOf("Util") != -1;
36+
}
37+
}

0 commit comments

Comments
 (0)