Context.hx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * Copyright (C)2005-2019 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 haxe.macro;
  23. import haxe.macro.Expr;
  24. import haxe.macro.Type.TypedExpr;
  25. enum Message {
  26. Info(msg:String, pos:Position);
  27. Warning(msg:String, pos:Position);
  28. }
  29. /**
  30. Context provides an API for macro programming.
  31. It contains common functions that interact with the macro interpreter to
  32. query or set information. Other API functions are available in the tools
  33. classes:
  34. - `haxe.macro.ComplexTypeTools`
  35. - `haxe.macro.ExprTools`
  36. - `haxe.macro.TypeTools`
  37. **/
  38. class Context {
  39. #if eval
  40. /**
  41. Displays a compilation error `msg` at the given `Position` `pos`
  42. and aborts the current macro call.
  43. **/
  44. public static function error(msg:String, pos:Position, ?depth:Int = 0):Dynamic {
  45. return load("error", 2)(msg, pos, depth);
  46. }
  47. /**
  48. Displays a compilation error `msg` at the given `Position` `pos`
  49. and aborts the compilation.
  50. **/
  51. public static function fatalError(msg:String, pos:Position, ?depth:Int = 0):Dynamic {
  52. return load("fatal_error", 2)(msg, pos, depth);
  53. }
  54. /**
  55. Displays a compilation error `msg` at the given `Position` `pos`
  56. without aborting the current macro call.
  57. **/
  58. public static function reportError(msg:String, pos:Position, ?depth:Int = 0):Void {
  59. load("report_error", 2)(msg, pos, depth);
  60. }
  61. /**
  62. Displays a compilation warning `msg` at the given `Position` `pos`.
  63. **/
  64. public static function warning(msg:String, pos:Position, ?depth:Int = 0) {
  65. load("warning", 2)(msg, pos, depth);
  66. }
  67. /**
  68. Displays a compilation info `msg` at the given `Position` `pos`.
  69. **/
  70. public static function info(msg:String, pos:Position, ?depth:Int = 0) {
  71. load("info", 2)(msg, pos, depth);
  72. }
  73. /**
  74. Gets a list of all current compilation info/warning messages.
  75. **/
  76. public static function getMessages():Array<Message> {
  77. return load("get_messages", 0)();
  78. }
  79. /**
  80. Filters all current info/warning messages. Filtered out messages will
  81. not be displayed by the compiler.
  82. **/
  83. public static function filterMessages(predicate:Message->Bool) {
  84. load("filter_messages", 1)(predicate);
  85. }
  86. /**
  87. Check if compiler is past initializations macros or not.
  88. When it is, configuration phase is over and parsing/typing can start.
  89. **/
  90. public static function initMacrosDone():Bool {
  91. return load("init_macros_done", 0)();
  92. }
  93. /**
  94. Resolves a file name `file` based on the current class paths.
  95. The resolution follows the usual class path rules where the last
  96. declared class path has priority.
  97. If a class path was declared relative, this method returns the relative
  98. file path. Otherwise it returns the absolute file path.
  99. If no type can be found, an exception of type `String` is thrown.
  100. **/
  101. public static function resolvePath(file:String):String {
  102. return load("resolve_path", 1)(file);
  103. }
  104. /**
  105. Returns an `Array` of current class paths in the order of their
  106. declaration.
  107. Modifying the returned array has no effect on the compiler. Class paths
  108. can be added using `haxe.macro.Compiler.addClassPath`.
  109. **/
  110. public static function getClassPath():Array<String> {
  111. return load("class_path", 0)();
  112. }
  113. /**
  114. Check if current display position is within `pos`.
  115. **/
  116. public static function containsDisplayPosition(pos:Position):Bool {
  117. return load("contains_display_position", 1)(pos);
  118. }
  119. public static function getDisplayMode():DisplayMode {
  120. return load("get_display_mode", 0)();
  121. }
  122. /**
  123. Returns the position at which the macro was called.
  124. **/
  125. public static function currentPos():Position {
  126. return load("current_pos", 0)();
  127. }
  128. /**
  129. Get the call stack (excluding the call to `Context.getMacroStack()`
  130. that led to current macro.
  131. **/
  132. public static function getMacroStack():Array<Position> {
  133. return load("get_macro_stack", 0)();
  134. }
  135. /**
  136. Returns the type which is expected at the place the macro is called.
  137. This affects usages such as `var x:Int = macroCall()`, where the
  138. expected type will be reported as `Int`.
  139. Might return `null` if no specific type is expected or if the calling
  140. macro is not an expression-macro.
  141. **/
  142. public static function getExpectedType():Null<Type> {
  143. assertInitMacrosDone(false);
  144. return load("get_expected_type", 0)();
  145. }
  146. /**
  147. Returns the call arguments that lead to the invocation of the current
  148. `@:genericBuild` macro, if available.
  149. Returns `null` if the current macro is not a `@:genericBuild` macro.
  150. **/
  151. public static function getCallArguments():Null<Array<Expr>> {
  152. assertInitMacrosDone(false);
  153. return load("get_call_arguments", 0)();
  154. }
  155. /**
  156. Returns the current class in which the macro was called.
  157. If no such class exists, `null` is returned.
  158. **/
  159. public static function getLocalClass():Null<Type.Ref<Type.ClassType>> {
  160. assertInitMacrosDone(false);
  161. var l:Type = load("get_local_type", 0)();
  162. if (l == null)
  163. return null;
  164. return switch (l) {
  165. case TInst(c, _): c;
  166. default: null;
  167. }
  168. }
  169. /**
  170. Returns the current module path in/on which the macro was called.
  171. **/
  172. public static function getLocalModule():String {
  173. assertInitMacrosDone(false);
  174. return load("get_local_module", 0)();
  175. }
  176. /**
  177. Returns the current type in/on which the macro was called.
  178. If no such type exists, `null` is returned.
  179. **/
  180. public static function getLocalType():Null<Type> {
  181. assertInitMacrosDone(false);
  182. return load("get_local_type", 0)();
  183. }
  184. /**
  185. Returns the name of the method from which the macro was called.
  186. If no such method exists, `null` is returned.
  187. **/
  188. public static function getLocalMethod():Null<String> {
  189. assertInitMacrosDone(false);
  190. return load("get_local_method", 0)();
  191. }
  192. /**
  193. Returns an `Array` of classes which are available for `using` usage in
  194. the context the macro was called.
  195. Modifying the returned array has no effect on the compiler.
  196. **/
  197. public static function getLocalUsing():Array<Type.Ref<Type.ClassType>> {
  198. assertInitMacrosDone(false);
  199. return load("get_local_using", 0)();
  200. }
  201. /**
  202. Returns an `Array` of all imports in the context the macro was called.
  203. Modifying the returned array has no effect on the compiler.
  204. **/
  205. public static function getLocalImports():Array<ImportExpr> {
  206. assertInitMacrosDone(false);
  207. return load("get_local_imports", 0)();
  208. }
  209. /**
  210. Returns a map of local variables accessible in the context the macro was
  211. called.
  212. The keys of the returned map are the variable names, the values are
  213. their types.
  214. Modifying the returned map has no effect on the compiler.
  215. **/
  216. @:deprecated("Use Context.getLocalTVars() instead")
  217. public static function getLocalVars():Map<String, Type> {
  218. assertInitMacrosDone(false);
  219. return load("local_vars", 1)(false);
  220. }
  221. /**
  222. Similar to `getLocalVars`, but returns elements of type `TVar` instead
  223. of `Type`.
  224. **/
  225. public static function getLocalTVars():Map<String, Type.TVar> {
  226. assertInitMacrosDone(false);
  227. return load("local_vars", 1)(true);
  228. }
  229. /**
  230. Tells if the conditional compilation flag `s` has been set.
  231. Compiler flags are set using the `-D` command line parameter, or
  232. by calling `haxe.macro.Compiler.define`.
  233. @see https://haxe.org/manual/lf-condition-compilation.html
  234. **/
  235. public static function defined(s:String):Bool {
  236. return load("defined", 1)(s);
  237. }
  238. /**
  239. Returns the value defined for the conditional compilation flag `key`.
  240. If no value is defined for `key`, `null` is returned.
  241. Compiler flags values are set using the `-D key=value` command line
  242. parameter, or by calling `haxe.macro.Compiler.define`.
  243. The default value is `"1"`.
  244. @see https://haxe.org/manual/lf-condition-compilation.html
  245. **/
  246. public static function definedValue(key:String):Null<String> {
  247. return load("defined_value", 1)(key);
  248. }
  249. /**
  250. Returns a map of all conditional compilation flags that have been set.
  251. Compiler flags are set using the `-D` command line parameter, or
  252. by calling `haxe.macro.Compiler.define`.
  253. Modifying the returned map has no effect on the compiler.
  254. @see https://haxe.org/manual/lf-condition-compilation.html
  255. **/
  256. public static function getDefines():Map<String, String> {
  257. return load("get_defines", 0)();
  258. }
  259. /**
  260. Resolves a type identified by `name`.
  261. The resolution follows the usual class path rules where the last
  262. declared class path has priority.
  263. If no type can be found, an exception of type `String` is thrown.
  264. Usage of this function from initialization macros is deprecated and may
  265. cause compilation server issues. Use `Context.onAfterInitMacros` to
  266. run your code once typer is ready to be used.
  267. **/
  268. public static function getType(name:String):Type {
  269. assertInitMacrosDone();
  270. return load("get_type", 1)(name);
  271. }
  272. /**
  273. Resolves a module identified by `name` and returns an `Array` of all
  274. its contained types.
  275. The resolution follows the usual class path rules where the last
  276. declared class path has priority.
  277. If no module can be found, an exception of type `String` is thrown.
  278. Usage of this function from initialization macros is deprecated and may
  279. cause compilation server issues. Use `Context.onAfterInitMacros` to
  280. run your code once typer is ready to be used.
  281. **/
  282. public static function getModule(name:String):Array<Type> {
  283. assertInitMacrosDone();
  284. return load("get_module", 1)(name);
  285. }
  286. /**
  287. Returns the typed expression of the call to the main function.
  288. This function will only work in the generation phase. Any calls
  289. made outside a function passed to `haxe.macro.Context.onGenerate`
  290. or `haxe.macro.Context.onAfterGenerate` will return `null`.
  291. **/
  292. public static function getMainExpr():Null<TypedExpr> {
  293. return load("get_main_expr", 0)();
  294. }
  295. /**
  296. Returns an array of module types to be generated in the output.
  297. This list may change depending on the phase of compilation and
  298. should not be treated as conclusive until the generation phase.
  299. Modifying the returned array has no effect on the compilation.
  300. Usage of this function from initialization macros is deprecated and may
  301. cause compilation server issues. Use `Context.onAfterInitMacros` to
  302. run your code once typer is ready to be used.
  303. **/
  304. public static function getAllModuleTypes():Array<haxe.macro.Type.ModuleType> {
  305. assertInitMacrosDone();
  306. return load("get_module_types", 0)();
  307. }
  308. /**
  309. Parses `expr` as Haxe code, returning the corresponding AST.
  310. String interpolation of single quote strings within `expr` is not
  311. supported.
  312. The provided `Position` `pos` is used for all generated inner AST nodes.
  313. **/
  314. public static function parse(expr:String, pos:Position):Expr {
  315. return load("do_parse", 3)(expr, pos, false);
  316. }
  317. /**
  318. Similar to `parse`, but error positions are reported within the provided
  319. String `expr`.
  320. **/
  321. public static function parseInlineString(expr:String, pos:Position):Expr {
  322. return load("do_parse", 3)(expr, pos, true);
  323. }
  324. /**
  325. Parse file content for newlines, allowing positions to be resolved
  326. properly inside that file later on (using `Context.parseInlineString`
  327. for example). Works with both real and virtual files.
  328. **/
  329. public static function registerFileContents(file:String, content:String):Void {
  330. load("register_file_contents", 2)(file, content);
  331. }
  332. /**
  333. Builds an expression from `v`.
  334. This method generates AST nodes depending on the macro-runtime value of
  335. `v`. As such, only basic types and enums are supported and the behavior
  336. for other types is undefined.
  337. The provided `Position` `pos` is used for all generated inner AST nodes.
  338. **/
  339. public static function makeExpr(v:Dynamic, pos:Position):Expr {
  340. return load("make_expr", 2)(v, pos);
  341. }
  342. /**
  343. Returns a hashed MD5 signature of value `v`.
  344. **/
  345. public static function signature(v:Dynamic):String {
  346. assertInitMacrosDone(false);
  347. return load("signature", 1)(v);
  348. }
  349. /**
  350. Adds a callback function `callback` which is invoked after the
  351. compiler's typing phase, just before its generation phase.
  352. The callback receives an `Array` containing all types which are about
  353. to be generated. Modifications are limited to metadata, it is mainly
  354. intended to obtain information.
  355. By default, the callback is made before types are stored in the compilation
  356. server, if active. This means that any effect persists for the next compilation.
  357. If `persistent` is set to `false`, changes to types made by the callback only
  358. affect the current compilation. If no compilation server is used, this flag has
  359. no effect.
  360. *Note*: the callback is still invoked when generation is disabled with `--no-output`.
  361. **/
  362. public static function onGenerate(callback:Array<Type>->Void, persistent:Bool = true) {
  363. load("on_generate", 2)(callback, persistent);
  364. }
  365. /**
  366. Adds a callback function `callback` which is invoked after the compiler
  367. generation phase.
  368. Compilation has completed at this point and cannot be influenced
  369. anymore. However, contextual information is still available.
  370. *Note*: the callback is still invoked when generation is disabled with `--no-output`.
  371. **/
  372. public static function onAfterGenerate(callback:Void->Void) {
  373. load("on_after_generate", 1)(callback);
  374. }
  375. /**
  376. Adds a callback function `callback` which is invoked after the compiler
  377. is done typing, but before optimization. The callback receives the types
  378. which have been typed.
  379. It is possible to define new types in the callback, in which case it
  380. will be called again with the new types as argument.
  381. **/
  382. public static function onAfterTyping(callback:Array<haxe.macro.Type.ModuleType>->Void) {
  383. load("on_after_typing", 1)(callback);
  384. }
  385. /**
  386. Adds a callback function `callback` which is invoked after the compiler
  387. is done running initialization macros, when typing begins.
  388. `onAfterInitMacros` should be used to delay typer-dependant code from
  389. your initialization macros, to properly separate configuration phase and
  390. actual typing.
  391. **/
  392. public static function onAfterInitMacros(callback:Void->Void):Void {
  393. if (Context.initMacrosDone()) {
  394. callback();
  395. } else {
  396. load("on_after_init_macros", 1)(callback);
  397. }
  398. }
  399. /**
  400. Adds a callback function `callback` which is invoked when a type name
  401. cannot be resolved.
  402. The callback may return a type definition, which is then used for the
  403. expected type. If it returns `null`, the type is considered to still not
  404. exist.
  405. **/
  406. public static function onTypeNotFound(callback:String->TypeDefinition) {
  407. load("on_type_not_found", 1)(callback);
  408. }
  409. /**
  410. Types expression `e` and returns its type.
  411. Typing the expression may result in a compiler error which can be
  412. caught using `try ... catch`.
  413. Usage of this function from initialization macros is deprecated and may
  414. cause compilation server issues. Use `Context.onAfterInitMacros` to
  415. run your code once typer is ready to be used.
  416. **/
  417. public static function typeof(e:Expr):Type {
  418. assertInitMacrosDone();
  419. return load("typeof", 1)(e);
  420. }
  421. /**
  422. Types expression `e` and returns the corresponding `TypedExpr`.
  423. Typing the expression may result in a compiler error which can be
  424. caught using `try ... catch`. Note that not all compiler errors can
  425. be caught this way because the compiler might delay various checks
  426. to a later stage, at which point the exception handler is no longer
  427. active.
  428. Usage of this function from initialization macros is deprecated and may
  429. cause compilation server issues. Use `Context.onAfterInitMacros` to
  430. run your code once typer is ready to be used.
  431. **/
  432. public static function typeExpr(e:Expr):TypedExpr {
  433. assertInitMacrosDone();
  434. return load("type_expr", 1)(e);
  435. }
  436. /**
  437. Resolve type `t` and returns the corresponding `Type`.
  438. Resolving the type may result in a compiler error which can be
  439. caught using `try ... catch`.
  440. Resolution is performed based on the current context in which the macro is called.
  441. Usage of this function from initialization macros is deprecated and may
  442. cause compilation server issues. Use `Context.onAfterInitMacros` to
  443. run your code once typer is ready to be used.
  444. **/
  445. public static function resolveType(t:ComplexType, p:Position):Type {
  446. assertInitMacrosDone();
  447. return load("resolve_type", 2)(t, p);
  448. }
  449. /**
  450. Resolve type `t` and returns the corresponding `ComplexType`.
  451. Resolving the type may result in a compiler error which can be
  452. caught using `try ... catch`.
  453. Resolution is performed based on the current context in which the macro is called.
  454. The difference with `resolveType` is that it only performs type resolution, it does not
  455. build any type or trigger macros.
  456. **/
  457. public static function resolveComplexType(t:ComplexType, p:Position):ComplexType {
  458. assertInitMacrosDone(false);
  459. return load("resolve_complex_type", 2)(t, p);
  460. }
  461. /**
  462. Returns the `ComplexType` corresponding to the given `Type` `t`.
  463. See `haxe.macro.TypeTools.toComplexType` for details.
  464. **/
  465. public static function toComplexType(t:Type):Null<ComplexType> {
  466. return load("to_complex_type", 1)(t);
  467. }
  468. /**
  469. Tries to unify `t1` and `t2` and returns `true` if successful.
  470. Usage of this function from initialization macros is deprecated and may
  471. cause compilation server issues. Use `Context.onAfterInitMacros` to
  472. run your code once typer is ready to be used.
  473. **/
  474. public static function unify(t1:Type, t2:Type):Bool {
  475. assertInitMacrosDone();
  476. return load("unify", 2)(t1, t2);
  477. }
  478. /**
  479. Follows a type.
  480. See `haxe.macro.TypeTools.follow` for details.
  481. Usage of this function from initialization macros is deprecated and may
  482. cause compilation server issues. Use `Context.onAfterInitMacros` to
  483. run your code once typer is ready to be used.
  484. **/
  485. public static function follow(t:Type, ?once:Bool):Type {
  486. assertInitMacrosDone();
  487. return load("follow", 2)(t, once);
  488. }
  489. /**
  490. Follows a type, including abstracts' underlying implementation
  491. See `haxe.macro.TypeTools.followWithAbstracts` for details.
  492. Usage of this function from initialization macros is deprecated and may
  493. cause compilation server issues. Use `Context.onAfterInitMacros` to
  494. run your code once typer is ready to be used.
  495. **/
  496. public static function followWithAbstracts(t:Type, once:Bool = false):Type {
  497. assertInitMacrosDone();
  498. return load("follow_with_abstracts", 2)(t, once);
  499. }
  500. /**
  501. Returns the information stored in `Position` `p`.
  502. **/
  503. public static function getPosInfos(p:Position):{min:Int, max:Int, file:String} {
  504. return load("get_pos_infos", 1)(p);
  505. }
  506. /**
  507. Builds a `Position` from `inf`.
  508. **/
  509. public static function makePosition(inf:{min:Int, max:Int, file:String}):Position {
  510. return load("make_position", 3)(inf.min, inf.max, inf.file);
  511. }
  512. /**
  513. Returns a map of all registered resources for this compilation unit.
  514. Modifying the returned map has no effect on the compilation, use
  515. `haxe.macro.Context.addResource` to add new resources to the compilation unit.
  516. **/
  517. public static function getResources():Map<String, haxe.io.Bytes> {
  518. return load("get_resources", 0)();
  519. }
  520. /**
  521. Makes resource `data` available as `name`.
  522. The resource is then available using the `haxe.macro.Resource` API.
  523. If a previous resource was bound to `name`, it is overwritten.
  524. Compilation server : when using the compilation server, the resource is bound
  525. to the Haxe module which calls the macro, so it will be included again if
  526. that module is reused. If this resource concerns several modules, prefix its
  527. name with a `$` sign, this will bind it to the macro module instead.
  528. **/
  529. public static function addResource(name:String, data:haxe.io.Bytes) {
  530. load("add_resource", 2)(name, data);
  531. }
  532. /**
  533. Returns an `Array` of fields of the class which is to be built.
  534. This is only defined for `@:build/@:autoBuild` macros.
  535. **/
  536. public static function getBuildFields():Array<Field> {
  537. assertInitMacrosDone(false);
  538. return load("get_build_fields", 0)();
  539. }
  540. /**
  541. Defines a new type from `TypeDefinition` `t`.
  542. If a matching module has already been loaded in current context, a
  543. `haxe.macro.Expr.Error` compiler error will be raised which can be
  544. caught using `try ... catch`.
  545. If `moduleDependency` is given and is not `null`, it should contain
  546. a module path that will be used as a dependency for the newly defined module
  547. instead of the current module.
  548. Usage of this function from initialization macros is deprecated and may
  549. cause compilation server issues. Use `Context.onAfterInitMacros` to
  550. run your code once typer is ready to be used.
  551. **/
  552. public static function defineType(t:TypeDefinition, ?moduleDependency:String):Void {
  553. assertInitMacrosDone();
  554. load("define_type", 2)(t, moduleDependency);
  555. }
  556. /**
  557. Creates and returns a new instance of monomorph (`TMono`) type.
  558. Returned monomorph can be used with e.g. `Context.unify` to make the compiler
  559. bind the monomorph to an actual type and let macro further process the resulting type.
  560. Usage of this function from initialization macros is deprecated and may
  561. cause compilation server issues. Use `Context.onAfterInitMacros` to
  562. run your code once typer is ready to be used.
  563. **/
  564. public static function makeMonomorph():Type {
  565. assertInitMacrosDone();
  566. return load("make_monomorph", 0)();
  567. }
  568. /**
  569. Defines a new module as `modulePath` with several `TypeDefinition`
  570. `types`. This is analogous to defining a .hx file.
  571. If a matching module has already been loaded in current context, a
  572. `haxe.macro.Expr.Error` compiler error will be raised which can be
  573. caught using `try ... catch`.
  574. The individual `types` can reference each other and any identifier
  575. respects the `imports` and `usings` as usual, expect that imports are
  576. not allowed to have `.*` wildcards or `as s` shorthands.
  577. Usage of this function from initialization macros is deprecated and may
  578. cause compilation server issues. Use `Context.onAfterInitMacros` to
  579. run your code once typer is ready to be used.
  580. **/
  581. public static function defineModule(modulePath:String, types:Array<TypeDefinition>, ?imports:Array<ImportExpr>, ?usings:Array<TypePath>):Void {
  582. if (imports == null)
  583. imports = [];
  584. if (usings == null)
  585. usings = [];
  586. assertInitMacrosDone();
  587. load("define_module", 4)(modulePath, types, imports, usings);
  588. }
  589. /**
  590. Returns a syntax-level expression corresponding to typed expression `t`.
  591. This process may lose some information.
  592. Usage of this function from initialization macros is deprecated and may
  593. cause compilation server issues. Use `Context.onAfterInitMacros` to
  594. run your code once typer is ready to be used.
  595. **/
  596. public static function getTypedExpr(t:Type.TypedExpr):Expr {
  597. assertInitMacrosDone();
  598. return load("get_typed_expr", 1)(t);
  599. }
  600. /**
  601. Store typed expression `t` internally and give a syntax-level expression
  602. that can be returned from a macro and will be replaced by the stored
  603. typed expression.
  604. If `t` is `null` or invalid, an exception is thrown.
  605. NOTE: the returned value references an internally stored typed expression
  606. that is reset between compilations, so care should be taken when storing
  607. the expression returned by this method in a static variable and using the
  608. compilation server.
  609. Usage of this function from initialization macros is deprecated and may
  610. cause compilation server issues. Use `Context.onAfterInitMacros` to
  611. run your code once typer is ready to be used.
  612. **/
  613. public static function storeTypedExpr(t:Type.TypedExpr):Expr {
  614. assertInitMacrosDone();
  615. return load("store_typed_expr", 1)(t);
  616. }
  617. /**
  618. Types expression `e`, stores the resulting typed expression internally and
  619. returns a syntax-level expression that can be returned from a macro and
  620. will be replaced by the stored typed expression.
  621. If `e` is `null` or invalid, an exception is thrown.
  622. A call to `storeExpr(e)` is equivalent to `storeTypedExpr(typeExpr(e))` without
  623. the overhead of encoding and decoding between regular and macro runtime.
  624. NOTE: the returned value references an internally stored typed expression
  625. that is reset between compilations, so care should be taken when storing
  626. the expression returned by this method in a static variable and using the
  627. compilation server.
  628. Usage of this function from initialization macros is deprecated and may
  629. cause compilation server issues. Use `Context.onAfterInitMacros` to
  630. run your code once typer is ready to be used.
  631. **/
  632. public static function storeExpr(e:Expr):Expr {
  633. assertInitMacrosDone();
  634. return load("store_expr", 1)(e);
  635. }
  636. /**
  637. This function works like `storeExpr`, but also returns access to the expression's
  638. type through the `type` field of the return value.
  639. Usage of this function from initialization macros is deprecated and may
  640. cause compilation server issues. Use `Context.onAfterInitMacros` to
  641. run your code once typer is ready to be used.
  642. **/
  643. public static function typeAndStoreExpr(e:Expr):{final type:Type.Ref<Type>; final expr:Expr;} {
  644. assertInitMacrosDone();
  645. return load("type_and_store_expr", 1)(e);
  646. }
  647. /**
  648. Manually adds a dependency between module `modulePath` and an external
  649. file `externFile`.
  650. This affects the compilation cache, causing the module to be typed if
  651. `externFile` has changed.
  652. Has no effect if the compilation cache is not used.
  653. Usage of this function from initialization macros is deprecated and may
  654. cause compilation server issues. Use `Context.onAfterInitMacros` to
  655. run your code once typer is ready to be used.
  656. **/
  657. public static function registerModuleDependency(modulePath:String, externFile:String) {
  658. onAfterInitMacros(() -> load("register_module_dependency", 2)(modulePath, externFile));
  659. }
  660. /**
  661. Creates a timer which will be printed in the compilation report
  662. if `--times` compilation argument is set.
  663. Note that a timer may be omitted from the report if the amount of time
  664. measured is too small.
  665. This method immediately starts a timer and returns a function to stop it:
  666. ```
  667. var stopTimer = haxe.macro.Context.timer("my heavy task");
  668. runTask();
  669. stopTimer();
  670. ```
  671. **/
  672. public static function timer(id:String):() -> Void {
  673. return load("timer", 1)(id);
  674. }
  675. /**
  676. Executes `code` in a context that has `imports` and `usings` added.
  677. This is equivalent to temporarily having `import` and `using` statements in a file. These
  678. are only active during the execution of `code` and do not affect anything afterwards. This
  679. is true even if `code` throws an exception.
  680. If any argument is `null`, the result is unspecified.
  681. Usage of this function from initialization macros is deprecated and may
  682. cause compilation server issues. Use `Context.onAfterInitMacros` to
  683. run your code once typer is ready to be used.
  684. **/
  685. public static function withImports<X>(imports:Array<String>, usings:Array<String>, code:() -> X):X {
  686. assertInitMacrosDone();
  687. return load("with_imports", 3)(imports, usings, code);
  688. }
  689. /**
  690. Executes `code` in a context that has some compiler options set, restore the compiler to its
  691. default behavior afterwards.
  692. `allowInlining`: enable or disable inlining during typing with `typeExpr`.
  693. `allowTransform`: when disabled, the code typed with `typeExpr` will be almost exactly the same
  694. as the input code. This will disable some abstract types transformations.
  695. Usage of this function from initialization macros is deprecated and may
  696. cause compilation server issues. Use `Context.onAfterInitMacros` to
  697. run your code once typer is ready to be used.
  698. **/
  699. public static function withOptions<X>(options:{?allowInlining:Bool,?allowTransform:Bool}, code : () -> X) : X {
  700. assertInitMacrosDone();
  701. return load("with_options", 2)(options, code);
  702. }
  703. @:deprecated
  704. public static function registerModuleReuseCall(modulePath:String, macroCall:String) {
  705. throw "This method is no longer supported. See https://github.com/HaxeFoundation/haxe/issues/5746";
  706. }
  707. @:deprecated
  708. public static function onMacroContextReused(callb:Void->Bool) {
  709. throw "This method is no longer supported. See https://github.com/HaxeFoundation/haxe/issues/5746";
  710. }
  711. @:allow(haxe.macro.TypeTools)
  712. @:allow(haxe.macro.MacroStringTools)
  713. @:allow(haxe.macro.TypedExprTools)
  714. @:allow(haxe.macro.PositionTools)
  715. static function load(f:String, nargs:Int):Dynamic {
  716. return eval.vm.Context.callMacroApi(f);
  717. }
  718. private static function includeFile(file:String, position:String) {
  719. load("include_file", 2)(file, position);
  720. }
  721. private static function sExpr(e:TypedExpr, pretty:Bool):String {
  722. return load("s_expr", 2)(e, pretty);
  723. }
  724. @:allow(haxe.macro.Compiler)
  725. private static function assertInitMacro():Void {
  726. if (initMacrosDone()) {
  727. var stack = getMacroStack();
  728. warning(
  729. "This API should only be used from initialization macros.",
  730. if (stack.length > 2) stack[2] else currentPos()
  731. );
  732. }
  733. }
  734. @:allow(haxe.macro.Compiler)
  735. private static function assertInitMacrosDone(includeSuggestion = true):Void {
  736. if (!initMacrosDone()) {
  737. var stack = getMacroStack();
  738. var suggestion = includeSuggestion
  739. ? "\nUse `Context.onAfterInitMacros` to register a callback to run when context is ready."
  740. : "";
  741. fatalError(
  742. "Cannot use this API from initialization macros." + suggestion,
  743. if (stack.length > 2) stack[2] else currentPos()
  744. );
  745. }
  746. }
  747. #end
  748. }