Boot.hx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package js;
  23. class Boot {
  24. private static function __unhtml(s : String) {
  25. return s.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
  26. }
  27. private static function __trace(v,i : haxe.PosInfos) {
  28. untyped {
  29. var msg = if( i != null ) i.fileName+":"+i.lineNumber+": " else "";
  30. #if jsfl
  31. msg += __string_rec(v,"");
  32. fl.trace(msg);
  33. #else
  34. msg += __string_rec(v,"");
  35. var d;
  36. if( __js__("typeof")(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null )
  37. d.innerHTML += __unhtml(msg)+"<br/>";
  38. else if( __js__("typeof")(console) != "undefined" && console.log != null )
  39. console.log(msg);
  40. #end
  41. }
  42. }
  43. private static function __clear_trace() {
  44. untyped {
  45. #if jsfl
  46. fl.outputPanel.clear();
  47. #else
  48. var d = document.getElementById("haxe:trace");
  49. if( d != null )
  50. d.innerHTML = "";
  51. #end
  52. }
  53. }
  54. static inline function isClass(o:Dynamic) : Bool {
  55. return untyped __define_feature__("js.Boot.isClass", o.__name__);
  56. }
  57. static inline function isEnum(e:Dynamic) : Bool {
  58. return untyped __define_feature__("js.Boot.isEnum", e.__ename__);
  59. }
  60. static inline function getClass(o:Dynamic) : Dynamic {
  61. return untyped __define_feature__("js.Boot.getClass", o.__class__);
  62. }
  63. @:ifFeature("has_enum")
  64. private static function __string_rec(o,s:String) {
  65. untyped {
  66. if( o == null )
  67. return "null";
  68. if( s.length >= 5 )
  69. return "<...>"; // too much deep recursion
  70. var t = __js__("typeof(o)");
  71. if( t == "function" && (isClass(o) || isEnum(o)) )
  72. t = "object";
  73. switch( t ) {
  74. case "object":
  75. if( __js__("o instanceof Array") ) {
  76. if( o.__enum__ ) {
  77. if( o.length == 2 )
  78. return o[0];
  79. var str = o[0]+"(";
  80. s += "\t";
  81. for( i in 2...o.length ) {
  82. if( i != 2 )
  83. str += "," + __string_rec(o[i],s);
  84. else
  85. str += __string_rec(o[i],s);
  86. }
  87. return str + ")";
  88. }
  89. var l = o.length;
  90. var i;
  91. var str = "[";
  92. s += "\t";
  93. for( i in 0...l )
  94. str += (if (i > 0) "," else "")+__string_rec(o[i],s);
  95. str += "]";
  96. return str;
  97. }
  98. var tostr;
  99. try {
  100. tostr = untyped o.toString;
  101. } catch( e : Dynamic ) {
  102. // strange error on IE
  103. return "???";
  104. }
  105. if( tostr != null && tostr != __js__("Object.toString") ) {
  106. var s2 = o.toString();
  107. if( s2 != "[object Object]")
  108. return s2;
  109. }
  110. var k : String = null;
  111. var str = "{\n";
  112. s += "\t";
  113. var hasp = (o.hasOwnProperty != null);
  114. __js__("for( var k in o ) { ");
  115. if( hasp && !o.hasOwnProperty(k) )
  116. __js__("continue");
  117. if( k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__" )
  118. __js__("continue");
  119. if( str.length != 2 )
  120. str += ", \n";
  121. str += s + k + " : "+__string_rec(o[k],s);
  122. __js__("}");
  123. s = s.substring(1);
  124. str += "\n" + s + "}";
  125. return str;
  126. case "function":
  127. return "<function>";
  128. case "string":
  129. return o;
  130. default:
  131. return String(o);
  132. }
  133. }
  134. }
  135. private static function __interfLoop(cc : Dynamic,cl : Dynamic) {
  136. if( cc == null )
  137. return false;
  138. if( cc == cl )
  139. return true;
  140. var intf : Dynamic = cc.__interfaces__;
  141. if( intf != null )
  142. for( i in 0...intf.length ) {
  143. var i : Dynamic = intf[i];
  144. if( i == cl || __interfLoop(i,cl) )
  145. return true;
  146. }
  147. return __interfLoop(cc.__super__,cl);
  148. }
  149. @:ifFeature("typed_catch") private static function __instanceof(o : Dynamic,cl) {
  150. untyped {
  151. try {
  152. if( __js__("o instanceof cl") ) {
  153. if( cl == Array )
  154. return (o.__enum__ == null);
  155. return true;
  156. }
  157. if( __interfLoop(js.Boot.getClass(o),cl) )
  158. return true;
  159. } catch( e : Dynamic ) {
  160. if( cl == null )
  161. return false;
  162. }
  163. switch( cl ) {
  164. case Int:
  165. return __js__("Math.ceil(o%2147483648.0) === o");
  166. case Float:
  167. return __js__("typeof(o)") == "number";
  168. case Bool:
  169. return __js__("o === true || o === false");
  170. case String:
  171. return __js__("typeof(o)") == "string";
  172. case Dynamic:
  173. return true;
  174. default:
  175. if( o == null )
  176. return false;
  177. // do not use isClass/isEnum here
  178. __feature__("Class.*",if( cl == Class && o.__name__ != null ) return true);
  179. __feature__("Enum.*",if( cl == Enum && o.__ename__ != null ) return true);
  180. return o.__enum__ == cl;
  181. }
  182. }
  183. }
  184. @:ifFeature("typed_cast") private static function __cast(o : Dynamic, t : Dynamic) {
  185. if (__instanceof(o, t)) return o;
  186. else throw "Cannot cast " +Std.string(o) + " to " +Std.string(t);
  187. }
  188. }