Skip to content

Commit

Permalink
Added ComparisonToEmptyList and ComparisonToEmptySet
Browse files Browse the repository at this point in the history
  • Loading branch information
t1b00 committed Sep 12, 2024
1 parent 97e3b59 commit 6842afb
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 1 deletion.
26 changes: 26 additions & 0 deletions input/src/main/scala/fix/ComparisonToEmptyList.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
rule = ComparisonToEmptyList
*/
package fix

object ComparisonToEmptyList {
val a = List(1, 2, 3)

val b = a == List() // assert: ComparisonToEmptyList
val c = List() == a // assert: ComparisonToEmptyList

val d = a == List.empty // assert: ComparisonToEmptyList
val e = List.empty == a // assert: ComparisonToEmptyList

val f = a == Nil // assert: ComparisonToEmptyList
val g = Nil == a // assert: ComparisonToEmptyList

val h = List.apply() == a // assert: ComparisonToEmptyList
val i = a == List.apply() // assert: ComparisonToEmptyList

val j = a == List(3, 4) // scalafix: ok;
val k = List(3, 4) == a // scalafix: ok;
val l = a != List(3, 4) // scalafix: ok;
val m = List(3, 4) != a // scalafix: ok;

}
22 changes: 22 additions & 0 deletions input/src/main/scala/fix/ComparisonToEmptySet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
rule = ComparisonToEmptySet
*/
package fix

object ComparisonToEmptySet {
val a = Set(1, 2, 3)

val b = a == Set() // assert: ComparisonToEmptySet
val c = Set() == a // assert: ComparisonToEmptySet

val d = a == Set.empty // assert: ComparisonToEmptySet
val e = Set.empty == a // assert: ComparisonToEmptySet

val h = Set.apply() == a // assert: ComparisonToEmptySet
val i = a == Set.apply() // assert: ComparisonToEmptySet

val j = a == Set(3, 4) // scalafix: ok;
val k = Set(3, 4) == a // scalafix: ok;
val l = a != Set(3, 4) // scalafix: ok;
val m = Set(3, 4) != a // scalafix: ok;
}
4 changes: 3 additions & 1 deletion rules/src/main/resources/META-INF/services/scalafix.v1.Rule
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ fix.BooleanParameter
fix.BoundedByFinalType
fix.BrokenOddness
fix.ClassNames
fix.CollectionNamingConfusion
fix.CollectionNamingConfusion
fix.ComparisonToEmptyList
fix.ComparisonToEmptySet
41 changes: 41 additions & 0 deletions rules/src/main/scala/fix/ComparisonToEmptyList.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
rule = ComparisonToEmptyList
*/
package fix

import scalafix.lint.LintSeverity
import scalafix.v1._

import scala.meta._

class ComparisonToEmptyList extends SemanticRule("ComparisonToEmptyList") {

private def diag(pos: Position) = Diagnostic(
"",
"Checks for code like `a == List()`, `a == Nil`, `a != List()` or `a != Nil`.",
pos,
"Prefer use of `isEmpty`, or `nonEmpty` instead of comparison to an empty List.",
LintSeverity.Info
)

override def fix(implicit doc: SemanticDocument): Patch = {

def isEmptyList(term: Term) = term match {
// List()
case Term.Apply.After_4_6_0(Term.Name("List"), Term.ArgClause(Nil, _)) => true
// List.apply()
case Term.Apply.After_4_6_0(Term.Select(Term.Name("List"), Term.Name("apply")), Term.ArgClause(Nil, _)) => true
// List.empty
case Term.Select(Term.Name("List"), Term.Name("empty")) => true
// Nil
case Term.Name("Nil") => true
case _ => false
}

doc.tree.collect {
// Corresponds to a == List() or List() == a, or any of the empty lists above. Also handles a != List() or List() != a, with the empty lists above too.
case Term.ApplyInfix.After_4_6_0(lhs, Term.Name("==" | "!="), _, Term.ArgClause(List(rhs), _)) if isEmptyList(lhs) || isEmptyList(rhs) => Patch.lint(diag(lhs.pos))
}.asPatch
}

}
39 changes: 39 additions & 0 deletions rules/src/main/scala/fix/ComparisonToEmptySet.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
rule = ComparisonToEmptySet
*/
package fix

import scalafix.lint.LintSeverity
import scalafix.v1._

import scala.meta._

class ComparisonToEmptySet extends SemanticRule("ComparisonToEmptySet") {

private def diag(pos: Position) = Diagnostic(
"",
"Checks for code like `a == Set()` or `a == Set.empty`.",
pos,
"Prefer use of `isEmpty` instead of comparison to an empty Set.",
LintSeverity.Info
)

override def fix(implicit doc: SemanticDocument): Patch = {

def isEmptySet(term: Term) = term match {
// Set()
case Term.Apply.After_4_6_0(Term.Name("Set"), Term.ArgClause(Nil, _)) => true
// Set.apply()
case Term.Apply.After_4_6_0(Term.Select(Term.Name("Set"), Term.Name("apply")), Term.ArgClause(Nil, _)) => true
// Set.empty
case Term.Select(Term.Name("Set"), Term.Name("empty")) => true
case _ => false
}

doc.tree.collect {
// Corresponds to a == Set() or Set() == a, or any of the empty sets above. Also handles a != Set() or Set() != a, with the empty sets above too.
case Term.ApplyInfix.After_4_6_0(lhs, Term.Name("==" | "!="), _, Term.ArgClause(List(rhs), _)) if isEmptySet(lhs) || isEmptySet(rhs) => Patch.lint(diag(lhs.pos))
}.asPatch
}

}

0 comments on commit 6842afb

Please sign in to comment.