This commit is contained in:
Dante
2026-05-21 23:40:20 -07:00
parent 3e2915dff7
commit 877a69d844
5737 changed files with 29796 additions and 1589684 deletions

View File

@ -47,45 +47,61 @@ class Context {
Displays a compilation error `msg` at the given `Position` `pos`
and aborts the current macro call.
**/
public static function error(msg:String, pos:Position):Dynamic {
return load("error", 2)(msg, pos);
public static function error(msg:String, pos:Position, ?depth:Int = 0):Dynamic {
return load("error", 2)(msg, pos, depth);
}
/**
Displays a compilation error `msg` at the given `Position` `pos`
and aborts the compilation.
**/
public static function fatalError(msg:String, pos:Position):Dynamic {
return load("fatal_error", 2)(msg, pos);
public static function fatalError(msg:String, pos:Position, ?depth:Int = 0):Dynamic {
return load("fatal_error", 2)(msg, pos, depth);
}
/**
Displays a compilation error `msg` at the given `Position` `pos`
without aborting the current macro call.
**/
public static function reportError(msg:String, pos:Position, ?depth:Int = 0):Void {
load("report_error", 2)(msg, pos, depth);
}
/**
Displays a compilation warning `msg` at the given `Position` `pos`.
**/
public static function warning(msg:String, pos:Position) {
load("warning", 2)(msg, pos);
public static function warning(msg:String, pos:Position, ?depth:Int = 0) {
load("warning", 2)(msg, pos, depth);
}
/**
Displays a compilation info `msg` at the given `Position` `pos`.
**/
public static function info(msg:String, pos:Position) {
load("info", 2)(msg, pos);
public static function info(msg:String, pos:Position, ?depth:Int = 0) {
load("info", 2)(msg, pos, depth);
}
/**
Gets a list of all current compilation info/warning messages.
**/
public static function getMessages() : Array<Message> {
return load("get_messages",0)();
public static function getMessages():Array<Message> {
return load("get_messages", 0)();
}
/**
Filters all current info/warning messages. Filtered out messages will
not be displayed by the compiler.
**/
public static function filterMessages( predicate : Message -> Bool ) {
load("filter_messages",1)(predicate);
public static function filterMessages(predicate:Message->Bool) {
load("filter_messages", 1)(predicate);
}
/**
Check if compiler is past initializations macros or not.
When it is, configuration phase is over and parsing/typing can start.
**/
public static function initMacrosDone():Bool {
return load("init_macros_done", 0)();
}
/**
@ -119,6 +135,10 @@ class Context {
return load("contains_display_position", 1)(pos);
}
public static function getDisplayMode():DisplayMode {
return load("get_display_mode", 0)();
}
/**
Returns the position at which the macro was called.
**/
@ -126,6 +146,14 @@ class Context {
return load("current_pos", 0)();
}
/**
Get the call stack (excluding the call to `Context.getMacroStack()`
that led to current macro.
**/
public static function getMacroStack():Array<Position> {
return load("get_macro_stack", 0)();
}
/**
Returns the type which is expected at the place the macro is called.
@ -136,6 +164,7 @@ class Context {
macro is not an expression-macro.
**/
public static function getExpectedType():Null<Type> {
assertInitMacrosDone(false);
return load("get_expected_type", 0)();
}
@ -146,6 +175,7 @@ class Context {
Returns `null` if the current macro is not a `@:genericBuild` macro.
**/
public static function getCallArguments():Null<Array<Expr>> {
assertInitMacrosDone(false);
return load("get_call_arguments", 0)();
}
@ -155,6 +185,7 @@ class Context {
If no such class exists, `null` is returned.
**/
public static function getLocalClass():Null<Type.Ref<Type.ClassType>> {
assertInitMacrosDone(false);
var l:Type = load("get_local_type", 0)();
if (l == null)
return null;
@ -168,6 +199,7 @@ class Context {
Returns the current module path in/on which the macro was called.
**/
public static function getLocalModule():String {
assertInitMacrosDone(false);
return load("get_local_module", 0)();
}
@ -177,6 +209,7 @@ class Context {
If no such type exists, `null` is returned.
**/
public static function getLocalType():Null<Type> {
assertInitMacrosDone(false);
return load("get_local_type", 0)();
}
@ -186,6 +219,7 @@ class Context {
If no such method exists, `null` is returned.
**/
public static function getLocalMethod():Null<String> {
assertInitMacrosDone(false);
return load("get_local_method", 0)();
}
@ -196,6 +230,7 @@ class Context {
Modifying the returned array has no effect on the compiler.
**/
public static function getLocalUsing():Array<Type.Ref<Type.ClassType>> {
assertInitMacrosDone(false);
return load("get_local_using", 0)();
}
@ -205,6 +240,7 @@ class Context {
Modifying the returned array has no effect on the compiler.
**/
public static function getLocalImports():Array<ImportExpr> {
assertInitMacrosDone(false);
return load("get_local_imports", 0)();
}
@ -219,6 +255,7 @@ class Context {
**/
@:deprecated("Use Context.getLocalTVars() instead")
public static function getLocalVars():Map<String, Type> {
assertInitMacrosDone(false);
return load("local_vars", 1)(false);
}
@ -227,6 +264,7 @@ class Context {
of `Type`.
**/
public static function getLocalTVars():Map<String, Type.TVar> {
assertInitMacrosDone(false);
return load("local_vars", 1)(true);
}
@ -279,8 +317,13 @@ class Context {
declared class path has priority.
If no type can be found, an exception of type `String` is thrown.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function getType(name:String):Type {
assertInitMacrosDone();
return load("get_type", 1)(name);
}
@ -292,11 +335,44 @@ class Context {
declared class path has priority.
If no module can be found, an exception of type `String` is thrown.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function getModule(name:String):Array<Type> {
assertInitMacrosDone();
return load("get_module", 1)(name);
}
/**
Returns the typed expression of the call to the main function.
This function will only work in the generation phase. Any calls
made outside a function passed to `haxe.macro.Context.onGenerate`
or `haxe.macro.Context.onAfterGenerate` will return `null`.
**/
public static function getMainExpr():Null<TypedExpr> {
return load("get_main_expr", 0)();
}
/**
Returns an array of module types to be generated in the output.
This list may change depending on the phase of compilation and
should not be treated as conclusive until the generation phase.
Modifying the returned array has no effect on the compilation.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function getAllModuleTypes():Array<haxe.macro.Type.ModuleType> {
assertInitMacrosDone();
return load("get_module_types", 0)();
}
/**
Parses `expr` as Haxe code, returning the corresponding AST.
@ -334,6 +410,7 @@ class Context {
Returns a hashed MD5 signature of value `v`.
**/
public static function signature(v:Dynamic):String {
assertInitMacrosDone(false);
return load("signature", 1)(v);
}
@ -382,6 +459,22 @@ class Context {
load("on_after_typing", 1)(callback);
}
/**
Adds a callback function `callback` which is invoked after the compiler
is done running initialization macros, when typing begins.
`onAfterInitMacros` should be used to delay typer-dependant code from
your initalization macros, to properly separate configuration phase and
actual typing.
**/
public static function onAfterInitMacros(callback:Void->Void):Void {
if (Context.initMacrosDone()) {
callback();
} else {
load("on_after_init_macros", 1)(callback);
}
}
/**
Adds a callback function `callback` which is invoked when a type name
cannot be resolved.
@ -399,8 +492,13 @@ class Context {
Typing the expression may result in a compiler error which can be
caught using `try ... catch`.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function typeof(e:Expr):Type {
assertInitMacrosDone();
return load("typeof", 1)(e);
}
@ -408,9 +506,17 @@ class Context {
Types expression `e` and returns the corresponding `TypedExpr`.
Typing the expression may result in a compiler error which can be
caught using `try ... catch`.
caught using `try ... catch`. Note that not all compiler errors can
be caught this way because the compiler might delay various checks
to a later stage, at which point the exception handler is no longer
active.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function typeExpr(e:Expr):TypedExpr {
assertInitMacrosDone();
return load("type_expr", 1)(e);
}
@ -420,8 +526,13 @@ class Context {
Resolving the type may result in a compiler error which can be
caught using `try ... catch`.
Resolution is performed based on the current context in which the macro is called.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function resolveType(t:ComplexType, p:Position):Type {
assertInitMacrosDone();
return load("resolve_type", 2)(t, p);
}
@ -436,8 +547,13 @@ class Context {
/**
Tries to unify `t1` and `t2` and returns `true` if successful.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function unify(t1:Type, t2:Type):Bool {
assertInitMacrosDone();
return load("unify", 2)(t1, t2);
}
@ -445,8 +561,13 @@ class Context {
Follows a type.
See `haxe.macro.TypeTools.follow` for details.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function follow(t:Type, ?once:Bool):Type {
assertInitMacrosDone();
return load("follow", 2)(t, once);
}
@ -454,8 +575,13 @@ class Context {
Follows a type, including abstracts' underlying implementation
See `haxe.macro.TypeTools.followWithAbstracts` for details.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function followWithAbstracts(t:Type, once:Bool = false):Type {
assertInitMacrosDone();
return load("follow_with_abstracts", 2)(t, once);
}
@ -505,6 +631,7 @@ class Context {
This is only defined for `@:build/@:autoBuild` macros.
**/
public static function getBuildFields():Array<Field> {
assertInitMacrosDone(false);
return load("get_build_fields", 0)();
}
@ -514,11 +641,31 @@ class Context {
If `moduleDependency` is given and is not `null`, it should contain
a module path that will be used as a dependency for the newly defined module
instead of the current module.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function defineType(t:TypeDefinition, ?moduleDependency:String):Void {
assertInitMacrosDone();
load("define_type", 2)(t, moduleDependency);
}
/**
Creates and returns a new instance of monomorph (`TMono`) type.
Returned monomorph can be used with e.g. `Context.unify` to make the compiler
bind the monomorph to an actual type and let macro further process the resulting type.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function makeMonomorph():Type {
assertInitMacrosDone();
return load("make_monomorph", 0)();
}
/**
Defines a new module as `modulePath` with several `TypeDefinition`
`types`. This is analogous to defining a .hx file.
@ -526,12 +673,17 @@ class Context {
The individual `types` can reference each other and any identifier
respects the `imports` and `usings` as usual, expect that imports are
not allowed to have `.*` wildcards or `as s` shorthands.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function defineModule(modulePath:String, types:Array<TypeDefinition>, ?imports:Array<ImportExpr>, ?usings:Array<TypePath>):Void {
if (imports == null)
imports = [];
if (usings == null)
usings = [];
assertInitMacrosDone();
load("define_module", 4)(modulePath, types, imports, usings);
}
@ -539,8 +691,13 @@ class Context {
Returns a syntax-level expression corresponding to typed expression `t`.
This process may lose some information.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function getTypedExpr(t:Type.TypedExpr):Expr {
assertInitMacrosDone();
return load("get_typed_expr", 1)(t);
}
@ -555,8 +712,13 @@ class Context {
that is reset between compilations, so care should be taken when storing
the expression returned by this method in a static variable and using the
compilation server.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function storeTypedExpr(t:Type.TypedExpr):Expr {
assertInitMacrosDone();
return load("store_typed_expr", 1)(t);
}
@ -574,11 +736,29 @@ class Context {
that is reset between compilations, so care should be taken when storing
the expression returned by this method in a static variable and using the
compilation server.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function storeExpr(e:Expr):Expr {
assertInitMacrosDone();
return load("store_expr", 1)(e);
}
/**
This function works like `storeExpr`, but also returns access to the expression's
type through the `type` field of the return value.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function typeAndStoreExpr(e:Expr):{final type:Type.Ref<Type>; final expr:Expr;} {
assertInitMacrosDone();
return load("type_and_store_expr", 1)(e);
}
/**
Manually adds a dependency between module `modulePath` and an external
file `externFile`.
@ -587,9 +767,13 @@ class Context {
`externFile` has changed.
Has no effect if the compilation cache is not used.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function registerModuleDependency(modulePath:String, externFile:String) {
load("register_module_dependency", 2)(modulePath, externFile);
onAfterInitMacros(() -> load("register_module_dependency", 2)(modulePath, externFile));
}
/**
@ -606,10 +790,47 @@ class Context {
stopTimer();
```
**/
public static function timer(id:String):()->Void {
public static function timer(id:String):() -> Void {
return load("timer", 1)(id);
}
/**
Executes `code` in a context that has `imports` and `usings` added.
This is equivalent to temporarily having `import` and `using` statements in a file. These
are only active during the execution of `code` and do not affect anything afterwards. This
is true even if `code` throws an exception.
If any argument is `null`, the result is unspecified.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function withImports<X>(imports:Array<String>, usings:Array<String>, code:() -> X):X {
assertInitMacrosDone();
return load("with_imports", 3)(imports, usings, code);
}
/**
Executes `code` in a context that has some compiler options set, restore the compiler to its
default behavior afterwards.
`allowInlining`: enable or disable inlining during typing with `typeExpr`.
`allowTransform`: when disabled, the code typed with `typeExpr` will be almost exactly the same
as the input code. This will disable some abstract types transformations.
Usage of this function from initialization macros is deprecated and may
cause compilation server issues. Use `Context.onAfterInitMacros` to
run your code once typer is ready to be used.
**/
public static function withOptions<X>(options:{?allowInlining:Bool,?allowTransform:Bool}, code : () -> X) : X {
assertInitMacrosDone();
return load("with_options", 2)(options, code);
}
@:deprecated
public static function registerModuleReuseCall(modulePath:String, macroCall:String) {
throw "This method is no longer supported. See https://github.com/HaxeFoundation/haxe/issues/5746";
@ -639,7 +860,36 @@ class Context {
}
private static function sExpr(e:TypedExpr, pretty:Bool):String {
return haxe.macro.Context.load("s_expr", 2)(e, pretty);
return load("s_expr", 2)(e, pretty);
}
@:allow(haxe.macro.Compiler)
private static function assertInitMacro():Void {
if (initMacrosDone()) {
var stack = getMacroStack();
warning(
"This API should only be used from initialization macros.",
if (stack.length > 2) stack[2] else currentPos()
);
}
}
@:allow(haxe.macro.Compiler)
private static function assertInitMacrosDone(includeSuggestion = true):Void {
#if haxe_next
if (!initMacrosDone()) {
var stack = getMacroStack();
var suggestion = includeSuggestion
? "\nUse `Context.onAfterInitMacros` to register a callback to run when context is ready."
: "";
warning(
"Cannot use this API from initialization macros." + suggestion,
if (stack.length > 2) stack[2] else currentPos()
);
}
#end
}
#end
}