Преглед изворни кода

add haxe.rtti.Rtti so we have something resembling an API (also add tests)

Simon Krajewski пре 11 година
родитељ
комит
17650eeed7
3 измењених фајлова са 156 додато и 0 уклоњено
  1. 57 0
      std/haxe/rtti/Rtti.hx
  2. 19 0
      tests/unit/TestSpecification.hx
  3. 80 0
      tests/unit/unitstd/haxe/rtti/Rtti.unit.hx

+ 57 - 0
std/haxe/rtti/Rtti.hx

@@ -0,0 +1,57 @@
+/*
+ * Copyright (C)2005-2014 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package haxe.rtti;
+import haxe.rtti.CType;
+
+/**
+	Rtti is a helper class which supplements the `@:rtti` metadata.
+**/
+class Rtti {
+
+	/**
+		Returns the `haxe.rtti.CType.Classdef` corresponding to class `c`.
+
+		If `c` has no RTTI information, e.g. because no `@:rtti@` was added,
+		`null` is returned.
+
+		If `c` is null, the result is unspecified.
+	**/
+	static public function getRtti<T>(c:Class<T>):Null<Classdef> {
+		var rtti = Reflect.field(c, "__rtti");
+		var x = Xml.parse(rtti).firstElement();
+		var infos = new haxe.rtti.XmlParser().processElement(x);
+		switch (infos) {
+			case TClassdecl(c): return c;
+			case t: throw 'Enum mismatch: expected TClassDecl but found $t';
+		}
+	}
+
+	/**
+		Tells if `c` has RTTI information.
+
+		If `c` is null, the result is unspecified.
+	**/
+	static public function hasRtti<T>(c:Class<T>):Bool {
+		return Lambda.has(Type.getClassFields(c), "__rtti");
+	}
+}

+ 19 - 0
tests/unit/TestSpecification.hx

@@ -122,6 +122,25 @@ enum EVMTest {
 	EVMF(a:Array<EVMTest>);
 }
 
+class NonRttiClass { }
+
+@:rtti
+@:keepSub
+class RttiClass1 {
+    static var v:String;
+    public function f() {
+        return 33.0;
+    }
+}
+
+class RttiClass2 extends RttiClass1 { }
+
+class RttiClass3 extends RttiClass1 {
+	override function f():Int {
+		return 33;
+	}
+}
+
 #if !macro
 @:build(unit.UnitBuilder.build("unitstd"))
 #end

+ 80 - 0
tests/unit/unitstd/haxe/rtti/Rtti.unit.hx

@@ -0,0 +1,80 @@
+haxe.rtti.Rtti.hasRtti(NonRttiClass) == false;
+haxe.rtti.Rtti.hasRtti(RttiClass1) == true;
+haxe.rtti.Rtti.hasRtti(RttiClass2) == true;
+
+var cl = haxe.rtti.Rtti.getRtti(RttiClass1);
+cl.isExtern == false;
+cl.isInterface == false;
+cl.params == [];
+cl.fields.length == 1;
+cl.superClass == null;
+cl.interfaces.length == 0;
+cl.fields.length == 1;
+cl.statics.length == 1;
+cl.tdynamic == null;
+
+var cf = cl.statics.first();
+cf.name == "v";
+haxe.rtti.CType.CTypeTools.toString(cf.type) == "String";
+cf.isPublic == false;
+cf.isOverride == false;
+cf.doc == null;
+cf.get == RNormal;
+cf.set == RNormal;
+cf.params == [];
+cf.platforms.length == 0;
+cf.meta.length == 0;
+cf.line == null;
+cf.overloads == null;
+
+var cf = cl.fields.first();
+cf.name == "f";
+haxe.rtti.CType.CTypeTools.toString(cf.type) == "Void -> Float";
+cf.isPublic == true;
+cf.isOverride == false;
+cf.doc == null;
+cf.get == RNormal;
+cf.set == RMethod;
+cf.params == [];
+cf.platforms.length == 0;
+cf.meta.length == 0;
+//cf.line == null;
+cf.overloads == null;
+
+var cl = haxe.rtti.Rtti.getRtti(RttiClass2);
+cl.isExtern == false;
+cl.isInterface == false;
+cl.params == [];
+cl.fields.length == 0;
+cl.superClass.path == "unit.RttiClass1";
+cl.superClass.params.length == 0;
+cl.interfaces.length == 0;
+cl.fields.length == 0;
+cl.statics.length == 0;
+cl.tdynamic == null;
+
+var cl = haxe.rtti.Rtti.getRtti(RttiClass3);
+cl.isExtern == false;
+cl.isInterface == false;
+cl.params == [];
+cl.fields.length == 1;
+cl.superClass.path == "unit.RttiClass1";
+cl.superClass.params.length == 0;
+cl.interfaces.length == 0;
+cl.fields.length == 1;
+cl.statics.length == 0;
+cl.tdynamic == null;
+
+var cf = cl.fields.first();
+cf.name == "f";
+haxe.rtti.CType.CTypeTools.toString(cf.type) == "Void -> Int";
+cf.isPublic == true;
+cf.isOverride == true;
+cf.doc == null;
+cf.get == RNormal;
+cf.set == RMethod;
+cf.params == [];
+cf.platforms.length == 0;
+cf.meta.length == 0;
+//cf.line == null;
+cf.overloads == null;