Git Product home page Git Product logo

scalafix's Introduction

scalafix's People

Contributors

ag91 avatar allanrenucci avatar barambani avatar bjaglin avatar bplommer avatar ckipp01 avatar dependabot[bot] avatar dwijnand avatar erikwj avatar fommil avatar gabro avatar giabao avatar github-brice-jaglin avatar insdami avatar jacoby6000 avatar liancheng avatar marcelocenerine avatar masseguillaume avatar mlachkar avatar olafurpg avatar rvacaru avatar scala-center-steward[bot] avatar scala-steward avatar sethtisue avatar taisukeoe avatar tanishiking avatar tgodzik avatar vovapolu avatar xeno-by avatar xuwei-k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scalafix's Issues

Stack overflow running organize imports on slick

java.lang.StackOverflowError
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Transformer.apply(Transformer.scala:4)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI$transformer$2$.apply(Api.scala:10)
	at scala.meta.transversers.Api$XtensionCollectionLikeUI.transform(Api.scala:13)
	at scalafix.nsc.NscScalafixMirror$$anonfun$2.apply(NscScalafixMirror.scala:58)
	at scalafix.nsc.NscScalafixMirror$$anonfun$2.apply(NscScalafixMirror.scala:63)
	at scala.Function1$$anonfun$andThen$1.apply(Function1.scala:52)

The sbt plugin should increase the stack size by default, since scala.meta uses some heavy recursion

Current documentation for sbt plugin refers to a version that can not be resolved

After adding the plugin as referred in the docs I get

$ sbt scalafix
(...)
[warn]  module not found: ch.epfl.scala#sbt-scalafix;0.1.0
[warn] ==== typesafe-ivy-releases: tried
[warn]   https://repo.typesafe.com/typesafe/ivy-releases/ch.epfl.scala/sbt-scalafix/scala_2.10/sbt_0.13/0.1.0/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/ch.epfl.scala/sbt-scalafix/scala_2.10/sbt_0.13/0.1.0/ivys/ivy.xml
[warn] ==== local: tried
[warn]   /Users/pedrorijo/.ivy2/local/ch.epfl.scala/sbt-scalafix/scala_2.10/sbt_0.13/0.1.0/ivys/ivy.xml
[warn] ==== public: tried
[warn]   https://repo1.maven.org/maven2/ch/epfl/scala/sbt-scalafix_2.10_0.13/0.1.0/sbt-scalafix-0.1.0.pom
[warn] ==== Typesafe repository: tried
[warn]   https://repo.typesafe.com/typesafe/releases/ch/epfl/scala/sbt-scalafix_2.10_0.13/0.1.0/sbt-scalafix-0.1.0.pom
[warn] ==== Era7 maven releases: tried
[warn]   http://releases.era7.com.s3.amazonaws.com/ch/epfl/scala/sbt-scalafix_2.10_0.13/0.1.0/sbt-scalafix-0.1.0.pom
[warn] ==== Sbt in bintray releases: tried
[warn]   https://dl.bintray.com/sbt/sbt-plugin-releases/ch/epfl/scala/sbt-scalafix_2.10_0.13/0.1.0/sbt-scalafix-0.1.0.pom
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: ch.epfl.scala#sbt-scalafix;0.1.0: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn]  Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.
[warn]      ch.epfl.scala:sbt-scalafix:0.1.0 (scalaVersion=2.10, sbtVersion=0.13)
[warn]
[warn]  Note: Unresolved dependencies path:
[warn]      ch.epfl.scala:sbt-scalafix:0.1.0 (scalaVersion=2.10, sbtVersion=0.13) (/Users/pedrorijo/git/<fake-project-name>/project/plugins.sbt#L38-39)
[warn]        +- root:root:0.1-SNAPSHOT (scalaVersion=2.10, sbtVersion=0.13)
sbt.ResolveException: unresolved dependency: ch.epfl.scala#sbt-scalafix;0.1.0: not found
    at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:313)
    at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:191)
    at sbt.IvyActions$$anonfun$updateEither$1.apply(IvyActions.scala:168)
    at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
    at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:156)
    at sbt.IvySbt$$anonfun$withIvy$1.apply(Ivy.scala:133)
    at sbt.IvySbt.sbt$IvySbt$$action$1(Ivy.scala:57)
    at sbt.IvySbt$$anon$4.call(Ivy.scala:65)
    at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:93)
    at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:78)
    at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:97)
    at xsbt.boot.Using$.withResource(Using.scala:10)
    at xsbt.boot.Using$.apply(Using.scala:9)
    at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:58)
    at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:48)
    at xsbt.boot.Locks$.apply0(Locks.scala:31)
    at xsbt.boot.Locks$.apply(Locks.scala:28)
    at sbt.IvySbt.withDefaultLogger(Ivy.scala:65)
    at sbt.IvySbt.withIvy(Ivy.scala:128)
    at sbt.IvySbt.withIvy(Ivy.scala:125)
    at sbt.IvySbt$Module.withModule(Ivy.scala:156)
    at sbt.IvyActions$.updateEither(IvyActions.scala:168)
    at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1442)
    at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1438)
    at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$90.apply(Defaults.scala:1473)
    at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$90.apply(Defaults.scala:1471)
    at sbt.Tracked$$anonfun$lastOutput$1.apply(Tracked.scala:37)
    at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1476)
    at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1470)
    at sbt.Tracked$$anonfun$inputChanged$1.apply(Tracked.scala:60)
    at sbt.Classpaths$.cachedUpdate(Defaults.scala:1493)
    at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1420)
    at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1372)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
    at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40)
    at sbt.std.Transform$$anon$4.work(System.scala:63)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:228)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
    at sbt.Execute.work(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:228)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
