-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from scalacenter/volatile
Implement VolatileLazyVal rewrite rule.
- Loading branch information
Showing
11 changed files
with
150 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package scalafix | ||
|
||
import scala.meta.inputs.Position | ||
|
||
abstract sealed class Fixed { | ||
def get: String = this match { | ||
case Fixed.Success(code) => code | ||
case Fixed.Failure(e) => throw e | ||
} | ||
} | ||
|
||
object Fixed { | ||
case class Success(code: String) extends Fixed | ||
class Failure(val e: Throwable) extends Fixed | ||
object Failure { | ||
def apply(exception: Throwable): Failure = new Failure(exception) | ||
def unapply(arg: Failure): Option[Throwable] = { | ||
Some(arg.e) | ||
} | ||
} | ||
|
||
case class ParseError(pos: Position, message: String, exception: Throwable) | ||
extends Failure(exception) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,30 @@ | ||
package scalafix.rewrite | ||
|
||
import scala.meta._ | ||
import scalafix.FixResult | ||
import scalafix.Fixed | ||
|
||
abstract class Rewrite { | ||
|
||
def rewrite(code: Input): FixResult | ||
def rewrite(code: Input): Fixed | ||
|
||
protected def withParsed(code: Input)(f: Tree => FixResult): FixResult = { | ||
protected def withParsed(code: Input)(f: Tree => Fixed): Fixed = { | ||
code.parse[Source] match { | ||
case Parsed.Success(ast) => f(ast) | ||
case Parsed.Error(pos, msg, details) => | ||
FixResult.ParseError(pos, msg, details) | ||
Fixed.ParseError(pos, msg, details) | ||
} | ||
} | ||
} | ||
|
||
object Rewrite { | ||
val default: List[Rewrite] = List( | ||
ProcedureSyntax | ||
private def nameMap[T](t: sourcecode.Text[T]*): Map[String, T] = { | ||
t.map(x => x.source -> x.value).toMap | ||
} | ||
|
||
val name2rewrite: Map[String, Rewrite] = nameMap[Rewrite]( | ||
ProcedureSyntax, | ||
VolatileLazyVal | ||
) | ||
|
||
val default: Seq[Rewrite] = name2rewrite.values.toSeq | ||
} |
34 changes: 34 additions & 0 deletions
34
core/src/main/scala/scalafix/rewrite/VolatileLazyVal.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package scalafix.rewrite | ||
|
||
import scala.meta._ | ||
import scalafix.Fixed | ||
import scalafix.util.logger | ||
|
||
object VolatileLazyVal extends Rewrite { | ||
private object NonVolatileLazyVal { | ||
def unapply(defn: Defn.Val): Option[Token] = { | ||
defn.mods.collectFirst { | ||
case x if x.syntax == "@volatile" => | ||
None | ||
case x if x.syntax == "lazy" => | ||
Some(x.tokens.head) | ||
} | ||
}.flatten | ||
} | ||
override def rewrite(code: Input): Fixed = { | ||
withParsed(code) { ast => | ||
val toPrepend: Seq[Token] = ast.collect { | ||
case NonVolatileLazyVal(tok) => tok | ||
} | ||
val sb = new StringBuilder | ||
ast.tokens.foreach { token => | ||
if (toPrepend.contains(token)) { | ||
sb.append("@volatile ") | ||
} | ||
sb.append(token.syntax) | ||
} | ||
val result = sb.toString() | ||
Fixed.Success(result) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package scalafix.rewrite | ||
|
||
import scala.meta.inputs.Input | ||
import scalafix.Fixed | ||
import scalafix.util.DiffAssertions | ||
|
||
import org.scalatest.FunSuiteLike | ||
|
||
class RewriteSuite(rewrite: Rewrite) extends FunSuiteLike with DiffAssertions { | ||
|
||
def rewriteTest(name: String, original: String, expected: String): Unit = { | ||
test(name) { | ||
rewrite.rewrite(Input.String(original)) match { | ||
case Fixed.Success(obtained) => | ||
assertNoDiff(obtained, expected) | ||
case Fixed.Failure(e) => | ||
throw e | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
class LazyValSuite extends RewriteSuite(VolatileLazyVal) { | ||
|
||
rewriteTest( | ||
"basic", | ||
"""|object a { | ||
| | ||
|val foo = 1 | ||
| | ||
| lazy val x = 2 | ||
| @volatile lazy val dontChangeMe = 2 | ||
| | ||
| class foo { | ||
| lazy val z = { | ||
| reallyHardStuff() | ||
| } | ||
| } | ||
|} | ||
""".stripMargin, | ||
"""|object a { | ||
| | ||
|val foo = 1 | ||
| | ||
| @volatile lazy val x = 2 | ||
| @volatile lazy val dontChangeMe = 2 | ||
| | ||
| class foo { | ||
| @volatile lazy val z = { | ||
| reallyHardStuff() | ||
| } | ||
| } | ||
|} | ||
""".stripMargin | ||
) | ||
} |