From 75cfd808aec7cd94ab3e2c13ffd4821887de6ddd Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 23 Mar 2016 11:23:41 -0700 Subject: SI-9314 No warn on ${nonid} Use the sym test on an expr that happens to be a subset of idents and is not in scope. Other `${ operator_* }` warn. --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1b55618691..facb695447 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -105,7 +105,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper // that are turned private by typedBlock private final val SYNTHETIC_PRIVATE = TRANS_FLAG - private final val InterpolatorCodeRegex = """\$\{(.*?)\}""".r + private final val InterpolatorCodeRegex = """\$\{\s*(.*?)\s*\}""".r private final val InterpolatorIdentRegex = """\$[$\w]+""".r // note that \w doesn't include $ abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tag with PatternTyper with TyperContextErrors { @@ -5211,14 +5211,18 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def maybeWarn(s: String): Unit = { def warn(message: String) = context.warning(lit.pos, s"possible missing interpolator: $message") def suspiciousSym(name: TermName) = context.lookupSymbol(name, _ => true).symbol - val suspiciousExpr = InterpolatorCodeRegex findFirstMatchIn s + val suspiciousExprs = InterpolatorCodeRegex findAllMatchIn s def suspiciousIdents = InterpolatorIdentRegex findAllIn s map (s => suspiciousSym(TermName(s drop 1))) - - if (suspiciousExpr.nonEmpty) - suspiciousExpr filter (!_.group(1).trim.isEmpty) foreach (_ => + def isCheapIdent(expr: String) = (Character.isJavaIdentifierStart(expr.charAt(0)) && + expr.tail.forall(Character.isJavaIdentifierPart)) + def warnableExpr(expr: String) = !expr.isEmpty && (!isCheapIdent(expr) || isPlausible(suspiciousSym(TermName(expr)))) + + if (suspiciousExprs.nonEmpty) { + val exprs = (suspiciousExprs map (_ group 1)).toList + // short-circuit on leading ${} + if (!exprs.head.isEmpty && exprs.exists(warnableExpr)) warn("detected an interpolated expression") // "${...}" - ) - else + } else suspiciousIdents find isPlausible foreach (sym => warn(s"detected interpolated identifier `$$${sym.name}`")) // "$id" } lit match { -- cgit v1.2.3