Skip to content

Commit

Permalink
Rewrite collection.{Map, Set}.+ and collection.Set.-
Browse files Browse the repository at this point in the history
This is incomplete since, it's blocked by scalameta/scalameta#1212 (Add support to query type of a term)

iset: immutable.Set[Int]
cset: collecion.Set[Int]

both have +/- implemented via SetLike

given

iset + 1
cset + 1

we know that + is from SetLike, but it's not possible to get the type of iset/cset
  • Loading branch information
MasseGuillaume committed Jun 25, 2018
1 parent f0da45e commit 5b8efb3
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 14 deletions.
22 changes: 16 additions & 6 deletions scalafix/input/src/main/scala/fix/SetMapSrc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@ rule = "scala:fix.Scalacollectioncompat_newcollections"
*/
package fix

class SetMapSrc(set: Set[Int], map: Map[Int, Int]) {
set + (2, 3)
map + (2 -> 3, 3 -> 4)
(set + (2, 3)).map(x => x)
set + (2, 3) - 4
}
import scala.collection
import scala.collection.immutable
import scala.collection.mutable.{Map, Set} // Challenge to make shure the scoping is correct

class SetMapSrc(iset: immutable.Set[Int],
cset: collection.Set[Int],
imap: immutable.Map[Int, Int],
cmap: collection.Map[Int, Int]) {
iset + (2, 3)
imap + (2 -> 3, 3 -> 4)
(iset + (2, 3)).toString
iset + (2, 3) - 4
iset + 1 - 2
cset + 1 - 2
cmap + (2 -> 3) + ((4, 5))
}
20 changes: 15 additions & 5 deletions scalafix/output/src/main/scala/fix/SetMapSrc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@

package fix

class SetMapSrc(set: Set[Int], map: Map[Int, Int]) {
set + 2 + 3
map + (2 -> 3) + (3 -> 4)
(set + 2 + 3).map(x => x)
set + 2 + 3 - 4
import scala.collection
import scala.collection.immutable
import scala.collection.mutable.{Map, Set} // Challenge to make shure the scoping is correct

class SetMapSrc(iset: immutable.Set[Int],
cset: collection.Set[Int],
imap: immutable.Map[Int, Int],
cmap: collection.Map[Int, Int]) {
iset + 2 + 3
imap + (2 -> 3) + (3 -> 4)
(iset + 2 + 3).toString
iset + 2 + 3 - 4
iset + 1 - 2
cset ++ _root_.scala.collection.Set(1) -- _root_.scala.collection.Set(2)
cmap ++ _root_.scala.collection.Map(2 -> 3) ++ _root_.scala.collection.Map((4, 5))
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
Symbol("_root_.scala.runtime.Tuple2Zipped.Ops.zipped."),
Symbol("_root_.scala.runtime.Tuple3Zipped.Ops.zipped.")
)
val setPlus =
SymbolMatcher.exact(
Symbol("_root_.scala.collection.SetLike#`+`(Ljava/lang/Object;)Lscala/collection/Set;.")
)
val setMinus =
SymbolMatcher.exact(
Symbol("_root_.scala.collection.SetLike#`-`(Ljava/lang/Object;)Lscala/collection/Set;.")
)
val mapPlus =
SymbolMatcher.exact(
Symbol("_root_.scala.collection.MapLike#`+`(Lscala/Tuple2;)Lscala/collection/Map;.")
)
val setPlus2 = SymbolMatcher.exact(
Symbol("_root_.scala.collection.SetLike#`+`(Ljava/lang/Object;Ljava/lang/Object;Lscala/collection/Seq;)Lscala/collection/Set;.")
)
Expand Down Expand Up @@ -66,6 +78,9 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
Symbol("_root_.scala.collection.mutable.SetLike.retain.")
)

def startsWithParens(tree: Tree): Boolean =
tree.tokens.headOption.map(_.is[Token.LeftParen]).getOrElse(false)

def replaceMutableSet(ctx: RuleCtx) =
ctx.tree.collect {
case retainSet(n: Name) =>
Expand Down Expand Up @@ -176,7 +191,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
def replaceSetMapPlus2(ctx: RuleCtx): Patch = {
def rewritePlus(ap: Term.ApplyInfix, lhs: Term, op: Term.Name, rhs1: Term, rhs2: Term): Patch = {
val tokensToReplace =
if(ap.tokens.headOption.map(_.is[Token.LeftParen]).getOrElse(false)) {
if(startsWithParens(ap)) {
// don't drop surrounding parens
ap.tokens.slice(1, ap.tokens.size - 1)
} else ap.tokens
Expand All @@ -201,6 +216,33 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
}.asPatch
}

def replaceSetMapPlusMinus(ctx: RuleCtx): Patch = {
def rewriteOp(op: Tree, rhs: Tree, doubleOp: String, col0: String): Patch = {
val col = "_root_.scala.collection." + col0
val callSite =
if (startsWithParens(rhs)) {
ctx.addLeft(rhs, col)
}
else {
ctx.addLeft(rhs, col + "(") +
ctx.addRight(rhs, ")")
}

ctx.addRight(op, doubleOp) + callSite
}

ctx.tree.collect {
case Term.ApplyInfix(_, op @ setPlus(_), Nil, List(rhs)) =>
rewriteOp(op, rhs, "+", "Set")

case Term.ApplyInfix(lhs, op @ setMinus(_), Nil, List(rhs)) =>
rewriteOp(op, rhs, "-", "Set")

case Term.ApplyInfix(lhs, op @ mapPlus(_), Nil, List(rhs)) =>
rewriteOp(op, rhs, "+", "Map")
}.asPatch
}

def replaceMutSetMapPlus(ctx: RuleCtx): Patch = {
def rewriteMutPlus(lhs: Term, op: Term.Name): Patch = {
ctx.addRight(lhs, ".clone()") +
Expand All @@ -227,8 +269,6 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
}

override def fix(ctx: RuleCtx): Patch = {
// println(ctx.index.database)

replaceToList(ctx) +
replaceSymbols(ctx) +
replaceTupleZipped(ctx) +
Expand All @@ -238,6 +278,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex)
replaceMutableSet(ctx) +
replaceSymbolicFold(ctx) +
replaceSetMapPlus2(ctx) +
replaceSetMapPlusMinus(ctx) +
replaceMutSetMapPlus(ctx) +
replaceMutMapUpdated(ctx)
}
Expand Down

0 comments on commit 5b8efb3

Please sign in to comment.