getter, setter and final for Custom Classes
full support for "var a(get, set):Int". Also, it takes into account final vars Soon for inline custom classes [UNTESTED]
This commit is contained in:
+2
-1
@@ -54,7 +54,7 @@ enum Expr {
|
||||
EIgnore(skip:Bool);
|
||||
EConst( c : Const );
|
||||
EIdent( v : String );
|
||||
EVar( n : String, ?t : CType, ?e : Expr, ?isPublic : Bool, ?isStatic : Bool, ?isPrivate : Bool, ?isFinal : Bool, ?isInline : Bool );
|
||||
EVar( n : String, ?t : CType, ?e : Expr, ?isPublic : Bool, ?isStatic : Bool, ?isPrivate : Bool, ?isFinal : Bool, ?isInline : Bool, ?get : String, ?set : String );
|
||||
EParent( e : Expr );
|
||||
EBlock( e : Array<Expr> );
|
||||
EField( e : Expr, f : String , ?safe : Bool );
|
||||
@@ -220,6 +220,7 @@ typedef VarDecl = {
|
||||
var set : Null<String>;
|
||||
var expr : Null<Expr>;
|
||||
var type : Null<CType>;
|
||||
var isFinal : Null<Bool>;
|
||||
}
|
||||
|
||||
typedef TypeParamDecl = {};
|
||||
|
||||
+6
-5
@@ -889,16 +889,17 @@ class Interp {
|
||||
};
|
||||
|
||||
customClassFields.push(fd);
|
||||
case EVar(n, t, e, isPublic, isStatic, isPrivate, isFinal, isInline):
|
||||
case EVar(n, t, e, isPublic, isStatic, isPrivate, isFinal, isInline, getter, setter):
|
||||
var varAcc:Array<FieldAccess> = [];
|
||||
if (isPublic) varAcc.push(APublic);
|
||||
if (isStatic) varAcc.push(AStatic);
|
||||
|
||||
var vrd:VarDecl = {
|
||||
get: null,
|
||||
set: null,
|
||||
get: getter,
|
||||
set: setter,
|
||||
expr: e,
|
||||
type: t
|
||||
type: t,
|
||||
isFinal: isFinal
|
||||
};
|
||||
var fd:FieldDecl = {
|
||||
name: n,
|
||||
@@ -928,7 +929,7 @@ class Interp {
|
||||
|
||||
var customClassDecl:CustomClassDecl = {
|
||||
classDecl: classDecl,
|
||||
imports: localImports,
|
||||
imports: localImports, // TODO: better way to reuse imported classes
|
||||
usings: [for(u in this.usings) u.name],
|
||||
pkg: null,
|
||||
ogInterp: this,
|
||||
|
||||
@@ -2,13 +2,14 @@ package hscript;
|
||||
|
||||
class InterpConfig {
|
||||
// Automatic import redirect for certain classes
|
||||
public static var IMPORT_REDIRECTS(default, never) = [
|
||||
public static final IMPORT_REDIRECTS = [
|
||||
"Type" => "hscript.proxy.ProxyType"
|
||||
];
|
||||
|
||||
// Incase an import fails
|
||||
// These are the module names
|
||||
@:unreflective public static var DISALLOW_IMPORT(default, never) = [
|
||||
@:unreflective
|
||||
public static final DISALLOW_IMPORT = [
|
||||
"Type"
|
||||
];
|
||||
}
|
||||
+5
-2
@@ -854,6 +854,8 @@ class Parser {
|
||||
}
|
||||
}
|
||||
var ident = getIdent();
|
||||
var get = null, set = null;
|
||||
// TODO: getter and setter
|
||||
var tk = token();
|
||||
var t = null;
|
||||
nextType = null;
|
||||
@@ -1775,10 +1777,10 @@ class Parser {
|
||||
ret : inf.ret,
|
||||
}),
|
||||
};
|
||||
case "var":
|
||||
case "var" | "final":
|
||||
var name = getIdent();
|
||||
var get = null, set = null;
|
||||
if( maybe(TPOpen) ) {
|
||||
if(id != "final" && maybe(TPOpen) ) {
|
||||
get = getIdent();
|
||||
ensure(TComma);
|
||||
set = getIdent();
|
||||
@@ -1806,6 +1808,7 @@ class Parser {
|
||||
set : set,
|
||||
type : type,
|
||||
expr : expr,
|
||||
isFinal: id == "final"
|
||||
}),
|
||||
};
|
||||
default:
|
||||
|
||||
@@ -315,15 +315,19 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
|
||||
}
|
||||
|
||||
if (hasVar(name)) {
|
||||
var v = getVar(name);
|
||||
var getter = v.get != null ? v.get : 'default';
|
||||
|
||||
var value:Dynamic = null;
|
||||
|
||||
if (__allowSetGet && hasFunction('get_${name}'))
|
||||
if(getter == "never")
|
||||
throw 'field $name cannot be accessed for reading';
|
||||
|
||||
if (__allowSetGet && getter == "get" && 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);
|
||||
@@ -344,10 +348,9 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
|
||||
|
||||
if (this.superClass is CustomClass) {
|
||||
var superCustomClass:CustomClass = cast(this.superClass, CustomClass);
|
||||
try {
|
||||
superCustomClass.__allowSetGet = this.__allowSetGet;
|
||||
return superCustomClass.hget(name);
|
||||
} catch (e) {}
|
||||
|
||||
superCustomClass.__allowSetGet = this.__allowSetGet;
|
||||
return superCustomClass.hget(name);
|
||||
}
|
||||
// Real Class
|
||||
var fields = Type.getInstanceFields(Type.getClass(this.superClass));
|
||||
@@ -366,17 +369,22 @@ class CustomClass implements IHScriptCustomAccessBehaviour {
|
||||
switch (name) {
|
||||
default:
|
||||
if (hasVar(name)) {
|
||||
if (__allowSetGet && hasFunction('set_${name}'))
|
||||
var v = getVar(name);
|
||||
var setter = v.set != null ? v.set : 'default';
|
||||
|
||||
if (setter == "never" || (v.isFinal != null && v.isFinal))
|
||||
throw 'field $name cannot be accessed for writing';
|
||||
|
||||
if (__allowSetGet && setter == "set" && hasFunction('set_${name}'))
|
||||
return __callSetter(name, val);
|
||||
|
||||
this.interp.variables.set(name, val);
|
||||
} else if (this.superClass != null) {
|
||||
if (this.superClass is CustomClass) {
|
||||
var superCustomClass:CustomClass = cast(this.superClass, CustomClass);
|
||||
try {
|
||||
superCustomClass.__allowSetGet = this.__allowSetGet;
|
||||
return superCustomClass.hset(name, val);
|
||||
} catch (e:Dynamic) {}
|
||||
|
||||
superCustomClass.__allowSetGet = this.__allowSetGet;
|
||||
return superCustomClass.hset(name, val);
|
||||
}
|
||||
// Real Class
|
||||
if (Type.getClass(this.superClass) == null) {
|
||||
|
||||
Reference in New Issue
Block a user