diff --git a/hscript/Tools.hx b/hscript/Tools.hx index a34902b..82ca423 100644 --- a/hscript/Tools.hx +++ b/hscript/Tools.hx @@ -163,6 +163,14 @@ class Tools { #end } + public static function getClassDeclFields(classDecl:hscript.Expr.ClassDecl, onlyStatic:Bool = false):Array { + var fields = classDecl.fields.filter(function(field:FieldDecl) { + var isStatic = field.access.contains(AStatic); + return onlyStatic ? isStatic : !isStatic; + }); + return fields; + } + } /** diff --git a/hscript/customclass/CustomClass.hx b/hscript/customclass/CustomClass.hx index f1d8d00..aa36720 100644 --- a/hscript/customclass/CustomClass.hx +++ b/hscript/customclass/CustomClass.hx @@ -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> = 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, ?extendFieldDecl:Map, ?ogInterp:Interp) { + public function new(__class:CustomClassDecl, args:Array, ?extendFieldDecl:Map, ?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) { diff --git a/hscript/proxy/ProxyType.hx b/hscript/proxy/ProxyType.hx index 2c0436a..b8bc940 100644 --- a/hscript/proxy/ProxyType.hx +++ b/hscript/proxy/ProxyType.hx @@ -15,8 +15,10 @@ class ProxyType { In general, type parameter information cannot be obtained at runtime. **/ - inline static function getClass(o:T):Null> { - return Type.getClass(o); + inline static function getClass(o:OneOfTwo):Null { + 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):Class { + // 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):String { - return Type.getClassName(c); + inline static function getClassName(c:OneOfTwo, 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(cl:OneOfTwo, CustomClassDecl>, args:Array):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(cl:Class):T { - return Type.createEmptyInstance(cl); + inline static function createEmptyInstance(cl:OneOfTwo, 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):Array { - return Type.getInstanceFields(c); + inline static function getInstanceFields(c:OneOfTwo, CustomClassDecl>):Array { + 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):Array { - return Type.getClassFields(c); + inline static function getClassFields(c:OneOfTwo, CustomClassDecl>):Array { + 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); } /**