diff --git a/scalafix/input/src/main/scala/fix/MutSetMapSrc.scala b/scalafix/input/src/main/scala/fix/MutSetMapSrc.scala new file mode 100644 index 00000000..d6aa62d3 --- /dev/null +++ b/scalafix/input/src/main/scala/fix/MutSetMapSrc.scala @@ -0,0 +1,12 @@ +/* +rule = "scala:fix.Scalacollectioncompat_newcollections" + */ +package fix + +import scala.collection.mutable + +class MutSetMapSrc(map: mutable.Map[Int, Int], set: mutable.Set[Int]) { + set + 2 + map + (2 -> 3) + (set + 2).size +} \ No newline at end of file diff --git a/scalafix/output/src/main/scala/fix/MutSetMapSrc.scala b/scalafix/output/src/main/scala/fix/MutSetMapSrc.scala new file mode 100644 index 00000000..5c963784 --- /dev/null +++ b/scalafix/output/src/main/scala/fix/MutSetMapSrc.scala @@ -0,0 +1,12 @@ + + + +package fix + +import scala.collection.mutable + +class MutSetMapSrc(map: mutable.Map[Int, Int], set: mutable.Set[Int]) { + set.clone() += 2 + map.clone() += (2 -> 3) + (set.clone() += 2).size +} \ No newline at end of file diff --git a/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala index 40579b3a..fb84550a 100644 --- a/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala +++ b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala @@ -35,6 +35,12 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) val mapPlus2 = SymbolMatcher.exact( Symbol("_root_.scala.collection.immutable.MapLike#`+`(Lscala/Tuple2;Lscala/Tuple2;Lscala/collection/Seq;)Lscala/collection/immutable/Map;.") ) + val mutSetPlus = SymbolMatcher.exact( + Symbol("_root_.scala.collection.mutable.SetLike#`+`(Ljava/lang/Object;)Lscala/collection/mutable/Set;.") + ) + val mutMapPlus = SymbolMatcher.exact( + Symbol("_root_.scala.collection.mutable.MapLike#`+`(Lscala/Tuple2;)Lscala/collection/mutable/Map;.") + ) def foldSymbol(isLeft: Boolean): SymbolMatcher = { val op = @@ -165,7 +171,6 @@ 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)) { // don't drop surrounding parens @@ -183,7 +188,6 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) ctx.removeTokens(tokensToReplace) + tokensToReplace.headOption.map(x => ctx.addRight(x, newTree)) } - ctx.tree.collect { case ap @ Term.ApplyInfix(lhs, op @ mapPlus2(_), _, List(a, b)) => rewritePlus(ap, lhs, op, a, b) @@ -193,6 +197,21 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) }.asPatch } + def replaceMutSetMapPlus(ctx: RuleCtx): Patch = { + def rewriteMutPlus(lhs: Term, op: Term.Name): Patch = { + ctx.addRight(lhs, ".clone()") + + ctx.addRight(op, "=") + } + + ctx.tree.collect { + case Term.ApplyInfix(lhs, op @ mutSetPlus(_), _, List(_)) => + rewriteMutPlus(lhs, op) + + case Term.ApplyInfix(lhs, op @ mutMapPlus(_), _, List(_)) => + rewriteMutPlus(lhs, op) + }.asPatch + } + override def fix(ctx: RuleCtx): Patch = { // println(ctx.index.database) @@ -204,6 +223,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) replaceMutableMap(ctx) + replaceMutableSet(ctx) + replaceSymbolicFold(ctx) + - replaceSetMapPlus2(ctx) + replaceSetMapPlus2(ctx) + + replaceMutSetMapPlus(ctx) } }