common.ml 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. (*
  2. The Haxe Compiler
  3. Copyright (C) 2005-2015 Haxe Foundation
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  15. *)
  16. open Ast
  17. open Type
  18. type package_rule =
  19. | Forbidden
  20. | Directory of string
  21. | Remap of string
  22. type pos = Ast.pos
  23. type basic_types = {
  24. mutable tvoid : t;
  25. mutable tint : t;
  26. mutable tfloat : t;
  27. mutable tbool : t;
  28. mutable tnull : t -> t;
  29. mutable tstring : t;
  30. mutable tarray : t -> t;
  31. }
  32. type stats = {
  33. s_files_parsed : int ref;
  34. s_classes_built : int ref;
  35. s_methods_typed : int ref;
  36. s_macros_called : int ref;
  37. }
  38. type platform =
  39. | Cross
  40. | Js
  41. | Neko
  42. | Flash
  43. | Php
  44. | Cpp
  45. | Cs
  46. | Java
  47. | Python
  48. (**
  49. The capture policy tells which handling we make of captured locals
  50. (the locals which are referenced in local functions)
  51. See details/implementation in Codegen.captured_vars
  52. *)
  53. type capture_policy =
  54. (** do nothing, let the platform handle it *)
  55. | CPNone
  56. (** wrap all captured variables into a single-element array to allow modifications *)
  57. | CPWrapRef
  58. (** similar to wrap ref, but will only apply to the locals that are declared in loops *)
  59. | CPLoopVars
  60. type platform_config = {
  61. (** has a static type system, with not-nullable basic types (Int/Float/Bool) *)
  62. pf_static : bool;
  63. (** has access to the "sys" package *)
  64. pf_sys : bool;
  65. (** local variables are block-scoped *)
  66. pf_locals_scope : bool;
  67. (** captured local variables are scoped *)
  68. pf_captured_scope : bool;
  69. (** generated locals must be absolutely unique wrt the current function *)
  70. pf_unique_locals : bool;
  71. (** captured variables handling (see before) *)
  72. pf_capture_policy : capture_policy;
  73. (** when calling a method with optional args, do we replace the missing args with "null" constants *)
  74. pf_pad_nulls : bool;
  75. (** add a final return to methods not having one already - prevent some compiler warnings *)
  76. pf_add_final_return : bool;
  77. (** does the platform natively support overloaded functions *)
  78. pf_overload : bool;
  79. (** does the platform generator handle pattern matching *)
  80. pf_pattern_matching : bool;
  81. (** can the platform use default values for non-nullable arguments *)
  82. pf_can_skip_non_nullable_argument : bool;
  83. (** type paths that are reserved on the platform *)
  84. pf_reserved_type_paths : path list;
  85. }
  86. type display_mode =
  87. | DMNone
  88. | DMDefault
  89. | DMUsage
  90. | DMPosition
  91. | DMToplevel
  92. | DMResolve of string
  93. | DMType
  94. type context = {
  95. (* config *)
  96. version : int;
  97. args : string list;
  98. mutable sys_args : string list;
  99. mutable display : display_mode;
  100. mutable debug : bool;
  101. mutable verbose : bool;
  102. mutable foptimize : bool;
  103. mutable platform : platform;
  104. mutable config : platform_config;
  105. mutable std_path : string list;
  106. mutable class_path : string list;
  107. mutable main_class : Type.path option;
  108. mutable defines : (string,string) PMap.t;
  109. mutable package_rules : (string,package_rule) PMap.t;
  110. mutable error : string -> pos -> unit;
  111. mutable warning : string -> pos -> unit;
  112. mutable load_extern_type : (path -> pos -> (string * Ast.package) option) list; (* allow finding types which are not in sources *)
  113. mutable filters : (unit -> unit) list;
  114. mutable final_filters : (unit -> unit) list;
  115. mutable defines_signature : string option;
  116. mutable print : string -> unit;
  117. mutable get_macros : unit -> context option;
  118. mutable run_command : string -> int;
  119. file_lookup_cache : (string,string option) Hashtbl.t;
  120. mutable stored_typed_exprs : (int, texpr) PMap.t;
  121. (* output *)
  122. mutable file : string;
  123. mutable flash_version : float;
  124. mutable features : (string,bool) Hashtbl.t;
  125. mutable modules : Type.module_def list;
  126. mutable main : Type.texpr option;
  127. mutable types : Type.module_type list;
  128. mutable resources : (string,string) Hashtbl.t;
  129. mutable neko_libs : string list;
  130. mutable include_files : (string * string) list;
  131. mutable php_front : string option;
  132. mutable php_lib : string option;
  133. mutable php_prefix : string option;
  134. mutable swf_libs : (string * (unit -> Swf.swf) * (unit -> ((string list * string),As3hl.hl_class) Hashtbl.t)) list;
  135. mutable java_libs : (string * bool * (unit -> unit) * (unit -> (path list)) * (path -> ((JData.jclass * string * string) option))) list; (* (path,std,close,all_files,lookup) *)
  136. mutable net_libs : (string * bool * (unit -> path list) * (path -> IlData.ilclass option)) list; (* (path,std,all_files,lookup) *)
  137. mutable net_std : string list;
  138. net_path_map : (path,string list * string list * string) Hashtbl.t;
  139. mutable c_args : string list;
  140. mutable js_gen : (unit -> unit) option;
  141. (* typing *)
  142. mutable basic : basic_types;
  143. memory_marker : float array;
  144. }
  145. exception Abort of string * Ast.pos
  146. let display_default = ref DMNone
  147. module Define = struct
  148. type strict_defined =
  149. | AbsolutePath
  150. | AdvancedTelemetry
  151. | Analyzer
  152. | As3
  153. | CheckXmlProxy
  154. | CoreApi
  155. | CoreApiSerialize
  156. | Cppia
  157. | Dce
  158. | DceDebug
  159. | Debug
  160. | Display
  161. | DllExport
  162. | DllImport
  163. | DocGen
  164. | Dump
  165. | DumpDependencies
  166. | DumpIgnoreVarIds
  167. | DynamicInterfaceClosures
  168. | EraseGenerics
  169. | Fdb
  170. | FileExtension
  171. | FlashStrict
  172. | FlashUseStage
  173. | ForceLibCheck
  174. | ForceNativeProperty
  175. | FormatWarning
  176. | GencommonDebug
  177. | HaxeBoot
  178. | HaxeVer
  179. | HxcppApiLevel
  180. | IncludePrefix
  181. | Interp
  182. | JavaVer
  183. | JqueryVer
  184. | JsClassic
  185. | JsEs5
  186. | JsUnflatten
  187. | KeepOldOutput
  188. | LoopUnrollMaxCost
  189. | Macro
  190. | MacroTimes
  191. | NekoSource
  192. | NekoV1
  193. | NetworkSandbox
  194. | NetVer
  195. | NetTarget
  196. | NoCompilation
  197. | NoCOpt
  198. | NoDeprecationWarnings
  199. | NoFlashOverride
  200. | NoDebug
  201. | NoInline
  202. | NoOpt
  203. | NoPatternMatching
  204. | NoRoot
  205. | NoSimplify
  206. | NoSwfCompress
  207. | NoTraces
  208. | Objc
  209. | PhpPrefix
  210. | RealPosition
  211. | ReplaceFiles
  212. | Scriptable
  213. | ShallowExpose
  214. | SourceHeader
  215. | SourceMapContent
  216. | Swc
  217. | SwfCompressLevel
  218. | SwfDebugPassword
  219. | SwfDirectBlit
  220. | SwfGpu
  221. | SwfMetadata
  222. | SwfPreloaderFrame
  223. | SwfProtected
  224. | SwfScriptTimeout
  225. | SwfUseDoAbc
  226. | Sys
  227. | Unsafe
  228. | UseNekoc
  229. | UseRttiDoc
  230. | Vcproj
  231. | NoMacroCache
  232. | Last (* must be last *)
  233. let infos = function
  234. | AbsolutePath -> ("absolute_path","Print absolute file path in trace output")
  235. | AdvancedTelemetry -> ("advanced-telemetry","Allow the SWF to be measured with Monocle tool")
  236. | Analyzer -> ("analyzer","Use static analyzer for optimization (experimental)")
  237. | As3 -> ("as3","Defined when outputing flash9 as3 source code")
  238. | CheckXmlProxy -> ("check_xml_proxy","Check the used fields of the xml proxy")
  239. | CoreApi -> ("core_api","Defined in the core api context")
  240. | CoreApiSerialize -> ("core_api_serialize","Mark some generated core api classes with the Serializable attribute on C#")
  241. | Cppia -> ("cppia", "Generate experimental cpp instruction assembly")
  242. | Dce -> ("dce","<mode:std|full||no> Set the dead code elimination mode (default std)")
  243. | DceDebug -> ("dce_debug","Show DCE log")
  244. | Debug -> ("debug","Activated when compiling with -debug")
  245. | Display -> ("display","Activated during completion")
  246. | DllExport -> ("dll_export", "GenCPP experimental linking")
  247. | DllImport -> ("dll_import", "GenCPP experimental linking")
  248. | DocGen -> ("doc_gen","Do not perform any removal/change in order to correctly generate documentation")
  249. | Dump -> ("dump","Dump the complete typed AST for internal debugging in a dump subdirectory - use dump=pretty for Haxe-like formatting")
  250. | DumpDependencies -> ("dump_dependencies","Dump the classes dependencies in a dump subdirectory")
  251. | DumpIgnoreVarIds -> ("dump_ignore_var_ids","Remove variable IDs from non-pretty dumps (helps with diff)")
  252. | DynamicInterfaceClosures -> ("dynamic_interface_closures","Use slow path for interface closures to save space")
  253. | EraseGenerics -> ("erase_generics","Erase generic classes on C#")
  254. | Fdb -> ("fdb","Enable full flash debug infos for FDB interactive debugging")
  255. | FileExtension -> ("file_extension","Output filename extension for cpp source code")
  256. | FlashStrict -> ("flash_strict","More strict typing for flash target")
  257. | FlashUseStage -> ("flash_use_stage","Keep the SWF library initial stage")
  258. (* force_lib_check is only here as a debug facility - compiler checking allows errors to be found more easily *)
  259. | ForceLibCheck -> ("force_lib_check","Force the compiler to check -net-lib and -java-lib added classes (internal)")
  260. | ForceNativeProperty -> ("force_native_property","Tag all properties with :nativeProperty metadata for 3.1 compatibility")
  261. | FormatWarning -> ("format_warning","Print a warning for each formated string, for 2.x compatibility")
  262. | GencommonDebug -> ("gencommon_debug","GenCommon internal")
  263. | HaxeBoot -> ("haxe_boot","Given the name 'haxe' to the flash boot class instead of a generated name")
  264. | HaxeVer -> ("haxe_ver","The current Haxe version value")
  265. | HxcppApiLevel -> ("hxcpp_api_level","Provided to allow compatibility between hxcpp versions")
  266. | IncludePrefix -> ("include_prefix","prepend path to generated include files")
  267. | Interp -> ("interp","The code is compiled to be run with --interp")
  268. | JavaVer -> ("java_ver", "<version:5-7> Sets the Java version to be targeted")
  269. | JqueryVer -> ("jquery_ver", "The jQuery version supported by js.jquery.*. The version is encoded as an interger. e.g. 1.11.3 is encoded as 11103")
  270. | JsClassic -> ("js_classic","Don't use a function wrapper and strict mode in JS output")
  271. | JsEs5 -> ("js_es5","Generate JS for ES5-compliant runtimes")
  272. | JsUnflatten -> ("js_unflatten","Generate nested objects for packages and types")
  273. | KeepOldOutput -> ("keep_old_output","Keep old source files in the output directory (for C#/Java)")
  274. | LoopUnrollMaxCost -> ("loop_unroll_max_cost","Maximum cost (number of expressions * iterations) before loop unrolling is canceled (default 250)")
  275. | Macro -> ("macro","Defined when code is compiled in the macro context")
  276. | MacroTimes -> ("macro_times","Display per-macro timing when used with --times")
  277. | NetVer -> ("net_ver", "<version:20-45> Sets the .NET version to be targeted")
  278. | NetTarget -> ("net_target", "<name> Sets the .NET target. Defaults to \"net\". xbox, micro (Micro Framework), compact (Compact Framework) are some valid values")
  279. | NekoSource -> ("neko_source","Output neko source instead of bytecode")
  280. | NekoV1 -> ("neko_v1","Keep Neko 1.x compatibility")
  281. | NetworkSandbox -> ("network-sandbox","Use local network sandbox instead of local file access one")
  282. | NoCompilation -> ("no-compilation","Disable final compilation for Cs, Cpp and Java")
  283. | NoCOpt -> ("no_copt","Disable completion optimization (for debug purposes)")
  284. | NoDebug -> ("no_debug","Remove all debug macros from cpp output")
  285. | NoDeprecationWarnings -> ("no-deprecation-warnings","Do not warn if fields annotated with @:deprecated are used")
  286. | NoFlashOverride -> ("no-flash-override", "Change overrides on some basic classes into HX suffixed methods, flash only")
  287. | NoOpt -> ("no_opt","Disable optimizations")
  288. | NoPatternMatching -> ("no_pattern_matching","Disable pattern matching")
  289. | NoInline -> ("no_inline","Disable inlining")
  290. | NoRoot -> ("no_root","Generate top-level types into haxe.root namespace")
  291. | NoMacroCache -> ("no_macro_cache","Disable macro context caching")
  292. | NoSimplify -> "no_simplify",("Disable simplification filter")
  293. | NoSwfCompress -> ("no_swf_compress","Disable SWF output compression")
  294. | NoTraces -> ("no_traces","Disable all trace calls")
  295. | Objc -> ("objc","Sets the hxcpp output to objective-c++ classes. Must be defined for interop")
  296. | PhpPrefix -> ("php_prefix","Compiled with --php-prefix")
  297. | RealPosition -> ("real_position","Disables haxe source mapping when targetting C#")
  298. | ReplaceFiles -> ("replace_files","GenCommon internal")
  299. | Scriptable -> ("scriptable","GenCPP internal")
  300. | ShallowExpose -> ("shallow-expose","Expose types to surrounding scope of Haxe generated closure without writing to window object")
  301. | SourceHeader -> ("source-header","Print value as comment on top of generated files, use '' value to disable")
  302. | SourceMapContent -> ("source-map-content","Include the hx sources as part of the JS source map")
  303. | Swc -> ("swc","Output a SWC instead of a SWF")
  304. | SwfCompressLevel -> ("swf_compress_level","<level:1-9> Set the amount of compression for the SWF output")
  305. | SwfDebugPassword -> ("swf_debug_password", "Set a password for debugging")
  306. | SwfDirectBlit -> ("swf_direct_blit", "Use hardware acceleration to blit graphics")
  307. | SwfGpu -> ("swf_gpu", "Use GPU compositing features when drawing graphics")
  308. | SwfMetadata -> ("swf_metadata", "<file> Include contents of <file> as metadata in the swf")
  309. | SwfPreloaderFrame -> ("swf_preloader_frame", "Insert empty first frame in swf")
  310. | SwfProtected -> ("swf_protected","Compile Haxe private as protected in the SWF instead of public")
  311. | SwfScriptTimeout -> ("swf_script_timeout", "Maximum ActionScript processing time before script stuck dialog box displays (in seconds)")
  312. | SwfUseDoAbc -> ("swf_use_doabc", "Use DoAbc swf-tag instead of DoAbcDefine")
  313. | Sys -> ("sys","Defined for all system platforms")
  314. | Unsafe -> ("unsafe","Allow unsafe code when targeting C#")
  315. | UseNekoc -> ("use_nekoc","Use nekoc compiler instead of internal one")
  316. | UseRttiDoc -> ("use_rtti_doc","Allows access to documentation during compilation")
  317. | Vcproj -> ("vcproj","GenCPP internal")
  318. | Last -> assert false
  319. end
  320. module MetaInfo = struct
  321. open Meta
  322. type meta_usage =
  323. | TClass
  324. | TClassField
  325. | TAbstract
  326. | TAbstractField
  327. | TEnum
  328. | TTypedef
  329. | TAnyField
  330. | TExpr
  331. | TTypeParameter
  332. type meta_parameter =
  333. | HasParam of string
  334. | Platform of platform
  335. | Platforms of platform list
  336. | UsedOn of meta_usage
  337. | UsedOnEither of meta_usage list
  338. | Internal
  339. let to_string = function
  340. | Abi -> ":abi",("Function ABI/calling convention",[Platforms [Cpp]])
  341. | Abstract -> ":abstract",("Sets the underlying class implementation as 'abstract'",[Platforms [Java;Cs]])
  342. | Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
  343. | Accessor -> ":accessor",("Used internally by DCE to mark property accessors",[UsedOn TClassField;Internal])
  344. | Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
  345. | Analyzer -> ":analyzer",("Used to configure the static analyzer",[])
  346. | Annotation -> ":annotation",("Annotation (@interface) definitions on -java-lib imports will be annotated with this metadata. Has no effect on types compiled by Haxe",[Platform Java; UsedOn TClass])
  347. | ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
  348. | Ast -> ":ast",("Internally used to pass the AST source into the typed AST",[Internal])
  349. | AutoBuild -> ":autoBuild",("Extends @:build metadata to all extending and implementing classes",[HasParam "Build macro call";UsedOn TClass])
  350. | Bind -> ":bind",("Override Swf class declaration",[Platform Flash;UsedOn TClass])
  351. | Bitmap -> ":bitmap",("Embeds given bitmap data into the class (must extend flash.display.BitmapData)",[HasParam "Bitmap file path";UsedOn TClass;Platform Flash])
  352. | BridgeProperties -> ":bridgeProperties",("Creates native property bridges for all Haxe properties in this class",[UsedOn TClass;Platform Cs])
  353. | Build -> ":build",("Builds a class or enum from a macro",[HasParam "Build macro call";UsedOnEither [TClass;TEnum]])
  354. | BuildXml -> ":buildXml",("Specify xml data to be injected into Build.xml",[Platform Cpp])
  355. | Callable -> ":callable",("Abstract forwards call to its underlying type",[UsedOn TAbstract])
  356. | Class -> ":class",("Used internally to annotate an enum that will be generated as a class",[Platforms [Java;Cs]; UsedOn TEnum; Internal])
  357. | ClassCode -> ":classCode",("Used to inject platform-native code into a class",[Platforms [Java;Cs]; UsedOn TClass])
  358. | Commutative -> ":commutative",("Declares an abstract operator as commutative",[UsedOn TAbstractField])
  359. | CompilerGenerated -> ":compilerGenerated",("Marks a field as generated by the compiler. Shouldn't be used by the end user",[Platforms [Java;Cs]])
  360. | Const -> ":const",("Allows a type parameter to accept expression values",[UsedOn TTypeParameter])
  361. | CoreApi -> ":coreApi",("Identifies this class as a core api class (forces Api check)",[UsedOnEither [TClass;TEnum;TTypedef;TAbstract]])
  362. | CoreType -> ":coreType",("Identifies an abstract as core type so that it requires no implementation",[UsedOn TAbstract])
  363. | CppFileCode -> ":cppFileCode",("Code to be injected into generated cpp file",[Platform Cpp])
  364. | CppInclude -> ":cppInclude",("File to be included in generated cpp file",[Platform Cpp])
  365. | CppNamespaceCode -> ":cppNamespaceCode",("",[Platform Cpp])
  366. | CsNative -> ":csNative",("Automatically added by -net-lib on classes generated from .NET DLL files",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
  367. | Dce -> ":dce",("Forces dead code elimination even when -dce full is not specified",[UsedOnEither [TClass;TEnum]])
  368. | Debug -> ":debug",("Forces debug information to be generated into the Swf even without -debug",[UsedOnEither [TClass;TClassField]; Platform Flash])
  369. | Decl -> ":decl",("",[Platform Cpp])
  370. | DefParam -> ":defParam",("?",[])
  371. | Delegate -> ":delegate",("Automatically added by -net-lib on delegates",[Platform Cs; UsedOn TAbstract])
  372. | Depend -> ":depend",("",[Platform Cpp])
  373. | Deprecated -> ":deprecated",("Automatically added by -java-lib on class fields annotated with @Deprecated annotation. Has no effect on types compiled by Haxe",[Platform Java; UsedOnEither [TClass;TEnum;TClassField]])
  374. | DirectlyUsed -> ":directlyUsed",("Marks types that are directly referenced by non-extern code",[Internal])
  375. | DynamicObject -> ":dynamicObject",("Used internally to identify the Dynamic Object implementation",[Platforms [Java;Cs]; UsedOn TClass; Internal])
  376. | Enum -> ":enum",("Defines finite value sets to abstract definitions",[UsedOn TAbstract])
  377. | EnumConstructorParam -> ":enumConstructorParam",("Used internally to annotate GADT type parameters",[UsedOn TClass; Internal])
  378. | Event -> ":event",("Automatically added by -net-lib on events. Has no effect on types compiled by Haxe",[Platform Cs; UsedOn TClassField])
  379. | Exhaustive -> ":exhaustive",("",[Internal])
  380. | Expose -> ":expose",("Makes the class available on the window object",[HasParam "?Name=Class path";UsedOn TClass;Platform Js])
  381. | Extern -> ":extern",("Marks the field as extern so it is not generated",[UsedOn TClassField])
  382. | FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
  383. | File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
  384. | Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
  385. | FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; Internal])
  386. | Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
  387. | Forward -> ":forward",("Forwards field access to underlying type",[HasParam "List of field names";UsedOn TAbstract])
  388. | From -> ":from",("Specifies that the field of the abstract is a cast operation from the type identified in the function",[UsedOn TAbstractField])
  389. | FunctionCode -> ":functionCode",("Used to inject platform-native code into a function",[Platforms [Cpp;Java;Cs]])
  390. | FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
  391. | Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
  392. | GenericBuild -> ":genericBuild",("Builds instances of a type using the specified macro",[UsedOn TClass])
  393. | GenericInstance -> ":genericInstance",("Internally used to mark instances of @:generic methods",[UsedOn TClassField;Internal])
  394. | Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
  395. | Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
  396. | HasUntyped -> (":has_untyped",("Used by the typer to mark fields that have untyped expressions",[Internal]))
  397. | HaxeGeneric -> ":haxeGeneric",("Used internally to annotate non-native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
  398. | HeaderClassCode -> ":headerClassCode",("Code to be injected into the generated class, in the header",[Platform Cpp])
  399. | HeaderCode -> ":headerCode",("Code to be injected into the generated header file",[Platform Cpp])
  400. | HeaderInclude -> ":headerInclude",("File to be included in generated header file",[Platform Cpp])
  401. | HeaderNamespaceCode -> ":headerNamespaceCode",("",[Platform Cpp])
  402. | HxGen -> ":hxGen",("Annotates that an extern class was generated by Haxe",[Platforms [Java;Cs]; UsedOnEither [TClass;TEnum]])
  403. | IfFeature -> ":ifFeature",("Causes a field to be kept by DCE if the given feature is part of the compilation",[HasParam "Feature name";UsedOn TClassField])
  404. | Impl -> ":impl",("Used internally to mark abstract implementation fields",[UsedOn TAbstractField; Internal])
  405. | PythonImport -> ":pythonImport",("Generates python import statement for extern classes",[Platforms [Python]; UsedOn TClass])
  406. | ImplicitCast -> ":implicitCast",("Generated automatically on the AST when an implicit abstract cast happens",[Internal; UsedOn TExpr])
  407. | Include -> ":include",("",[Platform Cpp])
  408. | InitPackage -> ":initPackage",("?",[])
  409. | Meta.Internal -> ":internal",("Generates the annotated field/class with 'internal' access",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum;TClassField]])
  410. | IsVar -> ":isVar",("Forces a physical field to be generated for properties that otherwise would not require one",[UsedOn TClassField])
  411. | JavaCanonical -> ":javaCanonical",("Used by the Java target to annotate the canonical path of the type",[HasParam "Output type package";HasParam "Output type name";UsedOnEither [TClass;TEnum]; Platform Java])
  412. | JavaNative -> ":javaNative",("Automatically added by -java-lib on classes generated from JAR/class files",[Platform Java; UsedOnEither[TClass;TEnum]; Internal])
  413. | JsRequire -> ":jsRequire",("Generate javascript module require expression for given extern",[Platform Js; UsedOn TClass])
  414. | Keep -> ":keep",("Causes a field or type to be kept by DCE",[])
  415. | KeepInit -> ":keepInit",("Causes a class to be kept by DCE even if all its field are removed",[UsedOn TClass])
  416. | KeepSub -> ":keepSub",("Extends @:keep metadata to all implementing and extending classes",[UsedOn TClass])
  417. | LibType -> ":libType",("Used by -net-lib and -java-lib to mark a class that shouldn't be checked (overrides, interfaces, etc) by the type loader",[Internal; UsedOn TClass; Platforms [Java;Cs]])
  418. | Meta -> ":meta",("Internally used to mark a class field as being the metadata field",[])
  419. | Macro -> ":macro",("(deprecated)",[])
  420. | MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
  421. | MergeBlock -> ":mergeBlock",("Merge the annotated block into the current scope",[UsedOn TExpr])
  422. | MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract; HasParam "Relevant type parameters"])
  423. | Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
  424. | NativeChildren -> ":nativeChildren",("Annotates that all children from a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOn TClass])
  425. | NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs;Python]; UsedOnEither[TClass;TEnum]])
  426. | NativeGeneric -> ":nativeGeneric",("Used internally to annotate native generic classes",[Platform Cs; UsedOnEither[TClass;TEnum]; Internal])
  427. | NativeProperty -> ":nativeProperty",("Use native properties which will execute even with dynamic usage",[Platform Cpp])
  428. | NoCompletion -> ":noCompletion",("Prevents the compiler from suggesting completion on this field",[UsedOn TClassField])
  429. | NoDebug -> ":noDebug",("Does not generate debug information into the Swf even if -debug is set",[UsedOnEither [TClass;TClassField];Platform Flash])
  430. | NoDoc -> ":noDoc",("Prevents a type from being included in documentation generation",[])
  431. | NoExpr -> ":noExpr",("Internally used to mark abstract fields which have no expression by design",[Internal])
  432. | NoImportGlobal -> ":noImportGlobal",("Prevents a static field from being imported with import Class.*",[UsedOn TAnyField])
  433. | NonVirtual -> ":nonVirtual",("Declares function to be non-virtual in cpp",[Platform Cpp])
  434. | NoPackageRestrict -> ":noPackageRestrict",("Allows a module to be accessed across all targets if found on its first type",[Internal])
  435. | NoPrivateAccess -> ":noPrivateAccess",("Disallow private access to anything for the annotated expression",[UsedOn TExpr])
  436. | NoStack -> ":noStack",("",[Platform Cpp])
  437. | NotNull -> ":notNull",("Declares an abstract type as not accepting null values",[UsedOn TAbstract])
  438. | NoUsing -> ":noUsing",("Prevents a field from being used with 'using'",[UsedOn TClassField])
  439. | Ns -> ":ns",("Internally used by the Swf generator to handle namespaces",[Platform Flash])
  440. | Objc -> ":objc",("Declares a class or interface that is used to interoperate with Objective-C code",[Platform Cpp;UsedOn TClass])
  441. | Op -> ":op",("Declares an abstract field as being an operator overload",[HasParam "The operation";UsedOn TAbstractField])
  442. | Optional -> ":optional",("Marks the field of a structure as optional",[UsedOn TClassField])
  443. | Overload -> ":overload",("Allows the field to be called with different argument types",[HasParam "Function specification (no expression)";UsedOn TClassField])
  444. | Public -> ":public",("Marks a class field as being public",[UsedOn TClassField])
  445. | PublicFields -> ":publicFields",("Forces all class fields of inheriting classes to be public",[UsedOn TClass])
  446. | QuotedField -> ":quotedField",("Used internally to mark structure fields which are quoted in syntax",[Internal])
  447. | PrivateAccess -> ":privateAccess",("Allow private access to anything for the annotated expression",[UsedOn TExpr])
  448. | Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
  449. | Property -> ":property",("Marks a property field to be compiled as a native C# property",[UsedOn TClassField;Platform Cs])
  450. | ReadOnly -> ":readOnly",("Generates a field with the 'readonly' native keyword",[Platform Cs; UsedOn TClassField])
  451. | RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[Internal])
  452. | Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
  453. | Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])
  454. | RequiresAssign -> ":requiresAssign",("Used internally to mark certain abstract operator overloads",[Internal])
  455. | Resolve -> ":resolve",("Abstract fields marked with this metadata can be used to resolve unknown fields",[UsedOn TClassField])
  456. | ReplaceReflection -> ":replaceReflection",("Used internally to specify a function that should replace its internal __hx_functionName counterpart",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]; Internal])
  457. | Rtti -> ":rtti",("Adds runtime type informations",[UsedOn TClass])
  458. | Runtime -> ":runtime",("?",[])
  459. | RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract])
  460. | SelfCall -> ":selfCall",("Translates method calls into calling object directly",[UsedOn TClassField; Platform Js])
  461. | Setter -> ":setter",("Generates a native setter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
  462. | StoredTypedExpr -> ":storedTypedExpr",("Used internally to reference a typed expression returned from a macro",[Internal])
  463. | SkipCtor -> ":skipCtor",("Used internally to generate a constructor as if it were a native type (no __hx_ctor)",[Platforms [Java;Cs]; Internal])
  464. | SkipReflection -> ":skipReflection",("Used internally to annotate a field that shouldn't have its reflection data generated",[Platforms [Java;Cs]; UsedOn TClassField; Internal])
  465. | Sound -> ":sound",( "Includes a given .wav or .mp3 file into the target Swf and associates it with the class (must extend flash.media.Sound)",[HasParam "File path";UsedOn TClass;Platform Flash])
  466. | SourceFile -> ":sourceFile",("Source code filename for external class",[Platform Cpp])
  467. | Strict -> ":strict",("Used to declare a native C# attribute or a native Java metadata. Is type checked",[Platforms [Java;Cs]])
  468. | Struct -> ":struct",("Marks a class definition as a struct",[Platform Cs; UsedOn TClass])
  469. | StructAccess -> ":structAccess",("Marks an extern class as using struct access('.') not pointer('->')",[Platform Cpp; UsedOn TClass])
  470. | SuppressWarnings -> ":suppressWarnings",("Adds a SuppressWarnings annotation for the generated Java class",[Platform Java; UsedOn TClass])
  471. | Throws -> ":throws",("Adds a 'throws' declaration to the generated function",[HasParam "Type as String"; Platform Java; UsedOn TClassField])
  472. | This -> ":this",("Internally used to pass a 'this' expression to macros",[Internal; UsedOn TExpr])
  473. | To -> ":to",("Specifies that the field of the abstract is a cast operation to the type identified in the function",[UsedOn TAbstractField])
  474. | ToString -> ":toString",("Internally used",[Internal])
  475. | Transient -> ":transient",("Adds the 'transient' flag to the class field",[Platform Java; UsedOn TClassField])
  476. | ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[Internal])
  477. | Volatile -> ":volatile",("",[Platforms [Java;Cs]])
  478. | Unbound -> ":unbound", ("Compiler internal to denote unbounded global variable",[])
  479. | UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField])
  480. | Unreflective -> ":unreflective",("",[Platform Cpp])
  481. | Unsafe -> ":unsafe",("Declares a class, or a method with the C#'s 'unsafe' flag",[Platform Cs; UsedOnEither [TClass;TClassField]])
  482. | Usage -> ":usage",("?",[])
  483. | Used -> ":used",("Internally used by DCE to mark a class or field as used",[Internal])
  484. | Value -> ":value",("Used to store default values for fields and function arguments",[UsedOn TClassField])
  485. | Void -> ":void",("Use Cpp native 'void' return type",[Platform Cpp])
  486. | Last -> assert false
  487. (* do not put any custom metadata after Last *)
  488. | Dollar s -> "$" ^ s,("",[])
  489. | Custom s -> s,("",[])
  490. let hmeta =
  491. let h = Hashtbl.create 0 in
  492. let rec loop i =
  493. let m = Obj.magic i in
  494. if m <> Last then begin
  495. Hashtbl.add h (fst (to_string m)) m;
  496. loop (i + 1);
  497. end;
  498. in
  499. loop 0;
  500. h
  501. let parse s = try Hashtbl.find hmeta (":" ^ s) with Not_found -> Custom (":" ^ s)
  502. let from_string s =
  503. if s = "" then Custom "" else match s.[0] with
  504. | ':' -> (try Hashtbl.find hmeta s with Not_found -> Custom s)
  505. | '$' -> Dollar (String.sub s 1 (String.length s - 1))
  506. | _ -> Custom s
  507. end
  508. let stats =
  509. {
  510. s_files_parsed = ref 0;
  511. s_classes_built = ref 0;
  512. s_methods_typed = ref 0;
  513. s_macros_called = ref 0;
  514. }
  515. let default_config =
  516. {
  517. pf_static = true;
  518. pf_sys = true;
  519. pf_locals_scope = true;
  520. pf_captured_scope = true;
  521. pf_unique_locals = false;
  522. pf_capture_policy = CPNone;
  523. pf_pad_nulls = false;
  524. pf_add_final_return = false;
  525. pf_overload = false;
  526. pf_pattern_matching = false;
  527. pf_can_skip_non_nullable_argument = true;
  528. pf_reserved_type_paths = [];
  529. }
  530. let get_config com =
  531. let defined f = PMap.mem (fst (Define.infos f)) com.defines in
  532. match com.platform with
  533. | Cross ->
  534. default_config
  535. | Js ->
  536. {
  537. pf_static = false;
  538. pf_sys = false;
  539. pf_locals_scope = false;
  540. pf_captured_scope = false;
  541. pf_unique_locals = false;
  542. pf_capture_policy = CPLoopVars;
  543. pf_pad_nulls = false;
  544. pf_add_final_return = false;
  545. pf_overload = false;
  546. pf_pattern_matching = false;
  547. pf_can_skip_non_nullable_argument = true;
  548. pf_reserved_type_paths = [([],"Object");([],"Error")];
  549. }
  550. | Neko ->
  551. {
  552. pf_static = false;
  553. pf_sys = true;
  554. pf_locals_scope = true;
  555. pf_captured_scope = true;
  556. pf_unique_locals = false;
  557. pf_capture_policy = CPNone;
  558. pf_pad_nulls = true;
  559. pf_add_final_return = false;
  560. pf_overload = false;
  561. pf_pattern_matching = false;
  562. pf_can_skip_non_nullable_argument = true;
  563. pf_reserved_type_paths = [];
  564. }
  565. | Flash when defined Define.As3 ->
  566. {
  567. pf_static = true;
  568. pf_sys = false;
  569. pf_locals_scope = false;
  570. pf_captured_scope = true;
  571. pf_unique_locals = true;
  572. pf_capture_policy = CPLoopVars;
  573. pf_pad_nulls = false;
  574. pf_add_final_return = true;
  575. pf_overload = false;
  576. pf_pattern_matching = false;
  577. pf_can_skip_non_nullable_argument = false;
  578. pf_reserved_type_paths = [];
  579. }
  580. | Flash ->
  581. {
  582. pf_static = true;
  583. pf_sys = false;
  584. pf_locals_scope = true;
  585. pf_captured_scope = true; (* handled by genSwf9 *)
  586. pf_unique_locals = false;
  587. pf_capture_policy = CPLoopVars;
  588. pf_pad_nulls = false;
  589. pf_add_final_return = false;
  590. pf_overload = false;
  591. pf_pattern_matching = false;
  592. pf_can_skip_non_nullable_argument = false;
  593. pf_reserved_type_paths = [([],"Object");([],"Error")];
  594. }
  595. | Php ->
  596. {
  597. pf_static = false;
  598. pf_sys = true;
  599. pf_locals_scope = false; (* some duplicate work is done in genPhp *)
  600. pf_captured_scope = false;
  601. pf_unique_locals = false;
  602. pf_capture_policy = CPNone;
  603. pf_pad_nulls = true;
  604. pf_add_final_return = false;
  605. pf_overload = false;
  606. pf_pattern_matching = false;
  607. pf_can_skip_non_nullable_argument = true;
  608. pf_reserved_type_paths = [];
  609. }
  610. | Cpp ->
  611. {
  612. pf_static = true;
  613. pf_sys = true;
  614. pf_locals_scope = true;
  615. pf_captured_scope = true;
  616. pf_unique_locals = false;
  617. pf_capture_policy = CPWrapRef;
  618. pf_pad_nulls = true;
  619. pf_add_final_return = true;
  620. pf_overload = false;
  621. pf_pattern_matching = false;
  622. pf_can_skip_non_nullable_argument = true;
  623. pf_reserved_type_paths = [];
  624. }
  625. | Cs ->
  626. {
  627. pf_static = true;
  628. pf_sys = true;
  629. pf_locals_scope = false;
  630. pf_captured_scope = true;
  631. pf_unique_locals = true;
  632. pf_capture_policy = CPWrapRef;
  633. pf_pad_nulls = true;
  634. pf_add_final_return = false;
  635. pf_overload = true;
  636. pf_pattern_matching = false;
  637. pf_can_skip_non_nullable_argument = true;
  638. pf_reserved_type_paths = [];
  639. }
  640. | Java ->
  641. {
  642. pf_static = true;
  643. pf_sys = true;
  644. pf_locals_scope = false;
  645. pf_captured_scope = true;
  646. pf_unique_locals = false;
  647. pf_capture_policy = CPWrapRef;
  648. pf_pad_nulls = true;
  649. pf_add_final_return = false;
  650. pf_overload = true;
  651. pf_pattern_matching = false;
  652. pf_can_skip_non_nullable_argument = true;
  653. pf_reserved_type_paths = [];
  654. }
  655. | Python ->
  656. {
  657. pf_static = false;
  658. pf_sys = true;
  659. pf_locals_scope = false;
  660. pf_captured_scope = false;
  661. pf_unique_locals = false;
  662. pf_capture_policy = CPLoopVars;
  663. pf_pad_nulls = false;
  664. pf_add_final_return = false;
  665. pf_overload = false;
  666. pf_pattern_matching = false;
  667. pf_can_skip_non_nullable_argument = true;
  668. pf_reserved_type_paths = [];
  669. }
  670. let memory_marker = [|Unix.time()|]
  671. let create v args =
  672. let m = Type.mk_mono() in
  673. let defines =
  674. PMap.add "true" "1" (
  675. PMap.add "source-header" "Generated by Haxe" (
  676. if !display_default <> DMNone then PMap.add "display" "1" PMap.empty else PMap.empty))
  677. in
  678. {
  679. version = v;
  680. args = args;
  681. sys_args = args;
  682. debug = false;
  683. display = !display_default;
  684. verbose = false;
  685. foptimize = true;
  686. features = Hashtbl.create 0;
  687. platform = Cross;
  688. config = default_config;
  689. print = (fun s -> print_string s; flush stdout);
  690. run_command = Sys.command;
  691. std_path = [];
  692. class_path = [];
  693. main_class = None;
  694. defines = defines;
  695. package_rules = PMap.empty;
  696. file = "";
  697. types = [];
  698. filters = [];
  699. final_filters = [];
  700. modules = [];
  701. main = None;
  702. flash_version = 10.;
  703. resources = Hashtbl.create 0;
  704. php_front = None;
  705. php_lib = None;
  706. swf_libs = [];
  707. java_libs = [];
  708. net_libs = [];
  709. net_std = [];
  710. net_path_map = Hashtbl.create 0;
  711. c_args = [];
  712. neko_libs = [];
  713. include_files = [];
  714. php_prefix = None;
  715. js_gen = None;
  716. load_extern_type = [];
  717. defines_signature = None;
  718. get_macros = (fun() -> None);
  719. warning = (fun _ _ -> assert false);
  720. error = (fun _ _ -> assert false);
  721. basic = {
  722. tvoid = m;
  723. tint = m;
  724. tfloat = m;
  725. tbool = m;
  726. tnull = (fun _ -> assert false);
  727. tstring = m;
  728. tarray = (fun _ -> assert false);
  729. };
  730. file_lookup_cache = Hashtbl.create 0;
  731. stored_typed_exprs = PMap.empty;
  732. memory_marker = memory_marker;
  733. }
  734. let log com str =
  735. if com.verbose then com.print (str ^ "\n")
  736. let clone com =
  737. let t = com.basic in
  738. { com with
  739. basic = { t with tvoid = t.tvoid };
  740. main_class = None;
  741. features = Hashtbl.create 0;
  742. file_lookup_cache = Hashtbl.create 0;
  743. }
  744. let file_time file =
  745. try (Unix.stat file).Unix.st_mtime with _ -> 0.
  746. let get_signature com =
  747. match com.defines_signature with
  748. | Some s -> s
  749. | None ->
  750. let str = String.concat "@" (PMap.foldi (fun k v acc ->
  751. (* don't make much difference between these special compilation flags *)
  752. match k with
  753. | "display" | "use_rtti_doc" | "macrotimes" -> acc
  754. | _ -> k :: v :: acc
  755. ) com.defines []) in
  756. let s = Digest.string str in
  757. com.defines_signature <- Some s;
  758. s
  759. let file_extension file =
  760. match List.rev (ExtString.String.nsplit file ".") with
  761. | e :: _ -> String.lowercase e
  762. | [] -> ""
  763. let platforms = [
  764. Js;
  765. Neko;
  766. Flash;
  767. Php;
  768. Cpp;
  769. Cs;
  770. Java;
  771. Python;
  772. ]
  773. let platform_name = function
  774. | Cross -> "cross"
  775. | Js -> "js"
  776. | Neko -> "neko"
  777. | Flash -> "flash"
  778. | Php -> "php"
  779. | Cpp -> "cpp"
  780. | Cs -> "cs"
  781. | Java -> "java"
  782. | Python -> "python"
  783. let flash_versions = List.map (fun v ->
  784. let maj = int_of_float v in
  785. let min = int_of_float (mod_float (v *. 10.) 10.) in
  786. v, string_of_int maj ^ (if min = 0 then "" else "_" ^ string_of_int min)
  787. ) [9.;10.;10.1;10.2;10.3;11.;11.1;11.2;11.3;11.4;11.5;11.6;11.7;11.8;11.9;12.0;13.0;14.0;15.0;16.0;17.0]
  788. let flash_version_tag = function
  789. | 6. -> 6
  790. | 7. -> 7
  791. | 8. -> 8
  792. | 9. -> 9
  793. | 10. | 10.1 -> 10
  794. | 10.2 -> 11
  795. | 10.3 -> 12
  796. | 11. -> 13
  797. | 11.1 -> 14
  798. | 11.2 -> 15
  799. | 11.3 -> 16
  800. | 11.4 -> 17
  801. | 11.5 -> 18
  802. | 11.6 -> 19
  803. | 11.7 -> 20
  804. | 11.8 -> 21
  805. | 11.9 -> 22
  806. | 12.0 -> 23
  807. | 13.0 -> 24
  808. | 14.0 -> 25
  809. | 15.0 -> 26
  810. | 16.0 -> 27
  811. | 17.0 -> 28
  812. | v -> failwith ("Invalid SWF version " ^ string_of_float v)
  813. let raw_defined ctx v =
  814. PMap.mem v ctx.defines
  815. let defined ctx v =
  816. raw_defined ctx (fst (Define.infos v))
  817. let raw_defined_value ctx k =
  818. PMap.find k ctx.defines
  819. let defined_value ctx v =
  820. raw_defined_value ctx (fst (Define.infos v))
  821. let defined_value_safe ctx v =
  822. try defined_value ctx v
  823. with Not_found -> ""
  824. let raw_define ctx v =
  825. let k,v = try ExtString.String.split v "=" with _ -> v,"1" in
  826. ctx.defines <- PMap.add k v ctx.defines;
  827. let k = String.concat "_" (ExtString.String.nsplit k "-") in
  828. ctx.defines <- PMap.add k v ctx.defines;
  829. ctx.defines_signature <- None
  830. let define_value ctx k v =
  831. raw_define ctx (fst (Define.infos k) ^ "=" ^ v)
  832. let define ctx v =
  833. raw_define ctx (fst (Define.infos v))
  834. let init_platform com pf =
  835. com.platform <- pf;
  836. let name = platform_name pf in
  837. let forbid acc p = if p = name || PMap.mem p acc then acc else PMap.add p Forbidden acc in
  838. com.package_rules <- List.fold_left forbid com.package_rules (List.map platform_name platforms);
  839. com.config <- get_config com;
  840. (* if com.config.pf_static then define com "static"; *)
  841. if com.config.pf_sys then define com Define.Sys else com.package_rules <- PMap.add "sys" Forbidden com.package_rules;
  842. raw_define com name
  843. let add_feature com f =
  844. Hashtbl.replace com.features f true
  845. let has_dce com =
  846. (try defined_value com Define.Dce <> "no" with Not_found -> false)
  847. (*
  848. TODO: The has_dce check is there because we mark types with @:directlyUsed in the DCE filter,
  849. which is not run in dce=no and thus we can't know if a type is used directly or not,
  850. so we just assume that they are.
  851. If we had dce filter always running (even with dce=no), we would have types marked with @:directlyUsed
  852. and we wouldn't need to generate unnecessary imports in dce=no, but that's good enough for now.
  853. *)
  854. let is_directly_used com meta =
  855. not (has_dce com) || Ast.Meta.has Ast.Meta.DirectlyUsed meta
  856. let rec has_feature com f =
  857. try
  858. Hashtbl.find com.features f
  859. with Not_found ->
  860. if com.types = [] then not (has_dce com) else
  861. match List.rev (ExtString.String.nsplit f ".") with
  862. | [] -> assert false
  863. | [cl] -> has_feature com (cl ^ ".*")
  864. | meth :: cl :: pack ->
  865. let r = (try
  866. let path = List.rev pack, cl in
  867. (match List.find (fun t -> t_path t = path && not (Ast.Meta.has Ast.Meta.RealPath (t_infos t).mt_meta)) com.types with
  868. | t when meth = "*" -> (match t with TAbstractDecl a -> Ast.Meta.has Ast.Meta.ValueUsed a.a_meta | _ ->
  869. Ast.Meta.has Ast.Meta.Used (t_infos t).mt_meta)
  870. | TClassDecl ({cl_extern = true} as c) when com.platform <> Js || cl <> "Array" && cl <> "Math" ->
  871. Meta.has Meta.Used (try PMap.find meth c.cl_statics with Not_found -> PMap.find meth c.cl_fields).cf_meta
  872. | TClassDecl c ->
  873. PMap.exists meth c.cl_statics || PMap.exists meth c.cl_fields
  874. | _ ->
  875. false)
  876. with Not_found ->
  877. false
  878. ) in
  879. let r = r || not (has_dce com) in
  880. Hashtbl.add com.features f r;
  881. r
  882. let allow_package ctx s =
  883. try
  884. if (PMap.find s ctx.package_rules) = Forbidden then ctx.package_rules <- PMap.remove s ctx.package_rules
  885. with Not_found ->
  886. ()
  887. let error msg p = raise (Abort (msg,p))
  888. let platform ctx p = ctx.platform = p
  889. let add_filter ctx f =
  890. ctx.filters <- f :: ctx.filters
  891. let add_final_filter ctx f =
  892. ctx.final_filters <- f :: ctx.final_filters
  893. let find_file ctx f =
  894. try
  895. (match Hashtbl.find ctx.file_lookup_cache f with
  896. | None -> raise Exit
  897. | Some f -> f)
  898. with Exit ->
  899. raise Not_found
  900. | Not_found ->
  901. let rec loop had_empty = function
  902. | [] when had_empty -> raise Not_found
  903. | [] -> loop true [""]
  904. | p :: l ->
  905. let file = p ^ f in
  906. if Sys.file_exists file then
  907. file
  908. else
  909. loop (had_empty || p = "") l
  910. in
  911. let r = (try Some (loop false ctx.class_path) with Not_found -> None) in
  912. Hashtbl.add ctx.file_lookup_cache f r;
  913. (match r with
  914. | None -> raise Not_found
  915. | Some f -> f)
  916. let get_full_path f = try Extc.get_full_path f with _ -> f
  917. let unique_full_path = if Sys.os_type = "Win32" || Sys.os_type = "Cygwin" then (fun f -> String.lowercase (get_full_path f)) else get_full_path
  918. let normalize_path p =
  919. let l = String.length p in
  920. if l = 0 then
  921. "./"
  922. else match p.[l-1] with
  923. | '\\' | '/' -> p
  924. | _ -> p ^ "/"
  925. let rec mkdir_recursive base dir_list =
  926. match dir_list with
  927. | [] -> ()
  928. | dir :: remaining ->
  929. let path = match base with
  930. | "" -> dir
  931. | "/" -> "/" ^ dir
  932. | _ -> base ^ "/" ^ dir
  933. in
  934. if not ( (path = "") || ( ((String.length path) = 2) && ((String.sub path 1 1) = ":") ) ) then
  935. if not (Sys.file_exists path) then
  936. Unix.mkdir path 0o755;
  937. mkdir_recursive (if (path = "") then "/" else path) remaining
  938. let mkdir_from_path path =
  939. let parts = Str.split_delim (Str.regexp "[\\/]+") path in
  940. match parts with
  941. | [] -> (* path was "" *) ()
  942. | _ ->
  943. let dir_list = List.rev (List.tl (List.rev parts)) in
  944. mkdir_recursive "" dir_list
  945. let mem_size v =
  946. Objsize.size_with_headers (Objsize.objsize v [] [])
  947. (* ------------------------- TIMERS ----------------------------- *)
  948. type timer_infos = {
  949. name : string;
  950. mutable start : float list;
  951. mutable total : float;
  952. }
  953. let get_time = Extc.time
  954. let htimers = Hashtbl.create 0
  955. let new_timer name =
  956. try
  957. let t = Hashtbl.find htimers name in
  958. t.start <- get_time() :: t.start;
  959. t
  960. with Not_found ->
  961. let t = { name = name; start = [get_time()]; total = 0.; } in
  962. Hashtbl.add htimers name t;
  963. t
  964. let curtime = ref []
  965. let close t =
  966. let start = (match t.start with
  967. | [] -> assert false
  968. | s :: l -> t.start <- l; s
  969. ) in
  970. let now = get_time() in
  971. let dt = now -. start in
  972. t.total <- t.total +. dt;
  973. let rec loop() =
  974. match !curtime with
  975. | [] -> failwith ("Timer " ^ t.name ^ " closed while not active")
  976. | tt :: l -> curtime := l; if t != tt then loop()
  977. in
  978. loop();
  979. (* because of rounding errors while adding small times, we need to make sure that we don't have start > now *)
  980. List.iter (fun ct -> ct.start <- List.map (fun t -> let s = t +. dt in if s > now then now else s) ct.start) !curtime
  981. let timer name =
  982. let t = new_timer name in
  983. curtime := t :: !curtime;
  984. (function() -> close t)
  985. let rec close_times() =
  986. match !curtime with
  987. | [] -> ()
  988. | t :: _ -> close t; close_times()
  989. ;;
  990. Ast.Meta.to_string_ref := fun m -> fst (MetaInfo.to_string m)
  991. (* Taken from OCaml source typing/oprint.ml
  992. This is a better version of string_of_float which prints without loss of precision
  993. so that float_of_string (float_repres x) = x for all floats x
  994. *)
  995. let valid_float_lexeme s =
  996. let l = String.length s in
  997. let rec loop i =
  998. if i >= l then s ^ "." else
  999. match s.[i] with
  1000. | '0' .. '9' | '-' -> loop (i+1)
  1001. | _ -> s
  1002. in loop 0
  1003. let float_repres f =
  1004. match classify_float f with
  1005. | FP_nan -> "nan"
  1006. | FP_infinite ->
  1007. if f < 0.0 then "neg_infinity" else "infinity"
  1008. | _ ->
  1009. let float_val =
  1010. let s1 = Printf.sprintf "%.12g" f in
  1011. if f = float_of_string s1 then s1 else
  1012. let s2 = Printf.sprintf "%.15g" f in
  1013. if f = float_of_string s2 then s2 else
  1014. Printf.sprintf "%.18g" f
  1015. in valid_float_lexeme float_val