diff --git a/polymod/hscript/_internal/PolymodAbstractScriptClass.hx b/polymod/hscript/_internal/PolymodAbstractScriptClass.hx index 32cc1ea6..d605d507 100644 --- a/polymod/hscript/_internal/PolymodAbstractScriptClass.hx +++ b/polymod/hscript/_internal/PolymodAbstractScriptClass.hx @@ -117,6 +117,11 @@ abstract PolymodAbstractScriptClass(PolymodScriptClass) from PolymodScriptClass case _: if (this.findVar(name) != null) { + if (this.findVar(name).isfinal && this.findVar(name).expr != null) // The variable already exists and has a set value. + { + throw "Invalid access to field " + name; + return null; + } this._interp.variables.set(name, value); return value; } diff --git a/polymod/hscript/_internal/PolymodInterpEx.hx b/polymod/hscript/_internal/PolymodInterpEx.hx index 9b6403eb..accd7a72 100644 --- a/polymod/hscript/_internal/PolymodInterpEx.hx +++ b/polymod/hscript/_internal/PolymodInterpEx.hx @@ -186,6 +186,20 @@ class PolymodInterpEx extends Interp return v; } } + + @:privateAccess + { + if (_proxy != null) + { + var variable = _proxy.findVar(id); + if (variable != null && variable.isfinal && variable.expr != null) + { + errorEx(EInvalidAccess(id)); + return null; + } + } + } + case EField(e0, id): // Make sure setting superclass fields works when using this. // Also ensures property functions are accounted for. @@ -229,7 +243,12 @@ class PolymodInterpEx extends Interp case EVar(n, _, e): // Fix to ensure local variables are committed properly. declared.push({n: n, old: locals.get(n)}); var result = (e == null) ? null : expr(e); - locals.set(n, {r: result}); + locals.set(n, {r: result, isfinal: false}); + return null; + case EFinal(n, _, e): // Fix to ensure local variables are committed properly. + declared.push({n: n, old: locals.get(n)}); + var result = (e == null) ? null : expr(e); + locals.set(n, {r: result, isfinal: true}); return null; case EFunction(params, fexpr, name, _): // Fix to ensure callback functions catch thrown errors. var capturedLocals = duplicate(locals);