"Type" for Custom Classes

This commit is contained in:
Jaime Humberto Macias Bustamante
2025-03-24 20:28:29 -07:00
parent 73c17e51dc
commit e71f5a0471
3 changed files with 56 additions and 25 deletions
+8
View File
@@ -163,6 +163,14 @@ class Tools {
#end
}
public static function getClassDeclFields(classDecl:hscript.Expr.ClassDecl, onlyStatic:Bool = false):Array<FieldDecl> {
var fields = classDecl.fields.filter(function(field:FieldDecl) {
var isStatic = field.access.contains(AStatic);
return onlyStatic ? isStatic : !isStatic;
});
return fields;
}
}
/**
+15 -13
View File
@@ -11,6 +11,8 @@ using Lambda;
using StringTools;
/**
* The Custom Class core.
*
* Provides handlers for custom classes.
* Based on Polymod Hscript class system
* @see https://github.com/larsiusprime/polymod/tree/master/polymod/hscript/_internal
@@ -23,6 +25,15 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
public var superConstructor(default, null):Dynamic;
public var className(get, never):String;
private function get_className():String {
// TODO: simplify this
var name = "";
if (__class.pkg != null) {
name += __class.pkg.join(".");
}
name += __class.classDecl.name;
return name;
}
private var __class:CustomClassDecl;
private var _cachedSuperFields:Null<Map<String, Dynamic>> = null;
@@ -33,16 +44,7 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
public var __allowSetGet:Bool = true;
private function get_className():String {
var name = "";
if (__class.pkg != null) {
name += __class.pkg.join(".");
}
name += __class.classDecl.name;
return name;
}
public function new(__class:CustomClassDecl, args:Array<Dynamic>, ?extendFieldDecl:Map<String, Dynamic>, ?ogInterp:Interp) {
public function new(__class:CustomClassDecl, args:Array<Dynamic>, ?extendFieldDecl:Map<String, Dynamic>, ?ogInterp:Interp, ?callNew:Bool = true) {
this.__class = __class;
this.interp = new Interp(this);
@@ -61,7 +63,7 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
buildClass();
if (hasFunction('new')) {
if (hasFunction('new') && callNew) {
buildSuperConstructor();
callFunction('new', args);
if (this.superClass == null && this.__class.classDecl.extend != null)
@@ -132,8 +134,8 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
}
if (Interp.customClassExist(extendString)) {
var abstractSuperClass:CustomClass = new CustomClass(Interp.getCustomClass(extendString), args, _cachedSuperFields, this.interp);
superClass = abstractSuperClass;
var customSuperClass:CustomClass = new CustomClass(Interp.getCustomClass(extendString), args, _cachedSuperFields, this.interp);
superClass = customSuperClass;
} else {
var c = Type.resolveClass('${extendString}_HSX');
if (c == null) {
+33 -12
View File
@@ -15,8 +15,10 @@ class ProxyType {
In general, type parameter information cannot be obtained at runtime.
**/
inline static function getClass<T>(o:T):Null<Class<T>> {
return Type.getClass(o);
inline static function getClass<T>(o:OneOfTwo<T, CustomClass>):Null<Dynamic> {
if(o is CustomClass)
@:privateAccess return cast(o, CustomClass).__class;
return Type.getClass(cast o);
}
/**
@@ -48,6 +50,7 @@ class ProxyType {
In general, type parameter information cannot be obtained at runtime.
**/
inline static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
// TODO: SuperClass declaration on CustomClassDecl instead of CustomClass
return Type.getSuperClass(c);
}
@@ -66,8 +69,15 @@ class ProxyType {
The class name does not include any type parameters.
**/
inline static function getClassName(c:Class<Dynamic>):String {
return Type.getClassName(c);
inline static function getClassName(c:OneOfTwo<Class<Dynamic>, CustomClassDecl>):String {
if(c is CustomClassDecl) {
var cls:CustomClassDecl = cast c;
var name = cls.classDecl.name;
if(cls.pkg != null)
name = cls.pkg.join('.') + name;
return name;
}
return Type.getClassName(cast c);
}
/**
@@ -147,9 +157,9 @@ class ProxyType {
guaranteed to be taken into account.
**/
inline static function createInstance<T>(cl:OneOfTwo<Class<T>, CustomClassDecl>, args:Array<Dynamic>):T {
// TODO: somehow pass the ogInterp argument without breaking the original functionality
if(cl is CustomClassDecl) {
//return cast new CustomClass(cast cl, args);
return cast Type.createInstance(CustomClass, [cast cl, args]);
return cast new CustomClass(cast cl, args);
}
return Type.createInstance(cast cl, args);
}
@@ -161,8 +171,11 @@ class ProxyType {
If `cl` is null, the result is unspecified.
**/
inline static function createEmptyInstance<T>(cl:Class<T>):T {
return Type.createEmptyInstance(cl);
inline static function createEmptyInstance<T>(cl:OneOfTwo<Class<T>, CustomClassDecl>):T {
// TODO: same as above
if(cl is CustomClassDecl)
return cast new CustomClass(cast cl, [], null, null, false);
return Type.createEmptyInstance(cast cl);
}
/**
@@ -217,8 +230,12 @@ class ProxyType {
If `c` is null, the result is unspecified.
**/
inline static function getInstanceFields(c:Class<Dynamic>):Array<String> {
return Type.getInstanceFields(c);
inline static function getInstanceFields(c:OneOfTwo<Class<Dynamic>, CustomClassDecl>):Array<String> {
if(c is CustomClassDecl) {
var cls:CustomClassDecl = cast c;
return [for(f in Tools.getClassDeclFields(cls.classDecl)) f.name];
}
return Type.getInstanceFields(cast c);
}
/**
@@ -230,8 +247,12 @@ class ProxyType {
If `c` is null, the result is unspecified.
**/
inline static function getClassFields(c:Class<Dynamic>):Array<String> {
return Type.getClassFields(c);
inline static function getClassFields(c:OneOfTwo<Class<Dynamic>, CustomClassDecl>):Array<String> {
if(c is CustomClassDecl) {
var cls:CustomClassDecl = cast c;
return [for(f in Tools.getClassDeclFields(cls.classDecl, true)) f.name];
}
return Type.getClassFields(cast c);
}
/**