Replace macros with code generation
L-Lavigne opened this issue · 2 comments
Due to ever-changing standards and poor IDE support for Scala macros, we should look into potential replacements for those as we migrate Mu towards Scala 2.13 and beyond.
(For reference, the current implementation is here in serviceImpl.scala.)
It has proven difficult in the past to predict which direction Scala macros will go. Here in Mu we've generally been moving in the right direction by migrating from scalameta.paradise
to scalamacros.paradise
, the latter of which was integrated into the Scala compiler in 2.13.0-M4.
Although this compiler integration gives hope for greater standardization and stability in the future, there are still significant downsides to using macros in this project. Foremost is the opacity of the generated code and its poor support by IDEs such as IntelliJ IDEA. Generated client and server types are generally unrecognized (marked red) by the IDE, and visual macro expansion toggles work unreliably if at all.
Using some form of code generation, yielding sources plainly visible to the developer, could alleviate these concerns.
Right now I'm looking at using a compiler plugin and the scala.tools.nsc._
tooling which allows re-using most of the existing quasiquotes implementation without involving macros. The main downside so far is that since we need one compilation process for generating the sources and another one to process them, we'd require the user to set up their services in a separate sbt subproject from the program that calls them. I believe this can be made a smooth process through good examples and tutorials, but I'm happy to hear different opinions on this.
I made a non-Mu POC with basic codegen that works with Scala 2.13 (Mu's dependencies are not yet 2.13-ready, hence the need for a side project). I'm going to port the code to a Mu branch to confirm it can work in 2.12 within the project's context. I'll provide a draft PR for this shortly.
Comments and suggestions welcome!
@L-Lavigne this looks good to me. This is an idea that we've been thinking about since some time ago. Thanks for trying to address it.
As a side note, I think it'd be very useful for mu-kotlin, in order to keep both libraries synchronized.