-
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
Escape hatch on Patch (fix #368) #503
Escape hatch on Patch (fix #368) #503
Conversation
} | ||
|
||
////////////////////////////// | ||
// Low-level patches | ||
////////////////////////////// | ||
trait LowLevelPatch | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this fucks up sublime syntax highlighting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awww, maybe get a better editor 😜
32b0e5c
to
ad04c99
Compare
|
||
import scala.collection.immutable // scalafix:ok RemoveUnusedImports | ||
|
||
import scala.collection.mutable.{ // scalafix:ok RemoveUnusedImports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@olafurpg we expected this to fail. It looks like it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's likely because removing Map
or Set
independently removes the {
which is escaped. If the comment only applies to import scala
I suspect it won't work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good then, it makes it really difficult to fall on the non-supported case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation looks great, only left a few minor comments otherwise I think this is good to merge 💯
|
||
import scala.collection.immutable // scalafix:ok RemoveUnusedImports | ||
|
||
import scala.collection.mutable.{ // scalafix:ok RemoveUnusedImports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's likely because removing Map
or Set
independently removes the {
which is escaped. If the comment only applies to import scala
I suspect it won't work
@@ -28,6 +28,6 @@ case class RemoveUnusedImports(index: SemanticdbIndex) | |||
} | |||
override def fix(ctx: RuleCtx): Patch = | |||
ctx.tree.collect { | |||
case i: Importee if isUnused(i) => ctx.removeImportee(i) | |||
case i: Importee if isUnused(i) => ctx.removeImportee(i).atomic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any other scalafix rules that could benefit from .atomic
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this is what I am doing right now. I'm making sure all the Scalafix rules uses atomic.
@@ -48,12 +48,14 @@ sealed abstract class Patch { | |||
def ++(other: Iterable[Patch]): Patch = other.foldLeft(this)(_ + _) | |||
def isEmpty: Boolean = this == EmptyPatch | |||
def nonEmpty: Boolean = !isEmpty | |||
def atomic: Patch = AtomicPatch(this) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add docstring. The other methods have no docstring since I think they're quite self explanatory but atomic is not as obvious
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will write user documentation with examples and limitation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should still have a docstring despite docs on the website, a single sentence like
Skip this entire patch if a part of it is disabled with
// scalafix:off
will do.
ded5ddf
to
4feb337
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking forward to the docs!
val result = compareContents(obtained, expected) | ||
if (result.nonEmpty) { | ||
println("###########> Diff <###########") | ||
println(error2message(obtained, expected)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the motivation for this change to copy-paste the terminal output? If so, we should include the filename since println is detached from the scalatest failure report.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no it's because it was failing too early with the unreported lint message. I want to see both the lint asserts and the diff for the fix.
@@ -123,7 +123,6 @@ case object RemoveXmlLiterals extends Rule("RemoveXmlLiterals") { | |||
patchXml(xml, tripleQuoted).atomic | |||
}.asPatch | |||
|
|||
if (patch.nonEmpty) (patch + importXmlQuote) | |||
else patch | |||
importXmlQuote.dependsOn(patch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@olafurpg what do you think about this?
I just added atomics for other rules like |
Ready for round 2. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dependsOn is unrelated to atomic, can you please open an issue or separate pr?
9d8f66e
to
30037d1
Compare
Ready for round 3. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see .atomic
work for the existing rules!
@@ -40,6 +40,7 @@ case class RemoveUnusedTerms(index: SemanticdbIndex) | |||
override def fix(ctx: RuleCtx): Patch = | |||
ctx.tree.collect { | |||
case i: Defn if isUnused(i) => | |||
tokensToRemove(i).fold(Patch.empty)(ctx.removeTokens) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could have added .atomic
on the whole thing 😉
}.asPatch | ||
|
||
// NB if all patches are not yet escaped here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -48,12 +48,14 @@ sealed abstract class Patch { | |||
def ++(other: Iterable[Patch]): Patch = other.foldLeft(this)(_ + _) | |||
def isEmpty: Boolean = this == EmptyPatch | |||
def nonEmpty: Boolean = !isEmpty | |||
def atomic: Patch = AtomicPatch(this) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should still have a docstring despite docs on the website, a single sentence like
Skip this entire patch if a part of it is disabled with
// scalafix:off
will do.
@@ -42,6 +42,9 @@ utility methods to accomplish common tasks. | |||
If you experience that it's difficult to implement something that | |||
seems simple then don't hesitate to ask on {% gitter %}. | |||
|
|||
It's possible to escape parts of the Patch with `// scalafix:ok`. If you want to treat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/the/a/
@@ -42,6 +42,9 @@ utility methods to accomplish common tasks. | |||
If you experience that it's difficult to implement something that | |||
seems simple then don't hesitate to ask on {% gitter %}. | |||
|
|||
It's possible to escape parts of the Patch with `// scalafix:ok`. If you want to treat | |||
the Patch as a transaction use `.atomic`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/the/a/
a5e9596
to
4726fcd
Compare
Ready for round 4. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍 Awesome work @MasseGuillaume 💯
@@ -48,12 +48,16 @@ sealed abstract class Patch { | |||
def ++(other: Iterable[Patch]): Patch = other.foldLeft(this)(_ + _) | |||
def isEmpty: Boolean = this == EmptyPatch | |||
def nonEmpty: Boolean = !isEmpty | |||
/** Skip this entire patch if a part of it is disabled with // scalafix:off |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick, single line docstrings should be /** Blah blah */
, I should make scalafmt enforce this 😅
This is so cool! 🎉 Thank you @MasseGuillaume, looking forward to use it! |
4726fcd
to
64b94b3
Compare
@gabro hehe, don't forget to set |
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)) } ```
64b94b3
to
20e445f
Compare
``` > 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) ```
This is a really raw first pass.