[error] (root/*:update) sbt.ResolveException: unresolved dependency: ch.epfl.scala#sbt-scalafix;0.1.0: not found
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?

ToolBox compilation fails in 2.12

[info] SemanticTests:
[info] scalafix.SemanticTests *** ABORTED *** (1 millisecond)
[info]   metaconfig.FailedToReadClass: Failed to read 'ScalafixConfig'. Errors: scala.tools.reflect.ToolBoxError: reflective compilation has failed:
[info]
[info] Error while emitting <no source file>
[info] assertion failed:
[info]   Cannot create ClassBType from NoSymbol
[info]      while compiling: <no file>
[info]         during phase: jvm
[info]      library version: version 2.12.1
[info]     compiler version: version 2.12.1
[info]   reconstructed args:
[info]
[info]   last tree to typer: TypeTree(object __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2)
[info]        tree position: line 17 of <toolbox>
[info]             tree tpe: __wrapper$1$4e604d538a4c404892c2ba044dcb7068.__wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2.type
[info]               symbol: case object __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2 in package __wrapper$1$4e604d538a4c404892c2ba044dcb7068
[info]    symbol definition: case class __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2 extends Rewrite with Product with Serializable (a ModuleClassSymbol with SynchronizedModuleClassSymbol)
[info]       symbol package: __wrapper$1$4e604d538a4c404892c2ba044dcb7068
[info]        symbol owners: object __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2
[info]            call site: constructor __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2 in object __wrapper$1$4e604d538a4c404892c2ba044dcb7068$MyRewrite2$2 in package __wrapper$1$4e604d538a4c404892c2ba044dcb7068
[info]
[info] <Cannot read source file>
[info] Error while emitting <no source file>
[info] assertion failed: ClassBType.info not yet assigned: Lscala/meta/Term$Name;
[info]   at scalafix.config.ScalafixConfig$$anon$1.read(ScalafixConfig.scala:23)
[info]   at metaconfig.hocon.Hocon2Class$.$anonfun$gimmeClass$1(Hocon2Class.scala:45)

Import rewriter creates ambiguities

Rewriter takes an import of the form import Foo.{ Bar, _ } and rewrites it to import Foo._ on the theory that Bar is redundant. Usually it's not redundant, it's there because without it Bar will be ambiguous with some other Bar. Wildcard imports have a different precedence than named imports.

I tried to compile a good sized codebase after an import rewriting and now having reverted the rewrites in 10 files and not near the end I admit defeat for now.

Optimizaion: resolve scalafix-nsc jar once

Currently, scalafix-nsc is resolved for every subproject in the build. This means a lot of time is spent waiting for

[info] Resolving ch.epfl.scala#scalafix-nsc_2.11;0.2.0-SNAPSHOT ...
...

It would only happen once if the dependency was defined in a synthetic project. Remember to handle 2.11 and 2.12 correctly.

Explicit type annotations for implicit definitions

Dotty requires implicit type annotations for implicit values. This means scalafix can help by rewriting code like this:

// before
implicit val x = 1
// after
implicit val x: Int = 2

To implement this rewrite, we need the scalac inferred types for bodies of Defn.{Val,Def} that contain the implicitmodifier.

Add Unit to Decl.Def with decltpe None

trait a {
- def x
+ def x: Unit
}

This should be easy to detect with tokens

@ "def x".parse[Stat].get.asInstanceOf[Decl.Def].decltpe.tokens
res5: Tokens = Tokens()
@ "def x: Unit".parse[Stat].get.asInstanceOf[Decl.Def].decltpe.tokens
res6: Tokens = Tokens(Unit)

Early initializers

Seems like there's no clear way to do this 100% automatically, test from srewrite

--- a/test/earlyinit.scala
+++ b/test/earlyinit.scala
@@ -6,26 +6,47 @@ object test {
    trait Bar {
       val y: Int
    }
-   def foo: Foo = new { val x: Int = 12345; val y: Int = 54321 } with Foo with Bar {
+   def foo: Foo = new Foo with Bar {
+// TODO NEEDS MANUAL CHANGE (early initializers)
+// BEGIN copied early initializers
+val x: Int = 12345; val y: Int = 54321
+// END copied early initializers
+
      val normalInit: Int = 333
    }
-   def foo2: Foo = new { val x: Int = 12345; val y: Int = 54321 } with Foo with Bar
+   def foo2: Foo = new Foo with Bar {
+// TODO NEEDS MANUAL CHANGE (early initializers)
+// BEGIN copied early initializers
+val x: Int = 12345; val y: Int = 54321
+// END copied early initializers
+}
    def bar: Bar = {
      println
-     new { val y = 7777 } with Bar { val yy = 8888 }
+     new Bar {
+// TODO NEEDS MANUAL CHANGE (early initializers)
+// BEGIN copied early initializers
+val y = 7777
+// END copied early initializers
+ val yy = 8888 }
    }

-   final class DupIterator[T](xs: T) extends {
-      val x = 22222
+   final class DupIterator[T](xs: T) extends Foo {
+// TODO NEEDS MANUAL CHANGE (early initializers)
+// BEGIN copied early initializers
+val x = 22222
       val init2 = 333333
-   } with Foo {
+// END copied early initializers
+
      final def getElem(x: AnyRef): T = ???
    }

-   final class DupIterator2[T](xs: T) extends {
-      val x = 22222
+   final class DupIterator2[T](xs: T) extends Foo {
+// TODO NEEDS MANUAL CHANGE (early initializers)
+// BEGIN copied early initializers
+val x = 22222
       val init2 = 333333
-   } with Foo
+// END copied early initializers
+}

    lazy val a: DupIterator[Int] = ???
 }

Allow rewrites to use Scalafix logger

I am unsure if Scalafix uses an internal logger or not.

What I think it would be useful is that rewrites had access to a logger, to be able to emit errors, warnings and infos by themselves without using the precarious println.

This would allow for cleaner error messages that can reuse the already existing Scalafix infrastructure and whose severity can be filtered by Scalafix itself (and enabled via CLI flags).

Organize imports ordering bug

Looking at the diff of running scalafix with config

rewrites = []
imports.spaceAroundCurlyBrace = false
imports.groupByPrefix = true
imports.organize = true
imports.removeUnused = true

on the slick codebase

+++ b/slick/src/main/scala/slick/basic/BasicBackend.scala
@@ -1,25 +1,22 @@
 package slick.basic
...

// Notice that org/slick are mixed, not sorted
-import slick.SlickException
+import com.typesafe.config.Config
 import slick.dbio._
+import slick.SlickException
+import org.slf4j.LoggerFactory
+import slick.util.AsyncExecutor.{ Continuation, Fresh, Priority, WithConnection }
 import slick.util._
+import org.reactivestreams._

Load rewrite rules from resources

This will allow projects to include their own rewrite rules specific to their project and allow library authors to export rewrite rules with their libraries.

No existentials

Test from srewrite

-  val w: Wrapper[TypArg] forSome { type TypArg >: Bar <: Foo } = ???
+  val w: existentials.Wrapper[_ >: existentials.Bar <: existentials.Foo] = ???

   val doNothingHere: Wrapper[_ >: Bar /* troll comment */ <: Foo] = ???

-  val p1: Pair[A, B] forSome {
-    type A <: Bar
-    type B >: Foo
-  } = ???
+  val p1: existentials.Pair[_ <: existentials.Bar, _ >: existentials.Foo] = ???

Var-arg pattern

Test from srewrite

 object Test {

   List(1, 2, 3, 4) match {
-    case List(1, 2, xs @ _*) =>
+    case List(1, 2, xs : _*) =>
       val ys: Seq[Int] = xs
       println(ys)
   }
-  val List(1, 2, x @ _*) = List(1, 2, 3, 4)
+  val List(1, 2, x : _*) = List(1, 2, 3, 4)

 }

Create rewrite rule to upgrade from cats.data.Xor to Either

Cats has removed Xor in 0.8 series and migrated to Either now that Either is right biased in Scala 2.12.

  • Rewrite usages of Xor to use Scala Either
  • Rewrite usages of Xor.Right/Left to Scala Right/Left
  • Rewrite usages of Xor methods that do not exist on Either to use Cats either enrichments
  • Rewrite usages of XorT to EitherT
  • Remove unused Xor imports
  • Add imports as needed for Either enrichments

Error when running on circe

When using the scalafix compiler plugin and compiling circe

[error] /home/geirsson/scalafix/target/it/circe/tests/shared/src/test/scala/io/circe/refined/RefinedSuite.scala:32: exception during macro expansion:
[error] java.lang.AssertionError: assertion failed: shapeless package shapeless <none>
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateOrRelink$1(Importers.scala:193)
[error]         at scala.reflect.internal.Importers$StandardImporter.importSymbol(Importers.scala:210)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreatedTreeCompleter(Importers.scala:298)
[error]         at scala.reflect.internal.Importers$StandardImporter$$anonfun$importTree$1.apply$mcV$sp(Importers.scala:417)
[error]         at scala.reflect.internal.Importers$StandardImporter.tryFixup(Importers.scala:49)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:418)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateTree(Importers.scala:383)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:415)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateTree(Importers.scala:383)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:415)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateTree(Importers.scala:367)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:415)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateTree(Importers.scala:374)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:415)
[error]         at scala.reflect.internal.Importers$StandardImporter$$anonfun$recreateTree$18.apply(Importers.scala:370)
[error]         at scala.reflect.internal.Importers$StandardImporter$$anonfun$recreateTree$18.apply(Importers.scala:370)
[error]         at scala.collection.immutable.List.map(List.scala:273)
[error]         at scala.reflect.internal.Importers$StandardImporter.recreateTree(Importers.scala:370)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:415)
[error]         at scala.reflect.internal.Importers$StandardImporter.importTree(Importers.scala:29)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2.apply(ToolBoxFactory.scala:426)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$$anonfun$compile$2.apply(ToolBoxFactory.scala:422)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.liftedTree2$1(ToolBoxFactory.scala:355)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$withCompilerApi$.apply(ToolBoxFactory.scala:355)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.compile(ToolBoxFactory.scala:422)
[error]         at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl.eval(ToolBoxFactory.scala:444)
[error]         at scala.reflect.macros.contexts.Evals$class.eval(Evals.scala:20)
[error]         at scala.reflect.macros.contexts.Context.eval(Context.scala:6)
[error]         at eu.timepit.refined.macros.MacroUtils$$anonfun$eval$1.apply(MacroUtils.scala:20)
[error]         at scala.Option.getOrElse(Option.scala:121)
[error]         at eu.timepit.refined.macros.MacroUtils$class.tryN(MacroUtils.scala:24)
[error]         at eu.timepit.refined.macros.RefineMacro.tryN(RefineMacro.scala:9)
[error]         at eu.timepit.refined.macros.MacroUtils$class.eval(MacroUtils.scala:20)
[error]         at eu.timepit.refined.macros.RefineMacro.eval(RefineMacro.scala:9)
[error]         at eu.timepit.refined.macros.RefineMacro.impl(RefineMacro.scala:22)
[error]     val n = refineMV[Greater[W.`2`.T]](5)

