From 7d8d01dfb5dc934dc57f08d9e24be38c67270ea3 Mon Sep 17 00:00:00 2001 From: megri Date: Mon, 12 Jun 2017 23:55:20 +0200 Subject: Rudimentary Macroparadise plugin, example and test --- examples/macroparadise-example/Hello.scala | 6 +++++ examples/macroparadise-example/build/build.scala | 19 +++++++++++++++ examples/macroparadise-example/macros/Main.scala | 25 +++++++++++++++++++ stage2/plugins/Macroparadise.scala | 31 ++++++++++++++++++++++++ test/test.scala | 6 +++++ 5 files changed, 87 insertions(+) create mode 100644 examples/macroparadise-example/Hello.scala create mode 100644 examples/macroparadise-example/build/build.scala create mode 100644 examples/macroparadise-example/macros/Main.scala create mode 100644 stage2/plugins/Macroparadise.scala diff --git a/examples/macroparadise-example/Hello.scala b/examples/macroparadise-example/Hello.scala new file mode 100644 index 0000000..7e04dcb --- /dev/null +++ b/examples/macroparadise-example/Hello.scala @@ -0,0 +1,6 @@ +package macroparadise_example +import macros._ + +@Main object Hello{ + println("hello, world!") +} diff --git a/examples/macroparadise-example/build/build.scala b/examples/macroparadise-example/build/build.scala new file mode 100644 index 0000000..28fb206 --- /dev/null +++ b/examples/macroparadise-example/build/build.scala @@ -0,0 +1,19 @@ +package macroparadise_example_build +import cbt._ + +trait SharedSettings extends Macroparadise{ + override def defaultScalaVersion = "2.12.2" +} + +class Build(val context: Context) extends SharedSettings{ + override def dependencies = + super.dependencies :+ + new MacroBuild( context.copy( workingDirectory = projectDirectory / "macros" ) ) +} + +class MacroBuild(val context: Context) extends SharedSettings{ + override def dependencies = + super.dependencies :+ + Resolver( mavenCentral ).bindOne( ScalaDependency( "org.scalameta", "scalameta", "1.8.0" ) ) +} + diff --git a/examples/macroparadise-example/macros/Main.scala b/examples/macroparadise-example/macros/Main.scala new file mode 100644 index 0000000..ecdce34 --- /dev/null +++ b/examples/macroparadise-example/macros/Main.scala @@ -0,0 +1,25 @@ +package macroparadise_example.macros + +import scala.meta._ +import scala.collection.immutable.Seq + +class Main extends scala.annotation.StaticAnnotation { + inline def apply(defn: Any): Any = meta { + defn match { + case q"object $name { ..$stats }" => + MainMacroImpl.expand(name, stats) + case _ => + abort("@main must annotate an object.") + } + } +} + +// This is an example how we can refactor the macro implementation into a utility +// function which can be used for unit testing, see MainUnitTest. +object MainMacroImpl { + def expand(name: Term.Name, stats: Seq[Stat]): Defn.Object = { + val main = q"def main(args: Array[String]): Unit = { ..$stats }" + q"object $name { $main }" + } +} + diff --git a/stage2/plugins/Macroparadise.scala b/stage2/plugins/Macroparadise.scala new file mode 100644 index 0000000..2b05c92 --- /dev/null +++ b/stage2/plugins/Macroparadise.scala @@ -0,0 +1,31 @@ +package cbt +import java.io.File + +trait Macroparadise extends BaseBuild{ + def macroParadiseVersion = "3.0.0-M9" + + override def scalacOptions = super.scalacOptions ++ Macroparadise.scalacOptions( + Macroparadise.dependencies( scalaVersion, macroParadiseVersion, context.cbtLastModified, context.paths.mavenCache ).jar + ) +} + +object Macroparadise{ + def dependencies( + scalaVersion: String, macroParadiseVersion: String, cbtLastModified: Long, mavenCache: java.io.File + )( + implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache + ) = + MavenResolver( cbtLastModified, mavenCache, mavenCentral ).bindOne( + MavenDependency( + "org.scalameta", "paradise_"+scalaVersion, macroParadiseVersion + ) + ) + + def scalacOptions( jarPath: File ) = + Seq( + "-Xplugin:" ++ jarPath.string, + "-Yrangepos", + "-Xplugin-require:macroparadise" + ) +} + diff --git a/test/test.scala b/test/test.scala index 74177c5..087bbd9 100644 --- a/test/test.scala +++ b/test/test.scala @@ -421,6 +421,12 @@ object Main{ assert(res.out.contains("All tests passed"), res.out) } + { + val res = runCbt("../examples/macroparadise-example", Seq("run")) + assert(res.exit0) + assert(res.out.contains("hello, world!"), res.out) + } + { val res = runCbt("../examples/resources-example", Seq("run")) assert(res.exit0) -- cgit v1.2.3