Skip to content

Commit

Permalink
Ylint to warn strict else warn multiple boolean lits
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Feb 28, 2024
1 parent fa3b77b commit 5b7820d
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
* -Y "Private" settings
*/
val Yhelp = BooleanSetting ("-Y", "Print a synopsis of private options.")
val Ylint = BooleanSetting ("-Ylint", "Use strict lints.")
val breakCycles = BooleanSetting ("-Ybreak-cycles", "Attempt to break cycles encountered during typing")
val check = PhasesSetting ("-Ycheck", "Check the tree at the end of")
val Ycompacttrees = BooleanSetting ("-Ycompact-trees", "Use compact tree printer when displaying trees.")
Expand Down
21 changes: 14 additions & 7 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,7 @@ abstract class RefChecks extends Transform {
def applyDepth: Int = {
def loop(t: Tree, d: Int): Int =
t match {
case Apply(f, _) => loop(f, d+1)
case Apply(t, _) => loop(t, d+1)
case _ => d
}
loop(fn, 0)
Expand All @@ -1736,13 +1736,20 @@ abstract class RefChecks extends Transform {
}
if (settings.lintNamedBooleans && !sym.isJavaDefined && !args.isEmpty) {
val params = sym.paramLists(applyDepth)
if (!isAssertParadigm(params))
foreach2(args, params)((arg, param) => arg match {
case Literal(Constant(_: Boolean))
if arg.hasAttachment[UnnamedArg.type] && param.tpe.typeSymbol == BooleanClass && !param.deprecatedParamName.contains(nme.NO_NAME) =>
if (!settings.Ylint.value || !isAssertParadigm(params)) {
val suspicious = args.lazyZip(params).iterator
.filter {
case (arg @ Literal(Constant(_: Boolean)) , param) =>
arg.hasAttachment[UnnamedArg.type] && param.tpe.typeSymbol == BooleanClass && !param.deprecatedParamName.contains(nme.NO_NAME)
case _ => false
}
.toList
val warn = if (settings.Ylint.value) suspicious.nonEmpty else suspicious.lengthCompare(2) >= 0
if (warn)
suspicious.foreach { case (arg, param) =>
runReporting.warning(arg.pos, s"Boolean literals should be passed using named argument syntax for parameter ${param.name}.", WarningCategory.LintNamedBooleans, sym)
case _ =>
})
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/named-booleans.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// scalac: -Werror -Xlint:named-booleans
//> using options -Werror -Xlint:named-booleans -Ylint

class C {
def f(n: Int = 42, x: Boolean, y: Boolean) = if (x && y) n else 0
Expand Down

0 comments on commit 5b7820d

Please sign in to comment.