CLI tool still exits `0` after an exception

Hey @olafurpg ! Thanks for the tool.

It looks like in 0.3.2, the CLI tool still exits with 0 after encountering the following error(s) (sent to stderr):

Unexpected error fixing file: Reporters.scala
Cause: java.lang.UnsupportedOperationException: scalafix.rewrite.ScalafixMirror.empty $anon#symbol requires the semantic api,
Unexpected error fixing file: Loggers.scala
Cause: java.lang.UnsupportedOperationException: scalafix.rewrite.ScalafixMirror.empty $anon#symbol requires the semantic api,

I'll look into the actual error with @xeno-by . But if you have time to make the edits to exit non-zero on error, it would be appreciated!

Empty `imports.groups` trigger `NoSuchElementException`

Invoking scalafix using

rewrites = []
imports.organize = true
imports.alwaysUsed = []
imports.expandRelative = false
imports.groups = []
imports.removeUnused = true
imports.groupByPrefix = false
imports.spaceAroundCurlyBrace = false

triggers

[error] Failed to fix Test.scala. Error: null. java.util.NoSuchElementException
[error] scala.collection.LinearSeqOptimized$class.last(LinearSeqOptimized.scala:148)
[error] scala.collection.immutable.List.last(List.scala:84)
[error] scalafix.util.OrganizeImports$$anonfun$9$$anonfun$apply$6.apply(OrganizeImports.scala:142)
[error] scalafix.util.OrganizeImports$$anonfun$9$$anonfun$apply$6.apply(OrganizeImports.scala:142)

