aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/cross-rewrite-example/Readme.md5
-rw-r--r--examples/cross-rewrite-example/build/build.scala72
-rw-r--r--examples/cross-rewrite-example/build/build/build.scala5
-rw-r--r--examples/cross-rewrite-example/src/Main.scala1
-rw-r--r--examples/scalafix-compiler-plugin-example/.scalafix.conf (renamed from examples/scalafix-example/.scalafix.conf)0
-rw-r--r--examples/scalafix-compiler-plugin-example/Main.scala9
-rw-r--r--examples/scalafix-compiler-plugin-example/build/build.scala3
-rw-r--r--examples/scalafix-compiler-plugin-example/build/build/build.scala5
-rw-r--r--examples/scalafix-example/build/build.scala27
-rw-r--r--plugins/scalafix-compiler-plugin/Scalafix.scala28
-rw-r--r--plugins/scalafix-compiler-plugin/build/build.scala12
-rw-r--r--plugins/scalafix/Scalafix.scala76
-rw-r--r--plugins/scalafix/build/build.scala23
-rw-r--r--stage2/plugins.scala1
-rw-r--r--stage2/plugins/Scalameta.scala26
-rw-r--r--test/test.scala32
16 files changed, 300 insertions, 25 deletions
diff --git a/examples/cross-rewrite-example/Readme.md b/examples/cross-rewrite-example/Readme.md
new file mode 100644
index 0000000..7d96da0
--- /dev/null
+++ b/examples/cross-rewrite-example/Readme.md
@@ -0,0 +1,5 @@
+This is an example of how to use scalafix rewrite rules to produce multiple
+variants of the same code base for different scala versions, e.g. 2.11.8 and
+2.12.1 and against different comparable libraries, e.g. cats and scalaz.
+
+To package the jars for all combinations run `cbt cross.package`.
diff --git a/examples/cross-rewrite-example/build/build.scala b/examples/cross-rewrite-example/build/build.scala
new file mode 100644
index 0000000..6d2ffac
--- /dev/null
+++ b/examples/cross-rewrite-example/build/build.scala
@@ -0,0 +1,72 @@
+package cbt_examples_build.cross_rewrite
+import cbt._
+import java.io.File
+import scala.meta._
+import scalafix.util._
+import scalafix.util.TreePatch._
+import scalafix.util.TokenPatch._
+
+class Build(val context: Context) extends BaseBuild{ outer =>
+ override def defaultScalaVersion = "2.11.8"
+
+ def versions = Seq[(String, Seq[Patch])](
+ scalaVersion -> Seq(),
+ "2.12.1" -> Seq(
+ RemoveGlobalImport(
+ importer"scala.concurrent.Future"
+ ),
+ AddGlobalImport(
+ importer"scala.util.Try"
+ )
+ )
+ )
+ def libs = Seq[(String, MavenDependency, Seq[Patch])](
+ (
+ "scalaz",
+ ScalaDependency( "org.scalaz", "scalaz-core", "7.2.2" ),
+ Seq(
+ )
+ ),
+ (
+ "cats",
+ ScalaDependency( "org.typelevel", "cats", "0.9.0" ),
+ Seq(
+ )
+ )
+ )
+
+ def cross = versions.flatMap{ case ( v, version_rewrites ) =>
+ libs.map{
+ case ( label, dep, lib_rewrites ) =>
+ val d = outer.target / "rewrites" / label ++ "-" ++ v
+ d.mkdirs
+ new Build(context) with Scalafix with PackageJars{
+ override def groupId = "org.cvogt"
+ override def artifactId = "cbt-examples-cross-rewrite-" + label
+ override def version = "0.1"
+ override def defaultScalaVersion = v
+ override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( dep )
+ override def projectDirectory = d
+ override def scaladoc = None
+ override def sources = {
+ val fromTo = lib.autoRelative( outer.sources ).collect{
+ case (location, relative) if location.isFile
+ => location -> projectDirectory / "src" / relative
+ }
+
+ val to = fromTo.map(_._2)
+ assert( ( to diff to.distinct ).isEmpty )
+
+ Scalafix.apply(lib).config(
+ outer.classpath,
+ files = fromTo,
+ patches = lib_rewrites ++ version_rewrites,
+ allowEmpty = true
+ ).apply
+
+ to
+ }
+ }
+ }
+ }
+}
diff --git a/examples/cross-rewrite-example/build/build/build.scala b/examples/cross-rewrite-example/build/build/build.scala
new file mode 100644
index 0000000..404356f
--- /dev/null
+++ b/examples/cross-rewrite-example/build/build/build.scala
@@ -0,0 +1,5 @@
+import cbt._
+
+class Build(val context: Context) extends BuildBuild {
+ override def dependencies = super.dependencies :+ plugins.scalafix
+}
diff --git a/examples/cross-rewrite-example/src/Main.scala b/examples/cross-rewrite-example/src/Main.scala
new file mode 100644
index 0000000..27ea3ff
--- /dev/null
+++ b/examples/cross-rewrite-example/src/Main.scala
@@ -0,0 +1 @@
+import scala.concurrent.Future
diff --git a/examples/scalafix-example/.scalafix.conf b/examples/scalafix-compiler-plugin-example/.scalafix.conf
index dbb79d7..dbb79d7 100644
--- a/examples/scalafix-example/.scalafix.conf
+++ b/examples/scalafix-compiler-plugin-example/.scalafix.conf
diff --git a/examples/scalafix-compiler-plugin-example/Main.scala b/examples/scalafix-compiler-plugin-example/Main.scala
new file mode 100644
index 0000000..c82c77b
--- /dev/null
+++ b/examples/scalafix-compiler-plugin-example/Main.scala
@@ -0,0 +1,9 @@
+object Main{
+ lazy val x = 1 + 1
+
+ implicit def toString(i :Int) = i.toString
+
+ def main( args: Array[String] ){
+ println("Hello world!")
+ }
+}
diff --git a/examples/scalafix-compiler-plugin-example/build/build.scala b/examples/scalafix-compiler-plugin-example/build/build.scala
new file mode 100644
index 0000000..9d85087
--- /dev/null
+++ b/examples/scalafix-compiler-plugin-example/build/build.scala
@@ -0,0 +1,3 @@
+import cbt._
+
+class Build(val context: Context) extends BaseBuild with ScalafixCompilerPlugin
diff --git a/examples/scalafix-compiler-plugin-example/build/build/build.scala b/examples/scalafix-compiler-plugin-example/build/build/build.scala
new file mode 100644
index 0000000..5b6286b
--- /dev/null
+++ b/examples/scalafix-compiler-plugin-example/build/build/build.scala
@@ -0,0 +1,5 @@
+import cbt._
+
+class Build(val context: Context) extends BuildBuild {
+ override def dependencies = super.dependencies :+ plugins.scalafixCompilerPlugin
+}
diff --git a/examples/scalafix-example/build/build.scala b/examples/scalafix-example/build/build.scala
index 776d1e0..eff4176 100644
--- a/examples/scalafix-example/build/build.scala
+++ b/examples/scalafix-example/build/build.scala
@@ -1,3 +1,28 @@
import cbt._
-class Build(val context: Context) extends BaseBuild with Scalafix
+import scala.meta._
+import scalafix.rewrite._
+import scalafix.util._
+import scalafix.util.TreePatch._
+import scalafix.util.TokenPatch._
+
+class Build(val context: Context) extends BaseBuild{
+ override def compile = {
+ new BasicBuild(context) with Scalafix{
+ override def scalafix = super.scalafix.copy(
+ patches =
+ Seq(
+ AddGlobalImport(
+ importer"scala.collection.immutable"
+ )
+ ),
+ rewrites = Seq(
+ ProcedureSyntax,
+ ExplicitImplicit,
+ VolatileLazyVal
+ )
+ )
+ }.scalafix.apply
+ super.compile // <- as scalafix trigger compile already before re-writing, this will just return the cached compile result before rewriting
+ }
+}
diff --git a/plugins/scalafix-compiler-plugin/Scalafix.scala b/plugins/scalafix-compiler-plugin/Scalafix.scala
new file mode 100644
index 0000000..2a18c5d
--- /dev/null
+++ b/plugins/scalafix-compiler-plugin/Scalafix.scala
@@ -0,0 +1,28 @@
+package cbt
+
+import cbt._
+import java.nio.file.Files._
+import java.nio.file._
+import java.io.File
+
+trait ScalafixCompilerPlugin extends BaseBuild {
+ def scalafixVersion = "0.3.1"
+
+ override def scalacOptions = super.scalacOptions ++
+ Scalafix.scalacOptions(projectDirectory.toPath,
+ Resolver( mavenCentral, sonatypeReleases ).bindOne(
+ ScalaDependency( "ch.epfl.scala", "scalafix-nsc", scalafixVersion )
+ ).jar)
+}
+
+object Scalafix {
+ def scalacOptions( rootPath: Path, nscJar: File ) =
+ Seq(
+ "-Xplugin:" ++ nscJar.string,
+ "-Yrangepos"
+ ) ++ configOption(rootPath)
+
+ def configOption( rootPath: Path ) =
+ Some( rootPath.resolve(".scalafix.conf").toAbsolutePath )
+ .filter(isRegularFile(_)).map("-P:scalafix:" ++ _.toString).toSeq
+}
diff --git a/plugins/scalafix-compiler-plugin/build/build.scala b/plugins/scalafix-compiler-plugin/build/build.scala
new file mode 100644
index 0000000..b25b54d
--- /dev/null
+++ b/plugins/scalafix-compiler-plugin/build/build.scala
@@ -0,0 +1,12 @@
+package scalafix_build
+
+import cbt._
+
+class Build(val context: Context) extends Plugin {
+ override def dependencies = (
+ super.dependencies ++
+ Resolver( mavenCentral, sonatypeReleases ).bind(
+ ScalaDependency( "ch.epfl.scala", "scalafix-nsc", "0.3.1" )
+ )
+ )
+}
diff --git a/plugins/scalafix/Scalafix.scala b/plugins/scalafix/Scalafix.scala
index cf808d7..e95840c 100644
--- a/plugins/scalafix/Scalafix.scala
+++ b/plugins/scalafix/Scalafix.scala
@@ -1,28 +1,66 @@
package cbt
-import cbt._
-import java.nio.file.Files._
-import java.nio.file._
import java.io.File
-trait Scalafix extends BaseBuild {
- def scalafixVersion = "0.3.1"
+import scala.meta._
+import scala.meta.semantic.v1._
+import scala.meta.{ Symbol => _, _ }
+import scalafix._, rewrite._, config._, util._
+import org.scalameta.{logger => scalametaLogger}
+
+import cbt._
- override def scalacOptions = super.scalacOptions ++
- Scalafix.scalacOptions(projectDirectory.toPath,
- Resolver( mavenCentral, sonatypeReleases ).bindOne(
- ScalaDependency( "ch.epfl.scala", "scalafix-nsc", scalafixVersion )
- ).jar)
+trait Scalafix extends Scalameta{
+ def scalafix = Scalafix.apply( lib ).config(
+ classpath,
+ sourceFiles zip sourceFiles
+ )
}
-object Scalafix {
- def scalacOptions( rootPath: Path, nscJar: File ) =
- Seq(
- "-Xplugin:" ++ nscJar.string,
- "-Yrangepos"
- ) ++ configOption(rootPath)
+object Scalafix{
+ case class apply( lib: Lib ){
+ case class config(
+ classpath: ClassPath,
+ files: Seq[(File,File)],
+ patches: Seq[Patch] = Seq(),
+ rewrites: Seq[ Rewrite[ScalafixMirror] ] = Seq(),
+ allowEmpty: Boolean = false
+ ){
+ def mirror =
+ Mirror(
+ classpath.string,
+ files.map(_._1).mkString(File.pathSeparator)
+ )
+
+ def context(file: File): ( RewriteCtx[Mirror], RewriteCtx[ScalafixMirror] ) = (
+ scalafix.rewrite.RewriteCtx(
+ mirror.dialect(file).parse[Source].get, ScalafixConfig(), mirror
+ ),
+ scalafix.rewrite.RewriteCtx(
+ mirror.dialect(file).parse[Source].get, ScalafixConfig(), ScalafixMirror.fromMirror( mirror )
+ )
+ )
- def configOption( rootPath: Path ) =
- Some( rootPath.resolve(".scalafix.conf").toAbsolutePath )
- .filter(isRegularFile(_)).map("-P:scalafix:" ++ _.toString).toSeq
+ def apply: Unit = {
+ require(
+ allowEmpty || rewrites.nonEmpty || patches.nonEmpty,
+ "You need to provide some rewrites via: `override def scalafix = super.scalafix.copy( rewrites = Seq(...) )`"
+ )
+ files.foreach{ case (from, to) =>
+ implicit val ( ctx, ctx2 ) = context(from)
+ lib.writeIfChanged(
+ to,
+ Patch(
+ (
+ patches
+ ++ rewrites.flatMap(
+ _.rewrite( ctx2 ).to
+ )
+ ).to
+ )
+ )
+ }
+ }
+ }
+ }
}
diff --git a/plugins/scalafix/build/build.scala b/plugins/scalafix/build/build.scala
index b25b54d..02dcc0c 100644
--- a/plugins/scalafix/build/build.scala
+++ b/plugins/scalafix/build/build.scala
@@ -3,10 +3,25 @@ package scalafix_build
import cbt._
class Build(val context: Context) extends Plugin {
- override def dependencies = (
- super.dependencies ++
- Resolver( mavenCentral, sonatypeReleases ).bind(
- ScalaDependency( "ch.epfl.scala", "scalafix-nsc", "0.3.1" )
+ override def dependencies = super.dependencies ++ Seq(
+ //plugins.scalameta
+ ) :+ Resolver( mavenCentral ).bindOne(
+ ScalaDependency(
+ "ch.epfl.scala", "scalafix-core", "0.3.2"
)
+ ).copy(
+ // required until https://github.com/scalacenter/scalafix/issues/100 is fixed
+ replace = _ => _.flatMap{
+ case m@MavenDependency("org.scalameta", artifactId,_,_,_)
+ if (artifactId startsWith "scalahost_")
+ || (artifactId startsWith "contrib_")
+ => Seq( m )
+ case MavenDependency("org.scalameta", _,_,_,_) => Seq(
+ MavenDependency(
+ "org.scalameta", "scalahost_" ++ scalaVersion, "1.6.0"
+ )
+ )
+ case other => Seq( other )
+ }
)
}
diff --git a/stage2/plugins.scala b/stage2/plugins.scala
index eca28f0..6c5ee29 100644
--- a/stage2/plugins.scala
+++ b/stage2/plugins.scala
@@ -6,6 +6,7 @@ class plugins( implicit context: Context ) {
final lazy val proguard = plugin( "proguard" )
final lazy val sbtLayout = plugin( "sbt_layout" )
final lazy val scalafix = plugin( "scalafix" )
+ final lazy val scalafixCompilerPlugin = plugin( "scalafix-compiler-plugin" )
final lazy val scalafmt = plugin( "scalafmt" )
final lazy val scalaJs = plugin( "scalajs" )
final lazy val scalapb = plugin( "scalapb" )
diff --git a/stage2/plugins/Scalameta.scala b/stage2/plugins/Scalameta.scala
new file mode 100644
index 0000000..663399d
--- /dev/null
+++ b/stage2/plugins/Scalameta.scala
@@ -0,0 +1,26 @@
+package cbt
+import java.io.File
+trait Scalameta extends BaseBuild{
+ override def scalacOptions = super.scalacOptions ++ Scalameta.scalacOptions(
+ Scalameta.scalaHost( scalaVersion, context.cbtLastModified, context.paths.mavenCache ).jar
+ )
+}
+object Scalameta{
+ def scalaHost(
+ scalaVersion: 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", "scalahost_"+scalaVersion, "1.6.0"
+ )
+ )
+
+ def scalacOptions( scalaHost: File ) =
+ Seq(
+ "-Xplugin:" ++ scalaHost.string,
+ "-Yrangepos",
+ "-Xplugin-require:scalahost"
+ )
+}
diff --git a/test/test.scala b/test/test.scala
index 5c107fe..f3fb7c5 100644
--- a/test/test.scala
+++ b/test/test.scala
@@ -257,7 +257,7 @@ object Main{
compile("../plugins/scalatest")
compile("../plugins/wartremover")
compile("../plugins/uber-jar")
- compile("../plugins/scalafix")
+ compile("../plugins/scalafix-compiler-plugin")
compile("../examples/scalafmt-example")
compile("../examples/scalariform-example")
compile("../examples/scalatest-example")
@@ -427,6 +427,35 @@ object Main{
}
{
+ val res = runCbt("../examples/cross-rewrite-example", Seq("cross.exportedClasspath"))
+ assert(res.exit0)
+ Seq("cats","scalaz","2.11.8","2.12.1").foreach(
+ s => assert(res.out contains s, res.out)
+ )
+ }
+
+ {
+ val sourceFile = cbtHome / "examples" / "scalafix-compiler-plugin-example" / "Main.scala"
+ val sourceBefore = sourceFile.readAsString
+ runCbt("../examples/scalafix-compiler-plugin-example", Seq("clean","force"))
+ val res = runCbt("../examples/scalafix-compiler-plugin-example", Seq("compile"))
+ assert(res.exit0)
+ val sourceAfter = sourceFile.readAsString
+ assert(!(sourceBefore contains "@volatile"))
+ assert(!(sourceBefore contains ": Unit"))
+ assert(!(sourceBefore contains ": String "))
+ assert(!(sourceBefore contains "import scala.collection.immutable"))
+ assert(sourceAfter contains "@volatile")
+ assert(sourceAfter contains ": Unit")
+ assert(sourceAfter contains ": String ")
+ assert(sourceAfter contains "import scala.collection.immutable")
+ lib.write(sourceFile, sourceBefore)
+ }
+
+ /*
+ // currently fails with
+ // java.lang.UnsupportedOperationException: scalafix.rewrite.ScalafixMirror.fromMirror $anon#typeSignature requires the semantic api
+ {
val sourceFile = cbtHome / "examples" / "scalafix-example" / "Main.scala"
val sourceBefore = sourceFile.readAsString
runCbt("../examples/scalafix-example", Seq("clean","force"))
@@ -443,6 +472,7 @@ object Main{
assert(sourceAfter contains "import scala.collection.immutable")
lib.write(sourceFile, sourceBefore)
}
+ */
System.err.println(" DONE!")
System.err.println( successes.toString ++ " succeeded, "++ failures.toString ++ " failed" )