Compare commits

...
Author SHA1 Message Date
gabry 75a21abecd revert accidental deletion of blocklist 2026-07-20 19:49:11 +02:00
gabry 763999c376 fix this binding loss on js 2026-07-20 19:10:23 +02:00
Jaime Humberto Macias Bustamante c1b23320c3 fixed set call with nullable values 2026-07-18 21:48:23 -07:00
Jaime Humberto Macias Bustamante 266bb67c93 moved import blacklist to Config.hx 2026-07-08 22:11:51 -07:00
Jaime Humberto Macias Bustamante 6276ddfc2c Update ClassExtendMacro.hx
i need a break...
2026-06-22 21:17:50 -07:00
Jaime Humberto Macias Bustamante b8ead38556 Squashed commit of the following:
commit 24abfa436e
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Sat Jun 20 23:29:32 2026 -0700

    Update CustomClassHandler.hx

    forgot to change this too...

commit 92e458876e
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Sat Jun 20 23:23:10 2026 -0700

    remove direct function call handling

    after testing, it turns out that trying to handle the direct getter/setter function will be so complex than I thought.

commit 44d8b1e0e1
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Sat Jun 20 19:39:17 2026 -0700

    better static field filtering

commit ff649efadf
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Sat Jun 20 18:50:03 2026 -0700

    better accessor bypass handling

