Skip to content

Commit

Permalink
Merge pull request scala#10797 from som-snytt/issue/8761-missing-inte…
Browse files Browse the repository at this point in the history
…rp-dollar

Better split for missing-interpolator
  • Loading branch information
lrytz authored Jun 25, 2024
2 parents 2c9b786 + 030255e commit 9e80aa3
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 102 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ trait Scanners extends ScannersCommon {
case COMMA => "','"
case CASECLASS => "case class"
case CASEOBJECT => "case object"
case XMLSTART => "$XMLSTART$<"
case XMLSTART => s"$$XMLSTART$$<"
case _ =>
(token2name get token) match {
case Some(name) => "'" + name + "'"
Expand Down
9 changes: 6 additions & 3 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
private final val SYNTHETIC_PRIVATE = TRANS_FLAG

private final val InterpolatorCodeRegex = """\$\{\s*(.*?)\s*\}""".r
private final val InterpolatorIdentRegex = """\$[$\w]+""".r // note that \w doesn't include $
private final val InterpolatorIdentRegex = """\$[\w]+""".r // note that \w doesn't include $

/** Check that type of given tree does not contain local or private
* components.
Expand Down Expand Up @@ -6101,8 +6101,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// short-circuit on leading ${}
if (!exprs.head.isEmpty && exprs.exists(warnableExpr))
warn("detected an interpolated expression") // "${...}"
} else
suspiciousIdents.find(id => isPlausible(id.substring(1))).foreach(id => warn(s"detected interpolated identifier `$id`"))
} else suspiciousIdents.toList match {
case Nil =>
case id :: Nil => if (isPlausible(id.substring(1))) warn(s"detected interpolated identifier `$id`")
case all => if (all.forall(id => isPlausible(id.substring(1)))) warn(all.mkString("detected interpolated identifiers `", "`, `", "`"))
}
}
lit match {
case Literal(Constant(s: String)) if mightBeMissingInterpolation => maybeWarn(s)
Expand Down
46 changes: 44 additions & 2 deletions test/files/neg/forgot-interpolator.check
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
forgot-interpolator.scala:6: warning: possible missing interpolator: detected interpolated identifier `$bippy`
forgot-interpolator.scala:6: warning: possible missing interpolator: detected interpolated identifiers `$bippy`, `$bippy`
def f = "Put the $bippy in the $bippy!" // warn 1
^
forgot-interpolator.scala:16: warning: possible missing interpolator: detected an interpolated expression
Expand All @@ -25,6 +25,48 @@ forgot-interpolator.scala:92: warning: possible missing interpolator: detected i
forgot-interpolator.scala:126: warning: possible missing interpolator: detected an interpolated expression
@deprecated("${myProperty}")
^
forgot-interpolator.scala:144: warning: possible missing interpolator: detected interpolated identifier `$foo`
"An important $foo message!" // warn on ident in scope
^
forgot-interpolator.scala:148: warning: possible missing interpolator: detected an interpolated expression
"A doubly important ${foo * 2} message!" // warn on some expr, see below
^
forgot-interpolator.scala:151: warning: possible missing interpolator: detected interpolated identifier `$bar`
def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test
^
forgot-interpolator.scala:152: warning: possible missing interpolator: detected interpolated identifier `$bar`
def j = s"Try using '${ "something like $bar" }' instead." // warn
^
forgot-interpolator.scala:158: warning: possible missing interpolator: detected an interpolated expression
def v = "${baz}${bar}" // warn on second expr
^
forgot-interpolator.scala:159: warning: possible missing interpolator: detected an interpolated expression
def w = "${ op_* }" // warn, only cheap ident parsing
^
forgot-interpolator.scala:160: warning: possible missing interpolator: detected an interpolated expression
def x = "${ bar }" // warn, a cheap ident in scope
^
forgot-interpolator.scala:162: warning: possible missing interpolator: detected an interpolated expression
def z = "${ baz * 3}" // warn, no expr parsing
^
forgot-interpolator.scala:164: warning: possible missing interpolator: detected interpolated identifier `$this`
def thisly = "$this"
^
forgot-interpolator.scala:165: warning: possible missing interpolator: detected an interpolated expression
def exprly = "${this}"
^
forgot-interpolator.scala:170: warning: possible missing interpolator: detected interpolated identifier `$s`
val t = "$s"
^
forgot-interpolator.scala:171: warning: possible missing interpolator: detected an interpolated expression
val u = "a${s}b"
^
forgot-interpolator.scala:172: warning: possible missing interpolator: detected interpolated identifier `$s`
val v = "a$s b"
^
forgot-interpolator.scala:177: warning: possible missing interpolator: detected interpolated identifiers `$foo`, `$bar`
def s = "$foo$bar"
^
error: No warnings can be incurred under -Werror.
9 warnings
23 warnings
1 error
50 changes: 50 additions & 0 deletions test/files/neg/forgot-interpolator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,53 @@ object t10456 {
@deprecated("${myProperty}")
var myProperty: String = _
}

package pancake { }

object Tester {
type NonVal = Int

def ok = "Don't warn on $nosymbol interpolated."

def pass = "Don't warn on $pancake package names."

def types = "Or $NonVal type symbols either."

def bar = "bar"
def f = {
val foo = "bar"
"An important $foo message!" // warn on ident in scope
}
def g = {
val foo = "bar"
"A doubly important ${foo * 2} message!" // warn on some expr, see below
}
def h = s"Try using '$$bar' instead." // no warn
def i = s"Try using '${ "$bar" }' instead." // was: no warn on space test
def j = s"Try using '${ "something like $bar" }' instead." // warn
def k = f"Try using '$bar' instead." // no warn on other std interps
def p = "Template ${} {}" // no warn on unlikely or empty expressions
def q = "${}$bar" // disables subsequent checks! (a feature)
def r = "${}${bar}" // disables subsequent checks! (a feature)

def v = "${baz}${bar}" // warn on second expr
def w = "${ op_* }" // warn, only cheap ident parsing
def x = "${ bar }" // warn, a cheap ident in scope
def y = "${ baz }" // no warn, cheap ident not in scope
def z = "${ baz * 3}" // warn, no expr parsing

def thisly = "$this"
def exprly = "${this}"
}

trait X {
val s = "hello"
val t = "$s"
val u = "a${s}b"
val v = "a$s b"
}

trait DollarDollar {
val foo, bar = 42
def s = "$foo$bar"
}
33 changes: 0 additions & 33 deletions test/files/neg/t7848-interp-warn.check

This file was deleted.

42 changes: 0 additions & 42 deletions test/files/neg/t7848-interp-warn.scala

This file was deleted.

12 changes: 0 additions & 12 deletions test/files/neg/t9127.check

This file was deleted.

9 changes: 0 additions & 9 deletions test/files/neg/t9127.scala

This file was deleted.

0 comments on commit 9e80aa3

Please sign in to comment.