Restructuring + KeyValueItherators + is + fixes
This commit is contained in:
+2
-2
@@ -1,3 +1,3 @@
|
||||
--macro keep('IntIterator')
|
||||
--macro hscript.UsingHandler.init()
|
||||
--macro hscript.ClassExtendMacro.init()
|
||||
--macro hscript.macros.UsingHandler.init()
|
||||
--macro hscript.macros.ClassExtendMacro.init()
|
||||
@@ -1233,6 +1233,7 @@ class Checker {
|
||||
mergeType( typeExpr(defaultExpr, withType), defaultExpr);
|
||||
return withType == NoValue ? TVoid : tmin == null ? makeMono() : tmin;
|
||||
case ENew(cl, params):
|
||||
default:
|
||||
}
|
||||
error("Don't know how to type "+edef(expr).getName(), expr);
|
||||
return TDynamic;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package hscript;
|
||||
|
||||
class Config {
|
||||
// Runs support for custom classes in these
|
||||
public static final ALLOWED_CUSTOM_CLASSES = [
|
||||
"flixel",
|
||||
];
|
||||
|
||||
// Runs support for abstract support in these
|
||||
public static final ALLOWED_ABSTRACT_AND_ENUM = [
|
||||
"flixel",
|
||||
"openfl.display.BlendMode",
|
||||
];
|
||||
|
||||
// Incase any of your files fail
|
||||
// These are the module names
|
||||
public static final DISALLOW_CUSTOM_CLASSES = [
|
||||
|
||||
];
|
||||
|
||||
public static final DISALLOW_ABSTRACT_AND_ENUM = [
|
||||
|
||||
];
|
||||
}
|
||||
@@ -35,18 +35,14 @@ class CustomClassHandler implements IHScriptCustomConstructor {
|
||||
|
||||
var disallowCopy = Type.getInstanceFields(cl);
|
||||
|
||||
//trace("Locals");
|
||||
for (key => value in capturedLocals) {
|
||||
if(!disallowCopy.contains(key)) {
|
||||
interp.locals.set(key, {r: value, depth: -1});
|
||||
//trace(key, value);
|
||||
}
|
||||
}
|
||||
//trace("Variables");
|
||||
for (key => value in ogInterp.variables) {
|
||||
if(!disallowCopy.contains(key)) {
|
||||
interp.variables.set(key, value);
|
||||
//trace(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ enum Expr {
|
||||
ECall( e : Expr, params : Array<Expr> );
|
||||
EIf( cond : Expr, e1 : Expr, ?e2 : Expr );
|
||||
EWhile( cond : Expr, e : Expr );
|
||||
EFor( v : String, it : Expr, e : Expr );
|
||||
EFor( v : String, it : Expr, e : Expr, ?ithv: String);
|
||||
EBreak;
|
||||
EContinue;
|
||||
EFunction( args : Array<Argument>, e : Expr, ?name : String, ?ret : CType, ?isPublic : Bool, ?isStatic : Bool, ?isOverride : Bool );
|
||||
|
||||
+40
-11
@@ -160,6 +160,7 @@ class Interp {
|
||||
binops.set("<", function(e1, e2) return me.expr(e1) < me.expr(e2));
|
||||
binops.set("||", function(e1, e2) return me.expr(e1) == true || me.expr(e2) == true);
|
||||
binops.set("&&", function(e1, e2) return me.expr(e1) == true && me.expr(e2) == true);
|
||||
binops.set("is", checkIsType);
|
||||
binops.set("=", assign);
|
||||
binops.set("??", function(e1, e2) {
|
||||
var expr1:Dynamic = me.expr(e1);
|
||||
@@ -182,11 +183,25 @@ class Interp {
|
||||
assignOp("<<=", function(v1, v2) return v1 << v2);
|
||||
assignOp(">>=", function(v1, v2) return v1 >> v2);
|
||||
assignOp(">>>=", function(v1, v2) return v1 >>> v2);
|
||||
assignOp("is", function(v1, v2) return Std.isOfType(v1, v2));
|
||||
assignOp("??=", function(v1, v2) return v1 == null ? v2 : v1);
|
||||
}
|
||||
|
||||
function setVar(name:String, v:Dynamic) {
|
||||
function checkIsType(e1,e2): Bool {
|
||||
var expr1:Dynamic = expr(e1);
|
||||
|
||||
return switch(Tools.expr(e2))
|
||||
{
|
||||
case EIdent("Class"):
|
||||
Std.isOfType(expr1, Class);
|
||||
case EIdent("Map") | EIdent("IMap"):
|
||||
Std.isOfType(expr1, IMap);
|
||||
default:
|
||||
var expr2:Dynamic = expr(e2);
|
||||
expr2 != null ? Std.isOfType(expr1, expr2) : false;
|
||||
}
|
||||
}
|
||||
|
||||
public function setVar(name:String, v:Dynamic) {
|
||||
if (allowStaticVariables && staticVariables.exists(name))
|
||||
staticVariables.set(name, v);
|
||||
else if (allowPublicVariables && publicVariables.exists(name))
|
||||
@@ -620,8 +635,8 @@ class Interp {
|
||||
case EDoWhile(econd, e):
|
||||
doWhileLoop(econd, e);
|
||||
return null;
|
||||
case EFor(v, it, e):
|
||||
forLoop(v, it, e);
|
||||
case EFor(v, it, e, ithv):
|
||||
forLoop(v, it, e, ithv);
|
||||
return null;
|
||||
case EBreak:
|
||||
throw SBreak;
|
||||
@@ -892,26 +907,40 @@ class Interp {
|
||||
restore(old);
|
||||
}
|
||||
|
||||
function makeIterator(v:Dynamic):Iterator<Dynamic> {
|
||||
function makeIterator(v:Dynamic, ?allowKeyValue = false):Iterator<Dynamic> {
|
||||
#if ((flash && !flash9) || (php && !php7 && haxe_ver < '4.0.0'))
|
||||
if (v.iterator != null)
|
||||
v = v.iterator();
|
||||
#else
|
||||
try
|
||||
v = v.iterator()
|
||||
catch (e:Dynamic) {};
|
||||
if(allowKeyValue) {
|
||||
try
|
||||
v = v.keyValueIterator()
|
||||
catch (e:Dynamic) {};
|
||||
}
|
||||
|
||||
if(v.hasNext == null || v.next == null) {
|
||||
try
|
||||
v = v.iterator()
|
||||
catch (e:Dynamic) {};
|
||||
}
|
||||
#end
|
||||
if (v.hasNext == null || v.next == null)
|
||||
error(EInvalidIterator(v));
|
||||
return v;
|
||||
}
|
||||
|
||||
function forLoop(n, it, e) {
|
||||
function forLoop(n, it, e, ?ithv) {
|
||||
var isKeyValue = ithv != null;
|
||||
var old = declared.length;
|
||||
if(isKeyValue)
|
||||
declared.push({n: ithv, old: locals.get(ithv), depth: depth});
|
||||
declared.push({n: n, old: locals.get(n), depth: depth});
|
||||
var it = makeIterator(expr(it));
|
||||
var it = makeIterator(expr(it), isKeyValue);
|
||||
while (it.hasNext()) {
|
||||
locals.set(n, {r: it.next(), depth: depth});
|
||||
var next = it.next();
|
||||
if(isKeyValue)
|
||||
locals.set(ithv, {r: next.key, depth: depth});
|
||||
locals.set(n, {r: isKeyValue ? next.value : next, depth: depth});
|
||||
try {
|
||||
expr(e);
|
||||
} catch (err:Stop) {
|
||||
|
||||
@@ -252,6 +252,8 @@ class Macro {
|
||||
EMeta({ name : m, params : params == null ? [] : [for( p in params ) convert(p)], pos : mpos }, convert(esub));
|
||||
case ECheckType(e, t):
|
||||
ECheckType(convert(e), convertType(t));
|
||||
default:
|
||||
null;
|
||||
}, pos : #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end }
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -185,6 +185,7 @@ class Parser {
|
||||
|
||||
public function parseString( s : String, ?origin : String = "hscript" ) {
|
||||
initParser(origin);
|
||||
if(s == "") s = "0;"; // fixing crash with empty file
|
||||
input = s;
|
||||
readPos = 0;
|
||||
var a = new Array();
|
||||
@@ -547,8 +548,8 @@ class Parser {
|
||||
function mapCompr( tmp : String, e : Expr ) {
|
||||
if( e == null ) return null;
|
||||
var edef = switch( expr(e) ) {
|
||||
case EFor(v, it, e2):
|
||||
EFor(v, it, mapCompr(tmp, e2));
|
||||
case EFor(v, it, e2, ithv):
|
||||
EFor(v, it, mapCompr(tmp, e2), ithv);
|
||||
case EWhile(cond, e2):
|
||||
EWhile(cond, mapCompr(tmp, e2));
|
||||
case EDoWhile(cond, e2):
|
||||
@@ -743,12 +744,21 @@ class Parser {
|
||||
mk(EDoWhile(econd,e),p1,pmax(econd));
|
||||
case "for":
|
||||
ensure(TPOpen);
|
||||
var ithv:String = null;
|
||||
var vname = getIdent();
|
||||
var tk = token();
|
||||
if( Type.enumEq(tk,TOp("=>")) ) {
|
||||
var old = vname;
|
||||
vname = getIdent();
|
||||
ithv = old;
|
||||
} else {
|
||||
push(tk);
|
||||
}
|
||||
ensureToken(TId("in"));
|
||||
var eiter = parseExpr();
|
||||
ensure(TPClose);
|
||||
var e = parseExpr();
|
||||
mk(EFor(vname,eiter,e),p1,pmax(e));
|
||||
mk(EFor(vname,eiter,e,ithv),p1,pmax(e));
|
||||
case "break": mk(EBreak);
|
||||
case "continue": mk(EContinue);
|
||||
case "else": unexpected(TId(id));
|
||||
@@ -1879,6 +1889,7 @@ class Parser {
|
||||
if( StringTools.isEof(char) ) char = 0;
|
||||
if( !idents[char] ) {
|
||||
this.char = char;
|
||||
if(id == "is") return TOp("is");
|
||||
return TId(id);
|
||||
}
|
||||
id += String.fromCharCode(char);
|
||||
|
||||
+5
-2
@@ -217,8 +217,11 @@ class Printer {
|
||||
add(" while ( ");
|
||||
expr(cond);
|
||||
add(" )");
|
||||
case EFor(v, it, e):
|
||||
add("for( "+v+" in ");
|
||||
case EFor(v, it, e, ithv):
|
||||
if(ithv != null)
|
||||
add("for( "+ithv+" => "+v+" in ");
|
||||
else
|
||||
add("for( "+v+" in ");
|
||||
expr(it);
|
||||
add(" ) ");
|
||||
expr(e);
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package hscript;
|
||||
|
||||
import Type.ValueType;
|
||||
import haxe.macro.ComplexTypeTools;
|
||||
#if macro
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Printer;
|
||||
import haxe.macro.Compiler;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class UsingHandler {
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
|
||||
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 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();
|
||||
|
||||
var shadowClass = macro class {
|
||||
|
||||
};
|
||||
shadowClass.kind = TDClass();
|
||||
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';
|
||||
|
||||
var imports = Context.getLocalImports().copy();
|
||||
ClassExtendMacro.setupMetas(shadowClass, imports);
|
||||
|
||||
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:
|
||||
}
|
||||
|
||||
Context.defineModule(cl.module, [shadowClass], imports);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#else
|
||||
class UsingHandler {
|
||||
public var usedClass:Class<Dynamic>;
|
||||
public var className:String;
|
||||
}
|
||||
#end
|
||||
@@ -1,7 +1,7 @@
|
||||
package hscript;
|
||||
package hscript.macros;
|
||||
|
||||
import haxe.macro.Type.ClassType;
|
||||
#if macro
|
||||
import haxe.macro.Type.ClassType;
|
||||
import Type.ValueType;
|
||||
import haxe.macro.Expr.Function;
|
||||
import haxe.macro.Expr;
|
||||
@@ -15,31 +15,19 @@ import Sys;
|
||||
using StringTools;
|
||||
|
||||
class ClassExtendMacro {
|
||||
public static var buildMacroString = '@:build(hscript.ClassExtendMacro.build())';
|
||||
|
||||
public static inline final FUNC_PREFIX = "_HX_SUPER__";
|
||||
public static inline final CLASS_SUFFIX = "_HSX";
|
||||
|
||||
public static var applyOn:Array<String> = [
|
||||
"funkin",
|
||||
"flixel",
|
||||
];
|
||||
public static var unallowedMetas:Array<String> = [":bitmap", ":noCustomClass", ":generic"];
|
||||
|
||||
public static var modifiedClasses:Array<String> = [];
|
||||
|
||||
public static function init() {
|
||||
#if !display
|
||||
for(apply in applyOn) {
|
||||
compile(apply);
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
public static function compile(name:String) {
|
||||
#if !display
|
||||
#if CUSTOM_CLASSES
|
||||
Compiler.addGlobalMetadata(name, buildMacroString);
|
||||
for(apply in Config.ALLOWED_CUSTOM_CLASSES) {
|
||||
Compiler.addGlobalMetadata(apply, "@:build(hscript.macros.ClassExtendMacro.build())");
|
||||
}
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -61,6 +49,20 @@ class ClassExtendMacro {
|
||||
if(cl.params.length > 0)
|
||||
return fields;
|
||||
|
||||
var key = cl.module;
|
||||
var fkey = cl.module + "." + cl.name;
|
||||
if(key == "sys.thread.FixedThreadPool") return fields; // Error: Type name sys.thread.Worker_HSX is redefined from module sys.thread.FixedThreadPool
|
||||
if(key == "StdTypes") return fields; // Error: Cant extend basic class
|
||||
if(key == "Xml") return fields; // Error: Cant extend basic class
|
||||
if(key == "Date") return fields; // Error: Cant extend basic class
|
||||
if(key == "away3d.tools.commands.Mirror") return fields; // Error: Unknown identifier
|
||||
if(key == "away3d.tools.commands.SphereMaker") return fields; // Error: Unknown identifier
|
||||
if(key == "away3d.tools.commands.Weld") return fields; // Error: Unknown identifier
|
||||
if(fkey == "hscript.CustomClassHandler.TemplateClass") return fields; // Error: Redefined
|
||||
if(key == "sys.thread.EventLoop") return fields; // Error: cant override force inlined
|
||||
if(Config.DISALLOW_CUSTOM_CLASSES.contains(cl.module) || Config.DISALLOW_CUSTOM_CLASSES.contains(fkey)) return fields;
|
||||
if(cl.module.contains("_")) return fields; // Weird issue, sorry
|
||||
|
||||
var superFields = [];
|
||||
if(cl.superClass != null) {
|
||||
var _superFields = cl.superClass.t.get().fields.get();
|
||||
@@ -85,7 +87,7 @@ class ClassExtendMacro {
|
||||
if (fun.params != null && fun.params.length > 0)
|
||||
continue;
|
||||
|
||||
fun.ret = fixStdTypes(fun.ret);
|
||||
fun.ret = Utils.fixStdTypes(fun.ret);
|
||||
|
||||
var metas = nfield.meta;
|
||||
var defaultValues:Map<String, Dynamic> = [];
|
||||
@@ -116,7 +118,7 @@ class ClassExtendMacro {
|
||||
arg.opt = false;
|
||||
}
|
||||
|
||||
arg.type = fixStdTypes(arg.type);
|
||||
arg.type = Utils.fixStdTypes(arg.type);
|
||||
|
||||
if(arg.opt) {
|
||||
if(arg.type.getParameters()[0].name != "Null")
|
||||
@@ -258,7 +260,7 @@ class ClassExtendMacro {
|
||||
], false, true, false);
|
||||
shadowClass.name = '${cl.name}$CLASS_SUFFIX';
|
||||
var imports = Context.getLocalImports().copy();
|
||||
setupMetas(shadowClass, imports);
|
||||
Utils.setupMetas(shadowClass, imports);
|
||||
|
||||
// Adding hscript getters and setters
|
||||
|
||||
@@ -414,205 +416,6 @@ class ClassExtendMacro {
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
static function fixStdTypes(type:ComplexType) {
|
||||
switch(type) {
|
||||
case TPath({name: "StdTypes"}):
|
||||
var a:TypePath = type.getParameters()[0];
|
||||
a.name = a.sub;
|
||||
a.sub = null;
|
||||
default:
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static function setupMetas(shadowClass:TypeDefinition, imports) {
|
||||
shadowClass.meta = [{
|
||||
name: ':dox',
|
||||
pos: Context.currentPos(),
|
||||
params: [
|
||||
{
|
||||
expr: EConst(CIdent("hide")),
|
||||
pos: Context.currentPos()
|
||||
}
|
||||
]
|
||||
}];
|
||||
var module = Context.getModule(Context.getLocalModule());
|
||||
for(t in module) {
|
||||
switch(t) {
|
||||
case TInst(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TEnum(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TType(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TAbstract(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
default:
|
||||
// not needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function processModule(shadowClass:TypeDefinition, module:String, n:String) {
|
||||
if (n.endsWith("_Impl_"))
|
||||
n = n.substr(0, n.length - 6);
|
||||
if (module.endsWith("_Impl_"))
|
||||
module = module.substr(0, module.length - 6);
|
||||
|
||||
shadowClass.meta.push(
|
||||
{
|
||||
name: ':access',
|
||||
params: [
|
||||
Context.parse(fixModuleName(module.endsWith('.${n}') ? module : '${module}.${n}'), Context.currentPos())
|
||||
],
|
||||
pos: Context.currentPos()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*public static function getModuleName(path:Type) {
|
||||
switch(path) {
|
||||
case TPath(name, pack):// | TDClass(name, pack):
|
||||
var str = "";
|
||||
for(p in pack) {
|
||||
str += p + ".";
|
||||
}
|
||||
str += name;
|
||||
return str;
|
||||
|
||||
default:
|
||||
}
|
||||
return "INVALID";
|
||||
}*/
|
||||
|
||||
public static function fixModuleName(name:String) {
|
||||
return [for(s in name.split(".")) if (s.charAt(0) == "_") s.substr(1) else s].join(".");
|
||||
}
|
||||
public static function processImport(imports:Array<ImportExpr>, module:String, n:String) {
|
||||
if (n.endsWith("_Impl_"))
|
||||
n = n.substr(0, n.length - 6);
|
||||
module = fixModuleName(module);
|
||||
if (module.endsWith("_Impl_"))
|
||||
module = module.substr(0, module.length - 6);
|
||||
|
||||
imports.push({
|
||||
path: [for(m in module.split(".")) {
|
||||
name: m,
|
||||
pos: Context.currentPos()
|
||||
}],
|
||||
mode: INormal
|
||||
});
|
||||
}
|
||||
|
||||
public static function cleanExpr(expr:Expr, oldFunc:String, newFunc:String) {
|
||||
if (expr == null) return;
|
||||
if (expr.expr == null) return;
|
||||
switch(expr.expr) {
|
||||
case EConst(c):
|
||||
switch(c) {
|
||||
case CIdent(s):
|
||||
if (s == oldFunc)
|
||||
expr.expr = EConst(CIdent(newFunc));
|
||||
case CString(s, b):
|
||||
if (s == oldFunc)
|
||||
expr.expr = EConst(CString(s, b));
|
||||
default:
|
||||
// nothing
|
||||
}
|
||||
case EField(e, field):
|
||||
if (field == oldFunc && e != null) {
|
||||
switch(e.expr) {
|
||||
case EConst(c):
|
||||
switch(c) {
|
||||
case CIdent(s):
|
||||
if (s == "super")
|
||||
expr.expr = EField(e, newFunc);
|
||||
default:
|
||||
|
||||
}
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
case EParenthesis(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EObjectDecl(fields):
|
||||
for(f in fields) {
|
||||
cleanExpr(f.expr, oldFunc, newFunc);
|
||||
}
|
||||
case EArrayDecl(values):
|
||||
for(a in values) {
|
||||
cleanExpr(a, oldFunc, newFunc);
|
||||
}
|
||||
case ECall(e, params):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EBlock(exprs):
|
||||
for(e in exprs)
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EFor(it, expr):
|
||||
cleanExpr(it, oldFunc, newFunc);
|
||||
cleanExpr(expr, oldFunc, newFunc);
|
||||
case EIf(econd, eif, eelse):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(eif, oldFunc, newFunc);
|
||||
cleanExpr(eelse, oldFunc, newFunc);
|
||||
case EWhile(econd, e, normalWhile):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ECast(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ECheckType(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ETry(e, catches):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
for(c in catches) {
|
||||
cleanExpr(c.expr, oldFunc, newFunc);
|
||||
}
|
||||
case EThrow(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ETernary(econd, eif, eelse):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(eif, oldFunc, newFunc);
|
||||
cleanExpr(eelse, oldFunc, newFunc);
|
||||
case ESwitch(e, cases, edef):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
for(c in cases) {
|
||||
cleanExpr(c.expr, oldFunc, newFunc);
|
||||
}
|
||||
cleanExpr(edef, oldFunc, newFunc);
|
||||
case EReturn(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EIs(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EVars(vars):
|
||||
for(v in vars) {
|
||||
cleanExpr(v.expr, oldFunc, newFunc);
|
||||
}
|
||||
case ENew(t, params):
|
||||
for(p in params) {
|
||||
cleanExpr(p, oldFunc, newFunc);
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
class ClassExtendMacro {
|
||||
@@ -0,0 +1,159 @@
|
||||
package hscript.macros;
|
||||
|
||||
#if macro
|
||||
import Type.ValueType;
|
||||
import haxe.macro.ComplexTypeTools;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Printer;
|
||||
import haxe.macro.Compiler;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class UsingHandler {
|
||||
public static function init() {
|
||||
#if !display
|
||||
for(apply in Config.ALLOWED_ABSTRACT_AND_ENUM) {
|
||||
Compiler.addGlobalMetadata(apply, '@:build(hscript.macros.UsingHandler.build())');
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
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") && !cl.name.contains("_HSC")) {
|
||||
var metas = cl.meta.get();
|
||||
|
||||
var trimEnum = cl.name.substr(0, cl.name.length - 6);
|
||||
|
||||
var key = cl.module;
|
||||
var fkey = cl.module + "." + trimEnum;
|
||||
if(key == "lime.system.Locale") return fields; // Error: Unknown identifier : currentLocale, Due to Func
|
||||
if(key == "cpp.Function") return fields; // Error: Unknown identifier : nativeGetProcAddress, Due to Func
|
||||
if(key == "haxe.ds.Vector") return fields; // Error: haxe.ds._Vector.VectorData<blit.T> has no field blit, Due to Func
|
||||
if(key == "haxe.display.Display") return fields; // Error: haxe.display.DisplayItemKind<haxe.display.DisplayLiteral<Dynamic>> has no field Null, Due to Func
|
||||
if(key == "cpp.Callable") return fields; // Error: cpp.Function.fromStaticFunction must be called on static function, Due to Func
|
||||
if(key == "haxe.display.JsonAnonStatusKind") return fields; // Error: cannot initialize a variable of type 'char *' with an rvalue of type 'const char *', Due to Func
|
||||
if(key == "cpp.CharStar") return fields; // Error: cannot initialize a variable of type 'char *' with an rvalue of type 'const char *', Due to Func
|
||||
if(Config.DISALLOW_ABSTRACT_AND_ENUM.contains(cl.module) || Config.DISALLOW_ABSTRACT_AND_ENUM.contains(fkey)) return fields;
|
||||
if(cl.module.contains("_")) return fields; // Weird issue, sorry
|
||||
|
||||
var shadowClass = macro class {
|
||||
|
||||
};
|
||||
shadowClass.kind = TDClass();
|
||||
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';
|
||||
|
||||
var imports = Context.getLocalImports().copy();
|
||||
Utils.setupMetas(shadowClass, imports);
|
||||
//trace(cl.module);
|
||||
|
||||
for(f in fields)
|
||||
switch(f.kind) {
|
||||
case FFun(fun):
|
||||
if (f.access.contains(AStatic)) {
|
||||
if (fun.expr != null) {
|
||||
fun.expr = macro @:privateAccess $e{fun.expr};
|
||||
shadowClass.fields.push(f);
|
||||
|
||||
/*var trimEnum = cl.name.substr(0, cl.name.length - 6);
|
||||
|
||||
var returns:Bool = !fun.ret.match(TPath({name: "Void"}));
|
||||
|
||||
var name = f.name;
|
||||
|
||||
var arguments = fun.args == null ? [] : [for(a in fun.args) macro $i{a.name}];
|
||||
|
||||
var expr:Expr = Context.parse('${returns?"return " : ""} $trimEnum.$name(${[for(a in fun.args) a.name].join(", ")})', f.pos);
|
||||
|
||||
var func:Function = {
|
||||
ret: fun.ret,
|
||||
params: fun.params.copy(),
|
||||
expr: expr,
|
||||
args: fun.args.copy()
|
||||
};
|
||||
|
||||
var field:Field = {
|
||||
pos: f.pos,
|
||||
name: f.name,
|
||||
meta: f.meta,
|
||||
kind: FFun(func),
|
||||
doc: null,//f.doc,
|
||||
access: [APublic, AStatic]
|
||||
}
|
||||
shadowClass.fields.push(field);*/
|
||||
}
|
||||
}
|
||||
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(".");
|
||||
|
||||
//trace(pack, cl.name, name, cl.module);
|
||||
|
||||
if(pack[pack.length - 1] == trimEnum)
|
||||
pack.pop();
|
||||
|
||||
var complexType:ComplexType = t;
|
||||
if(complexType == null && e != null) {
|
||||
complexType = switch(e.expr) {
|
||||
case EConst(CRegexp(_)): TPath({ name: "EReg", pack: [] });
|
||||
|
||||
default: null;
|
||||
}
|
||||
}
|
||||
if(complexType == null) {
|
||||
complexType = TPath({
|
||||
name: trimEnum,
|
||||
pack: [],//pack
|
||||
});
|
||||
}
|
||||
|
||||
var code = Context.parse('@:privateAccess ($trimEnum.$name)', f.pos); // '${pack.join(".")}.${trimEnum}.$name'
|
||||
|
||||
var field:Field = {
|
||||
pos: f.pos,
|
||||
name: f.name,
|
||||
meta: f.meta,
|
||||
kind: FVar(null, code),
|
||||
doc: f.doc,
|
||||
access: [APublic, AStatic]
|
||||
}
|
||||
|
||||
shadowClass.fields.push(field);
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
//var printer = new Printer();
|
||||
//for(field in shadowClass.fields)
|
||||
// trace(printer.printField(field));
|
||||
|
||||
Context.defineModule(cl.module, [shadowClass], imports);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -0,0 +1,209 @@
|
||||
package hscript.macros;
|
||||
|
||||
#if macro
|
||||
import haxe.macro.Type.ClassType;
|
||||
import Type.ValueType;
|
||||
import haxe.macro.Expr.Function;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Type.MetaAccess;
|
||||
import haxe.macro.Type.FieldKind;
|
||||
import haxe.macro.Type.ClassField;
|
||||
import haxe.macro.Type.VarAccess;
|
||||
import haxe.macro.*;
|
||||
|
||||
using StringTools;
|
||||
|
||||
class Utils {
|
||||
public static function fixStdTypes(type:ComplexType) {
|
||||
switch(type) {
|
||||
case TPath({name: "StdTypes"}):
|
||||
var a:TypePath = type.getParameters()[0];
|
||||
a.name = a.sub;
|
||||
a.sub = null;
|
||||
default:
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static function setupMetas(shadowClass:TypeDefinition, imports) {
|
||||
shadowClass.meta = [];
|
||||
shadowClass.meta.push({name: ":dox", params: [macro hide], pos: Context.currentPos()});
|
||||
shadowClass.meta.push({name: ":noCompletion", params: [], pos: Context.currentPos()});
|
||||
var module = Context.getModule(Context.getLocalModule());
|
||||
for(t in module) {
|
||||
switch(t) {
|
||||
case TInst(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TEnum(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TType(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
case TAbstract(t, params):
|
||||
if (t != null) {
|
||||
var e = t.get();
|
||||
processModule(shadowClass, e.module, e.name);
|
||||
processImport(imports, e.module, e.name);
|
||||
}
|
||||
default:
|
||||
// not needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function processModule(shadowClass:TypeDefinition, module:String, n:String) {
|
||||
if (n.endsWith("_Impl_"))
|
||||
n = n.substr(0, n.length - 6);
|
||||
if (module.endsWith("_Impl_"))
|
||||
module = module.substr(0, module.length - 6);
|
||||
|
||||
shadowClass.meta.push(
|
||||
{
|
||||
name: ':access',
|
||||
params: [
|
||||
Context.parse(fixModuleName(module.endsWith('.${n}') ? module : '${module}.${n}'), Context.currentPos())
|
||||
],
|
||||
pos: Context.currentPos()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*public static function getModuleName(path:Type) {
|
||||
switch(path) {
|
||||
case TPath(name, pack):// | TDClass(name, pack):
|
||||
var str = "";
|
||||
for(p in pack) {
|
||||
str += p + ".";
|
||||
}
|
||||
str += name;
|
||||
return str;
|
||||
|
||||
default:
|
||||
}
|
||||
return "INVALID";
|
||||
}*/
|
||||
|
||||
public static function fixModuleName(name:String) {
|
||||
return [for(s in name.split(".")) if (s.charAt(0) == "_") s.substr(1) else s].join(".");
|
||||
}
|
||||
public static function processImport(imports:Array<ImportExpr>, module:String, n:String) {
|
||||
if (n.endsWith("_Impl_"))
|
||||
n = n.substr(0, n.length - 6);
|
||||
module = fixModuleName(module);
|
||||
if (module.endsWith("_Impl_"))
|
||||
module = module.substr(0, module.length - 6);
|
||||
|
||||
imports.push({
|
||||
path: [for(m in module.split(".")) {
|
||||
name: m,
|
||||
pos: Context.currentPos()
|
||||
}],
|
||||
mode: INormal
|
||||
});
|
||||
}
|
||||
|
||||
public static function cleanExpr(expr:Expr, oldFunc:String, newFunc:String) {
|
||||
if (expr == null) return;
|
||||
if (expr.expr == null) return;
|
||||
switch(expr.expr) {
|
||||
case EConst(c):
|
||||
switch(c) {
|
||||
case CIdent(s):
|
||||
if (s == oldFunc)
|
||||
expr.expr = EConst(CIdent(newFunc));
|
||||
case CString(s, b):
|
||||
if (s == oldFunc)
|
||||
expr.expr = EConst(CString(s, b));
|
||||
default:
|
||||
// nothing
|
||||
}
|
||||
case EField(e, field):
|
||||
if (field == oldFunc && e != null) {
|
||||
switch(e.expr) {
|
||||
case EConst(c):
|
||||
switch(c) {
|
||||
case CIdent(s):
|
||||
if (s == "super")
|
||||
expr.expr = EField(e, newFunc);
|
||||
default:
|
||||
|
||||
}
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
case EParenthesis(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EObjectDecl(fields):
|
||||
for(f in fields) {
|
||||
cleanExpr(f.expr, oldFunc, newFunc);
|
||||
}
|
||||
case EArrayDecl(values):
|
||||
for(a in values) {
|
||||
cleanExpr(a, oldFunc, newFunc);
|
||||
}
|
||||
case ECall(e, params):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EBlock(exprs):
|
||||
for(e in exprs)
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EFor(it, expr):
|
||||
cleanExpr(it, oldFunc, newFunc);
|
||||
cleanExpr(expr, oldFunc, newFunc);
|
||||
case EIf(econd, eif, eelse):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(eif, oldFunc, newFunc);
|
||||
cleanExpr(eelse, oldFunc, newFunc);
|
||||
case EWhile(econd, e, normalWhile):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ECast(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ECheckType(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ETry(e, catches):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
for(c in catches) {
|
||||
cleanExpr(c.expr, oldFunc, newFunc);
|
||||
}
|
||||
case EThrow(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case ETernary(econd, eif, eelse):
|
||||
cleanExpr(econd, oldFunc, newFunc);
|
||||
cleanExpr(eif, oldFunc, newFunc);
|
||||
cleanExpr(eelse, oldFunc, newFunc);
|
||||
case ESwitch(e, cases, edef):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
for(c in cases) {
|
||||
cleanExpr(c.expr, oldFunc, newFunc);
|
||||
}
|
||||
cleanExpr(edef, oldFunc, newFunc);
|
||||
case EReturn(e):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EIs(e, t):
|
||||
cleanExpr(e, oldFunc, newFunc);
|
||||
case EVars(vars):
|
||||
for(v in vars) {
|
||||
cleanExpr(v.expr, oldFunc, newFunc);
|
||||
}
|
||||
case ENew(t, params):
|
||||
for(p in params) {
|
||||
cleanExpr(p, oldFunc, newFunc);
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
#end
|
||||
Reference in New Issue
Block a user