Skip to content

Commit

Permalink
Fix: Scalafix rename that leads to a name collision breaks compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcrawford45 committed Oct 17, 2022
1 parent 8e355d3 commit b8ff3d6
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import scalafix.patch.Patch
import scalafix.patch.Patch.internal.ReplaceSymbol
import scalafix.syntax._
import scalafix.v0._
import scala.annotation.tailrec


object ReplaceSymbolOps {
private object Select {
Expand All @@ -19,6 +21,20 @@ object ReplaceSymbolOps {
case _ => None
}
}
private def extractImports(stats: Seq[Stat]): Seq[Import] = {
stats
.takeWhile(_.is[Import])
.collect { case i: Import => i }
}

@tailrec private final def getGlobalImports(ast: Tree): Seq[Import] =
ast match {
case Pkg(_, Seq(pkg: Pkg)) => getGlobalImports(pkg)
case Source(Seq(pkg: Pkg)) => getGlobalImports(pkg)
case Pkg(_, stats) => extractImports(stats)
case Source(stats) => extractImports(stats)
case _ => Nil
}

def naiveMoveSymbolPatch(
moveSymbols: Seq[ReplaceSymbol]
Expand Down Expand Up @@ -92,6 +108,7 @@ object ReplaceSymbolOps {
case _ => None
}
}

val patches = ctx.tree.collect { case n @ Move(to) =>
// was this written as `to = "blah"` instead of `to = _root_.blah`
val isSelected = to match {
Expand Down Expand Up @@ -126,10 +143,20 @@ object ReplaceSymbolOps {
if sig.name != parent.value =>
Patch.empty // do nothing because it was a renamed symbol
case Some(parent) =>
val causesCollision = getGlobalImports(ctx.tree).exists { importStmt =>
importStmt.importers.flatMap(_.importees).exists {
case Importee.Name(name) => name.value == to.signature.name
case Importee.Rename(_, rename) => rename.value == to.signature.name
case _ => false
}
}
val addImport =
if (n.isDefinition) Patch.empty
if (n.isDefinition || causesCollision) Patch.empty
else ctx.addGlobalImport(to)
addImport + ctx.replaceTree(n, to.signature.name)
if(causesCollision)
addImport + ctx.replaceTree(n, to.owner.syntax + to.signature.name)
else
addImport + ctx.replaceTree(n, to.signature.name)
case _ =>
Patch.empty
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ patches.replaceSymbols = [
to = "com.geirsson.mutable.CoolBuffer" }
{ from = "scala.collection.mutable.HashMap"
to = "com.geirsson.mutable.unsafe.CoolMap" }
{ from = "scala.collection.immutable.TreeMap"
to = "com.geirsson.immutable.SortedMap" }
{ from = "scala.math.sqrt"
to = "com.geirsson.fastmath.sqrt" }
// normalized symbol renames all overloaded methods
Expand All @@ -29,6 +31,8 @@ patches.replaceSymbols = [
*/
package fix

import scala.collection.immutable.SortedMap
import scala.collection.immutable.TreeMap
import scala.collection.mutable.HashMap
import scala.collection.mutable.ListBuffer
import scala.collection.mutable
Expand All @@ -42,8 +46,9 @@ object ReplaceSymbol {
"blah".substring(1)
"blah".substring(1, 2)
val u: mutable.HashMap[Int, Int] = HashMap.empty[Int, Int]
val v: SortedMap[Int, Int] = TreeMap.empty[Int, Int]
val x: ListBuffer[Int] = ListBuffer.empty[Int]
val y: mutable.ListBuffer[Int] = mutable.ListBuffer.empty[Int]
val z: scala.collection.mutable.ListBuffer[Int] =
scala.collection.mutable.ListBuffer.empty[Int]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.geirsson

import scala.collection.immutable.TreeMap

package object immutable {
type SortedMap[A, B] = TreeMap[A, B]

object SortedMap {
def empty[A : Ordering, B]: SortedMap[A, B] = TreeMap.empty[A, B]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fix

import scala.collection.immutable.SortedMap
import com.geirsson.Future
import com.geirsson.{ fastmath, mutable }
import com.geirsson.mutable.{ CoolBuffer, unsafe }
Expand All @@ -13,8 +14,9 @@ object ReplaceSymbol {
"blah".substringFrom(1)
"blah".substringBetween(1, 2)
val u: unsafe.CoolMap[Int, Int] = CoolMap.empty[Int, Int]
val v: SortedMap[Int, Int] = com.geirsson.immutable.SortedMap.empty[Int, Int]
val x: CoolBuffer[Int] = CoolBuffer.empty[Int]
val y: mutable.CoolBuffer[Int] = mutable.CoolBuffer.empty[Int]
val z: com.geirsson.mutable.CoolBuffer[Int] =
com.geirsson.mutable.CoolBuffer.empty[Int]
}
}

0 comments on commit b8ff3d6

Please sign in to comment.