Property combination check
Also, it parses 'dynamic'. Still working on getter/setter for variables
This commit is contained in:
+2
-1
@@ -233,9 +233,10 @@ enum EnumType {
|
||||
enum abstract FieldPropertyAccess(UInt8) {
|
||||
var ADefault;
|
||||
var ANull;
|
||||
var ANever;
|
||||
var AGet;
|
||||
var ASet;
|
||||
var ADynamic;
|
||||
var ANever;
|
||||
}
|
||||
|
||||
enum AccessContext {
|
||||
|
||||
+24
-4
@@ -65,9 +65,10 @@ enum abstract ScriptObjectType(UInt8) {
|
||||
class DeclaredVar {
|
||||
public var r:Dynamic;
|
||||
public var depth:Int;
|
||||
public var isFinal:Null<Bool> = null;
|
||||
// TODO: getter/setter for variables
|
||||
public var getter:FieldPropertyAccess = null;
|
||||
public var setter:FieldPropertyAccess = null;
|
||||
public var getter:Null<FieldPropertyAccess> = null;
|
||||
public var setter:Null<FieldPropertyAccess> = null;
|
||||
}
|
||||
|
||||
@:structInit
|
||||
@@ -156,6 +157,7 @@ class Interp {
|
||||
|
||||
var isBypassAccessor:Bool = false;
|
||||
var isPrivateAccess:Bool = false;
|
||||
//var isVar:Bool = false;
|
||||
|
||||
public var importEnabled:Bool = true;
|
||||
|
||||
@@ -379,6 +381,7 @@ class Interp {
|
||||
setVar(id, v);
|
||||
}
|
||||
} else {
|
||||
// TODO: call "set_" if available
|
||||
l.r = v;
|
||||
if (l.depth == 0) {
|
||||
setVar(id, v);
|
||||
@@ -509,6 +512,7 @@ class Interp {
|
||||
}
|
||||
else {
|
||||
var l = locals.get(id);
|
||||
// TODO: call "set_" if available
|
||||
l.r = v;
|
||||
if (l.depth == 0) {
|
||||
setVar(id, v);
|
||||
@@ -568,6 +572,7 @@ class Interp {
|
||||
switch (e) {
|
||||
case EIdent(id):
|
||||
var l = locals.get(id);
|
||||
// TODO: call "set_" if available
|
||||
if(l != null) {
|
||||
var v:Dynamic = l.r;
|
||||
if (prefix) {
|
||||
@@ -725,6 +730,7 @@ class Interp {
|
||||
|
||||
if (locals.exists(id)) {
|
||||
var l = locals.get(id);
|
||||
// TODO: call get or set if available.
|
||||
if(l != null)
|
||||
return l.r;
|
||||
}
|
||||
@@ -1024,8 +1030,19 @@ class Interp {
|
||||
case EIdent(id):
|
||||
return resolve(id);
|
||||
case EVar(n, _, e, isPublic, isStatic, _, isFinal, _, getter, setter):
|
||||
if(depth > 0 && (getter != null || setter != null)) {
|
||||
error(ECustom("Property Accessor for local variables is not allowed"));
|
||||
return null;
|
||||
}
|
||||
declared.push({n: n, old: locals.get(n), depth: depth});
|
||||
locals.set(n, {r: (e == null) ? null : expr(e), depth: depth});
|
||||
var declVar:DeclaredVar = {
|
||||
r: (e == null) ? null : expr(e),
|
||||
depth: depth,
|
||||
isFinal: isFinal,
|
||||
getter: getter,
|
||||
setter: setter
|
||||
};
|
||||
locals.set(n, declVar);
|
||||
if (depth == 0) {
|
||||
if(allowStaticVariables && isStatic == true) {
|
||||
if(!staticVariables.exists(n)) // make it so it only sets it once
|
||||
@@ -1394,6 +1411,7 @@ class Interp {
|
||||
return val;
|
||||
case EMeta(a, b, e):
|
||||
var val:Dynamic = null;
|
||||
|
||||
switch(a) {
|
||||
case ":bypassAccessor":
|
||||
var oldAccessor = isBypassAccessor;
|
||||
@@ -1408,6 +1426,9 @@ class Interp {
|
||||
isPrivateAccess = oldPrivate;
|
||||
return val;
|
||||
}
|
||||
|
||||
val = expr(e);
|
||||
return val;
|
||||
/*
|
||||
var oldAccessor = isBypassAccessor;
|
||||
if(a == ":bypassAccessor") {
|
||||
@@ -1418,7 +1439,6 @@ class Interp {
|
||||
isBypassAccessor = oldAccessor;
|
||||
return val;
|
||||
*/
|
||||
return val;
|
||||
case ECheckType(e, _):
|
||||
return expr(e);
|
||||
case EUsing(name):
|
||||
|
||||
+44
-14
@@ -103,6 +103,8 @@ class Parser {
|
||||
|
||||
var disableOrOp : Bool = false;
|
||||
|
||||
var isVar : Bool = false;
|
||||
|
||||
#if hscriptPos
|
||||
var origin : String;
|
||||
var tokenMin : Int;
|
||||
@@ -857,16 +859,20 @@ class Parser {
|
||||
var ident = getIdent();
|
||||
var get = ADefault, set = ADefault;
|
||||
var hasGetSet:Bool = false;
|
||||
|
||||
var tk = token();
|
||||
// TODO: throw "Missing ;" if tried to use (get, set) on final
|
||||
if( tk == TPOpen && id != "final" ) {
|
||||
if( tk == TPOpen) {
|
||||
if( id == "final" )
|
||||
unexpected(tk);
|
||||
|
||||
var getId = getIdent();
|
||||
switch (getId) {
|
||||
case 'default': // Do nothing
|
||||
case 'get': get = AGet;
|
||||
case 'null': get = ANull;
|
||||
case 'dynamic': get = ADynamic;
|
||||
case 'never': get = ANever;
|
||||
default: unexpected(TId(getId));
|
||||
default: error(ECustom("Custom property accessor is not supported"), p1, tokenMax);
|
||||
}
|
||||
ensure(TComma);
|
||||
var setId = getIdent();
|
||||
@@ -874,8 +880,9 @@ class Parser {
|
||||
case 'default': // Do nothing
|
||||
case 'set': set = ASet;
|
||||
case 'null': set = ANull;
|
||||
case 'dynamic': set = ADynamic;
|
||||
case 'never': set = ANever;
|
||||
default: unexpected(TId(getId));
|
||||
default: error(ECustom("Custom property accessor is not supported"), p1, tokenMax);
|
||||
}
|
||||
ensure(TPClose);
|
||||
|
||||
@@ -898,8 +905,8 @@ class Parser {
|
||||
else
|
||||
push(tk);
|
||||
|
||||
if(hasGetSet && (e == null || (allowTypes && t == null)))
|
||||
error(ECustom("Property requires type-hint or initialization"), p1, tokenMax);
|
||||
if(hasGetSet)
|
||||
checkAccess(get, set, e, t);
|
||||
|
||||
nextType = null;
|
||||
mk(EVar(ident, t, e, nextIsPublic, nextIsStatic, nextIsPrivate, id == "final", nextIsInline, get, set), p1, (e == null) ? tokenMax : pmax(e));
|
||||
@@ -1604,6 +1611,24 @@ class Parser {
|
||||
return args;
|
||||
}
|
||||
|
||||
function checkAccess(get:FieldPropertyAccess, set:FieldPropertyAccess, ?expr:Expr, ?type:CType) {
|
||||
#if hscriptPos
|
||||
var p1 = tokenMin;
|
||||
#end
|
||||
switch([get, set]) {
|
||||
case [AGet, ASet] | [AGet, ANever] | [ANever, ASet]:
|
||||
if(expr != null && !isVar)
|
||||
error(ECustom("Attempt to assign on field that is not a real variable"), p1, pmax(expr));
|
||||
else if(type == null)
|
||||
error(ECustom("Property requires type-hint"), p1, tokenMax);
|
||||
case [ANever, ANever]:
|
||||
error(ECustom("Unsupported property combination"), p1, (expr == null) ? tokenMax : pmax(expr));
|
||||
default:
|
||||
if(expr == null && type == null)
|
||||
error(ECustom("Property requires type-hint or initialization"), p1, tokenMax);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------ module -------------------------------
|
||||
|
||||
public function parseModule( content : String, ?origin : String = "hscript" ):Array<ModuleDecl> {
|
||||
@@ -1812,15 +1837,19 @@ class Parser {
|
||||
var name = getIdent();
|
||||
var get = ADefault, set = ADefault;
|
||||
var hasGetSet:Bool = false;
|
||||
// TODO: throw "Missing ;" if tried to use (get, set) on final
|
||||
if(maybe(TPOpen) && id != "final") {
|
||||
|
||||
if(maybe(TPOpen)) {
|
||||
if(id == "final")
|
||||
unexpected(TPOpen);
|
||||
|
||||
var getId = getIdent();
|
||||
switch(getId) {
|
||||
case 'default': // Do nothing
|
||||
case 'get': get = AGet;
|
||||
case 'null': get = ANull;
|
||||
case 'dynamic': get = ADynamic;
|
||||
case 'never': get = ANever;
|
||||
default: unexpected(TId(getId));
|
||||
default: error(ECustom("Custom property accessor is not supported"), tokenMin, tokenMax);
|
||||
}
|
||||
ensure(TComma);
|
||||
var setId = getIdent();
|
||||
@@ -1828,17 +1857,18 @@ class Parser {
|
||||
case 'default': // Do nothing
|
||||
case 'set': set = ASet;
|
||||
case 'null': set = ANull;
|
||||
case 'dynamic': set = ADynamic;
|
||||
case 'never': set = ANever;
|
||||
default: unexpected(TId(getId));
|
||||
default: error(ECustom("Custom property accessor is not supported"), tokenMin, tokenMax);
|
||||
}
|
||||
ensure(TPClose);
|
||||
hasGetSet = true;
|
||||
}
|
||||
var type = maybe(TDoubleDot) ? parseType() : null;
|
||||
var expr = maybe(TOp("=")) ? parseExpr() : null;
|
||||
var type:Null<CType> = maybe(TDoubleDot) ? parseType() : null;
|
||||
var expr:Null<Expr> = maybe(TOp("=")) ? parseExpr() : null;
|
||||
|
||||
if(hasGetSet && (expr == null || type == null))
|
||||
error(ECustom("Property requires type-hint or initialization"), p1, tokenMax);
|
||||
if(hasGetSet)
|
||||
checkAccess(get, set, expr, type);
|
||||
|
||||
if( expr != null ) {
|
||||
if( isBlock(expr) )
|
||||
|
||||
Reference in New Issue
Block a user