diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 31 | ||||
-rw-r--r-- | test/files/neg/forgot-interpolator.check | 17 | ||||
-rw-r--r-- | test/files/neg/forgot-interpolator.scala | 32 |
3 files changed, 66 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 88b9b2c71c..3343ee2bcc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4876,25 +4876,30 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case Apply(fn, _) => fn.symbol.enclClass == ImplicitNotFoundClass case _ => false } + def warnAbout(s: String) = { + def names = InterpolatorIdentRegex findAllIn s map (n => TermName(n stripPrefix "$")) + def isSuspiciousExpr = (InterpolatorCodeRegex findFirstIn s).nonEmpty + //def isSuspiciousName = names exists (lookUp _ andThen (_.exists)) + def suspiciousName = names find (lookUp _ andThen (_.exists)) + def lookUp(n: TermName) = context.lookupSymbol(n, !_.alternatives.exists(symRequiresArg)).symbol + def symRequiresArg(s: Symbol) = ( + s.paramss.nonEmpty + && (s.paramss.head.headOption filterNot (_.isImplicit)).isDefined + ) + val suggest = "Did you forget the interpolator?" + if (isSuspiciousExpr) + unit.warning(tree.pos, s"That looks like an interpolated expression! $suggest") + else /* if (isSuspiciousName) */ suspiciousName foreach (n => + unit.warning(tree.pos, s"`$$$n` looks like an interpolated identifier! $suggest") + ) + } tree.value match { case Constant(s: String) => - def names = InterpolatorIdentRegex findAllIn s map (n => TermName(n stripPrefix "$")) - def isSuspiciousExpr = (InterpolatorCodeRegex findFirstIn s).nonEmpty - //def isSuspiciousName = names exists symExists - def suspiciousName = names find symExists - def symExists(n: TermName) = context.lookupSymbol(n, _ => true).symbol.exists val noWarn = ( isArgToImplicitNotFound || !(s contains ' ') // another heuristic - e.g. a string with only "$asInstanceOf" ) - if (!noWarn) { - val suggest = "Did you forget the interpolator?" - if (isSuspiciousExpr) - unit.warning(tree.pos, s"That looks like an interpolated expression! $suggest") - else /* if (isSuspiciousName) */ suspiciousName foreach (n => - unit.warning(tree.pos, s"`$$$n` looks like an interpolated identifier! $suggest") - ) - } + if (!noWarn) warnAbout(s) case _ => } } diff --git a/test/files/neg/forgot-interpolator.check b/test/files/neg/forgot-interpolator.check index 1aad3b0003..a96431841f 100644 --- a/test/files/neg/forgot-interpolator.check +++ b/test/files/neg/forgot-interpolator.check @@ -4,6 +4,21 @@ forgot-interpolator.scala:4: warning: `$bippy` looks like an interpolated identi forgot-interpolator.scala:14: warning: That looks like an interpolated expression! Did you forget the interpolator? def f = """Put the ${println("bippy")} in the bippy!""" // warn ^ +forgot-interpolator.scala:30: warning: `$beppo` looks like an interpolated identifier! Did you forget the interpolator? + def f = "$beppo was a marx bros who saw dollars." // warn + ^ +forgot-interpolator.scala:34: warning: `$aleppo` looks like an interpolated identifier! Did you forget the interpolator? + def f = "$aleppo is a pepper and a city." // warn + ^ +forgot-interpolator.scala:40: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator? + def f = "$bar is private, shall we warn just in case?" // warn + ^ +forgot-interpolator.scala:45: warning: `$hippo` looks like an interpolated identifier! Did you forget the interpolator? + def h = "$hippo takes an implicit" // warn + ^ +forgot-interpolator.scala:37: warning: private method in class Bar is never used + private def bar = 8 + ^ error: No warnings can be incurred under -Xfatal-warnings. -two warnings found +7 warnings found one error found diff --git a/test/files/neg/forgot-interpolator.scala b/test/files/neg/forgot-interpolator.scala index d67db82643..5067f1dce9 100644 --- a/test/files/neg/forgot-interpolator.scala +++ b/test/files/neg/forgot-interpolator.scala @@ -13,3 +13,35 @@ class B { class C { def f = """Put the ${println("bippy")} in the bippy!""" // warn } + +package object test { + def aleppo = 9 + def greppo(n: Int) = ??? + def zappos(n: Int)(implicit ord: math.Ordering[Int]) = ??? + def hippo(implicit n: Int) = ??? +} + +package test { + // not sure if overloading is kosher in pkg obj yet + class Doo { + def beppo(i: Int) = 8 * i + def beppo = 8 + class Dah extends Doo { + def f = "$beppo was a marx bros who saw dollars." // warn + } + } + class E { + def f = "$aleppo is a pepper and a city." // warn + } + class Bar { + private def bar = 8 + } + class Baz extends Bar { + def f = "$bar is private, shall we warn just in case?" // warn + } + class G { + def g = "$greppo takes an arg" // no warn + def z = "$zappos takes an arg too" // no warn + def h = "$hippo takes an implicit" // warn + } +} |