scalafix
scalafix copied to clipboard
scalameta 4.9.x
https://github.com/scalameta/scalameta/releases/tag/v4.9.0
https://github.com/scalameta/scalameta/issues/3425 is a non-backward compatible feature, as quasiquotes expand to code referencing scala.meta.trees.Origin which does not exist in 4.8.x.
This means that Scalafix rules containing quasiquotes compiled against scalameta 4.9.x will cause link errors if ran on older Scalafix versions. As a result, we need a minor Scalafix bump when taking that in, despite the fact that it's "just" a minor bump in a SemVer lib (we could argue that a major bump of scalameta was needed, but backward compatibility guarantees with macros is not very well defined).
6d8b555147fdab3d001fc24411dabb237bde6512 causes core compilation to succeed, but docs2_13 to fail
[error] Caused by: java.lang.ClassNotFoundException: scala.meta.trees.Origin
That's because for some reason, coursier prefers 4.8.15 over 4.8.15+150-a7c0baa0-SNAPSHOT there:
sbt:scalafix> show docs2_13/evicted
...
[info] * org.scalameta:scalameta_2.13:4.8.15 is selected over {4.8.15+150-a7c0baa0-SNAPSHOT, 4.8.15+150-a7c0baa0-SNAPSHOT, 4.8.15+150-a7c0baa0-SNAPSHOT, 4.8.15+150-a7c0baa0-SNAPSHOT
[info] +- org.scalameta:mdoc_2.13:2.5.2 (depends on 4.8.15)
[info] +- org.scalameta:mdoc-cli_2.13:2.5.2 (depends on 4.8.15)
[info] +- org.scalameta:semanticdb-scalac-core_2.13.12:4.8.15+150-a7c0baa0-SNAPSHOT (depends on 4.8.15+150-a7c0baa0-SNAPSHOT)
[info] +- ch.epfl.scala:scalafix-core_2.13:0.11.1+108-789b602c-SNAPSHOT (depends on 4.8.15+150-a7c0baa0-SNAPSHOT)
Adding scalameta at the root does affect resolution, so it looks like Coursier is following nearest-win instead of latest-win (despite what's expected).
lazy val docs = projectMatrix
.in(file("scalafix-docs"))
.settings(
+ libraryDependencies += scalameta,
sbt:scalafix> show docs2_13/evicted
...
[info] * org.scalameta:scalameta_2.13:4.8.15+150-a7c0baa0-SNAPSHOT is selected over {4.8.15, 4.8.15}
[info] +- ch.epfl.scala:scalafix-docs_2.13:0.11.1+108-789b602c+20240211-1152-SNAPSHOT (depends on 4.8.15+150-a7c0baa0-SNAPSHOT)
[info] +- ch.epfl.scala:scalafix-core_2.13:0.11.1+108-789b602c+20240211-1152-SNAPSHOT (depends on 4.8.15+150-a7c0baa0-SNAPSHOT)
[info] +- org.scalameta:semanticdb-scalac-core_2.13.12:4.8.15+150-a7c0baa0-SNAPSHOT (depends on 4.8.15+150-a7c0baa0-SNAPSHOT)
[info] +- org.scalameta:mdoc_2.13:2.5.2 (depends on 4.8.15)
[info] +- org.scalameta:mdoc-cli_2.13:2.5.2 (depends on 4.8.15)
Forcing eviction via ea2e835ecdb817268bc963a4093d7913daed8498
ea2e835ecdb817268bc963a4093d7913daed8498 exposes an incompatibility between mdoc and the latest scalameta SNAPSHOT
[error] Caused by: java.lang.ClassNotFoundException: scala.meta.internal.prettyprinters.enquote$
Following-up in https://github.com/scalameta/mdoc/pull/842
[info] warning: patch.md:168:22: local val dialectOnly$macro$4 in value qual$12 is never used
[info] Patch.removeImportee(importee"Future").showDiff()
[info] ^^^^^^^^
Following-up in https://github.com/scalameta/scalameta/issues/3546
[info] error: patch.md:168:1: token not found:
[info] Patch.removeImportee(importee"Future").showDiff()
[info] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[info] java.util.NoSuchElementException: token not found:
[info] at scalafix.util.TokenList.$anonfun$tok2idx$2(TokenList.scala:27)
[info] at scala.collection.immutable.Map$WithDefault.default(Map.scala:181)
[info] at scala.collection.MapOps.apply(Map.scala:176)
[info] at scala.collection.MapOps.apply$(Map.scala:175)
[info] at scala.collection.AbstractMap.apply(Map.scala:405)
[info] at scalafix.util.TokenList.leading(TokenList.scala:15)
[info] at scalafix.internal.patch.ImportPatchOps$.remove$1(ImportPatchOps.scala:229)
[info] at scalafix.internal.patch.ImportPatchOps$.$anonfun$superNaiveImportPatchToTokenPatchConverter$34(ImportPatchOps.scala:264)
[info] at scala.collection.StrictOptimizedIterableOps.map(StrictOptimizedIterableOps.scala:100)
[info] at scala.collection.StrictOptimizedIterableOps.map$(StrictOptimizedIterableOps.scala:87)
[info] at scala.collection.mutable.LinkedHashSet.map(LinkedHashSet.scala:34)
[info] at scalafix.internal.patch.ImportPatchOps$.superNaiveImportPatchToTokenPatchConverter(ImportPatchOps.scala:264)
[info] at scalafix.internal.patch.PatchInternals$.treePatchApply(PatchInternals.scala:118)
https://github.com/scalacenter/scalafix/blob/61dce03ff6f6513e0b275dba72a935615099b2f4/scalafix-core/src/main/scala/scalafix/internal/patch/ImportPatchOps.scala#L203 brings false negatives for quasiquotes-built trees since https://github.com/scalameta/scalameta/pull/3450, resulting in an exception instead of the documented no-op.
Another similar guard is impacted, although it causes a slight regression that might not be worth fixing: https://github.com/scalacenter/scalafix/blob/61dce03ff6f6513e0b275dba72a935615099b2f4/scalafix-core/src/main/scala/scalafix/patch/Patch.scala#L103
Patch.replaceTree(q"foo", "bar")is no-longer a no-op as the early-return no longer applies now that quasiquotes generate trees with positions- It is now the same as
Patch.addLeft(q"foo", "bar")orPatch.addLeft(Term.Name("foo"), "bar")(unchanged behavior for them): it adds a leading string to any tree, as the BOF token has the same hash no matter the origin, causing a false positive
- It is now the same as
Patch.replaceTree(Term.Name("foo"), "bar")remains a no-op thanks to the early-return