From 10b67def7414516a69cb4e6955a00494623667a0 Mon Sep 17 00:00:00 2001 From: Jaime Humberto Macias Bustamante Date: Sun, 11 May 2025 00:27:40 -0700 Subject: [PATCH] Moved "resolveField" to "hget" + fixes --- hscript/Interp.hx | 37 ++---- hscript/Tools.hx | 17 ++- hscript/customclass/CustomClass.hx | 152 +++++++++++-------------- hscript/customclass/CustomClassDecl.hx | 4 +- 4 files changed, 95 insertions(+), 115 deletions(-) diff --git a/hscript/Interp.hx b/hscript/Interp.hx index 9e75636..6b2fa29 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -110,14 +110,7 @@ class Interp { switch(Type.typeof(v)) { case TClass(c): // Class Access __instanceFields = Type.getInstanceFields(c); - /* - if(v is IHScriptCustomClassBehaviour) { - var v:IHScriptCustomClassBehaviour = cast v; - var classFields = v.__class__fields; - if(classFields != null) - __instanceFields = __instanceFields.concat(classFields); - _scriptObjectType = SCustomClass; - } else*/ if(v is IHScriptCustomAccessBehaviour) { + if(v is IHScriptCustomAccessBehaviour) { _scriptObjectType = SAccessBehaviourObject; } else if(v is IHScriptCustomBehaviour) { _scriptObjectType = SBehaviourClass; @@ -165,7 +158,7 @@ class Interp { public var allowStaticVariables:Bool = false; public var allowPublicVariables:Bool = false; - public var importBlocklist:Array = [ + public var importBlocklist:Array = [ // Should I remove this since we have "InterpConfig"??? // "flixel.FlxG" ]; @@ -322,7 +315,7 @@ class Interp { return v; } */ - else if (_proxy.superClass == null && _proxy.__class.classDecl.extend != null) { + if (_proxy.superClass == null && _proxy.__class.classDecl.extend != null && !_proxy.hasVar(id)) { // Caches the declaration to set it once superClass is created var v = expr(e2); _proxy.cacheSuperField(id, v); @@ -403,7 +396,7 @@ class Interp { } } */ - if(_proxy.superClass == null && _proxy.__class.classDecl.extend != null){ + if(_proxy.superClass == null && _proxy.__class.classDecl.extend != null && !_proxy.hasVar(f)){ // Caches the declaration to set it once superClass is created var v = expr(e2); _proxy.cacheSuperField(f, v); @@ -468,7 +461,7 @@ class Interp { return v; } */ - else if ((_proxy.superClass == null && _proxy.__class.classDecl.extend != null)) { + else if ((_proxy.superClass == null && _proxy.__class.classDecl.extend != null && !_proxy.hasVar(id))) { _proxy.cacheSuperField(id, v); return v; } @@ -550,7 +543,7 @@ class Interp { } } */ - if(_proxy.superClass == null && _proxy.__class.classDecl.extend != null){ + if(_proxy.superClass == null && _proxy.__class.classDecl.extend != null && !_proxy.hasVar(f)){ // Caches the declaration to set it once superClass is created v = fop(get(obj, f), expr(e2)); _proxy.cacheSuperField(f, v); @@ -777,14 +770,14 @@ class Interp { // We are calling a LOCAL function from the same module. if (_proxy.hasFunction(id)) { _nextCallObject = _proxy; - return _proxy.resolveField(id); + return _proxy.hget(id); } if (_proxy.superHasField(id)) { _nextCallObject = _proxy.superClass; return Reflect.getProperty(_proxy.superClass, id); } else { try { - var r = _proxy.resolveField(id); + var r = _proxy.hget(id); _nextCallObject = _proxy; return r; } catch (e:Dynamic) { @@ -863,7 +856,7 @@ class Interp { #end switch (e) { case EIgnore(_): - case EClass(name, fields, extend, interfaces): //Not sure if leave the old system or implement the new one. + case EClass(name, fields, extend, interfaces): inline function importVar(thing:String):String { if (thing == null) return null; @@ -1632,18 +1625,6 @@ class Interp { }) { return _getRedirect(o, f); } - /* - if(o is IHScriptCustomClassBehaviour) { - var obj:IHScriptCustomClassBehaviour = cast o; - if(isBypassAccessor) { - obj.__allowSetGet = false; - var res = obj.hget(f); - obj.__allowSetGet = true; - return res; - } - return obj.hget(f); - } - */ if (o is IHScriptCustomAccessBehaviour) { var obj:IHScriptCustomAccessBehaviour = cast o; if(isBypassAccessor) { diff --git a/hscript/Tools.hx b/hscript/Tools.hx index deb5f18..1600f0f 100644 --- a/hscript/Tools.hx +++ b/hscript/Tools.hx @@ -22,6 +22,8 @@ package hscript; import hscript.Expr; +using StringTools; + class Tools { public static function iter( e : Expr, f : Expr -> Void ):Void { @@ -112,6 +114,14 @@ class Tools { #end } + @:access(hscript.Interp) + public static function clearClasses() { + #if CUSTOM_CLASSES + Interp._customClasses.clear(); + Interp._customClassAliases.clear(); + #end + } + public static function removeInnerClass(name: String): String { var ll = name.lastIndexOf("."); if (name.indexOf(".") != ll) { // checks if there are 2 or more dots @@ -125,7 +135,10 @@ class Tools { // TODO: maybe use this function for import since also check for innerclasses public static function getClass(name: String): Dynamic { - var c: Dynamic = Type.resolveClass(name); + var splitClassName = [for (e in name.split(".")) e.trim()]; + var realClassName = splitClassName.join("."); + + var c: Dynamic = Type.resolveClass(realClassName); if (c == null) // try importing as enum try c = Type.resolveEnum(name); @@ -135,7 +148,7 @@ class Tools { // this allows you to import stuff like // flixel.text.FlxText.FlxTextBorderStyle // without the script crashing immediately - var className = removeInnerClass(name); + var className = removeInnerClass(realClassName); if (className != name) { c = Type.resolveClass(className); if (c == null) diff --git a/hscript/customclass/CustomClass.hx b/hscript/customclass/CustomClass.hx index 13e35bc..c154c3b 100644 --- a/hscript/customclass/CustomClass.hx +++ b/hscript/customclass/CustomClass.hx @@ -108,8 +108,8 @@ class CustomClass implements IHScriptCustomAccessBehaviour { #else var fexpr = Expr.EFunction(fn.args, fn.body, f.name, fn.ret, false, false); #end - var f0 = this.interp.expr(fexpr); - this.interp.variables.set(f.name, f0); + var func:Function = this.interp.expr(fexpr); + this.interp.variables.set(f.name, func); case KVar(v): __cachedVarDecls.set(f.name, v); if (v.expr != null) { @@ -300,7 +300,66 @@ class CustomClass implements IHScriptCustomAccessBehaviour { // Access fields public function hget(name:String):Dynamic { - return resolveField(name); + switch (name) { + case "superClass": return this.superClass; + case "createSuperClass": return this.createSuperClass; + case "hasFunction": return this.hasFunction; + case "callFunction": return this.callFunction; + default: + if (hasFunction(name)) { + var fn:Function = Reflect.makeVarArgs(function(args:Array) { + return this.callFunction(name, args); + }); + + return fn; + } + + if (hasVar(name)) { + var value:Dynamic = null; + + if (__allowSetGet && hasFunction('get_${name}')) + value = __callGetter(name); + else if (this.interp.variables.exists(name)) + value = this.interp.variables.get(name); + else { + var v = getVar(name); + + if (v.expr != null) { + value = this.interp.expr(v.expr); + this.interp.variables.set(name, value); + } + } + + return value; + } + + if (this.superClass != null) { + if (Type.getClass(this.superClass) == null) { + // Anonymous structure + if (Reflect.hasField(this.superClass, name)) + return Reflect.field(this.superClass, name); + else + throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '[ANONYMOUS STRUCTURE]'"; + } + + if (this.superClass is CustomClass) { + var superCustomClass:CustomClass = cast(this.superClass, CustomClass); + try { + superCustomClass.__allowSetGet = this.__allowSetGet; + return superCustomClass.hget(name); + } catch (e) {} + } + // Real Class + var fields = Type.getInstanceFields(Type.getClass(this.superClass)); + if (fields.contains(name)) + return __allowSetGet ? Reflect.getProperty(this.superClass, name) : Reflect.field(this.superClass, name); + else + throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '" + Type.getClassName(Type.getClass(this.superClass)) + "'"; + } + else + throw "field '" + name + "' does not exist in custom class '" + this.className + "'"; + } + return null; } public function hset(name:String, val:Dynamic):Dynamic { @@ -319,11 +378,12 @@ class CustomClass implements IHScriptCustomAccessBehaviour { return superCustomClass.hset(name, val); } catch (e:Dynamic) {} } + // Real Class if (Type.getClass(this.superClass) == null) { // Anonymous structure - if (Reflect.hasField(this.superClass, name)) { + if (Reflect.hasField(this.superClass, name)) Reflect.setField(this.superClass, name, val); - } + return val; } else if (superHasField(name)) { @@ -332,13 +392,11 @@ class CustomClass implements IHScriptCustomAccessBehaviour { else Reflect.setField(this.superClass, name, val); } - else { - throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '" - + Type.getClassName(Type.getClass(this.superClass)) + "'"; - } - } else { + else + throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '" + Type.getClassName(Type.getClass(this.superClass)) + "'"; + } + else throw "field '" + name + "' does not exist in custom class '" + this.className + "'"; - } } return val; } @@ -357,78 +415,6 @@ class CustomClass implements IHScriptCustomAccessBehaviour { return r; } - // TODO: move this to "hget" directly - private function resolveField(name:String):Dynamic { - switch (name) { - case "superClass": - return this.superClass; - case "createSuperClass": - return this.createSuperClass; - case "hasFunction": - return this.hasFunction; - case "callFunction": - return this.callFunction; - default: - if (hasFunction(name)) { - var fn:Function = Reflect.makeVarArgs(function(args:Array) { - return this.callFunction(name, args); - }); - - return fn; - } - - if (hasVar(name)) { - var value:Dynamic = null; - - if (__allowSetGet && hasFunction('get_${name}')) { - value = __callGetter(name); - } else if (this.interp.variables.exists(name)) { - value = this.interp.variables.get(name); - } else { - var v = getVar(name); - - if (v.expr != null) { - value = this.interp.expr(v.expr); - this.interp.variables.set(name, value); - } - } - - return value; - } - - if (this.superClass != null) { - if (Type.getClass(this.superClass) == null) { - // Anonymous structure - if (Reflect.hasField(this.superClass, name)) { - return Reflect.field(this.superClass, name); - } else { - throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '" - + Type.getClassName(Type.getClass(this.superClass)) + "'"; - } - } - - if (this.superClass is CustomClass) { - var superCustomClass:CustomClass = cast(this.superClass, CustomClass); - try { - superCustomClass.__allowSetGet = this.__allowSetGet; - return superCustomClass.hget(name); - } catch (e) {} - } - // Real Class - var fields = Type.getInstanceFields(Type.getClass(this.superClass)); - if (fields.contains(name)) { - return __allowSetGet ? Reflect.getProperty(this.superClass, name) : Reflect.field(this.superClass, name); - } else { - throw "field '" + name + "' does not exist in custom class '" + this.className + "' or super class '" - + Type.getClassName(Type.getClass(this.superClass)) + "'"; - } - } else { - throw "field '" + name + "' does not exist in custom class '" + this.className + "'"; - } - } - return null; - } - /** * Returns the real superClass if the Custom Class * extends another Custom Class, and so on until diff --git a/hscript/customclass/CustomClassDecl.hx b/hscript/customclass/CustomClassDecl.hx index 265fba9..a532f90 100644 --- a/hscript/customclass/CustomClassDecl.hx +++ b/hscript/customclass/CustomClassDecl.hx @@ -108,8 +108,8 @@ class CustomClassDecl implements IHScriptCustomAccessBehaviour { #else var fexpr = Expr.EFunction(fn.args, fn.body, f.name, fn.ret, false, false); #end - var f0 = this.staticInterp.expr(fexpr); - this.staticInterp.variables.set(f.name, f0); + var func:Function = this.staticInterp.expr(fexpr); + this.staticInterp.variables.set(f.name, func); case KVar(v): _cachedStaticVariables.set(f.name, v); if (v.expr != null) {