-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added BigDecimalScaleWithoutRoundingMode and BooleanParameter
Improved documentation in BigDecimalDoubleConstructor
- Loading branch information
Showing
6 changed files
with
122 additions
and
2 deletions.
There are no files selected for viewing
23 changes: 23 additions & 0 deletions
23
input/src/main/scala/fix/BigDecimalScaleWithoutRoundingMode.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
rule = BigDecimalScaleWithoutRoundingMode | ||
*/ | ||
package fix | ||
|
||
import scala.math.BigDecimal.RoundingMode | ||
|
||
object BigDecimalScaleWithoutRoundingMode { | ||
def test(): Unit = { | ||
val b = BigDecimal(10) | ||
b.setScale(2) // assert: BigDecimalScaleWithoutRoundingMode | ||
BigDecimal(10).setScale(2) // assert: BigDecimalScaleWithoutRoundingMode | ||
|
||
val b1 = new java.math.BigDecimal(2) | ||
b1.setScale(2) // assert: BigDecimalScaleWithoutRoundingMode | ||
new java.math.BigDecimal(2).setScale(2) // assert: BigDecimalScaleWithoutRoundingMode | ||
|
||
b.setScale(2, RoundingMode.UP) // scalafix: ok; | ||
BigDecimal(10).setScale(2, RoundingMode.DOWN) // scalafix: ok; | ||
new java.math.BigDecimal(2).setScale(2, RoundingMode.FLOOR) // scalafix: ok; | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
rule = BooleanParameter | ||
*/ | ||
package fix | ||
|
||
object BooleanParameter { | ||
def foo(bool: Boolean) = 4 // assert: BooleanParameter | ||
|
||
def foo2(value: Int)(bool: Boolean) = 4 // assert: BooleanParameter | ||
|
||
def foo3(value: Int) = 4 // scalafix: ok; | ||
def foo3(value: Int)(dob: Double) = 4 // scalafix: ok; | ||
|
||
final case class Test(bool: Boolean) // scalafix: ok; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
rules/src/main/scala/fix/BigDecimalScaleWithoutRoundingMode.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
rule = BigDecimalScaleWithoutRoundingMode | ||
*/ | ||
package fix | ||
|
||
import scalafix.lint.LintSeverity | ||
import scalafix.v1._ | ||
|
||
import scala.meta._ | ||
|
||
class BigDecimalScaleWithoutRoundingMode extends SemanticRule("BigDecimalScaleWithoutRoundingMode") { | ||
|
||
private def diag(pos: Position) = Diagnostic( | ||
"", | ||
"Checks for use of 'setScale()' on a BigDecimal without setting the rounding mode can throw an exception.", | ||
pos, | ||
"When using 'setScale()' on a BigDecimal without setting the rounding mode, this can throw an exception if rounding is required. Did you mean to call 'setScale(s, RoundingMode.XYZ)'?", | ||
LintSeverity.Warning | ||
) | ||
|
||
override def fix(implicit doc: SemanticDocument): Patch = { | ||
|
||
def isBigDecimal(arg: Stat) = Util.matchType(arg, "scala/math/BigDecimal") || Util.matchType(arg, "java/math/BigDecimal") | ||
|
||
doc.tree.collect { | ||
// Corresponds to b.setScale(2) where b is a BigDecimal or BigDecimal(2).setScale(2), i.e. there is only one argument passed. | ||
// Also corresponds to new java.math.BigDecimal(2).setScale(2) or b.setScale(2) where b is a java.math.BigDecimal | ||
case t @ Term.Apply.After_4_6_0(Term.Select(_, Term.Name("setScale")), Term.ArgClause(List(_), _)) if isBigDecimal(t) => Patch.lint(diag(t.pos)) | ||
}.asPatch | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
rule = BooleanParameter | ||
*/ | ||
package fix | ||
|
||
import scalafix.lint.LintSeverity | ||
import scalafix.v1._ | ||
|
||
import scala.meta._ | ||
|
||
class BooleanParameter extends SemanticRule("BooleanParameter") { | ||
|
||
private def diag(pos: Position) = Diagnostic( | ||
"", | ||
"Checks for functions that have a Boolean parameter.", | ||
pos, | ||
"Method has Boolean parameter. Consider splitting into two methods or using a case class.", | ||
LintSeverity.Warning | ||
) | ||
|
||
override def fix(implicit doc: SemanticDocument): Patch = { | ||
|
||
def shouldBeIgnored(mods: List[Mod]) = mods.exists { | ||
case Mod.Override() => true | ||
case Mod.Annot(Init.After_4_6_0(Type.Name("getter" | "setter"), _, _)) => true | ||
case Mod.Abstract() => true | ||
case _ => false | ||
} | ||
|
||
def hasBooleanParameter(paramClauseGroups: List[Member.ParamClauseGroup]) = paramClauseGroups.exists { | ||
case Member.ParamClauseGroup(_, paramClauses) => paramClauses.exists { | ||
case Term.ParamClause(params, _) => params.exists { | ||
case Term.Param(_, _, Some(Type.Name("Boolean")), _) => true | ||
case _ => false | ||
} | ||
case _ => false | ||
} | ||
case _ => false | ||
} | ||
|
||
doc.tree.collect { | ||
// Corresponds to def foo(..., bool: Boolean, ...) where ... is a list of parameters (possibly empty). Also handles function with multiple param clauses | ||
case d @ Defn.Def.After_4_7_3(mods, _, paramClauseGroups, _, _) if !shouldBeIgnored(mods) && hasBooleanParameter(paramClauseGroups) => Patch.lint(diag(d.pos)) | ||
}.asPatch | ||
} | ||
|
||
} |