Created
July 5, 2023 12:14
-
-
Save sergkh/37448ad06aeef6436917ee1d97a74335 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package fix | |
import scalafix.v1._ | |
import scala.meta._ | |
import scala.reflect.internal.Importers | |
import scala.collection.mutable | |
// Scalafix rule to migrate from sp-commons 1.8.X to 2.0.0 | |
class MigrationToV2 extends SyntacticRule("MigrationToV2") { | |
final val movedModels = List("FieldModels", "BaseModels", "CcmModels", "Models", "CardModels") | |
final val dropImports = List( | |
"com.fidesmo.sp.delivery.free.Delivery.DeliveryFailedException", | |
"com.fidesmo.sp.delivery.free.Delivery.ActionProps" | |
) | |
override def fix(implicit doc: SyntacticDocument): Patch = { | |
//println("Tree.structureLabeled: " + doc.tree.structureLabeled) | |
val imports = mutable.Map.empty[String, Importer] | |
def addImporter(importer: Importer, importees: List[Importee] = Nil): Patch = { | |
var importsRemovalPatch = Patch.empty | |
imports(importer.syntax) = importer | |
importees.foreach { i => | |
importsRemovalPatch += Patch.removeImportee(i) | |
} | |
importsRemovalPatch | |
} | |
doc.tree.collect { | |
case t:Importer if dropImports.exists(t.toString.contains) => | |
Patch.replaceTree(t.parent.get, "") | |
// Free subpackage moved into delivery | |
case t: Importer if t.toString().contains("com.fidesmo.sp.delivery.free") => | |
Patch.replaceTree(t, t.toString().replace("com.fidesmo.sp.delivery.free", "com.fidesmo.sp.delivery")) | |
case t @ Type.Name("DeliveryFailedException") => | |
addImporter(importer"com.fidesmo.sp.delivery.DeliveryFailedException") | |
case t @ Type.Name("DeliveryException") => | |
addImporter(importer"com.fidesmo.sp.delivery.DeliveryException") | |
// For some reason pattern extraction not always matches exception types | |
case c: Pat.Extract if c.children.exists(_.syntax == "DeliveryFailedException") => | |
addImporter(importer"com.fidesmo.sp.delivery.DeliveryFailedException") | |
// For some reason pattern extraction not always matches exception types | |
case c: Pat.Extract if c.children.exists(_.syntax == "DeliveryException") => | |
addImporter(importer"com.fidesmo.sp.delivery.DeliveryException") | |
case t @ Term.Name("ActionProps") => | |
addImporter(importer"com.fidesmo.sp.delivery.ActionProps") | |
// buildStateless is deprecated so let's use simple build | |
case t @ q"buildStateless" => | |
Patch.replaceTree(t, "build") | |
// replace exact match of any of classes imports, e.g. import com.fidesmo.sp.models.{Models, BaseModels} | |
case t: Importer if t.toString().contains("com.fidesmo.sp.models") && t.importees.exists(i => movedModels.exists(m => m == i.toString())) => | |
addImporter(importer"com.fidesmo.sp.models._", t.importees) | |
// replace subclass match of any of classes imports, e.g. import com.fidesmo.sp.models.BaseModels.Dgi | |
case t: Importer if movedModels.map("com.fidesmo.sp.models." + _).exists(path => t.toString().contains(path)) => | |
val tokens = t.tokens | |
val subImports = tokens.takeRightWhile(t => !movedModels.contains(t.toString())) // skip com.fidesmo.sp.models.X part | |
val tokensNumber = subImports.size | |
if (tokensNumber > 2) { | |
// a compound import, something like BaseModels.Operation._, better apply in place fix | |
val groupObject = tokens(tokens.size - tokensNumber - 1) | |
val groupObjectDot = tokens(tokens.size - tokensNumber) | |
Patch.removeTokens(List(groupObject, groupObjectDot)) | |
} else { | |
// likely a direct import like BaseModels.Dgi or FieldModels._, safe to replace with _ | |
addImporter(importer"com.fidesmo.sp.models._", t.importees) | |
} | |
case t @ q"props" if t.parent.exists(_.is[Term.Apply]) => | |
addImporter(importer"com.fidesmo.sp.delivery.ActionProps.props", List.empty) | |
case t @ Term.Name(name) if t.parent.exists(_.is[Term.Select]) && movedModels.contains(name) => | |
val select = t.parent.get.asInstanceOf[Term.Select] | |
val tokens = select.tokens | |
if (movedModels.contains(tokens.head.toString())) { | |
Patch.removeTokens(tokens.take(2)) // 2 tokens: FieldModels and . | |
} else { | |
Patch.empty | |
} | |
}.asPatch ++ imports.values.map(Patch.addGlobalImport) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment