|
@@ -0,0 +1,274 @@
|
|
|
+/*
|
|
|
+ * Copyright (c) 2005, The haXe Project Contributors
|
|
|
+ * All rights reserved.
|
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
|
+ * modification, are permitted provided that the following conditions are met:
|
|
|
+ *
|
|
|
+ * - Redistributions of source code must retain the above copyright
|
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
|
+ * - Redistributions in binary form must reproduce the above copyright
|
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
|
+ *
|
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
|
|
|
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
|
|
|
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
|
+ * DAMAGE.
|
|
|
+ */
|
|
|
+
|
|
|
+enum ValueType {
|
|
|
+ TNull;
|
|
|
+ TInt;
|
|
|
+ TFloat;
|
|
|
+ TBool;
|
|
|
+ TObject;
|
|
|
+ TFunction;
|
|
|
+ TClass( c : Class<Dynamic> );
|
|
|
+ TEnum( e : Enum<Dynamic> );
|
|
|
+ TUnknown;
|
|
|
+}
|
|
|
+
|
|
|
+@:core_api class Type {
|
|
|
+
|
|
|
+ public static function getClass<T>( o : T ) : Class<T> untyped {
|
|
|
+ var cname = __global__["flash.utils.getQualifiedClassName"](o);
|
|
|
+ if( cname == "null" || cname == "Object" || cname == "int" || cname == "Number" || cname == "Boolean" )
|
|
|
+ return null;
|
|
|
+ if( o.hasOwnProperty("prototype") )
|
|
|
+ return null;
|
|
|
+ var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
|
|
|
+ if( c.__isenum )
|
|
|
+ return null;
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getEnum( o : Dynamic ) : Enum<Dynamic> untyped {
|
|
|
+ var cname = __global__["flash.utils.getQualifiedClassName"](o);
|
|
|
+ if( cname == "null" || cname.substr(0,8) == "builtin." )
|
|
|
+ return null;
|
|
|
+ // getEnum(Enum) should be null
|
|
|
+ if( o.hasOwnProperty("prototype") )
|
|
|
+ return null;
|
|
|
+ var c = __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
|
|
|
+ if( !c.__isenum )
|
|
|
+ return null;
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> untyped {
|
|
|
+ var cname = __global__["flash.utils.getQualifiedSuperclassName"](c);
|
|
|
+ if( cname == "Object" )
|
|
|
+ return null;
|
|
|
+ return __as__(__global__["flash.utils.getDefinitionByName"](cname),Class);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getClassName( c : Class<Dynamic> ) : String {
|
|
|
+ if( c == null )
|
|
|
+ return null;
|
|
|
+ var str : String = untyped __global__["flash.utils.getQualifiedClassName"](c);
|
|
|
+ switch( str ) {
|
|
|
+ case "int": return "Int";
|
|
|
+ case "Number": return "Float";
|
|
|
+ case "Boolean": return "Bool";
|
|
|
+ default:
|
|
|
+ }
|
|
|
+ return str.split("::").join(".");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getEnumName( e : Enum<Dynamic> ) : String {
|
|
|
+ return getClassName(cast e);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function resolveClass( name : String ) : Class<Dynamic> untyped {
|
|
|
+ var cl : Class<Dynamic>;
|
|
|
+ try {
|
|
|
+ cl = __as__(__global__["flash.utils.getDefinitionByName"](name),Class);
|
|
|
+ if( cl.__isenum )
|
|
|
+ return null;
|
|
|
+ return cl; // skip test below
|
|
|
+ } catch( e : Dynamic ) {
|
|
|
+ switch( name ) {
|
|
|
+ case "Int": return Int;
|
|
|
+ case "Float": return Float;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // ensure that this is a class
|
|
|
+ if( cl == null || cl.__name__ == null )
|
|
|
+ return null;
|
|
|
+ return cl;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
|
|
|
+ var e : Dynamic;
|
|
|
+ try {
|
|
|
+ e = __global__["flash.utils.getDefinitionByName"](name);
|
|
|
+ if( !e.__isenum )
|
|
|
+ return null;
|
|
|
+ return e;
|
|
|
+ } catch( e : Dynamic ) {
|
|
|
+ if( name == "Bool" ) return Bool;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // ensure that this is an enum
|
|
|
+ if( e == null || e.__ename__ == null )
|
|
|
+ return null;
|
|
|
+ return e;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T untyped {
|
|
|
+ return switch( args.length ) {
|
|
|
+ case 0: __new__(cl);
|
|
|
+ case 1: __new__(cl,args[0]);
|
|
|
+ case 2: __new__(cl,args[0],args[1]);
|
|
|
+ case 3: __new__(cl,args[0],args[1],args[2]);
|
|
|
+ case 4: __new__(cl,args[0],args[1],args[2],args[3]);
|
|
|
+ case 5: __new__(cl,args[0],args[1],args[2],args[3],args[4]);
|
|
|
+ case 6: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5]);
|
|
|
+ case 7: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
|
|
|
+ case 8: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
|
|
|
+ case 9: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
|
|
|
+ case 10: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
|
|
|
+ case 11: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
|
|
|
+ case 12: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
|
|
|
+ case 13: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]);
|
|
|
+ case 14: __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]);
|
|
|
+ default: throw "Too many arguments";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped {
|
|
|
+ try {
|
|
|
+ flash.Boot.skip_constructor = true;
|
|
|
+ var i = __new__(cl);
|
|
|
+ flash.Boot.skip_constructor = false;
|
|
|
+ return i;
|
|
|
+ } catch( e : Dynamic ) {
|
|
|
+ flash.Boot.skip_constructor = false;
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T {
|
|
|
+ var f = Reflect.field(e,constr);
|
|
|
+ if( f == null ) throw "No such constructor "+constr;
|
|
|
+ if( Reflect.isFunction(f) ) {
|
|
|
+ if( params == null ) throw "Constructor "+constr+" need parameters";
|
|
|
+ return Reflect.callMethod(e,f,params);
|
|
|
+ }
|
|
|
+ if( params != null && params.length != 0 )
|
|
|
+ throw "Constructor "+constr+" does not need parameters";
|
|
|
+ return f;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function createEnumIndex<T>( e : Enum<T>, index : Int, ?params : Array<Dynamic> ) : T {
|
|
|
+ var c = Type.getEnumConstructs(e)[index];
|
|
|
+ if( c == null ) throw index+" is not a valid enum constructor index";
|
|
|
+ return createEnum(e,c,params);
|
|
|
+ }
|
|
|
+
|
|
|
+ static function describe( t : Dynamic, fact : Bool ) : Array<String> untyped {
|
|
|
+ var fields = new Array();
|
|
|
+ var xml : flash.xml.XML = __global__["flash.utils.describeType"](t);
|
|
|
+ if( fact )
|
|
|
+ xml = xml.factory[0];
|
|
|
+ var methods = xml.child("method");
|
|
|
+ for( i in 0...methods.length() )
|
|
|
+ fields.push( Std.string(methods[i].attribute("name")) );
|
|
|
+ var vars = xml.child("variable");
|
|
|
+ for( i in 0...vars.length() )
|
|
|
+ fields.push( Std.string(vars[i].attribute("name")) );
|
|
|
+ var accs = xml.child("accessor");
|
|
|
+ for( i in 0...accs.length() )
|
|
|
+ fields.push( Std.string(accs[i].attribute("name")) );
|
|
|
+ return fields;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> {
|
|
|
+ return describe(c,true);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
|
|
|
+ var a = describe(c,false);
|
|
|
+ a.remove("__construct__");
|
|
|
+ a.remove("prototype");
|
|
|
+ return a;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function getEnumConstructs( e : Enum<Dynamic> ) : Array<String> untyped {
|
|
|
+ return untyped e.__constructs__;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function typeof( v : Dynamic ) : ValueType untyped {
|
|
|
+ var cname = __global__["flash.utils.getQualifiedClassName"](v);
|
|
|
+ switch(cname) {
|
|
|
+ case "null": return TNull;
|
|
|
+ case "void": return TNull; // undefined
|
|
|
+ case "int": return TInt;
|
|
|
+ case "Number":
|
|
|
+ // integers >28 bits are stored as Numbers in avm2
|
|
|
+ if( (v < -0x10000000 || v >= 0x10000000) && Std.int(v) == v )
|
|
|
+ return TInt;
|
|
|
+ return TFloat;
|
|
|
+ case "Boolean": return TBool;
|
|
|
+ case "Object": return TObject;
|
|
|
+ case "Function": return TFunction;
|
|
|
+ default:
|
|
|
+ var c : Dynamic = null;
|
|
|
+ try {
|
|
|
+ c = __global__["flash.utils.getDefinitionByName"](cname);
|
|
|
+ if( v.hasOwnProperty("prototype") )
|
|
|
+ return TObject;
|
|
|
+ if( c.__isenum )
|
|
|
+ return TEnum(c);
|
|
|
+ return TClass(c);
|
|
|
+ } catch( e : Dynamic ) {
|
|
|
+ if( cname == "builtin.as$0::MethodClosure" || cname.indexOf("-") != -1 )
|
|
|
+ return TFunction;
|
|
|
+ return if( c == null ) TFunction else TClass(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function enumEq<T>( a : T, b : T ) : Bool untyped {
|
|
|
+ if( a == b )
|
|
|
+ return true;
|
|
|
+ try {
|
|
|
+ if( a.index != b.index )
|
|
|
+ return false;
|
|
|
+ var ap : Array<Dynamic> = a.params;
|
|
|
+ var bp : Array<Dynamic> = b.params;
|
|
|
+ for( i in 0...ap.length )
|
|
|
+ if( !enumEq(ap[i],bp[i]) )
|
|
|
+ return false;
|
|
|
+ } catch( e : Dynamic ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function enumConstructor( e : Dynamic ) : String {
|
|
|
+ return e.tag;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function enumParameters( e : Dynamic ) : Array<Dynamic> {
|
|
|
+ return if( e.params == null ) [] else e.params;
|
|
|
+ }
|
|
|
+
|
|
|
+ public inline static function enumIndex( e : Dynamic ) : Int {
|
|
|
+ return e.index;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|