Added inferred map types and bypassAccessor
This commit is contained in:
+1
-1
@@ -60,7 +60,7 @@ enum Expr {
|
||||
EFunction( args : Array<Argument>, e : Expr, ?name : String, ?ret : CType, ?isPublic : Bool, ?isStatic : Bool);
|
||||
EReturn( ?e : Expr );
|
||||
EArray( e : Expr, index : Expr );
|
||||
EArrayDecl( e : Array<Expr> );
|
||||
EArrayDecl( e : Array<Expr>, ?wantedType: CType);
|
||||
ENew( cl : String, params : Array<Expr> );
|
||||
EThrow( e : Expr );
|
||||
ETry( e : Expr, v : String, t : Null<CType>, ecatch : Expr );
|
||||
|
||||
+64
-11
@@ -23,6 +23,8 @@
|
||||
/*
|
||||
* YoshiCrafter Engine fixes:
|
||||
* - Added Error handler
|
||||
* - Added Imports
|
||||
* - Added @:bypassAccessor
|
||||
*/
|
||||
package hscript;
|
||||
|
||||
@@ -69,6 +71,8 @@ class Interp {
|
||||
var declared:Array<{n:String, old:{r:Dynamic, depth:Int}, depth:Int}>;
|
||||
var returnValue:Dynamic;
|
||||
|
||||
var isBypassAccessor:Bool = false;
|
||||
|
||||
public var importEnabled:Bool = true;
|
||||
|
||||
public var allowStaticVariables:Bool = false;
|
||||
@@ -431,7 +435,6 @@ class Interp {
|
||||
}
|
||||
if (doException)
|
||||
error(EUnknownVariable(id));
|
||||
|
||||
}
|
||||
return v;
|
||||
}
|
||||
@@ -464,7 +467,15 @@ class Interp {
|
||||
// ENUM!!!!
|
||||
var enumThingy = {};
|
||||
for (c in en.getConstructors()) {
|
||||
Reflect.setField(enumThingy, c, en.createByName(c));
|
||||
try {
|
||||
Reflect.setField(enumThingy, c, en.createByName(c));
|
||||
} catch(e) {
|
||||
try {
|
||||
Reflect.setField(enumThingy, c, Reflect.field(en, c));
|
||||
} catch(ex) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
variables.set(splitClassName[splitClassName.length - 1], enumThingy);
|
||||
} else {
|
||||
@@ -488,7 +499,8 @@ class Interp {
|
||||
case EVar(n, _, e, isPublic, isStatic):
|
||||
declared.push({n: n, old: locals.get(n), depth: depth});
|
||||
locals.set(n, {r: (e == null) ? null : expr(e), depth: depth});
|
||||
if (depth == 0) (isStatic == true ? staticVariables : (isPublic ? publicVariables : variables)).set(n, locals[n].r);
|
||||
if (depth == 0)
|
||||
(isStatic == true ? staticVariables : (isPublic ? publicVariables : variables)).set(n, locals[n].r);
|
||||
return null;
|
||||
case EParent(e):
|
||||
return expr(e);
|
||||
@@ -634,8 +646,16 @@ class Interp {
|
||||
}
|
||||
}
|
||||
return f;
|
||||
case EArrayDecl(arr):
|
||||
if (arr.length > 0 && Tools.expr(arr[0]).match(EBinop("=>", _))) {
|
||||
case EArrayDecl(arr, wantedType):
|
||||
var isMap = false;
|
||||
var isTypeMap = false;
|
||||
if(!isMap && wantedType != null) {
|
||||
isMap = wantedType.match(CTPath(["Map"], [_, _]));
|
||||
isTypeMap = true;
|
||||
} else {
|
||||
isMap = arr.length > 0 && Tools.expr(arr[0]).match(EBinop("=>", _));
|
||||
}
|
||||
if (isMap) {
|
||||
var isAllString:Bool = true;
|
||||
var isAllInt:Bool = true;
|
||||
var isAllObject:Bool = true;
|
||||
@@ -657,6 +677,22 @@ class Interp {
|
||||
default: throw("=> expected");
|
||||
}
|
||||
}
|
||||
|
||||
if(isTypeMap) {
|
||||
if(wantedType != null) {
|
||||
isAllString = wantedType.match(CTPath(["Map"], [CTPath(["String"], _), _]));
|
||||
isAllInt = wantedType.match(CTPath(["Map"], [CTPath(["Int"], _), _]));
|
||||
if(isAllString || isAllInt) {
|
||||
isAllObject = false;
|
||||
isAllEnum = false;
|
||||
} else {
|
||||
if(!isAllObject && !isAllEnum) {
|
||||
throw("Unknown Type Key");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var map:Dynamic = {
|
||||
if (isAllInt)
|
||||
new haxe.ds.IntMap<Dynamic>();
|
||||
@@ -742,8 +778,15 @@ class Interp {
|
||||
if (!match)
|
||||
val = def == null ? null : expr(def);
|
||||
return val;
|
||||
case EMeta(_, _, e):
|
||||
return expr(e);
|
||||
case EMeta(a, b, e):
|
||||
var oldAccessor = isBypassAccessor;
|
||||
if(a == ":bypassAccessor") {
|
||||
isBypassAccessor = true;
|
||||
}
|
||||
var val = expr(e);
|
||||
|
||||
isBypassAccessor = oldAccessor;
|
||||
return val;
|
||||
case ECheckType(e, _):
|
||||
return expr(e);
|
||||
}
|
||||
@@ -860,8 +903,15 @@ class Interp {
|
||||
return obj.hget(f);
|
||||
} else {
|
||||
var v = null;
|
||||
if ((v = Reflect.getProperty(o, f)) == null)
|
||||
v = Reflect.getProperty(Type.getClass(o), f);
|
||||
if(isBypassAccessor) {
|
||||
if ((v = Reflect.field(o, f)) == null)
|
||||
v = Reflect.field(Type.getClass(o), f);
|
||||
}
|
||||
|
||||
if(v == null) {
|
||||
if ((v = Reflect.getProperty(o, f)) == null)
|
||||
v = Reflect.getProperty(Type.getClass(o), f);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
@@ -890,8 +940,11 @@ class Interp {
|
||||
var obj = cast(o, IHScriptCustomBehaviour);
|
||||
return obj.hset(f, v);
|
||||
}
|
||||
|
||||
Reflect.setProperty(o, f, v);
|
||||
if(isBypassAccessor) {
|
||||
Reflect.setField(o, f, v);
|
||||
} else {
|
||||
Reflect.setProperty(o, f, v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
+71
-66
@@ -275,19 +275,19 @@ class Parser {
|
||||
function isBlock(e) {
|
||||
if( e == null ) return false;
|
||||
return switch( expr(e) ) {
|
||||
case EBlock(_), EObject(_), ESwitch(_): true;
|
||||
case EFunction(_,e,_,_,_,_): isBlock(e);
|
||||
case EVar(_, t, e, _,_): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false;
|
||||
case EIf(_,e1,e2): if( e2 != null ) isBlock(e2) else isBlock(e1);
|
||||
case EBinop(_,_,e): isBlock(e);
|
||||
case EUnop(_,prefix,e): !prefix && isBlock(e);
|
||||
case EWhile(_,e): isBlock(e);
|
||||
case EDoWhile(_,e): isBlock(e);
|
||||
case EFor(_,_,e): isBlock(e);
|
||||
case EReturn(e): e != null && isBlock(e);
|
||||
case ETry(_, _, _, e): isBlock(e);
|
||||
case EMeta(_, _, e): isBlock(e);
|
||||
default: false;
|
||||
case EBlock(_), EObject(_), ESwitch(_): true;
|
||||
case EFunction(_,e,_,_,_,_): isBlock(e);
|
||||
case EVar(_, t, e, _,_): e != null ? isBlock(e) : t != null ? t.match(CTAnon(_)) : false;
|
||||
case EIf(_,e1,e2): if( e2 != null ) isBlock(e2) else isBlock(e1);
|
||||
case EBinop(_,_,e): isBlock(e);
|
||||
case EUnop(_,prefix,e): !prefix && isBlock(e);
|
||||
case EWhile(_,e): isBlock(e);
|
||||
case EDoWhile(_,e): isBlock(e);
|
||||
case EFor(_,_,e): isBlock(e);
|
||||
case EReturn(e): e != null && isBlock(e);
|
||||
case ETry(_, _, _, e): isBlock(e);
|
||||
case EMeta(_, _, e): isBlock(e);
|
||||
default: false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,29 +318,29 @@ class Parser {
|
||||
var tk = token();
|
||||
var id = null;
|
||||
switch( tk ) {
|
||||
case TId(i): id = i;
|
||||
case TConst(c):
|
||||
if( !allowJSON )
|
||||
case TId(i): id = i;
|
||||
case TConst(c):
|
||||
if( !allowJSON )
|
||||
unexpected(tk);
|
||||
switch( c ) {
|
||||
case CString(s): id = s;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
case TBrClose:
|
||||
break;
|
||||
default:
|
||||
unexpected(tk);
|
||||
switch( c ) {
|
||||
case CString(s): id = s;
|
||||
default: unexpected(tk);
|
||||
}
|
||||
case TBrClose:
|
||||
break;
|
||||
default:
|
||||
unexpected(tk);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
ensure(TDoubleDot);
|
||||
fl.push({ name : id, e : parseExpr() });
|
||||
tk = token();
|
||||
switch( tk ) {
|
||||
case TBrClose:
|
||||
break;
|
||||
case TComma:
|
||||
default:
|
||||
unexpected(tk);
|
||||
case TBrClose:
|
||||
break;
|
||||
case TComma:
|
||||
default:
|
||||
unexpected(tk);
|
||||
}
|
||||
}
|
||||
return parseExprNext(mk(EObject(fl),p1));
|
||||
@@ -372,27 +372,27 @@ class Parser {
|
||||
var e = parseExpr();
|
||||
tk = token();
|
||||
switch( tk ) {
|
||||
case TPClose:
|
||||
return parseExprNext(mk(EParent(e),p1,tokenMax));
|
||||
case TDoubleDot:
|
||||
var t = parseType();
|
||||
tk = token();
|
||||
switch( tk ) {
|
||||
case TPClose:
|
||||
return parseExprNext(mk(ECheckType(e,t),p1,tokenMax));
|
||||
return parseExprNext(mk(EParent(e),p1,tokenMax));
|
||||
case TDoubleDot:
|
||||
var t = parseType();
|
||||
tk = token();
|
||||
switch( tk ) {
|
||||
case TPClose:
|
||||
return parseExprNext(mk(ECheckType(e,t),p1,tokenMax));
|
||||
case TComma:
|
||||
switch( expr(e) ) {
|
||||
case EIdent(v): return parseLambda([{ name : v, t : t }], pmin(e));
|
||||
default:
|
||||
}
|
||||
default:
|
||||
}
|
||||
case TComma:
|
||||
switch( expr(e) ) {
|
||||
case EIdent(v): return parseLambda([{ name : v, t : t }], pmin(e));
|
||||
default:
|
||||
case EIdent(v): return parseLambda([{name:v}], pmin(e));
|
||||
default:
|
||||
}
|
||||
default:
|
||||
}
|
||||
case TComma:
|
||||
switch( expr(e) ) {
|
||||
case EIdent(v): return parseLambda([{name:v}], pmin(e));
|
||||
default:
|
||||
}
|
||||
default:
|
||||
}
|
||||
return unexpected(tk);
|
||||
case TBrOpen:
|
||||
@@ -417,9 +417,9 @@ class Parser {
|
||||
push(tk2);
|
||||
push(tk);
|
||||
switch( tk2 ) {
|
||||
case TDoubleDot:
|
||||
return parseExprNext(parseObject(p1));
|
||||
default:
|
||||
case TDoubleDot:
|
||||
return parseExprNext(parseObject(p1));
|
||||
default:
|
||||
}
|
||||
default:
|
||||
push(tk);
|
||||
@@ -445,12 +445,12 @@ class Parser {
|
||||
if( e == null )
|
||||
return makeUnop(op,e);
|
||||
switch( expr(e) ) {
|
||||
case EConst(CInt(i)):
|
||||
return mk(EConst(CInt(-i)), start, pmax(e));
|
||||
case EConst(CFloat(f)):
|
||||
return mk(EConst(CFloat(-f)), start, pmax(e));
|
||||
default:
|
||||
return makeUnop(op,e);
|
||||
case EConst(CInt(i)):
|
||||
return mk(EConst(CInt(-i)), start, pmax(e));
|
||||
case EConst(CFloat(f)):
|
||||
return mk(EConst(CFloat(-f)), start, pmax(e));
|
||||
default:
|
||||
return makeUnop(op,e);
|
||||
}
|
||||
}
|
||||
if( opPriority.get(op) < 0 )
|
||||
@@ -466,19 +466,19 @@ class Parser {
|
||||
if( tk == TComma )
|
||||
tk = token();
|
||||
}
|
||||
if( a.length == 1 && a[0] != null )
|
||||
if( a.length == 1 && a[0] != null ) // What is this for???
|
||||
switch( expr(a[0]) ) {
|
||||
case EFor(_), EWhile(_), EDoWhile(_):
|
||||
var tmp = "__a_" + (uid++);
|
||||
var e = mk(EBlock([
|
||||
mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1),
|
||||
mapCompr(tmp, a[0]),
|
||||
mk(EIdent(tmp),p1),
|
||||
]),p1);
|
||||
return parseExprNext(e);
|
||||
default:
|
||||
case EFor(_), EWhile(_), EDoWhile(_):
|
||||
var tmp = "__a_" + (uid++);
|
||||
var e = mk(EBlock([
|
||||
mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1),
|
||||
mapCompr(tmp, a[0]),
|
||||
mk(EIdent(tmp),p1),
|
||||
]),p1);
|
||||
return parseExprNext(e);
|
||||
default:
|
||||
}
|
||||
return parseExprNext(mk(EArrayDecl(a), p1));
|
||||
return parseExprNext(mk(EArrayDecl(a, nextType), p1));
|
||||
case TMeta(id) if( allowMetadata ):
|
||||
var args = parseMetaArgs();
|
||||
return mk(EMeta(id, args, parseExpr()),p1);
|
||||
@@ -583,6 +583,7 @@ class Parser {
|
||||
|
||||
var nextIsStatic:Bool = false;
|
||||
var nextIsPublic:Bool = false;
|
||||
var nextType:CType = null;
|
||||
function parseStructure(id, ?oldPos:Int) {
|
||||
#if hscriptPos
|
||||
var p1 = tokenMin;
|
||||
@@ -653,15 +654,19 @@ class Parser {
|
||||
var ident = getIdent();
|
||||
var tk = token();
|
||||
var t = null;
|
||||
nextType = null;
|
||||
if( tk == TDoubleDot && allowTypes ) {
|
||||
t = parseType();
|
||||
tk = token();
|
||||
|
||||
nextType = t;
|
||||
}
|
||||
var e = null;
|
||||
if( Type.enumEq(tk,TOp("=")) )
|
||||
e = parseExpr();
|
||||
else
|
||||
push(tk);
|
||||
nextType = null;
|
||||
mk(EVar(ident,t,e,nextIsPublic,nextIsStatic),p1,(e == null) ? tokenMax : pmax(e));
|
||||
case "while":
|
||||
var econd = parseExpr();
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ class Printer {
|
||||
add("[");
|
||||
expr(index);
|
||||
add("]");
|
||||
case EArrayDecl(el):
|
||||
case EArrayDecl(el, _):
|
||||
add("[");
|
||||
var first = true;
|
||||
for( e in el ) {
|
||||
|
||||
+77
-77
@@ -11,95 +11,95 @@ import haxe.macro.Compiler;
|
||||
using StringTools;
|
||||
|
||||
class UsingHandler {
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
|
||||
public function new(className:String, usedClass:Class<Dynamic>) {
|
||||
this.className = className;
|
||||
this.usedClass = usedClass;
|
||||
}
|
||||
public function new(className:String, usedClass:Class<Dynamic>) {
|
||||
this.className = className;
|
||||
this.usedClass = usedClass;
|
||||
}
|
||||
|
||||
public static function init() {
|
||||
Compiler.addGlobalMetadata('flixel', '@:build(hscript.UsingHandler.build())');
|
||||
Compiler.addGlobalMetadata('openfl.display.BlendMode', '@:build(hscript.UsingHandler.build())');
|
||||
}
|
||||
public static function init() {
|
||||
Compiler.addGlobalMetadata('flixel', '@:build(hscript.UsingHandler.build())');
|
||||
Compiler.addGlobalMetadata('openfl.display.BlendMode', '@:build(hscript.UsingHandler.build())');
|
||||
}
|
||||
|
||||
public static function build():Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
var clRef = Context.getLocalClass();
|
||||
if (clRef == null) return fields;
|
||||
var cl = clRef.get();
|
||||
public static function build():Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
var clRef = Context.getLocalClass();
|
||||
if (clRef == null) return fields;
|
||||
var cl = clRef.get();
|
||||
|
||||
if (/* cl.name.startsWith("Flx") && */ cl.name.endsWith("_Impl_") && cl.params.length <= 0 && !cl.meta.has(":multiType")) {
|
||||
var metas = cl.meta.get();
|
||||
if (/* cl.name.startsWith("Flx") && */ cl.name.endsWith("_Impl_") && cl.params.length <= 0 && !cl.meta.has(":multiType")) {
|
||||
var metas = cl.meta.get();
|
||||
|
||||
var shadowClass = macro class {
|
||||
var shadowClass = macro class {
|
||||
|
||||
};
|
||||
shadowClass.params = switch(cl.params.length) {
|
||||
case 0:
|
||||
null;
|
||||
case 1:
|
||||
[
|
||||
{
|
||||
name: "T",
|
||||
}
|
||||
];
|
||||
default:
|
||||
[for(k=>e in cl.params) {
|
||||
name: "T" + Std.int(k+1)
|
||||
}];
|
||||
};
|
||||
shadowClass.name = '${cl.name.substr(0, cl.name.length - 6)}_HSC';
|
||||
};
|
||||
shadowClass.params = switch(cl.params.length) {
|
||||
case 0:
|
||||
null;
|
||||
case 1:
|
||||
[
|
||||
{
|
||||
name: "T",
|
||||
}
|
||||
];
|
||||
default:
|
||||
[for(k=>e in cl.params) {
|
||||
name: "T" + Std.int(k+1)
|
||||
}];
|
||||
};
|
||||
shadowClass.name = '${cl.name.substr(0, cl.name.length - 6)}_HSC';
|
||||
|
||||
for(f in fields)
|
||||
switch(f.kind) {
|
||||
case FFun(fun):
|
||||
if (f.access.contains(AStatic)) {
|
||||
if (fun.expr != null)
|
||||
shadowClass.fields.push(f);
|
||||
}
|
||||
case FProp(get, set, t, e):
|
||||
if (get == "default" && (set == "never" || set == "null"))
|
||||
shadowClass.fields.push(f);
|
||||
case FVar(t, e):
|
||||
if (f.access.contains(AStatic) || cl.meta.has(":enum") || f.name.toUpperCase() == f.name) {
|
||||
var name:String = f.name;
|
||||
var enumType:String = cl.name;
|
||||
var pack = cl.module.split(".");
|
||||
pack.pop();
|
||||
var complexType:ComplexType = t != null ? t : (name.contains("REGEX") ? TPath({
|
||||
name: "EReg",
|
||||
pack: []
|
||||
}) : TPath({
|
||||
name: cl.name.substr(0, cl.name.length - 6),
|
||||
pack: pack}));
|
||||
var field:Field = {
|
||||
pos: f.pos,
|
||||
name: f.name,
|
||||
meta: f.meta,
|
||||
kind: FVar(complexType, {
|
||||
pos: Context.currentPos(),
|
||||
expr: ECast(e, complexType)
|
||||
}),
|
||||
doc: f.doc,
|
||||
access: [APublic, AStatic]
|
||||
}
|
||||
for(f in fields)
|
||||
switch(f.kind) {
|
||||
case FFun(fun):
|
||||
if (f.access.contains(AStatic)) {
|
||||
if (fun.expr != null)
|
||||
shadowClass.fields.push(f);
|
||||
}
|
||||
case FProp(get, set, t, e):
|
||||
if (get == "default" && (set == "never" || set == "null"))
|
||||
shadowClass.fields.push(f);
|
||||
case FVar(t, e):
|
||||
if (f.access.contains(AStatic) || cl.meta.has(":enum") || f.name.toUpperCase() == f.name) {
|
||||
var name:String = f.name;
|
||||
var enumType:String = cl.name;
|
||||
var pack = cl.module.split(".");
|
||||
pack.pop();
|
||||
var complexType:ComplexType = t != null ? t : (name.contains("REGEX") ? TPath({
|
||||
name: "EReg",
|
||||
pack: []
|
||||
}) : TPath({
|
||||
name: cl.name.substr(0, cl.name.length - 6),
|
||||
pack: pack}));
|
||||
var field:Field = {
|
||||
pos: f.pos,
|
||||
name: f.name,
|
||||
meta: f.meta,
|
||||
kind: FVar(complexType, {
|
||||
pos: Context.currentPos(),
|
||||
expr: ECast(e, complexType)
|
||||
}),
|
||||
doc: f.doc,
|
||||
access: [APublic, AStatic]
|
||||
}
|
||||
|
||||
shadowClass.fields.push(field);
|
||||
}
|
||||
default:
|
||||
}
|
||||
shadowClass.fields.push(field);
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
Context.defineModule(cl.module, [shadowClass], Context.getLocalImports());
|
||||
}
|
||||
Context.defineModule(cl.module, [shadowClass], Context.getLocalImports());
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#else
|
||||
class UsingHandler {
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
}
|
||||
#end
|
||||
Reference in New Issue
Block a user