Rewrites option in CLI is ignored

There are two ways of setting the rewrites to run programmatically:

  • One via ScalafixConfig.
  • Other one via ScalafixOptions.

The first one works in latest master, while the last one seems to be ignored. So if someone does not set the rewrites option in the config but sets them in the options, the rewrites are silently ignored.

Unnamed typeparams

Test from srewrite

-trait T[_] {
-  def foo[_] = 0
-  def foo2[_, B] = 0
+trait T[X_1048515161] {
+  def foo[X_1761091284] = 0
+  def foo2[X_400804573, B] = 0
   def bar[M[_]] = 0
 }

-trait T2[_, K] {}
+trait T2[X_1009028577, K] {}

It would be nice to come up with a slightly less verbose type name.

Fail fast on sbt <0.13.13

The current error is cryptic:

[error] Reference to undefined setting:
[error]
[error]   scalafix-stub/*:update from */*:scalafixInternalJar ((scalafix.sbt.ScalafixPlugin) ScalafixPlugin.scala:58)
[error]
[error] Use 'last' for the full log.

It should be possible to check that sbtVersion.value is > 0.13.13

Preserve multiple importers when using relative imports

It's common to write imports like this

import scala.meta._, contrib._

Scalafix currently expands those like this

import scala.meta._

import contrib._

It would be nice if scalafix preserved the original syntax (as long as the second import is relative to the first).

More rewrites

Happy to see that such rewriting can now be done with scalameta instead of manipulating strings 😃

If you're looking for more rewrites needed to go from Scala to Dotty, you can have a look at the list in the README of the srewrite tool that I wrote some time ago to port scalac tests to dotty.

Scalafix's dependencies have conflicting class files

Scalafix has these dependencies among others:

  ch.epfl.scala:scalafix-core_2.11:0.3.2
    com.lihaoyi:sourcecode_2.11:0.1.3
      ...
    org.scalameta:contrib_2.11:1.6.0
      org.scalameta:scalameta_2.11:1.6.0
        ...
    org.scalameta:scalahost_2.11.8:1.6.0
      ...
    ...

scalahost brings in some of the same class files as sourcecode and scalameta. This is not a problem when running everything inside of a single, flat classloader like java -cp or sbt do, because one of each of the duplicates wins by being earlier on the flat classpath.

But it is a problem for non-private dependencies when tools like CBT or OSGI isolate classloaders for security and performance reasons. With non-private I mean when project has types of their dependencies in their public API. In scalafix sourcecode is probably private, but scalameta is public and brought in by both scalahost and transitively by contrib, which leads to link-time exceptions like IncompatibleClassChange. (For projects CBT optionally allows using a flat classloader, too, but not for builds at this time and scalafix is generally used as part of the build).

Publishing a version of scalahost that depends on those other libraries instead of including their class files should fix the problem. This was also discussed here: https://gitter.im/scala/tooling-contrib?at=58d7ec158e4b63533d66068d (and above). There may still have to be a flat version published until sbt fixes this: sbt/sbt#2255

P.S. CBT is about to add a verifyClasspath task that finds such conflicts. Replacing contrib's scalameta dependency with scalahost works as a workaround for now.

SBT scalafix does not work

With the following steps the sbt-test fails for me, not sure what I am doing wrong?

  • git clone https://github.com/scalacenter/scalafix
  • cd ./scalafix/scalafix-sbt/src/sbt-test/sbt-scalafix/basic
  • echo 'addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.2.1" )' > ./project/plugins.sbt
  • sbt compile scalafix check

Output:

[error] p1/src/test/scala/Test.scala
[error] File: p1/src/test/scala/Test.scala
[error] Obtained output:
[error] object TestMain {
[error] implicit val x = 2
[error] lazy val y = 2
[error] def main(args: Array[String]) {
[error] println("hello")
[error] }
[error] }
[error] Expected:
[error] object TestMain {
[error] implicit val x: Int = 2
[error] lazy val y = 2
[error] def main(args: Array[String]): Unit = {
[error] println("hello")
[error] }
[error] }
...

Imports changing targets

The import rewriter turns this, which compiles:

package a

import _root_.scalaz._, Scalaz._

package object scalaz {
  Tree
}

into this, which does not.

package a

import _root_.scalaz._
import scalaz.Scalaz._

package object scalaz {
  Tree
}

Allow custom file://rewrites to specify dependencies

Following up on a private discussion with @jvican about his experience implementing rewrites in https://github.com/jvican/sbt-migration-rewrites. The sbt-migrator uses coursier, which means the recommended way to ship that rewrite is to

  1. publish the artifacts to maven/bintray
  2. build a custom command-line interface with coursier bootstrap customrewrite,scalafix-cli -f sbt-migrator
  3. run that rewrites by fully-qualified name sbt-migrator --rewrites scala:foo.SbtMigrator

If the rewrite could specify the dependency on coursier, those steps would be replaced with instructions to run

scalafix --rewrites https://github.com/sbt-migrator/Rewrite.scala

I agree this would be nice-to-have. However, I'm not yet sold on adding this feature because I want to avoid creating a scalafix build-tool. I suspect it become tempting add more nifty features like multiple source files, custom scalacOptions or compiler plugins which better belong to proper build tools like sbt/cbt.

XML Interpolator

Dotty does not support XML literals. The current plan is to translate xml literals into xml interpolators, like this

// before
<foo attr={doSomething()}>{message + "!"}</foo>
// after
xml"""<foo attr=${doSomething()}>${message + "!"}</foo>"""

What needed to make this happen:

  • Add proper xml support in scala.meta. Almost complete PR: scalameta/scalameta#469
  • Implement scalafix XML rewrite rule that insert the appropriate Xml.{Start,Splice,...}
  • Implement XML interpolator (maybe hardest part). Previous work: https://github.com/densh/scala-xml-quote An alternative approach is to convert the interpolator to a string and then Xml.load(str) it. This approach will not work in the unapply case. However, I suspect that most (>99%) usage of XML literals is the apply case.

Cross-compile to 2.12

Scala.meta v1.4 will release against 2.12 so there is scalafix should be able to cross-build against 2.12 as well.

Make ExplicitImplicit work in Scala.js repo

Compiling ExplicitImplicit with Scala.js introduces compilation errors. To re-run the experiment

sbt "very publishLocal"
# Set "skip = false" in IntegrationPropertyTest.scala for ScalaJs
sbt "scalafix-tests/testOnly scalafix.tests.ScalaJs"

Rewrite creates unused imports

The import rewriter transforms this, which compiles:

package a

import scalaz.Scalaz, Scalaz._

package object b {
  5.some
}

into this, which does not - at least, not if you're using our compiler options, because it creates an unused import where there was no unused import and -Xfatal-warnings steps in.

package a

import scalaz.Scalaz
import scalaz.Scalaz._

package object b {
  5.some
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.