7

I seem to have found my way to a weird error message. I'm storing a password, and I have a comment that says

/** A password hash is stored as `"algorithm$iterations$salt$hash"`
 *  with the number of iterations optional for some algorithms

When I tried to create a distribution jar for my project, I got this warning:

Variable iterations undefined in comment for...

I tracked the warning down to the trait package scala.tools.nsc.ast.DocComments, where I discovered it is apparently possible to put variables of some sort in ScalaDoc. Unfortunately, Googling for "variables in Scaladoc" or "ScalaDoc dollar sign" returns nothing useful.

Does anyone know what feature I'm using incorrectly and how I can include a dollar sign in a ScalaDoc comment without getting a warning?

Todd O'Bryan
  • 2,234
  • 17
  • 30

1 Answers1

7

I'd start with "$$", as a guess. Then I'd try backslash to escape it, which is the answer.

The standard lib is replete with these macros. (For instance, in immutable.MapLike,

 *  @define Coll immutable.Map

for the usage $Coll, for inherited doc.)

You'd think StringInterpolator would show how to include a dollar.

 [scaladoc] /localhome/jenkins/a/workspace/pr-checkin-per-commit/src/library/scala/StringContext.scala:17: warning: Variable name undefined in comment for class StringContext in class StringContext
 [scaladoc]  *   println(s"Hello, $name")  // Hello, James
 [scaladoc]                        ^
 [scaladoc] /localhome/jenkins/a/workspace/pr-checkin-per-commit/src/library/scala/StringContext.scala:23: warning: Variable name undefined in comment for class StringContext in class StringContext
 [scaladoc]  *   s"Hello, $name"
 [scaladoc]                ^
 [scaladoc] /localhome/jenkins/a/workspace/pr-checkin-per-commit/src/library/scala/StringContext.scala:41: warning: Variable a undefined in comment for class StringContext in class StringContext
 [scaladoc]  *    val x: JSONObject = json"{ a: $a }"
 [scaladoc]                                      ^

That's from a sample sanity build for pull requests.

All those errors are from the class doc, not member doc, so maybe that is a hint; or maybe it just stops complaining at that point.

The tool emits a wonderful primer in its output, but not to your problem:

 [scaladoc] Quick crash course on using Scaladoc links
 [scaladoc] ==========================================
 [scaladoc] Disambiguating terms and types: Prefix terms with '$' and types with '!' in case both names are in use:
 [scaladoc]  - [[scala.collection.immutable.List!.apply class List's apply method]] and
 [scaladoc]  - [[scala.collection.immutable.List$.apply object List's apply method]]
 [scaladoc] Disambiguating overloaded members: If a term is overloaded, you can indicate the first part of its signature followed by *:
 [scaladoc]  - [[[scala.collection.immutable.List$.fill[A](Int)(⇒A):List[A]* Fill with a single parameter]]]
 [scaladoc]  - [[[scala.collection.immutable.List$.fill[A](Int,Int)(⇒A):List[List[A]]* Fill with a two parameters]]]
 [scaladoc] Notes:
 [scaladoc]  - you can use any number of matching square brackets to avoid interference with the signature
 [scaladoc]  - you can use \\. to escape dots in prefixes (don't forget to use * at the end to match the signature!)
 [scaladoc]  - you can use \\# to escape hashes, otherwise they will be considered as delimiters, like dots.

Update 1: Guess what, that guess seems to work. It no longer complains about $ROOT in this output:

docs.partest:
 [scaladoc] Documenting 33 source files to /home/apm/projects/snytt/build/scaladoc/partest
 [scaladoc] model contains 110 documentable templates
 [scaladoc] /home/apm/projects/snytt/src/partest/scala/tools/partest/BytecodeTest.scala:14: warning: Variable TESTDIR undefined in comment for class BytecodeTest in class BytecodeTest
 [scaladoc]  * 1. Create subdirectory in test/files/jvm for your test. Let's name it $TESTDIR.
 [scaladoc]                                                                           ^
 [scaladoc] /home/apm/projects/snytt/src/partest/scala/tools/partest/BytecodeTest.scala:15: warning: Variable TESTDIR undefined in comment for class BytecodeTest in class BytecodeTest
 [scaladoc]  * 2. Create $TESTDIR/BytecodeSrc_1.scala that contains Scala source file that you
 [scaladoc]               ^
 [scaladoc] /home/apm/projects/snytt/src/partest/scala/tools/partest/BytecodeTest.scala:18: warning: Variable TESTDIR undefined in comment for class BytecodeTest in class BytecodeTest
 [scaladoc]  * 3. Create $TESTDIR/Test.scala:
 [scaladoc]               ^
 [scaladoc] Document succeeded with 3 warnings; see the documenter output for details.
 [scaladoc] three warnings found
[stopwatch] [docs.partest.timer: 19.486 sec]

Now I'll go for $TESTDIR.

Wow, this is really empowering. Thanks for the question!

First let me just go check if the scaladoc actually includes the $ROOT word in its html output.

Update 2: You know what? Just never mind. This is the result, ha:

 A string that looks like a file path is normalized by replacing the leading segments (the root) with "$$ROOT"

Update 3: Actually, \$ backslash escape works fine. Actual on-screen live output:

with "$ROOT" 
som-snytt
  • 39,429
  • 2
  • 47
  • 129
  • Okay, so `$$` avoids the warning, but results in two dollar signs in the docs. That's lovely. I'm also a bit confused where it says to *pre*fix terms and types with `$` or `!` and then proceeds to place them after `List` in the example. I think that's a suffix, not a prefix. On the other hand, it complains about `$ROOT` and `$iterations`, so something is looking for a prefix... – Todd O'Bryan Aug 12 '13 at 03:21
  • @TOB I know! Updated again. – som-snytt Aug 12 '13 at 03:22
  • Thanks for figuring that out. `\$` it is! Now if we can just get somebody to document something. I suppose it's too much to hope for unification of dollar-sign escaping in ScalaDoc and string interpolation, huh? – Todd O'Bryan Aug 12 '13 at 03:27
  • The hope is that by Scala 2.13, all the scaladoc will be one huge multiline string interpolation. Actually that would be cool if they used the strip margin VBAR delimiter. – som-snytt Aug 12 '13 at 03:34