-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rule.apply: List[Patch] #368
Comments
+1 to the overall design, having a single "action" that returns a rich data structure feels more natural. Now, for the bikeshedding:
|
I'm on this. |
I was thinking about this yesterday. That's great @MasseGuillaume! I think will make it easier to start treating the current fixes as lint rules too. For instance: |
Yup, we discovered something call CodeLens in lsp where you can attach an action such as remove import. This way you could just do it on one item. |
Absolutely, CodeLens is exactly what I was implying we'd use in the future :) |
Pending PR to fix this in #503 We went with a design that does not require any changes to the existing API. There is a new method To simplify the Rule API, I think we should consider deprecating
IntelliJ has this option to run all fixes of a given category in the open file. I use this quite frequently to fix things like repeated missing |
I found one counter example in RemoveXmlLiterals: ``` // scalafix-tests/input/src/main/scala/test/RemoveXmlLiteralsAtomic.scala /* rules = RemoveXmlLiterals */ package test class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } // scalafix-tests/output/src/main/scala/test/RemoveXmlLiteralsAtomic.scala package test import scala.xml.quote._ // <<< fail class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } ``` This happens because of: ```` if (patch.nonEmpty) patch + importXmlQuote else patch ``` At this point, patch is not empty but it will be removed subsequently by the escape hatch. The solution would be to add a `dependsOn` on Patch ``` case class DependsOn(parent: Patch, child: Patch) extends Patch class Patch { // ... def dependsOn(other: Patch): Patch = DependsOn(this, other) } object Patch { private def foreach // ... case DependsOn(parent, child) => loop(parent) loop(child) // ... } } class EscapeHatch { def filter // ... case DependsOn(parent, child) => val childs = loop(name, child) if (childs == EmptyPatch) EmptyPatch else loop(name, Concat(parent, childs)) } ```
I found one counter example in RemoveXmlLiterals: ``` // scalafix-tests/input/src/main/scala/test/RemoveXmlLiteralsAtomic.scala /* rules = RemoveXmlLiterals */ package test class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } // scalafix-tests/output/src/main/scala/test/RemoveXmlLiteralsAtomic.scala package test import scala.xml.quote._ // <<< fail class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } ``` This happens because of: ```` if (patch.nonEmpty) patch + importXmlQuote else patch ``` At this point, patch is not empty but it will be removed subsequently by the escape hatch. The solution would be to add a `dependsOn` on Patch ``` case class DependsOn(parent: Patch, child: Patch) extends Patch class Patch { // ... def dependsOn(other: Patch): Patch = DependsOn(this, other) } object Patch { private def foreach // ... case DependsOn(parent, child) => loop(parent) loop(child) // ... } } class EscapeHatch { def filter // ... case DependsOn(parent, child) => val childs = loop(name, child) if (childs == EmptyPatch) EmptyPatch else loop(name, Concat(parent, childs)) } ```
I found one counter example in RemoveXmlLiterals: ``` // scalafix-tests/input/src/main/scala/test/RemoveXmlLiteralsAtomic.scala /* rules = RemoveXmlLiterals */ package test class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } // scalafix-tests/output/src/main/scala/test/RemoveXmlLiteralsAtomic.scala package test import scala.xml.quote._ // <<< fail class RemoveXmlLiteralsAtomic { <div></div>// scalafix:ok RemoveXmlLiterals } ``` This happens because of: ```` if (patch.nonEmpty) patch + importXmlQuote else patch ``` At this point, patch is not empty but it will be removed subsequently by the escape hatch. The solution would be to add a `dependsOn` on Patch ``` case class DependsOn(parent: Patch, child: Patch) extends Patch class Patch { // ... def dependsOn(other: Patch): Patch = DependsOn(this, other) } object Patch { private def foreach // ... case DependsOn(parent, child) => loop(parent) loop(child) // ... } } class EscapeHatch { def filter // ... case DependsOn(parent, child) => val childs = loop(name, child) if (childs == EmptyPatch) EmptyPatch else loop(name, Concat(parent, childs)) } ```
Escape hatch on Patch (fix #368)
``` > scalafix --diff-base <tab> HEAD ag/gh-pages ag/issue-260 ag/issue-319 ag/master ... v0.5.5 v0.5.6 |00| 51abefa -- wip improve sbt completion (13 hours ago) |01| 3f63b5b -- Merge pull request scalacenter#474 from marcelocenerine/trim_includeNewLine (13 hours ago) |02| 47b94c0 -- Add leadingSpaces/trailingSpaces methods to TokenList (13 hours ago) |03| 8bd026d -- Merge pull request scalacenter#503 from MasseGuillaume/feature/368-escape-patches (13 hours ago) |04| 20e445f -- Escape hatch on Patch (fix scalacenter#368) (13 hours ago) |05| a2c5d70 -- Merge pull request scalacenter#500 from MasseGuillaume/feature/495-custom-id (13 hours ago) |06| 59efe7d -- Add CustomMessage to the public api (13 hours ago) |07| 9ae6071 -- Add id for CustomMessage (fix scalacenter#495) (13 hours ago) |08| e4a5c35 -- Merge pull request scalacenter#494 from MasseGuillaume/disable-regex (13 hours ago) |09| a422860 -- Merge pull request scalacenter#497 from olafurpg/disable-signatures (13 hours ago) |10| 7930947 -- DisableSyntax add regex (13 hours ago) |11| 5dbdd6b -- IntervalSet test for empty and add toString (13 hours ago) |12| b022fbd -- DisableSyntax don't repeat DisableSyntax.keyword in message (13 hours ago) |13| a992b02 -- Assert instead of scalafix:ok (13 hours ago) |14| 7896ccd -- Refactor Disable to use views. (13 hours ago) |15| 58acdbe -- Fix scalacenter#493, handle synthetics and symbol signatures in Disable. (13 hours ago) |16| b48d7f0 -- Merge pull request scalacenter#490 from olafurpg/unmanagedSources (13 hours ago) |17| e9b2b0a -- s/canFormat/canFix/ (13 hours ago) |18| 26be6fa -- Use unmanagedSources instead of unmanagedSourceDirectories. (13 hours ago) |19| 4d46001 -- Merge pull request scalacenter#488 from olafurpg/master (13 hours ago) ```
``` > scalafix --diff-base <tab> HEAD ag/gh-pages ag/issue-260 ag/issue-319 ag/master ... v0.5.5 v0.5.6 |00| 51abefa -- wip improve sbt completion (13 hours ago) |01| 3f63b5b -- Merge pull request scalacenter#474 from marcelocenerine/trim_includeNewLine (13 hours ago) |02| 47b94c0 -- Add leadingSpaces/trailingSpaces methods to TokenList (13 hours ago) |03| 8bd026d -- Merge pull request scalacenter#503 from MasseGuillaume/feature/368-escape-patches (13 hours ago) |04| 20e445f -- Escape hatch on Patch (fix scalacenter#368) (13 hours ago) |05| a2c5d70 -- Merge pull request scalacenter#500 from MasseGuillaume/feature/495-custom-id (13 hours ago) |06| 59efe7d -- Add CustomMessage to the public api (13 hours ago) |07| 9ae6071 -- Add id for CustomMessage (fix scalacenter#495) (13 hours ago) |08| e4a5c35 -- Merge pull request scalacenter#494 from MasseGuillaume/disable-regex (13 hours ago) |09| a422860 -- Merge pull request scalacenter#497 from olafurpg/disable-signatures (13 hours ago) |10| 7930947 -- DisableSyntax add regex (13 hours ago) |11| 5dbdd6b -- IntervalSet test for empty and add toString (13 hours ago) |12| b022fbd -- DisableSyntax don't repeat DisableSyntax.keyword in message (13 hours ago) |13| a992b02 -- Assert instead of scalafix:ok (13 hours ago) |14| 7896ccd -- Refactor Disable to use views. (13 hours ago) |15| 58acdbe -- Fix scalacenter#493, handle synthetics and symbol signatures in Disable. (13 hours ago) |16| b48d7f0 -- Merge pull request scalacenter#490 from olafurpg/unmanagedSources (13 hours ago) |17| e9b2b0a -- s/canFormat/canFix/ (13 hours ago) |18| 26be6fa -- Use unmanagedSources instead of unmanagedSourceDirectories. (13 hours ago) |19| 4d46001 -- Merge pull request scalacenter#488 from olafurpg/master (13 hours ago) ```
Following a conversation with @xeno-by from his experience with the scalafix api. This is a proposal to replace
Rule.fix/check
with a single methodRule.apply(ctx: RuleCtx): List[Fix]
where (roughly)This change addresses several problems with the current design
Patch
can contain a sequence ofctx.addLeft/addRight/remove
edits that need atomically trigger or not. See example below, ifBaz
is inserted insidefoo(...)
along with an import at the top of a file, then that import should not be inserted since scalafix is disabled aroundfoo(...)
..asPatch
in most cases.I think it's possible to introduce this change while keeping compatibility with the current design, and we deprecate
Rule.fix/check
.The text was updated successfully, but these errors were encountered: