The Beginning of the End (Old Custom Class)

This commit is contained in:
Jaime Humberto Macias Bustamante
2025-05-04 23:20:56 -07:00
parent bf602f758b
commit 742b40c86c
3 changed files with 89 additions and 62 deletions
+39 -27
View File
@@ -55,7 +55,7 @@ enum abstract ScriptObjectType(UInt8) {
var SClass;
var SObject;
var SStaticClass;
var SCustomClass; // custom classes
//var SCustomClass; // custom classes
var SBehaviourClass; // hget and hset
var SAccessBehaviourObject; // hget and hset with __allowSetGet
var SNull;
@@ -110,13 +110,14 @@ 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) {
} else*/ if(v is IHScriptCustomAccessBehaviour) {
_scriptObjectType = SAccessBehaviourObject;
} else if(v is IHScriptCustomBehaviour) {
_scriptObjectType = SBehaviourClass;
@@ -191,7 +192,7 @@ class Interp {
}
private function resetVariables():Void {
customClasses = new Map<String, Dynamic>();
//customClasses = new Map<String, Dynamic>();
variables = new Map<String, Dynamic>();
publicVariables = new Map<String, Dynamic>();
staticVariables = new Map<String, Dynamic>();
@@ -326,7 +327,9 @@ class Interp {
if (_scriptObjectType == SObject && instanceHasField) {
UnsafeReflect.setField(scriptObject, id, v);
return v;
} else if (_scriptObjectType == SCustomClass && instanceHasField) {
}
/*
else if (_scriptObjectType == SCustomClass && instanceHasField) {
var obj:IHScriptCustomClassBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -335,7 +338,8 @@ class Interp {
return res;
}
return obj.hset(id, v);
} else if(_scriptObjectType == SAccessBehaviourObject) {
} */
else if(_scriptObjectType == SAccessBehaviourObject) {
var obj:IHScriptCustomAccessBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -437,7 +441,9 @@ class Interp {
if (_scriptObjectType == SObject && instanceHasField) {
UnsafeReflect.setField(scriptObject, id, v);
return v;
} else if (_scriptObjectType == SCustomClass && instanceHasField) {
}
/*
else if (_scriptObjectType == SCustomClass && instanceHasField) {
var obj:IHScriptCustomClassBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -446,7 +452,8 @@ class Interp {
return res;
}
return obj.hset(id, v);
} else if(_scriptObjectType == SAccessBehaviourObject) {
} */
else if(_scriptObjectType == SAccessBehaviourObject) {
var obj:IHScriptCustomAccessBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -683,9 +690,10 @@ class Interp {
return publicVariables.get(id);
if(staticVariables.exists(id))
return staticVariables.get(id);
/*
if(customClasses.exists(id))
return customClasses.get(id);
*/
if(customClassExist(id))
return getCustomClass(id);
@@ -724,7 +732,7 @@ class Interp {
if (_scriptObjectType == SObject && instanceHasField) {
return UnsafeReflect.field(scriptObject, id);
} else if(_scriptObjectType == SCustomClass && instanceHasField) {
}/* else if(_scriptObjectType == SCustomClass && instanceHasField) {
var obj:IHScriptCustomClassBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -733,7 +741,8 @@ class Interp {
return res;
}
return obj.hget(id);
} else if(_scriptObjectType == SAccessBehaviourObject) {
}*/
else if(_scriptObjectType == SAccessBehaviourObject) {
var obj:IHScriptCustomAccessBehaviour = cast scriptObject;
if(isBypassAccessor) {
obj.__allowSetGet = false;
@@ -799,7 +808,7 @@ class Interp {
final variable:Class<Any> = variables.exists(thing) ? cast variables.get(thing) : null;
return variable == null ? thing : Type.getClassName(variable);
}
/*
if (!newCustomClass) {
if (customClasses.exists(name))
error(EAlreadyExistingClass(name));
@@ -808,7 +817,7 @@ class Interp {
customClasses.set(name, new CustomClassHandler(this, name, fields, importVar(extend), [for (i in interfaces) importVar(i)]));
return null;
}
*/
// New Custom Class system
if (localParsedClasses.contains(name))
@@ -1182,26 +1191,26 @@ class Interp {
me.depth = depth;
return r;
};
var f:Function = Reflect.makeVarArgs(f);
var fn:Function = Reflect.makeVarArgs(f);
if (name != null) {
if (depth == 0) {
// global function
if(isStatic && allowStaticVariables) {
staticVariables.set(name, f);
staticVariables.set(name, fn);
} else if(isPublic && allowPublicVariables) {
publicVariables.set(name, f);
publicVariables.set(name, fn);
} else {
variables.set(name, f);
variables.set(name, fn);
}
} else {
// function-in-function is a local function
declared.push({n: name, old: locals.get(name), depth: depth});
var ref:DeclaredVar = {r: f, depth: depth};
var ref:DeclaredVar = {r: fn, depth: depth};
locals.set(name, ref);
capturedLocals.set(name, ref); // allow self-recursion
}
}
return f;
return fn;
case EArrayDecl(arr, wantedType):
var isMap = false;
@@ -1296,10 +1305,12 @@ class Interp {
return arr[index];
}
case ENew(cl, params):
/*
var a = [];
for (e in params)
a.push(expr(e));
return cnew(cl, a);
*/
return cnew(cl, makeArgs(params));
case EThrow(e):
throw expr(e);
case ETry(e, n, _, ecatch):
@@ -1476,7 +1487,7 @@ class Interp {
var ident = resolve(id);
if (ident is CustomClass) {
var customClass:CustomClass = cast ident; // Pass the underlying superclass if exist
args.push(customClass.superClass != null ? customClass.superClass : customClass);
args.push(customClass.superClass != null ? customClass.getSuperclass() : customClass);
} else {
args.push(ident);
}
@@ -1575,7 +1586,7 @@ class Interp {
}) {
return _getRedirect(o, f);
}
/*
if(o is IHScriptCustomClassBehaviour) {
var obj:IHScriptCustomClassBehaviour = cast o;
if(isBypassAccessor) {
@@ -1586,7 +1597,7 @@ class Interp {
}
return obj.hget(f);
}
*/
if (o is IHScriptCustomAccessBehaviour) {
var obj:IHScriptCustomAccessBehaviour = cast o;
if(isBypassAccessor) {
@@ -1631,7 +1642,7 @@ class Interp {
cl != null && setRedirects.exists(cl) && (_setRedirect = setRedirects[cl]) != null;
})
return _setRedirect(o, f, v);
/*
if(o is IHScriptCustomClassBehaviour) {
var obj:IHScriptCustomClassBehaviour = cast o;
if(isBypassAccessor) {
@@ -1642,7 +1653,7 @@ class Interp {
}
return obj.hset(f, v);
}
*/
if (o is IHScriptCustomAccessBehaviour) {
var obj:IHScriptCustomAccessBehaviour = cast o;
if(isBypassAccessor) {
@@ -1794,11 +1805,11 @@ class Interp {
if(staticClass.hasFunction(f))
return staticClass.callFunction(f, args);
}
/*
if(_hasScriptObject && o == CustomClassHandler.staticHandler) {
return UnsafeReflect.callMethodUnsafe(scriptObject, UnsafeReflect.field(scriptObject, "_HX_SUPER__" + f), args);
}
*/
var func = get(o, f);
// Workaround for an HTML5-specific issue.
@@ -1813,10 +1824,11 @@ class Interp {
}
function call(o:Dynamic, f:Dynamic, args:Array<Dynamic>):Dynamic {
/*
if(f == CustomClassHandler.staticHandler) {
return null;
}
*/
if (_inCustomClass) {
if (o == null && _nextCallObject != null) {
o = _nextCallObject;
+34 -34
View File
@@ -14,6 +14,9 @@ using StringTools;
* The Custom Class core.
*
* Provides handlers for custom classes.
*
* Rest in peace, CustomClassHandler.hx
*
* Based on Polymod Hscript class system
* @see https://github.com/larsiusprime/polymod/tree/master/polymod/hscript/_internal
*/
@@ -23,20 +26,18 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
public var superClass:Dynamic;
public var superConstructor(default, null):Dynamic;
// TODO: move this to CustomClassDecl
public var className(get, never):String;
private function get_className():String {
var pkg = __class.pkg != null ? '${__class.pkg.join(".")}.' : "";
var name = __class.classDecl.name;
return '$pkg$name';
return __class.toString();
}
private var __class:CustomClassDecl;
private var _cachedSuperFields:Null<Map<String, Dynamic>> = null;
private var __cachedSuperFields:Null<Map<String, Dynamic>> = null;
private var _cachedFieldDecls:Map<String, FieldDecl> = null;
private var _cachedFunctionDecls:Map<String, FunctionDecl> = null;
private var _cachedVarDecls:Map<String, VarDecl> = null;
private var __cachedFieldDecls:Map<String, FieldDecl> = null;
private var __cachedFunctionDecls:Map<String, FunctionDecl> = null;
private var __cachedVarDecls:Map<String, VarDecl> = null;
public var __allowSetGet:Bool = false;
@@ -65,7 +66,7 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
buildUsings();
if (extendFieldDecl != null)
_cachedSuperFields = extendFieldDecl;
__cachedSuperFields = extendFieldDecl;
buildClass();
@@ -80,22 +81,22 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
}
function buildClass() {
_cachedFieldDecls = [];
_cachedFunctionDecls = [];
_cachedVarDecls = [];
__cachedFieldDecls = [];
__cachedFunctionDecls = [];
__cachedVarDecls = [];
if (_cachedSuperFields == null)
_cachedSuperFields = [];
if (__cachedSuperFields == null)
__cachedSuperFields = [];
for (f in __class.classDecl.fields) {
if (f.access.contains(AStatic))
continue; // Skip static field. It's handled by CustomClassDecl.hx
_cachedFieldDecls.set(f.name, f);
__cachedFieldDecls.set(f.name, f);
switch (f.kind) {
case KFunction(fn):
if(f.name.startsWith('set_') || f.name.startsWith('get_'))
__allowSetGet = true;
_cachedFunctionDecls.set(f.name, fn);
__cachedFunctionDecls.set(f.name, fn);
#if hscriptPos
var fexpr:Expr = {
e: ExprDef.EFunction(fn.args, fn.body, f.name, fn.ret, false, false),
@@ -110,7 +111,7 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
var f0 = this.interp.expr(fexpr);
this.interp.variables.set(f.name, f0);
case KVar(v):
_cachedVarDecls.set(f.name, v);
__cachedVarDecls.set(f.name, v);
if (v.expr != null) {
var varValue = this.interp.expr(v.expr);
this.interp.variables.set(f.name, varValue);
@@ -118,11 +119,11 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
}
}
if (!_cachedSuperFields.empty()) {
for (f => v in _cachedSuperFields) {
if (!__cachedSuperFields.empty()) {
for (f => v in __cachedSuperFields) {
this.hset(f, v);
}
_cachedSuperFields.clear();
__cachedSuperFields.clear();
}
}
@@ -132,16 +133,16 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
});
}
private function createSuperClass(args:Array<Dynamic> = null) {
private function createSuperClass(?args:Array<Dynamic>) {
if (args == null)
args = [];
// TODO: disallow copy for super Custom Class
if(__class.superClassDecl is CustomClassDecl)
superClass = new CustomClass(__class.superClassDecl, args, _cachedFieldDecls, this.interp);
superClass = new CustomClass(__class.superClassDecl, args, __cachedFieldDecls, this.interp);
else {
if (_cachedSuperFields != null) {
Reflect.setField(__class.superClassDecl, "__cachedFields", _cachedSuperFields); // Static field
if (__cachedSuperFields != null) {
Reflect.setField(__class.superClassDecl, "__cachedFields", __cachedSuperFields); // Static field
}
var disallowCopy = Type.getInstanceFields(__class.superClassDecl);
@@ -231,7 +232,6 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
}
} else {
var fixedArgs = [];
// OVERRIDE CHANGE: Use _HX_SUPER__ when calling superclass
var fixedName = '_HX_SUPER__${name}';
for (a in args) {
if ((a is CustomClass)) {
@@ -255,23 +255,23 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
// Field check
private function hasField(name:String):Bool {
return _cachedFieldDecls != null ? _cachedFieldDecls.exists(name) : false;
return __cachedFieldDecls != null ? __cachedFieldDecls.exists(name) : false;
}
private function getField(name:String):FieldDecl {
return _cachedFieldDecls != null ? _cachedFieldDecls.get(name) : null;
return __cachedFieldDecls != null ? __cachedFieldDecls.get(name) : null;
}
private function hasVar(name:String):Bool {
return _cachedVarDecls != null ? _cachedVarDecls.exists(name) : false;
return __cachedVarDecls != null ? __cachedVarDecls.exists(name) : false;
}
private function getVar(name:String):VarDecl {
return _cachedVarDecls != null ? _cachedVarDecls.get(name) : null;
return __cachedVarDecls != null ? __cachedVarDecls.get(name) : null;
}
private function hasFunction(name:String):Bool {
return _cachedFunctionDecls != null ? _cachedFunctionDecls.exists(name) : false;
return __cachedFunctionDecls != null ? __cachedFunctionDecls.exists(name) : false;
}
private function getFunction(name:String):Function {
@@ -282,8 +282,8 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
// SuperClass field check
private function cacheSuperField(name:String, value:Dynamic) {
if (_cachedSuperFields != null) {
_cachedSuperFields.set(name, value);
if (__cachedSuperFields != null) {
__cachedSuperFields.set(name, value);
}
}
@@ -307,8 +307,8 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
* @param name The name of the function to remove from the cache.
*/
private function purgeFunction(name:String):Void {
if (_cachedFunctionDecls != null) {
_cachedFunctionDecls.remove(name);
if (__cachedFunctionDecls != null) {
__cachedFunctionDecls.remove(name);
}
}
+16 -1
View File
@@ -7,6 +7,10 @@ import hscript.Expr.FieldDecl;
import hscript.Expr.VarDecl;
import hscript.Expr.FunctionDecl;
/**
* The ACTUAL "StaticHandler"
* @author Jamextreme140
*/
@:access(hscript.Interp)
@:structInit
class CustomClassDecl implements IHScriptCustomAccessBehaviour {
@@ -129,7 +133,12 @@ class CustomClassDecl implements IHScriptCustomAccessBehaviour {
extendString = this.pkg.join(".") + "." + extendString;
}
superClassDecl = ProxyType.resolveClass(extendString);
var cls:Dynamic = Type.resolveClass('${extendString}_HSX');
if(cls == null)
cls = ProxyType.resolveClass(extendString);
superClassDecl = cls;
if(superClassDecl == null)
staticInterp.error(ECustom("could not resolve super class: " + extendString));
}
@@ -234,6 +243,12 @@ class CustomClassDecl implements IHScriptCustomAccessBehaviour {
__allowSetGet = true;
return r;
}
public function toString():String {
var pkg = pkg != null ? '${pkg.join(".")}.' : "";
var name = classDecl.name;
return '$pkg$name';
}
}
typedef CustomClassImport = {