41

I'm documenting a Scala class with overloaded methods. How can I distinguish them when referring to them in scaladoc comments? For example, if I have

/**
 * The most important method is [[Doc.foo]].
 */
object Doc {
  def foo[A]: A = throw new UnsupportedOperationException;
  def foo[A,B >: A](x: A): B = x;
}

and run sbt doc I get

Doc.scala:1: warning: The link target "Doc.foo" is ambiguous. Several (possibly overloaded) members fit the target:

  • method foo[A,B>:A](x:A):B in object Doc [chosen]
  • method foo[A]:Nothing in object Doc

Using foo[A,B >: A] etc. to the link doesn't work.

Petr
  • 62,528
  • 13
  • 153
  • 317
  • 1
    Would using `[[Doc.foo()]]` work? I know that in C# when there's an ambiguous reference in documentation, you have to either use `()` when you one the method without parameters or spell out the *argument types*, e.g. `foo(string)`. Maybe it's similar here... – Patryk Ćwiek Mar 13 '13 at 21:10
  • @Trustme-I'maDoctor That doesn't work, complains with: _warning: Could not find any member to link for "Doc.foo()"._ – Petr Mar 13 '13 at 21:42
  • 1
    a PR at https://github.com/scala/docs.scala-lang adding documentation on this to http://docs.scala-lang.org/overviews/scaladoc/for-library-authors.html would be welcome – Seth Tisue Feb 26 '18 at 21:19

4 Answers4

35

The following seems do the trick in Scala 2.10.

/**
 * The most important method is [[Doc.foo[A]:A*]].
 */

And here is some hint scaladoc gives me:

[warn] Quick crash course on using Scaladoc links
[warn] ==========================================
[warn] Disambiguating terms and types: Prefix terms with '$' and types with '!' in case both names are in use:
[warn]  - [[scala.collection.immutable.List!.apply class List's apply method]] and
[warn]  - [[scala.collection.immutable.List$.apply object List's apply method]]
[warn] Disambiguating overloaded members: If a term is overloaded, you can indicate the first part of its signature followed by *:
[warn]  - [[[scala.collection.immutable.List$.fill[A](Int)(⇒A):List[A]* Fill with a single parameter]]]
[warn]  - [[[scala.collection.immutable.List$.fill[A](Int,Int)(⇒A):List[List[A]]* Fill with a two parameters]]]
[warn] Notes: 
[warn]  - you can use any number of matching square brackets to avoid interference with the signature
[warn]  - you can use \. to escape dots in prefixes (don't forget to use * at the end to match the signature!)
[warn]  - you can use \# to escape hashes, otherwise they will be considered as delimiters, like dots.
Brian Hsu
  • 8,781
  • 3
  • 47
  • 59
  • 16
    I find it abominable that ScalDoc can't resolve names via imports. I refuse to use fully qualified names in documentation comments. – Randall Schulz Mar 14 '13 at 02:29
  • Apparently, the hint is displayed only if I use scaladoc directly. I used sbt, which didn't show it. – Petr Mar 14 '13 at 06:01
  • @Randall Schulz This should be fixed according to this issue: https://issues.scala-lang.org/browse/SI-3695 – EECOLOR Mar 14 '13 at 07:24
  • 2
    Alas, this has not consistently worked for me with complex type signatures. But with simpler ones, it does. (I have found no solution for more complex signatures.) – Rex Kerr Mar 14 '13 at 15:13
  • This answer was not helpful to me. I'm trying to disambiguate 'apply' methods that have the same type args but different argument signatures. And I need it to work with Intellij IDEA 'Quick Documentation' (Ctrl-Q) for viewing scaladoc of a method. – Peter L May 22 '15 at 00:31
  • This information ought to be in the official doc. Volunteer to PR it? issue here: https://github.com/scala/docs.scala-lang/issues/1698 – Seth Tisue May 29 '20 at 16:38
13

What I found very usefull in IntelliJ is right clicking on a method you would like to put in [[ ]] and choosing "Copy reference".

Steps:

  1. You find a method you'd like to reference somewhere else.

enter image description here

  1. You right click on the method name and choose "Copy reference".

enter image description here

  1. You paste it in [[ ]] in your documentation (and write a label of your choice next to it, e.g. "apply(String)").

enter image description here

  1. Voilà.

enter image description here

Lukasz Czerwinski
  • 13,499
  • 10
  • 55
  • 65
11

I'm still surprised at how difficult it is to get this working and the lack of documentation for scaladoc itself. I decided to search the scala code base itself in hope of some useful examples. The best ones that I found were in https://github.com/scala/scala/blob/2.12.x/test/scaladoc/resources/links.scala. Hopefully this is useful for someone else who comes across this.

steinybot
  • 5,491
  • 6
  • 37
  • 55
10

I found a solution (apparently the unique solution) for complex signatures, by studying the doc of scaladoc.

  • Don't use space in the signature
  • Use the arguments name
  • For argument types as well as return types, prefix all dots with a single backslash \
  • Use the star * at the end of the signature
  • Use the complete signature (as the ambiguous signatures are proposed to you). This step is optional, you may be able to stop the signature earlier, as long as you finish it with *

Example:

package org.my.stuff

class ReturnType

object Foo {
  class Bar {
    def lara(s: String): String = ???
    def lara(s: Foo.Bar): ReturnType= ???
  }
}

/** [[org.my.stuff.Foo$.Bar.lara(s:org\.my\.stuff\.Foo\.Bar):org\.my\.stuff\.ReturnType* The link to the right lara method]]
  */
object DocumentFooBarBingComplex {
}
Mikaël Mayer
  • 10,425
  • 6
  • 64
  • 101
  • "Don't use a space in the signature" -- What if there is an implicit parameter? – Michael Zajac Oct 17 '15 at 00:47
  • Alas, that would not work indeed. You may try adding \ in front of the space, or make sure you don't need to write up to the implicit parameters to disambiguate your code. – Mikaël Mayer Oct 19 '15 at 08:45