dkhalansky / paradise-ng

Plugin for scalac for operating on ASTs

GitHub

Build Status ParadiseNg

This project is intended as a successor to and replacement for the deprecated Scalameta Paradise scala compiler plugin.

The plugin provides the functionality of assigning a limited form of macros to annotations.

Getting started

First example

Let's define a macro annotation by extending the ParadiseNgAnnotation trait defined in the library part of the project.

import scala.meta._
import com.github.dkhalansky.paradiseng.lib._
class replaceWithFoo(val barValue: Int) extends ParadiseNgAnnotation {
    override def apply(stat: Stat) = q"object Foo { val bar = $barValue }": Stat
}

If we have the plugin enabled, now in a separate subproject we can do

@replaceWithFoo(42) class arbitraryAndWillBeRemovedAnyway
assert(Foo.bar == 42)

You can test this by firing up the REPL with sbt console from the root of this project and copy-pasting these lines there. Make sure not to enable the :paste mode though, or it won't work!

Project overview

Goals

  • Feature parity with the subset of the paradise compiler plugin that provides new-style (scalameta-based) macro annotations.
  • Consistency: the thought model behind how macro annotations are expanded should be simple. Due to how volatile macros often are, this requirement is a must for making understanding complex macro expansion scenarios at least possible.
  • Ease of defining new macro annotations and testing them. Ability to test macro annotations without resorting to ingenuous tricks such as calling the compiler from the test suite and checking its output in order to see if the annotations throws the proper exception on wrong input.
  • Helpful error messages.
  • Minimization of the amount of magic required to define new annotations and use them. This goal is almost a direct consequence of the previous one but has a merit on its own.
  • Easily understandable user-space part of the project: the code in the library and the accompanying comments should be enough on their own to provide understanding of how to make everything work.
  • Stability: starting from 1.0, the user-space part must be either backward-compatible or versioned.
  • Supporting as many versions of scalac as is possible without severely interfering with the aforementioned goals.

If a part of the project isn't supported by any of these goals, it's redundant. If a part of the project, when modified, could serve the goals better, the fact that it hasn't been modified is a bug.

Non-goals

  • Providing a drop-in replacement for paradise or even just for its part that deals with new-style annotations.
  • Making macro annotations Turing-complete. No, we won't accept your pull request that wraps all the macro expansion logic in a loop just for that, you have to provide another reason.