HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.09k stars 647 forks source link

Define type with module dependency + @:build : "Type Not Found" using Context.getType() #11297

Closed filt3rek closed 1 month ago

filt3rek commented 1 year ago

Hej,

I stuck with that for hours now and can't see where does it come from.

Let's say I have a @:build( Macro.build() ) on a class. Inside Macro.build I only get a type named A (which is a module Test) using Context.getType( "A" ) Then, in the Context.onAfterTyping callback, I define a new type with Context.defineType on which I also put @:build( Macro.build() ). (When I define this type, I give it module dependecy of my type A ... I don't know if it's important here but maybe, so they are both in the same module...) The first time build process runs, it reachs correctly the A type, but the second time (for the new defined type), it throws Uncaught exception Type not found 'A' It only works the second time, when I do Context.getType( "Test.A" ) instead of Context.getType( "A" ).

Is there a reason for that please or it's a bug ?

I have a minimal example here : https://try.haxe.org/#fE9E086A

Thx for reading

back2dos commented 1 year ago

That's how modules work. Type A is defined in module Test, so outside of that module, you have to either:

  1. refer to it by fully qualified name, i.e. Test.A.
  2. import it (i.e. import Test; or import Test.A;)
  3. use Context.getModule('Test') and grab it from the returned types (particularly useful if you're trying to access a private subtype).

You could also move A to its own module in A.hx and then simply refer to it as A from everywhere.

filt3rek commented 1 year ago

Hej Juraj,

I hope you're fine and thanks for taking time to answer !

I agree if Context.getType( "A" ) didn't work at all but it does work the first time build macro context is running and just doesn't work the second time, why ?

filt3rek commented 1 year ago

Ok I've understood something : when using haxe.macro.Context.defineType() with module dependency, it doesn't "place" the new type inside this module... How can we define a new type and place it in an existing module please ?

Edit : I tried to put the module inside the pack on the type declaration, it seems to work a half : the module of the new type is Test but Haxe mix things then and it's not working better : https://try.haxe.org/#552C2e86

kLabz commented 2 months ago

How can we define a new type and place it in an existing module please ?

Context.defineModule(cl.module, [newT]); https://try.haxe.org/#7d2C7e94

(I know, this isn't intuitive at all :sweat_smile:)

filt3rek commented 2 months ago

Thx Rudy ! So doing that, it won't "destroy" the yet existing types in this module right ?

Simn commented 2 months ago

We should definitely disallow defining types into existing modules for Haxe 5, if we didn't do that yet.

kLabz commented 2 months ago

We should definitely disallow defining types into existing modules for Haxe 5, if we didn't do that yet.

We didn't, but that should be easy enough: https://github.com/HaxeFoundation/haxe/blob/development/src/typing/macroContext.ml#L505-L513

filt3rek commented 2 months ago

I use it with onAfterTyping in order to kind of "delay" the build macro when needed. Will Haxe 5 have something to do this ? (reorder build macros ?)

kLabz commented 2 months ago

Depends what you mean exactly with reorder build macros

filt3rek commented 2 months ago

Sometimes I need a @:build on a class runs after another one @:build ... Idk if it's more clear ...

kLabz commented 2 months ago

That is planned, yeah (as long as it's on the same type).

filt3rek commented 2 months ago

Hmm I meant on 2 or more different types... Let's say a build macro on A has to collect the fields that are in another type B, but B has also a build macro that add or modify its fields.. I want build macro on B runs first because if not the build that is on A will get fields from B that will not be already added/modified ...

kLabz commented 2 months ago

That will likely stay undefined build order.

kLabz commented 2 months ago

But you can make sure a type is built (entirely) before another one: https://try.haxe.org/#2Afb983e

Macro.hx:5: Building,TInst(B,[])
Macro.hx:5: Building,TInst(A,[])
Macro.hx:16: Done building,TInst(A,[])
Macro.hx:16: Done building,TInst(B,[])
filt3rek commented 2 months ago

Thx I'll try that ;)