Custom Classes rework progress
This commit is contained in:
+96
-19
@@ -1,5 +1,7 @@
|
||||
package hscript;
|
||||
|
||||
import hscript.utils.UnsafeReflect;
|
||||
import haxe.Constraints.Function;
|
||||
using Lambda;
|
||||
|
||||
// TODO
|
||||
@@ -11,40 +13,115 @@ using Lambda;
|
||||
* @author Jamextreme140
|
||||
*/
|
||||
@:access(hscript.CustomClassHandler)
|
||||
class CustomClass /*implements IHScriptCustomClassBehaviour*/{
|
||||
class CustomClass implements IHScriptCustomClassBehaviour{
|
||||
|
||||
public var className(get, never):String;
|
||||
private function get_className():String
|
||||
return __class.name;
|
||||
|
||||
var interp:Interp;
|
||||
public var __interp:Interp;
|
||||
public var __custom__variables:Map<String, Dynamic>; // TODO: remove this
|
||||
public var __real_fields:Array<String>;
|
||||
public var __class__fields:Array<String>; // Declared fields
|
||||
|
||||
public var __allowSetGet:Bool = true;
|
||||
|
||||
var __class:CustomClassHandler;
|
||||
var __superClass:IHScriptCustomClassBehaviour;
|
||||
var __constructor:Function;
|
||||
var fields:Array<Expr>;
|
||||
|
||||
public function new(__class:CustomClassHandler) {
|
||||
public function new(__class:CustomClassHandler, args:Array<Dynamic>) {
|
||||
this.__class = __class;
|
||||
|
||||
interp = new Interp();
|
||||
interp.errorHandler = __class.staticInterp.errorHandler;
|
||||
interp.scriptObject = this;
|
||||
__interp = new Interp();
|
||||
__interp.errorHandler = __class.staticInterp.errorHandler;
|
||||
__interp.importFailedCallback = __class.staticInterp.importFailedCallback;
|
||||
|
||||
fields = [];
|
||||
/*
|
||||
for(e in __class.fields) {
|
||||
switch (Tools.expr(e)) {
|
||||
case EVar(n, _, e, _, isStatic, _, isFinal, _, get, set, isVar):
|
||||
if(!isStatic)
|
||||
fields.push(e);
|
||||
case EFunction(args, e, name, ret, _, isStatic, _, _, isFinal, _):
|
||||
if(!isStatic)
|
||||
fields.push(e);
|
||||
__interp.variables = __class.staticInterp.variables; // This will access to static fields
|
||||
__interp.allowPublicVariables = __class.ogInterp.allowPublicVariables;
|
||||
__interp.publicVariables = __class.ogInterp.publicVariables;
|
||||
__interp.allowStaticVariables = __class.ogInterp.allowStaticVariables;
|
||||
__interp.staticVariables = __class.ogInterp.staticVariables;
|
||||
|
||||
__interp.scriptObject = this;
|
||||
|
||||
this.fields = __class.fields;
|
||||
for(f in fields) {
|
||||
switch(Tools.expr(f)) {
|
||||
case EVar(n):
|
||||
__class__fields.push(n);
|
||||
case EFunction(_, _, n):
|
||||
__class__fields.push(n);
|
||||
default:
|
||||
}
|
||||
@:privateAccess __interp.exprReturn(f);
|
||||
}
|
||||
*/
|
||||
for(f in fields)
|
||||
@:privateAccess interp.exprReturn(f);
|
||||
|
||||
if(hasField('new')) {
|
||||
buildConstructor();
|
||||
call('new', args);
|
||||
|
||||
if(this.__superClass == null && __class.extend != null)
|
||||
__interp.error(ECustom("super() not called"));
|
||||
}
|
||||
else if(__class.extend != null) {
|
||||
buildSuperClass(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function buildConstructor() {
|
||||
__constructor = Reflect.makeVarArgs(buildSuperClass);
|
||||
}
|
||||
|
||||
function buildSuperClass(?args:Array<Dynamic>) {
|
||||
if(args == null)
|
||||
args = [];
|
||||
|
||||
if(__class.cl == null) __interp.error(ECustom('Current class does not have a super'));
|
||||
|
||||
if (__class.cl == CustomClassHandler) {
|
||||
__superClass = new CustomClass(__class.cl, args);
|
||||
} else {
|
||||
var disallowCopy = Type.getInstanceFields(__class.cl);
|
||||
__superClass = Type.createInstance(__class.cl, args);
|
||||
__superClass.__real_fields = disallowCopy;
|
||||
__superClass.__interp = this.__interp;
|
||||
}
|
||||
}
|
||||
|
||||
function call(name:String, ?args:Array<Dynamic>):Dynamic {
|
||||
var fn = __interp.variables.get(name);
|
||||
if(fn != null && Reflect.isFunction(fn))
|
||||
return UnsafeReflect.callMethodUnsafe(null, fn, (args == null) ? [] : args);
|
||||
|
||||
__interp.error(ECustom('$name is not a function'));
|
||||
return null;
|
||||
}
|
||||
|
||||
function hasField(name:String) {
|
||||
return __interp.variables.exists(name);
|
||||
}
|
||||
|
||||
public function hget(name:String):Dynamic {
|
||||
switch (name) {
|
||||
case 'superClass': return __superClass;
|
||||
case 'superConstructor': return __constructor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __callGetter(name:String):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hset(name:String, val:Dynamic):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __callSetter(name:String, val:Dynamic):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toString():String
|
||||
|
||||
@@ -8,18 +8,21 @@ using StringTools;
|
||||
/**
|
||||
* Provides handlers for static custom class fields and instantiation.
|
||||
*/
|
||||
class CustomClassHandler implements IHScriptCustomConstructor {
|
||||
class CustomClassHandler implements IHScriptCustomConstructor implements IHScriptCustomBehaviour{
|
||||
public static var staticHandler = new StaticHandler();
|
||||
|
||||
public var __allowSetGet:Bool = true;
|
||||
|
||||
public var ogInterp:Interp;
|
||||
public var name:String;
|
||||
public var fields:Array<Expr>;
|
||||
public var extend:String;
|
||||
public var extend:Null<String>;
|
||||
public var interfaces:Array<String>;
|
||||
|
||||
public var cl:Class<Dynamic>;
|
||||
public var cl:Dynamic;
|
||||
|
||||
private var staticInterp:Interp;
|
||||
private var staticFields:Array<String>;
|
||||
|
||||
public function new(ogInterp:Interp, name:String, fields:Array<Expr>, ?extend:String, ?interfaces:Array<String>) {
|
||||
this.ogInterp = ogInterp;
|
||||
@@ -28,17 +31,55 @@ class CustomClassHandler implements IHScriptCustomConstructor {
|
||||
this.extend = extend;
|
||||
this.interfaces = interfaces;
|
||||
|
||||
this.cl = extend == null ? CustomTemplateClass : Type.resolveClass('${extend}_HSX');
|
||||
if(cl == null)
|
||||
ogInterp.error(EInvalidClass(extend));
|
||||
if(extend != null) {
|
||||
if(ogInterp.customClasses.exists(extend))
|
||||
this.cl = ogInterp.customClasses.get(extend);
|
||||
else
|
||||
this.cl = Type.resolveClass('${extend}_HSX');
|
||||
}
|
||||
//this.cl = extend == null ? CustomTemplateClass : Type.resolveClass('${extend}_HSX');
|
||||
//if(cl == null)
|
||||
// ogInterp.error(EInvalidClass(extend));
|
||||
|
||||
initStatic();
|
||||
}
|
||||
|
||||
@:access(hscript.Interp)
|
||||
function initStatic() {
|
||||
staticInterp = new Interp();
|
||||
staticInterp.errorHandler = ogInterp.errorHandler;
|
||||
staticInterp.importFailedCallback = ogInterp.importFailedCallback;
|
||||
|
||||
staticInterp.variables = ogInterp.variables;
|
||||
staticInterp.allowPublicVariables = ogInterp.allowPublicVariables;
|
||||
staticInterp.publicVariables = ogInterp.publicVariables;
|
||||
staticInterp.allowStaticVariables = ogInterp.allowStaticVariables;
|
||||
staticInterp.staticVariables = ogInterp.staticVariables;
|
||||
|
||||
// TODO: optimize this
|
||||
for(ex in fields) {
|
||||
switch (Tools.expr(ex)) {
|
||||
case EVar(n, _, _, _, isStatic, _, _, _, _, _, _):
|
||||
if(isStatic) {
|
||||
staticInterp.exprReturn(ex);
|
||||
staticFields.push(n);
|
||||
fields.remove(ex);
|
||||
}
|
||||
case EFunction(_, _, n, _, _, isStatic, _, _, _, _):
|
||||
if(isStatic) {
|
||||
staticInterp.exprReturn(ex);
|
||||
staticFields.push(n);
|
||||
fields.remove(ex);
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function hnew(args:Array<Dynamic>):Dynamic {
|
||||
// TODO: clean this up, it sucks, i hate it
|
||||
// TODO: make static vars work correctly
|
||||
/*
|
||||
var interp = new Interp();
|
||||
|
||||
interp.errorHandler = ogInterp.errorHandler;
|
||||
@@ -152,11 +193,29 @@ class CustomClassHandler implements IHScriptCustomConstructor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
var _class = new CustomClass(this, args);
|
||||
|
||||
return _class;
|
||||
}
|
||||
|
||||
public function hget(name:String):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hset(name:String, val:Dynamic):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __callGetter(name:String):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __callSetter(name:String, val:Dynamic):Dynamic {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -592,6 +592,12 @@ class Interp {
|
||||
return null;
|
||||
id = StringTools.trim(id);
|
||||
|
||||
if(inCustomClass && id == 'super') {
|
||||
var customClass:IHScriptCustomClassBehaviour = cast scriptObject;
|
||||
var superClass = customClass.hget('superClass');
|
||||
return superClass == null ? customClass.hget('superConstructor') : superClass;
|
||||
}
|
||||
|
||||
if (locals.exists(id)) {
|
||||
var l = locals.get(id);
|
||||
if(l != null) {
|
||||
|
||||
Reference in New Issue
Block a user