commit 4625529be7
Author: Crimson-is-stupid <89041944+Crimson-is-stupid@users.noreply.github.com>
Date:   Thu Jun 4 09:32:25 2026 +0300

    Reimplement Trigraph Fix (#18)

    * replace all "??=" with "??" + "="

    * Update Expr.hx

commit b9da833bb5
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Wed Jun 3 17:14:08 2026 -0700

    better callAccessor + optimize "__allowGetSet"

commit 0c08f64274
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Wed Jun 3 16:57:58 2026 -0700

    Update Property.hx

commit 3add08e0ee
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Fri May 29 10:23:56 2026 -0700

    some docs + small optimizations

commit 77fae88890
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Thu Apr 30 11:32:13 2026 -0700

    oversight again...

commit 2a301ea591
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Thu Apr 30 11:27:07 2026 -0700

    fixed small oversight

commit 634d819cc2
Author: Jaime Humberto Macias Bustamante <jamextreme140@outlook.com>
Date:   Thu Apr 30 11:02:47 2026 -0700

    Refactor property fields

    Now you can call directly the getter/setter functions without triggering them again.
2026-06-20 23:46:55 -07:00
Crimson-is-stupidandGitHub 1972ae6a82 Reimplement Trigraph Fix (#18)
* replace all "??=" with "??" + "="

* Update Expr.hx
2026-06-03 23:32:25 -07:00
7 changed files with 158 additions and 100 deletions
+5
View File
@@ -21,4 +21,9 @@ class Config {
public static final DISALLOW_ABSTRACT_AND_ENUM = [ public static final DISALLOW_ABSTRACT_AND_ENUM = [
]; ];
@:unreflective
public static final IMPORT_BLACKLIST:Array<String> = [
// "flixel.FlxG"
];
} }
+7 -7
View File
@@ -13,7 +13,6 @@ using Lambda;
* @author Jamextreme140 * @author Jamextreme140
*/ */
@:access(hscript.CustomClassHandler) @:access(hscript.CustomClassHandler)
@:access(hscript.Property)
class CustomClass implements IHScriptCustomClassBehaviour { class CustomClass implements IHScriptCustomClassBehaviour {
public var className(get, never):String; public var className(get, never):String;
@@ -174,9 +173,9 @@ class CustomClass implements IHScriptCustomClassBehaviour {
var f = __interp.variables.get(name); var f = __interp.variables.get(name);
if (f != null && allowProperty && f is Property) { if (f != null && allowProperty && f is Property) {
var prop:Property = cast f; var prop:Property = cast f;
prop.__allowSetGet = this.__allowSetGet; //prop.__allowSetGet = this.__allowSetGet;
var r = prop.callGetter(name); var r = prop.get(!__allowSetGet);
prop.__allowSetGet = null; //prop.__allowSetGet = true;
return r; return r;
} }
return f; return f;
@@ -186,9 +185,9 @@ class CustomClass implements IHScriptCustomClassBehaviour {
var f = getField(name, false); var f = getField(name, false);
if (f != null && f is Property) { if (f != null && f is Property) {
var prop:Property = cast f; var prop:Property = cast f;
prop.__allowSetGet = this.__allowSetGet; //prop.__allowSetGet = this.__allowSetGet;
var r = prop.callSetter(name, val); var r = prop.set(val, !__allowSetGet);
prop.__allowSetGet = null; //prop.__allowSetGet = true;
return r; return r;
} }
__interp.variables.set(name, val); __interp.variables.set(name, val);
@@ -354,6 +353,7 @@ class CustomClass implements IHScriptCustomClassBehaviour {
return cls; return cls;
} }
// TODO: scriptable "toString" function
public function toString():String public function toString():String
return className; return className;
} }
+15 -20
View File
@@ -60,23 +60,19 @@ class CustomClassHandler implements IHScriptCustomConstructor implements IHScrip
if(!__interp.variables.exists(f)) if(!__interp.variables.exists(f))
__interp.variables.set(f, v); __interp.variables.set(f, v);
for(e in fields.copy()) { for(i => e in fields.copy()) {
var validField:Bool = false; var isValid:Bool = false;
var staticField:Bool = false; var staticField:Bool = false;
var fieldName:String = ""; var fieldName:String = null;
switch (Tools.expr(e)) { switch (Tools.expr(e)) {
case EVar(n, _, _, _, isStatic): case EVar(n, _, _, _, isStatic) | EFunction(_, _, n, _, _, isStatic):
validField = true; isValid = true;
staticField = isStatic;
fieldName = n;
case EFunction(_, _, n, _, _, isStatic, _, _, _, _):
validField = true;
staticField = isStatic; staticField = isStatic;
fieldName = n; fieldName = n;
default: default:
} }
if(staticField && validField) { if(staticField && isValid) {
__interp.exprReturn(e); __interp.exprReturn(e);
__staticFields.push(fieldName); __staticFields.push(fieldName);
fields.remove(e); fields.remove(e);
@@ -88,7 +84,7 @@ class CustomClassHandler implements IHScriptCustomConstructor implements IHScrip
return new CustomClass(this, args); return new CustomClass(this, args);
@:allow(hscript.Interp) @:allow(hscript.Interp)
function hasField(name:String) { inline function hasField(name:String) {
return __staticFields.contains(name); return __staticFields.contains(name);
} }
@@ -96,9 +92,9 @@ class CustomClassHandler implements IHScriptCustomConstructor implements IHScrip
var f = __interp.variables.get(name); var f = __interp.variables.get(name);
if(f is Property && allowProperty) { if(f is Property && allowProperty) {
var prop:Property = cast f; var prop:Property = cast f;
prop.__allowSetGet = this.__allowSetGet; //prop.__allowSetGet = this.__allowSetGet;
var r = prop.callGetter(name); var r = prop.get(!__allowSetGet);
prop.__allowSetGet = null; //prop.__allowSetGet = true;
return r; return r;
} }
return f; return f;
@@ -108,9 +104,9 @@ class CustomClassHandler implements IHScriptCustomConstructor implements IHScrip
var f = getField(name, false); var f = getField(name, false);
if(f is Property) { if(f is Property) {
var prop:Property = cast f; var prop:Property = cast f;
prop.__allowSetGet = this.__allowSetGet; //prop.__allowSetGet = this.__allowSetGet;
var r = prop.callSetter(name, val); var r = prop.set(val, !__allowSetGet);
prop.__allowSetGet = null; //prop.__allowSetGet = true;
return r; return r;
} }
__interp.variables.set(name, val); __interp.variables.set(name, val);
@@ -119,10 +115,9 @@ class CustomClassHandler implements IHScriptCustomConstructor implements IHScrip
public function hget(name:String):Dynamic { public function hget(name:String):Dynamic {
if(name == 'new') { if(name == 'new') {
var __constructor = Reflect.makeVarArgs(function(args:Array<Dynamic>) { return Reflect.makeVarArgs(function(args:Array<Dynamic>):Dynamic {
return this.hnew(args); return inline this.hnew(args);
}); });
return __constructor;
} }
if(hasField(name)) { if(hasField(name)) {
+2 -2
View File
@@ -106,7 +106,7 @@ enum abstract Binop(Int) from Int to Int {
case "<<=": OpShlAssign; case "<<=": OpShlAssign;
case ">>=": OpShrAssign; case ">>=": OpShrAssign;
case ">>>=": OpUshrAssign; case ">>>=": OpUshrAssign;
case "??=": OpNcoalAssign; case _ if (s == "??" + "="): OpNcoalAssign;
default: -1; default: -1;
} }
} }
@@ -149,7 +149,7 @@ enum abstract Binop(Int) from Int to Int {
case OpShlAssign: "<<="; case OpShlAssign: "<<=";
case OpShrAssign: ">>="; case OpShrAssign: ">>=";
case OpUshrAssign: ">>>="; case OpUshrAssign: ">>>=";
case OpNcoalAssign: "??="; case OpNcoalAssign: "??" + "=";
default: "?"; default: "?";
} }
} }
+52 -48
View File
@@ -28,6 +28,7 @@
*/ */
package hscript; package hscript;
import haxe.Exception;
import haxe.ds.StringMap; import haxe.ds.StringMap;
import hscript.HEnum.HEnumValue; import hscript.HEnum.HEnumValue;
import haxe.CallStack; import haxe.CallStack;
@@ -135,11 +136,16 @@ class Interp {
public var errorHandler:Error->Void; public var errorHandler:Error->Void;
public var warnHandler:Error->Void; public var warnHandler:Error->Void;
// TODO: set this callback as a Global Resolver
/**
* Custom Import resolver. It's called when an import couldn't be resolved.
*/
public var importFailedCallback:Array<String>->Null<String>->Bool; public var importFailedCallback:Array<String>->Null<String>->Bool;
public var customClasses:Map<String, CustomClassHandler>; public var customClasses:Map<String, CustomClassHandler>;
public var variables:Map<String, Dynamic>; public var variables:Map<String, Dynamic>;
public var publicVariables:Map<String, Dynamic>; public var publicVariables:Map<String, Dynamic>;
// TODO: maybe turn this completely static
public var staticVariables:Map<String, Dynamic>; public var staticVariables:Map<String, Dynamic>;
// warning can be null // warning can be null
@@ -160,15 +166,19 @@ class Interp {
public var allowStaticVariables:Bool = false; public var allowStaticVariables:Bool = false;
public var allowPublicVariables:Bool = false; public var allowPublicVariables:Bool = false;
// TODO: move this to an external class public var importBlocklist(get, never):Array<String>;
public var importBlocklist:Array<String> = [ private inline function get_importBlocklist():Array<String> {
// "flixel.FlxG" return Config.IMPORT_BLACKLIST;
]; }
var usingHandler:UsingHandler; var usingHandler:UsingHandler;
var varLocationCache:Map<String, VarLocation> = new Map(); // TODO: separate cache into a class
var cacheValid:Bool = true; var varLocationCache:Map<String, VarLocation> = [];
public var cacheValid(default, set):Bool = true;
function set_cacheValid(valid:Bool):Bool {
return cacheValid = valid;
}
#if hscriptPos #if hscriptPos
var curExpr:Expr; var curExpr:Expr;
@@ -291,14 +301,14 @@ class Interp {
var obj = resolve(id, false, false); var obj = resolve(id, false, false);
if (obj != null && obj is Property) { if (obj != null && obj is Property) {
var prop:Property = cast obj; var prop:Property = cast obj;
return prop.callSetter(id, v); return prop.set(v, isBypassAccessor);
} }
varLocationCache.remove(id); varLocationCache.remove(id);
setVar(id, v); setVar(id, v);
} }
} else if (l.r is Property) { } else if (l.r is Property) {
var prop:Property = cast l.r; var prop:Property = cast l.r;
return prop.callSetter(id, v); return prop.set(v, isBypassAccessor);
} else { } else {
l.r = v; l.r = v;
if (l.depth == 0) { if (l.depth == 0) {
@@ -372,7 +382,7 @@ class Interp {
var obj = resolve(id, true, false); var obj = resolve(id, true, false);
if (obj != null && obj is Property) { if (obj != null && obj is Property) {
var prop:Property = cast obj; var prop:Property = cast obj;
return prop.callSetter(id, v); return prop.set(v, isBypassAccessor);
} }
varLocationCache.remove(id); varLocationCache.remove(id);
setVar(id, v); setVar(id, v);
@@ -382,7 +392,7 @@ class Interp {
var l = locals.get(id); var l = locals.get(id);
if (l.r is Property) { if (l.r is Property) {
var prop:Property = cast l.r; var prop:Property = cast l.r;
return prop.callSetter(id, v); return prop.set(v, isBypassAccessor);
} }
l.r = v; l.r = v;
if (l.depth == 0) { if (l.depth == 0) {
@@ -426,18 +436,18 @@ class Interp {
var prop:Property = null; var prop:Property = null;
if (v is Property) { if (v is Property) {
prop = cast v; prop = cast v;
v = prop.callGetter(id); v = prop.get(isBypassAccessor);
} }
if (prefix) { if (prefix) {
v += delta; v += delta;
if (prop != null) if (prop != null)
prop.callSetter(id, v); prop.set(v, isBypassAccessor);
else else
l.r = v; l.r = v;
} else { } else {
if (prop != null) if (prop != null)
prop.callSetter(id, v + delta); prop.set(v + delta, isBypassAccessor);
else else
l.r = v + delta; l.r = v + delta;
} }
@@ -448,20 +458,20 @@ class Interp {
var prop:Property = null; var prop:Property = null;
if (v is Property) { if (v is Property) {
prop = cast v; prop = cast v;
v = prop.callGetter(id); v = prop.get(isBypassAccessor);
} }
if (prefix) { if (prefix) {
v += delta; v += delta;
if (prop != null) if (prop != null)
prop.callSetter(id, v); prop.set(v, isBypassAccessor);
else { else {
varLocationCache.remove(id); varLocationCache.remove(id);
setVar(id, v); setVar(id, v);
} }
} else { } else {
if (prop != null) if (prop != null)
prop.callSetter(id, v + delta); prop.set(v + delta, isBypassAccessor);
else { else {
varLocationCache.remove(id); varLocationCache.remove(id);
setVar(id, v + delta); setVar(id, v + delta);
@@ -601,8 +611,10 @@ class Interp {
} }
inline function getProperty(o:Null<Dynamic>, n:String, allowProperty:Bool = true):Dynamic { inline function getProperty(o:Null<Dynamic>, n:String, allowProperty:Bool = true):Dynamic {
if(allowProperty && o != null && o is Property) if(allowProperty && o != null && o is Property) {
return cast(o, Property).callGetter(n); var prop:Property = cast o;
return prop.get(isBypassAccessor);
}
else else
return o; return o;
} }
@@ -631,7 +643,7 @@ class Interp {
case VPublic: getProperty(publicVariables.get(id), id, allowProperty); case VPublic: getProperty(publicVariables.get(id), id, allowProperty);
case VStatic: getProperty(staticVariables.get(id), id, allowProperty); case VStatic: getProperty(staticVariables.get(id), id, allowProperty);
case VScriptObject: isBypassAccessor ? UnsafeReflect.field(scriptObject, id) : UnsafeReflect.getProperty(scriptObject, id); case VScriptObject: isBypassAccessor ? UnsafeReflect.field(scriptObject, id) : UnsafeReflect.getProperty(scriptObject, id);
case VScriptObjectGetter: UnsafeReflect.getProperty(scriptObject, 'get_$id')(); case VScriptObjectGetter: UnsafeReflect.callFieldUnsafe(scriptObject, 'get_$id', []);
case VCustomClass: (cast scriptObject:IHScriptCustomAccessBehaviour).hget(id); case VCustomClass: (cast scriptObject:IHScriptCustomAccessBehaviour).hget(id);
case VCustomClassBypass: case VCustomClassBypass:
var obj:IHScriptCustomAccessBehaviour = cast scriptObject; var obj:IHScriptCustomAccessBehaviour = cast scriptObject;
@@ -709,9 +721,10 @@ class Interp {
varLocationCache.set(id, VScriptObject); varLocationCache.set(id, VScriptObject);
return UnsafeReflect.getProperty(scriptObject, id); return UnsafeReflect.getProperty(scriptObject, id);
} }
} else if (__instanceFields.contains('get_$id')) { // getter } else if (__instanceFields.contains('get_$id')) { // getter
return UnsafeReflect.getProperty(scriptObject, 'get_$id')(); varLocationCache.set(id, VScriptObjectGetter);
} return UnsafeReflect.callFieldUnsafe(scriptObject, 'get_$id', []);
}
} }
varLocationCache.set(id, VNotFound); varLocationCache.set(id, VNotFound);
@@ -725,14 +738,10 @@ class Interp {
} }
public function invalidateCache():Void { public function invalidateCache():Void {
varLocationCache = new Map(); varLocationCache.clear();
cacheValid = true; cacheValid = true;
} }
public function setCacheValid(valid:Bool):Void {
cacheValid = valid;
}
public static var importRedirects:Map<String, String> = new Map(); public static var importRedirects:Map<String, String> = new Map();
public static function getImportRedirect(className:String):String { public static function getImportRedirect(className:String):String {
return importRedirects.exists(className) ? importRedirects.get(className) : className; return importRedirects.exists(className) ? importRedirects.get(className) : className;
@@ -748,6 +757,7 @@ class Interp {
return className; return className;
} }
// TODO: separate large declarations (EClass, EEnum, etc...) into inline functions
public function expr(e:Expr):Dynamic { public function expr(e:Expr):Dynamic {
#if hscriptPos #if hscriptPos
curExpr = e; curExpr = e;
@@ -808,7 +818,6 @@ class Interp {
function importResolve(__clsName:String):Null<Dynamic> { function importResolve(__clsName:String):Null<Dynamic> {
var _realClassName = getLocalImportRedirect(__clsName); var _realClassName = getLocalImportRedirect(__clsName);
if(importBlocklist.contains(_realClassName)) return null;
var _cl = Type.resolveClass(_realClassName); var _cl = Type.resolveClass(_realClassName);
if(_cl == null) _cl = Type.resolveClass('${_realClassName}_HSC'); if(_cl == null) _cl = Type.resolveClass('${_realClassName}_HSC');
@@ -1001,20 +1010,14 @@ class Interp {
return null; return null;
} }
declared.push({n: n, old: locals.get(n), depth: depth}); declared.push({n: n, old: locals.get(n), depth: depth});
var r:Dynamic = (e == null) ? null : expr(e); var v:Dynamic = (e == null) ? null : expr(e);
var declProp:Property = null; var r:Dynamic = null;
if (hasGetSet) { if (hasGetSet)
declProp = { r = new Property(n, v, getter, setter, isVar, isStatic, this);
r: r, else
getter: getter, r = v;
setter: setter,
isVar: isVar,
isStatic: isStatic,
interp: this,
}
}
var declVar:DeclaredVar = { var declVar:DeclaredVar = {
r: (!hasGetSet) ? r : declProp, r: r,
depth: depth depth: depth
}; };
locals.set(n, declVar); locals.set(n, declVar);
@@ -1131,7 +1134,7 @@ class Interp {
} }
return fcall(obj, f, args); return fcall(obj, f, args);
default: default:
return call(null, expr(e), args); return call(hasScriptObject ? scriptObject : null, expr(e), args);
} }
case EIf(econd, e1, e2): case EIf(econd, e1, e2):
return if (expr(econd) == true) expr(e1) else if (e2 == null) null else expr(e2); return if (expr(econd) == true) expr(e1) else if (e2 == null) null else expr(e2);
@@ -1400,12 +1403,12 @@ class Interp {
for (i => p in params) { for (i => p in params) {
switch (Tools.expr(p)) { switch (Tools.expr(p)) {
case EIdent(n): case EIdent(n):
declared.push({ declared.push({
n: n, n: n,
old: {r: locals.get(n), depth: depth}, old: {r: locals.get(n), depth: depth},
depth: depth depth: depth
}); });
locals.set(n, {r: valParams[i], depth: depth}); locals.set(n, {r: valParams[i], depth: depth});
default: default:
} }
} }
@@ -1798,6 +1801,7 @@ class Interp {
if (usingHandler.usingEntries.iterator().hasNext()) { // If is not empty if (usingHandler.usingEntries.iterator().hasNext()) { // If is not empty
var v:Dynamic = null; var v:Dynamic = null;
var clsName:String = o is CustomClassHandler ? cast(o, CustomClassHandler).name : Type.getClassName(Type.getClass(o)); var clsName:String = o is CustomClassHandler ? cast(o, CustomClassHandler).name : Type.getClassName(Type.getClass(o));
// TODO: optimize this
if(!usingHandler.entryExists(clsName)) { if(!usingHandler.entryExists(clsName)) {
for (n => us in usingHandler.usingEntries) { for (n => us in usingHandler.usingEntries) {
if (us.hasField(f)) { if (us.hasField(f)) {
+68 -18
View File
@@ -26,15 +26,33 @@ import hscript.Expr.FieldPropertyAccess;
* @see https://haxe.org/manual/class-field-property.html * @see https://haxe.org/manual/class-field-property.html
*/ */
@:access(hscript.Interp) @:access(hscript.Interp)
@:structInit
class Property { class Property {
private static inline var GET = 'get_'; private static inline var GET = 'get_';
private static inline var SET = 'set_'; private static inline var SET = 'set_';
public var r:Dynamic; /**
public var getter:FieldPropertyAccess; * Name of the attached field.
public var setter:FieldPropertyAccess; */
public final name:String;
/**
* The current value. If isn't initialized, it's always `null`.
*/
public var r:Dynamic;
/**
* The getter property kind
*/
public final getter:FieldPropertyAccess;
/**
* The setter property kind
*/
public final setter:FieldPropertyAccess;
/**
* If the field is declared as static.
*/
public var isStatic(get, never):Bool; public var isStatic(get, never):Bool;
function get_isStatic() { function get_isStatic() {
return __isStatic && interp.allowStaticVariables; return __isStatic && interp.allowStaticVariables;
@@ -43,7 +61,20 @@ class Property {
var isVar:Bool; var isVar:Bool;
var interp:Interp; var interp:Interp;
public function new(r:Dynamic, getter:FieldPropertyAccess, setter:FieldPropertyAccess, isVar:Bool, isStatic:Bool, interp:Interp) { @:allow(hscript.Interp)
private var getterFunc(get, never):String;
private inline function get_getterFunc():String {
return '$GET$name';
}
@:allow(hscript.Interp)
private var setterFunc(get, never):String;
private inline function get_setterFunc():String {
return '$SET$name';
}
public function new(name:String, r:Dynamic, getter:FieldPropertyAccess, setter:FieldPropertyAccess, isVar:Bool, isStatic:Bool, interp:Interp) {
this.name = name;
this.r = r; this.r = r;
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
@@ -52,23 +83,41 @@ class Property {
this.interp = interp; this.interp = interp;
} }
// Internal flags to gain access to the current field value (if isn't a property field)
var __allowReadAccess:Bool = false; var __allowReadAccess:Bool = false;
var __allowWriteAccess:Bool = false; var __allowWriteAccess:Bool = false;
var __allowSetGet:Null<Bool> = null; // Internal flag to gain access if the field is accessed with @:bypassAccessor
var __allowSetGet:Bool = true;
final __isStatic:Bool = false; final __isStatic:Bool = false;
public function callGetter(name:String) { public function get(isBypassAccessor:Bool) {
if(isBypassAccessor) __allowSetGet = false;
var r:Dynamic = callGetter();
if(isBypassAccessor) __allowSetGet = true;
return r;
}
public function set(value:Dynamic, isBypassAccessor:Bool) {
if(isBypassAccessor) __allowSetGet = false;
var r:Dynamic = callSetter(value);
if(isBypassAccessor) __allowSetGet = true;
return r;
}
private function callGetter():Dynamic {
switch (getter) { switch (getter) {
case AGet | ADynamic: case AGet | ADynamic:
var fName:String = '$GET$name'; var fName:String = getterFunc;
if (!__allowReadAccess && (__allowSetGet != null && __allowSetGet || !interp.isBypassAccessor)) { if (!__allowReadAccess && __allowSetGet) {
if (varExists(fName)) { if (varExists(fName)) {
return callAccessor(fName); return callAccessor(fName);
} else } else
interp.error(ECustom('Method $fName required by property $name is missing')); interp.error(ECustom('Method $fName required by property $name is missing'));
} else { } else {
if ((setter == ADefault || setter == ANull) || isVar) if ((setter == ADefault || setter == ANull) || isVar) {
return r; return r;
}
else else
interp.error(ECustom('Field $name cannot be accessed because it is not a real variable${interp.isBypassAccessor ? '. Add @:isVar to enable it' : ''}')); interp.error(ECustom('Field $name cannot be accessed because it is not a real variable${interp.isBypassAccessor ? '. Add @:isVar to enable it' : ''}'));
} }
@@ -80,18 +129,19 @@ class Property {
return r; return r;
} }
public function callSetter(name:String, val:Dynamic) { private function callSetter(val:Dynamic):Dynamic {
switch (setter) { switch (setter) {
case ASet | ADynamic: case ASet | ADynamic:
var fName:String = '$SET$name'; var fName:String = setterFunc;
if (!__allowWriteAccess && (__allowSetGet != null && __allowSetGet || !interp.isBypassAccessor)) { if (!__allowWriteAccess && __allowSetGet) {
if (varExists(fName)) if (varExists(fName))
return callAccessor(fName, [val], true); return callAccessor(fName, true, val);
else else
interp.error(ECustom('Method $fName required by property $name is missing')); interp.error(ECustom('Method $fName required by property $name is missing'));
} else { } else {
if ((getter == ADefault || getter == ANull) || isVar) if ((getter == ADefault || getter == ANull) || isVar) {
return r = val; return r = val;
}
else else
interp.error(ECustom('Field $name cannot be accessed because it is not a real variable${interp.isBypassAccessor ? '. Add @:isVar to enable it' : ''}')); interp.error(ECustom('Field $name cannot be accessed because it is not a real variable${interp.isBypassAccessor ? '. Add @:isVar to enable it' : ''}'));
} }
@@ -103,14 +153,14 @@ class Property {
return r = val; return r = val;
} }
private function callAccessor(f:String, ?args:Array<Dynamic>, isWrite:Bool = false):Dynamic { private function callAccessor(f:String, isWrite:Bool = false, ?value:Dynamic):Dynamic {
var fn = isStatic ? interp.staticVariables.get(f) : interp.variables.get(f); var fn = isStatic ? interp.staticVariables.get(f) : interp.variables.get(f);
var rt:Dynamic = null; var rt:Dynamic = null;
if (fn != null && Reflect.isFunction(fn)) { if (fn != null && Reflect.isFunction(fn)) {
if (isWrite) __allowWriteAccess = true; if (isWrite) __allowWriteAccess = true;
else __allowReadAccess = true; else __allowReadAccess = true;
rt = UnsafeReflect.callMethodUnsafe(null, fn, args == null ? [] : args); rt = UnsafeReflect.callMethodUnsafe(null, fn, isWrite ? [value] : []);
if (isWrite) __allowWriteAccess = false; if (isWrite) __allowWriteAccess = false;
else __allowReadAccess = false; else __allowReadAccess = false;
@@ -122,7 +172,7 @@ class Property {
return rt; return rt;
} }
private function varExists(n:String) { private inline function varExists(n:String) {
return isStatic ? interp.staticVariables.exists(n) : interp.variables.exists(n); return isStatic ? interp.staticVariables.exists(n) : interp.variables.exists(n);
} }
} }
+8 -4
View File
@@ -483,8 +483,9 @@ class ClassExtendMacro {
if (__interp != null) { if (__interp != null) {
if(__class__fields.contains(name)) { if(__class__fields.contains(name)) {
var v:Dynamic = __interp.variables.get(name); var v:Dynamic = __interp.variables.get(name);
var ba:Bool = @:privateAccess __interp.isBypassAccessor;
if(v != null && v is hscript.Property) if(v != null && v is hscript.Property)
return cast(v, hscript.Property).callGetter(name); return cast(v, hscript.Property).get(ba);
return v; return v;
} }
else @:privateAccess { else @:privateAccess {
@@ -508,8 +509,9 @@ class ClassExtendMacro {
if (__interp != null) { if (__interp != null) {
if(__class__fields.contains(name)) { if(__class__fields.contains(name)) {
var v:Dynamic = __interp.variables.get(name); var v:Dynamic = __interp.variables.get(name);
var ba:Bool = @:privateAccess __interp.isBypassAccessor;
if(v != null && v is hscript.Property) if(v != null && v is hscript.Property)
return cast(v, hscript.Property).callGetter(name); return cast(v, hscript.Property).get(ba);
return v; return v;
} }
else @:privateAccess { else @:privateAccess {
@@ -535,8 +537,9 @@ class ClassExtendMacro {
if (__interp != null) { if (__interp != null) {
if(__class__fields.contains(name)) { if(__class__fields.contains(name)) {
var v:Dynamic = __interp.variables.get(name); var v:Dynamic = __interp.variables.get(name);
var ba:Bool = @:privateAccess __interp.isBypassAccessor;
if(v != null && v is hscript.Property) if(v != null && v is hscript.Property)
return cast(v, hscript.Property).callSetter(name, val); return cast(v, hscript.Property).set(val, ba);
__interp.variables.set(name, val); __interp.variables.set(name, val);
return val; return val;
} }
@@ -565,8 +568,9 @@ class ClassExtendMacro {
if (__interp != null) { if (__interp != null) {
if(__class__fields.contains(name)) { if(__class__fields.contains(name)) {
var v:Dynamic = __interp.variables.get(name); var v:Dynamic = __interp.variables.get(name);
var ba:Bool = @:privateAccess __interp.isBypassAccessor;
if(v != null && v is hscript.Property) if(v != null && v is hscript.Property)
return cast(v, hscript.Property).callSetter(name, val); return cast(v, hscript.Property).set(val, ba);
__interp.variables.set(name, val); __interp.variables.set(name, val);
return val; return val;
} }