Viewing the compiler's transformations of code

@SethTisue posted on Twitter:

To understand what the Scala compiler does, in general or on a particular piece of code, scalac -Vprint:_ S.scala is your best friend. It shows how your code is transformed by each compiler phase. (2.13 change alert! In 2.12 and earlier, it was -Xprint:all.)

I’ve added these flags before, but not on a single file, because I can’t possibly generate the correct scalac command-line for a project with various dependencies. Maybe this is a bad idea, but I’ve then added those flags to the project config itself, and then when the project compiles, a zillion lines of compiler logging gets spat out onto the console.

My first question is, how does one realistically view the compiler’s transformation of just one source file, when in the context of a large project, typically managed by sbt? Is there a different strategy than turning on flags and doing lots of terminal grepping?

To address the compiler-DDOSing-my-terminal problem, I posted a tooling request:

i would like to have that output be (a) a data structure like JSON so it can be consumed and parsed, and (b) emitted to an arbitrary file handle so we don’t have to scrape stdout/stderrr.

So in the scenario where one does add the compiler flags to a project, producing a structured output would allow easier analysis of the information the compiler produced (it isn’t some arbitrary strings that would take forever to write a parser for), and the output could be redirected/duplicated to another file handle so as not to spam the terminal where the compiler is running.

This is similar to the work of Metals and LSP: add structured channels between the code and the compiler.

1 Like

where one does add the compiler flags to a project, producing a structured output

I’d suggest writing a compiler plugin to do this. The plugin could call the same code that -Vprint calls. In the plugin, you’ll have direct access to trees, so you can either process the trees directly, or generate any kind of output you like, depending on your use case.

how does one realistically view the compiler’s transformation of just one source file, when in the context of a large project, typically managed by sbt

I don’t know of a way. I think a pull request on this would be accepted, adding -Vprint:_:Foo.scala or some such. (As above, you could also write a compiler plugin to do it, but this is a modest enough change that I think you might as well just add it into the compiler directly.)