From 9f01ba541f9e628a17e9e3b3592e132d52ba756c Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 11 Jan 2024 19:57:43 +0100 Subject: [PATCH 1/5] scalameta 4.9.x --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 62365d900..12e5b92b1 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -20,7 +20,7 @@ object Dependencies { val metaconfigV = "0.12.0" val nailgunV = "0.9.1" val scalaXmlV = "2.2.0" - val scalametaV = "4.8.15" + val scalametaV = "4.9.0" val scalatestV = "3.2.18" val munitV = "0.7.29" From 2b0d32ddfeb1cde2d1e08f25cd8d374c5c9b9da4 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Thu, 11 Jan 2024 20:13:55 +0100 Subject: [PATCH 2/5] Origin is now part of the public API --- .../main/scala/org/langmeta/internal/ScalametaInternals.scala | 2 +- .../scala/meta/internal/scalafix/ScalafixScalametaHacks.scala | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/scalafix-core/src/main/scala/org/langmeta/internal/ScalametaInternals.scala b/scalafix-core/src/main/scala/org/langmeta/internal/ScalametaInternals.scala index d528c7cd2..bf07a7b50 100644 --- a/scalafix-core/src/main/scala/org/langmeta/internal/ScalametaInternals.scala +++ b/scalafix-core/src/main/scala/org/langmeta/internal/ScalametaInternals.scala @@ -4,8 +4,8 @@ import scala.meta._ import scala.meta.internal.inputs.XtensionInputSyntaxStructure import scala.meta.internal.semanticdb.Scala.Descriptor import scala.meta.internal.semanticdb.Scala.DescriptorParser -import scala.meta.internal.trees.Origin import scala.meta.internal.{semanticdb => s} +import scala.meta.trees.Origin object ScalametaInternals { private val EOL = System.lineSeparator() diff --git a/scalafix-core/src/main/scala/scala/meta/internal/scalafix/ScalafixScalametaHacks.scala b/scalafix-core/src/main/scala/scala/meta/internal/scalafix/ScalafixScalametaHacks.scala index 7ee42dc13..aa63eb59d 100644 --- a/scalafix-core/src/main/scala/scala/meta/internal/scalafix/ScalafixScalametaHacks.scala +++ b/scalafix-core/src/main/scala/scala/meta/internal/scalafix/ScalafixScalametaHacks.scala @@ -1,10 +1,7 @@ package scala.meta.internal.scalafix -import scala.meta.Tree import scala.meta.internal.semanticdb.Scala.Names -import scala.meta.internal.trees.Origin object ScalafixScalametaHacks { - def resetOrigin(tree: Tree): Tree = tree.withOrigin(Origin.None) def encode(name: String): String = Names.encode(name) } From 0816e76028760dbb593628fb1e5b808a60e590f7 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 11 Feb 2024 12:11:02 +0100 Subject: [PATCH 3/5] force usage of custom scalameta for mdoc Coursier seems to prefer mdoc's scalameta 4.8.15 over core2_13's scalameta 4.8.15+150-a7c0baa0-SNAPSHOT. Adding scalameta as a top-level docs2_13 libraryDependencies does change this behavior, so I suspect Coursier is following nearest-wins semantics for some reason, while we expect it to following latest-wins semantics. http://eed3si9n.com/dependency-resolver-semantics#coursiers-latest-wins-semantics By using dependencyOverrides, we ensure that docs run are generated with the actual scalameta version used in scalafix, rather than the one used in mdoc. --- build.sbt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2ea5da1b3..38122c9c7 100644 --- a/build.sbt +++ b/build.sbt @@ -383,7 +383,8 @@ lazy val docs = projectMatrix scalacOptions += "-Wconf:msg='match may not be exhaustive':s", // silence exhaustive pattern matching warning for documentation scalacOptions += "-Xfatal-warnings", mdoc := (Compile / run).evaluated, - libraryDependencies += metaconfigDoc + libraryDependencies += metaconfigDoc, + dependencyOverrides += scalameta // force eviction of mdoc transitive dependency ) .defaultAxes(VirtualAxis.jvm) .jvmPlatform(scalaVersions = Seq(scala213)) From e3709f55ea9167b948db2e9a65a1ac33263f5717 Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 11 Feb 2024 12:47:57 +0100 Subject: [PATCH 4/5] compatibility hack until mdoc#842 is released --- .../scala/meta/internal/prettyprinters/Enquote.scala | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 scalafix-docs/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala diff --git a/scalafix-docs/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala b/scalafix-docs/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala new file mode 100644 index 000000000..0c64c2247 --- /dev/null +++ b/scalafix-docs/src/main/scala/scala/meta/internal/prettyprinters/Enquote.scala @@ -0,0 +1,8 @@ +package scala.meta.internal.prettyprinters + +// compatibility hack until https://github.com/scalameta/mdoc/pull/842 is released +object enquote { + def apply(s: String, style: QuoteStyle): String = { + style(s) + } +} From 5f4ef49a64478e4a9855b8e54932fc90bdebe37b Mon Sep 17 00:00:00 2001 From: Brice Jaglin Date: Sun, 11 Feb 2024 19:23:18 +0100 Subject: [PATCH 5/5] preserve no-op behavior when passing trees built with quasiquotes Quasiquotes-generated trees have positions since scalameta#3450. Fixes: error: patch.md:168:1: token not found: Patch.removeImportee(importee"Future").showDiff() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ java.util.NoSuchElementException: token not found: at scalafix.util.TokenList.$anonfun$tok2idx$2(TokenList.scala:27) at scala.collection.immutable.Map$WithDefault.default(Map.scala:181) at scala.collection.MapOps.apply(Map.scala:176) at scala.collection.MapOps.apply$(Map.scala:175) at scala.collection.AbstractMap.apply(Map.scala:405) at scalafix.util.TokenList.leading(TokenList.scala:15) at scalafix.internal.patch.ImportPatchOps$.remove$1(ImportPatchOps.scala:229) --- .../scala/scalafix/internal/patch/ImportPatchOps.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scalafix-core/src/main/scala/scalafix/internal/patch/ImportPatchOps.scala b/scalafix-core/src/main/scala/scalafix/internal/patch/ImportPatchOps.scala index 55c8bd8b0..28000106c 100644 --- a/scalafix-core/src/main/scala/scalafix/internal/patch/ImportPatchOps.scala +++ b/scalafix-core/src/main/scala/scalafix/internal/patch/ImportPatchOps.scala @@ -4,6 +4,7 @@ import scala.annotation.tailrec import scala.collection.mutable import scala.meta._ +import scala.meta.trees.Origin import scalafix.XtensionOptionPatch import scalafix.XtensionSeqPatch @@ -200,7 +201,11 @@ object ImportPatchOps { allImports.filter(_.importers.forall(isRemovedImporter)) def remove(toRemove: Tree): Patch = { - if (toRemove.pos == Position.None) return Patch.empty + val isSameInput = (toRemove.origin, ctx.tree.origin) match { + case (a: Origin.Parsed, b: Origin.Parsed) => a.input == b.input + case _ => false + } + if (!isSameInput) return Patch.empty // Imagine "import a.b, c.d, e.f, g.h" where a.b, c.d and g.h are unused. // All unused imports are responible to delete their leading comma but // c.d is additionally responsible for deleting its trailling comma.