Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable false warning "possible missing interpolator"

I have some nested case classes, and for a specific serialization mechanism I need to provide a productPrefix that contains $ characters. Like so

object Foo {
  case class Bar() {
    override def productPrefix = "Foo$Bar"
  }
}

Now I get a compiler warning from this:

Warning:(53, 42) possible missing interpolator: detected interpolated identifier `$Bar`
    override def productPrefix: String = "Foo$Bar"

Is there a way to disable the warning, if possible only for this instance? Scala version is 2.11.8.


Edit: I just thought I was clever: "Foo\u0024Bar". But the compiler even warns about this. Another solution is classOf[Bar].getName, given the constraint that there are no further outer objects.

like image 470
0__ Avatar asked Sep 08 '16 22:09

0__


4 Answers

If there's a way to compose the string from its parts you could do something like this.

override def productPrefix = "Foo$" + "Bar"

You could also quiet the "missing interpolator" warning by actually invoking the interpolator, but escaping the $.

override def productPrefix = f"Foo$$Bar"
like image 50
jwvh Avatar answered Oct 16 '22 13:10

jwvh


The warning only happens when there is an identifier with that name in the lexical scope. In case the linter complains about it when the identifier is a val/var, you could just rename the val/var

like image 23
Ballekens Bruno Avatar answered Oct 16 '22 14:10

Ballekens Bruno


The warning is induced by -Xlint. The specific linter about the supposedly missing interpolator can be disabled by giving the scalac command line option as

-Xlint:_,-missing-interpolator

The underscore (_) is for "everything" and the -missing-interpolator is for "except the missing interpolator warning".

like image 7
scravy Avatar answered Oct 16 '22 14:10

scravy


-Xlint warns if it sees a var in scope:

$ scala -Xlint
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_101).
Type in expressions for evaluation. Or try :help.

scala> { val x = "hi" ; s"$x" }
res0: String = hi

scala> { val x = "hi" ; "$x" }
<console>:12: warning: possible missing interpolator: detected interpolated identifier `$x`
       { val x = "hi" ; "$x" }
                        ^
res1: String = $x

scala> { val y = "hi" ; "$x" }  // no warning if x is not a symbol
res2: String = $x

scala> object Foo { case class Bar() { override def productPrefix = "Foo$Bar" } }
<console>:11: warning: possible missing interpolator: detected interpolated identifier `$Bar`
       object Foo { case class Bar() { override def productPrefix = "Foo$Bar" } }
                                                                    ^
defined object Foo

Usually, use double dollar for literal dollar when interpolating. (Edit: to be clear, $$ is like \$.)

scala> object Foo { case class Bar() { override def productPrefix = s"Foo$$Bar" } }
defined object Foo

scala> Foo.Bar().productPrefix
res8: String = Foo$Bar

Use f-interpolator to get a constant string.

scala> def productPrefix = f"Foo$$Bar"
productPrefix: String

scala> :javap -pv -
[snip]
  public java.lang.String productPrefix();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: ldc           #16                 // String Foo$Bar
         2: areturn

You can also put your funky constants in a quarantined scope:

scala> :pa -raw
// Entering paste mode (ctrl-D to finish)

package k {
trait K { final val p = "Foo$Bar" }
}
package q {
  case class Bar() { override def productPrefix = (null: k.K).p }
}

// Exiting paste mode, now interpreting.


scala> q.Bar().productPrefix
res1: String = Foo$Bar

The constant is inlined. The trick of the null reference avoids any allocations, including any singleton object.

like image 4
som-snytt Avatar answered Oct 16 '22 13:10

som-snytt