dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.21k stars 1.57k forks source link

Macros: Add a way to obtain the StackTrace responsible for generating a code. #56916

Open rrousselGit opened 1 week ago

rrousselGit commented 1 week ago

Hello!

Problem

When using code-generators, one challenge is: It's difficult to know what line was responsible for the generation of a piece of code.

Code-generators can become quite complex. It can take a lot of time to find exactly which line was responsible for generating a specific code.

Proposal

It would be interesting to have a "jump to the macro code that generated this line".
Since macros don't actually write to the file system but rather use some virtual file ; we could use this as an opportunity to store extra metadata.

Specifically, we could associate any piece of generated code with a Stacktrace that points to the exact line responsible for this generation.
The IDE could then use this StackTrace to jump to the macro code ; how could display the whole stacktrace to help debugging.

Of course, accessing the StackTrace can be slow. For the sake of efficiency, I see two possible solutions:

dart-github-bot commented 1 week ago

Summary: The user proposes adding a mechanism to associate generated code with the stack trace of the macro that generated it. This would allow users to easily navigate from generated code back to the macro code responsible for its creation, aiding in debugging complex code generators.

lrhn commented 1 week ago

It can take a lot of time to find exactly which line was responsible for generating a specific code.

How would one define which line was responsible for a specific output? The one that called the macro server with output?

I can see myself writing a macro that does a whole bunch of computations and then spits out code using a templating mechanism at the end. Telling you that the code was generated by a function called _templateWrite isn't useful. There may be a stack trace, but there may also not be one that's useful. Just like it's not useful that all the output of a command line program comes from the line print(combinedOutput);.

rrousselGit commented 1 week ago

How would one define which line was responsible for a specific output? The one that called the macro server with output?

We'd use the stacktrace to the "write(code)" line, whatever api that is.

I can see myself writing a macro that does a whole bunch of computations and then spits out code using a templating mechanism at the end. Telling you that the code was generated by a function called _templateWrite isn't useful.

Indeed. But one could argue that the problem is your API ; which isn't very debuggable.

If you were to write your macro with:

write(someFunction())

When the stacktrace points to write, you'll know that someFunction was involved.