Please note that the Scala wikis are in a state of flux. We strongly encourage you to add content but avoid creating permanent links. URLs will frequently change. For our long-term plans see this post by the doc czar.
Skip to end of metadata
Go to start of metadata
 
 
 

Tags

After the main body of a comment, it is possible to add a tags block. A tags block is composed of at least one tag element. A tag element starts with a recognised tag (listed below) and ends before the next recognised tag or at the end of the comment.

Primary Constructor Tag

  • @constructor <body>: Class and primary constructor documentation shares the same header, with the main body of the comment applying to the class, rather than the primary constructor.  This tag allows documentation to be provided for the constructor and is entered in the class header.

Primary Constructor Tag Example

Example of using the constructor tag.

/** Class representing a thing.  This will appear in the class
* documentation.
*
* Some further documentation that will appear in the class docs.
*
* @constructor Create a new Thing instance from a Wotsit. This
* will appear in the primary constructor documentation.
*
* @param wotsit Wotsit to be converted into a Thing. This tag
* appears in the primary constructor docs.
*/

class Thing (wotsit: Wotsit) {
// ...
}

Parameter Tags

  • @param <name> <body>: Documents a specific value parameter of a method or class constructor. One @param tag allowed per value parameter in comment for method, constructor or class (documents primary constructor). <name> argument must correspond to an existing value parameter.
  • @tparam <name> <body>: Documents a specific type parameter of a method, class, trait or abstract type. One @tparam tag allowed per type parameter in comment for method, class, trait or abstract type. <name> argument must correspond to an existing type parameter.
  • @return <body>: Documents the return value of a method. One @return tag allowed in comment for method.
  • @throws <name> <body>: Documents an exception type that may be thrown by a method or class constructor. Any number of @throws tags allowed in comment for method, constructor or class (documents primary constructor), no duplicate names allowed.

Usage Tags

  • @see <body>: Points to other sources of information such as external documentation or related entities in the documentation. Any number of @see tags allowed in any comment.
  • @note <body>: Documents pre- and post-conditions as well as other notable requirements or restrictions. Any number of @note tags allowed in any comment.
  • @example <body>: Provides example code and related descriptions. Any number of @example tags allowed in any comment.
  • @usecase <simple definition> In case the method definition is too complex, you can add simple aliasing definition as a usecase. It will create another entry in the scaladoc page as if the <simple definition> actually existed. The description for the newly created entry is the same as the one for the current symbol, just that it's preceded by [use case] to signal it's not a real entry. An example can be seen in the ++ method of scala.collections.immutable.Set.

Inventory Tags

  • @author <author>: Attributes an entity to one author. Any number of @author tags allowed in any comment: if multiple authors contributed, use one tag per author.
  • @version <version>: The version of the system or API that a class, trait, object or package is part of. One @version tag allowed in comments for class, trait, object or package.
  • @since <version>: The version of the system or API that an entity was first defined in. One @since tag allowed in any comment. This tag should only be used in conjunction with a @version tag in an enclosing class, trait, object or package.

Other Tags

  • @todo <body>: Documents unimplemented features in an entity. Any number of @todo tags allowed in any comment.

Annotations

The following annotations which can be added to entities like classes, methods and objects are also supported by ScalaDoc.

  • @deprecated(<message>, <version>): Marks an entity as deprecated. The message should describe replacement implementation. The version number specifies when the @deprecated annotation was added to the entity. Note that deprecating a class, trait, object or package also deprecates all entities within.
  • @migration(<message>, <version>): Adds a migration warning to an entity signaling that the behavior of the entity will change. The message should describe how the user of this entity might have to adapt his code. The version number specifies when the change in behavior will come into effect.

Macros

It is possible in a class, trait, object or package to define a macro using a tag:

@define <name> <body>

When $name is used in comments of the class, trait, object or package (including those of members), it will be replaced by Scaladoc by the defined body (macro system).

If a comment containing macros is inherited, macros will normally be extended to the bodies defined in the super-class. However, It is possible to redefine macros in the sub-class (using @define tags with the same names) such that macros in inherited comments are extended to the redefined bodies. This happens even if members are inherited, as opposed to being overridden or implemented.

Using macros allows writing documentation at the top-level of a complex class hierarchy and automatically specialise the comment for more specific sub-classes.

Comment Inheritance

A number of features help documentation writers by using the compiler to complete comments. This is called comment inheritance and takes place either implicitly or explicitly:

  • implicit comment inheritance
    • if the comment main body is not defined, it is copied from the overridden value or method / the superclass
    • if comment annotations are missing (like @param and @tparam tags, and @return) they are copied from the overridden value or method / the superclass
  • explicit comment inheritance
    • is done using the @inheritdoc tag, in either the main comment or any comment tag/annotation

Comment inheritance (both implicit and explicit) takes place:

  • from the superclass to any of its superclasses (including mixnins)
  • from a method/value/variable to the overridden method/value/variable
  • from a method/value/variable to its use cases

Comment variables can be defined for classes and used in member comments. Variables can be redefined in sub-classes and inherited comments get automatically rewritten.

More information on @inheritdoc is avaiscaladoc-example.scalalable in the javadoc documentation.

Inheritance Example

An example of using variables and inheritance: (the file is also attached to this page)

package scaladoc.example
/**
* The A class
* @define THIS A
* @define PARENT no other class
* @define RESULT 3
*/
class A {
/**
* The function f defined in $THIS returns some integer without no special property. (previously defined in $PARENT)
* @param i An ignored parameter.
* @return The value $RESULT.
*/
def f(i: Int) = 3
}
/**
* The B class, that extends A
* @define THIS B
* @define PARENT A
* @define RESULT `i + 3`
*/
class B extends A {
/*
* The next comment shows the three ways of inheritance:
* - we use "@inheritdoc" to explicitly inherit the main comment of A and add our specific explanation later
* - we override the "@param i" with a new explanation and use @inheritdoc to also inherit the previous explanation
* - we leave the "@return" statement alone, it will be inherited anyway
*
* As you can see, variables are orthogonal to the problem: they are always updated
*/
 /**
* @inheritdoc
* Some notes on implementation performance, the function runs in O(1).
* @param i An important parameter
*/
override def f(i: Int) = i + 3
}

Compile-time Error Checking

The Scaladoc comment parser will report invalid tags.

 
  • No labels

13 Comments

  1. There does not seem to be any way to document public properties of classes defined in a constructor. For example, the following does not result in any ScalaDoc output:

    /**
    * @param ipAddr asdf
    * @param date blah
    */
    class Download(val ipAddr: String, val date: Date) 

    Similarly, this does nothing as well:

    class Download(
    /** asdf */
    val ipAddr: String,
    /** blah */
    val date: Date) 
    1. Hi Mike,

      The parameter descriptions should appear in the "Instance Constructors" and "Value Members". Don't they?
      Since there can be multiple constructors to a class, the parameters do not appear in the main description on the top of the page. You can add them by hand, in the class description, if you really want to document the parameters on the main page:

      /** 
      * This will appear in the class documentation. `ipAddr` is the IP address and `date` is the date.
      * @param ipAddr asdf
      * @param date blah
      */
      class Download(val ipAddr: String, val date: Date)

      HTH
      Vlad

  2. ScalaDoc appears to support a tag called "@constructor" which is used to document the primary constructor - but there's no mention of it here.  It appears to be current and not deprecated, although I haven't checked the source.

    My understanding is that it's used like this:

    /** Class representing a thing.
    *
    * Some other documentation that appears in the class header.
    *
    * @constructor Create a new thing instance from a wotsit. Other
    * documentation that will appear in the primary constructor docs.
    *
    * @param wotsit Wotsit to be converted into a thing.
    */

    class Thing (wotsit: Wotsit) {
    // ...
    }

    Without this tag, it's not possible to document the primary constructor, to the best of my knowledge.  Do I have that right?

    I guess there's issues here because of the apparent intermingling of the class header and primary constructor documentation.  Does (or could) the "@constructor" tag act as a separator in the class header?  That is, will "@example" or "@note" tags that follow "@constructor" appear in the primary constructor docs or will they always appear in the class header?

  3. Hi Mike!

    You are right regarding the @constructor annotation, its purpose is to document the primary constructor of a class. The tags from the class will not be inherited to the primary constructor, aside from parameters, type parameters and throws. Can you complete the wiki with your example?

    As for the @constructor separation, I don't think it makes sense to overcrowd the primary constructor with notes and examples which would be displayed in the class description anyway. If you strongly feel this should be implemented (although it requires some focused work to do it) please file a bug at issues.scala-lang.org and be ready to defend the idea.

    Vlad

  4. Is there an equivalent to the overview.html file used by Javadoc to provide a top level entry document for a project? I have figured out how to use package.scala to replace the package.html from Javadoc (and I actually like the Scaladoc solution), but I'm still not able to figure out how to replace the overview.html part of Javadoc.

    1. There is. Pass a file containing standard scaladoc markdoc to scaladoc with the parameter -doc-root-content. See also the other scaladoc options, as there's useful stuff in there. More generally, look at what Scala library has to know what is possible.

      1. I have tried to get a rootdoc in a bunch of ways using SBT (0.13) with Scala 2.10.3. All fail. This seems to have haunted others as well and it isn't well documented. So if I get useful help on this, I'll pay it back by writing up a nice Scala Wiki page to reduce the frustration others face. I have an SBT multi-project build. So I have to use a .scala build file as opposed to a build.sbt. In that .scala file I have:

          object MyBuild extends Build {
            scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature", "-language:postfixOps")
            scalacOptions in doc ++= Seq("-doc-root-content", "rootdoc.txt")  //  KEY LINE
            lazy val proj_one = Project(
              base = file("./proj_one"); ...
            )
            lazy val  proj_two = Project(
              base = file("./proj_two"); ...
            )
          }

        I expect that the line marked "KEY LINE" will cause Scaladoc to look for the root doc markup for each project in a file called rootdoc.txt in the base directories of those projects. I.e. for the project defined as proj_one, it would be in the directory called proj_one right beneath the main directory of my multi-project build. That isn't happening. I've tried moving rootdoc.txt to lots of other possible places (src, src/main/scala, projects, etc.) and Scaladoc just doesn't seem to find it. Does anyone know how to get an SBT multi-project build to find the root doc markup file?

        1. Jamie, your proposition sparked my interest: https://github.com/VladUreche/scaladoc-sbt. Looking forward to your contributions to the wiki (big grin)

        2. In case I decide to remove the github repo at some point in the future, the solution is:

          1. rootdoc.txt files have to be placed in the proj_one and proj_two directories
          2. the following sbt config works:
          object MyBuild extends Build {
            // settings need to be given for each subproject:
            val mysettings = Defaults.defaultSettings ++ Seq(
              scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature", "-language:postfixOps"),
              // be more precise: give the absolute path to the rootdoc file:
              scalacOptions in (Compile, doc) ++= Seq("-doc-root-content", baseDirectory.value + "/rootdoc.txt")
            )
            lazy val proj_one = Project(
              id = "one",
              base = file("./proj_one"),
              settings = mysettings
            )
            lazy val proj_two = Project(
              id = "two",
              base = file("./proj_two"),
              settings = mysettings
            )
          }
          1. Thanks Vlad! 

            As promised, I added a page entitled "Configuring SBT to Generate a Scaladoc Root Page" under the "Using ScalaDoc" Scala Wiki topic. It is a bad title but was designed to make it easy for Google to find when presented with the search queries I have been giving. I think the content is reasonably clear; clear enough to get people over the hump. Then they can edit and improve that page.

            1. Jamie, thanks a lot! The explanation you wrote is great!

              If you'd like to help out with the long-overdue scaladoc tutorial on the docs.scala-lang.org page, ping me and I'll help out as much as I can. By the way, did you also use scaladoc diagrams(big grin)

  5. Vlad–I knew about diagrams but had never used them in Scaladoc. I got it working. Automatically generated diagrams are hard to make useful to the developer, but you did a good job. NOTE: I DON'T SEEM TO GET THE PACKAGE DIAGRAMS, JUST THE CLASS DIAGRAMS. By the way, I saw the Scaladoc option "-diagrams-debug" in the paper you and your student wrote, and it is very useful, but I don't see it in Scaladoc help! So you have to find the paper to know that the option is out there. 

    In any case, I'll take the bait. I would like to help out on the Scaladoc tutorial. I still haven't gotten used to indenting the extra space before the * so this will force me. There is material about Scaladoc on scala-lang.org and so I'm sure you have specific objectives with the tutorial. What are those objectives? 

    1. Jamie, regarding the package diagrams – if the classes in that package are not connected (just a bunch of unrelated classes) then the package diagram won't appear. We could create a diagram even if there are no edges, but Damien figured it wouldn't be very useful. (smile)

      Regarding the "-diagrams-debug" flag, it appears in the help screen, but in a separate tab:

      Additional debug settings:
        -diagrams-debug                             Show debugging information for the diagram creation process.
        -implicits-debug                            Show debugging information for members inherited by implicit conversions.

      The goals of making a tutorial on docs.scala-lang.org are threefold:

      • state what scaladoc can do for your documentation
      • give practical instructions on how to do it (including in sbt)
      • curate the content of the wiki, which has some useful information, but is neither complete nor very well organized

      I should have written the tutorial myself, but it's hard to get in the shoes of a developer seeing scaladoc for the first time, so I tend to give very technical explanations, which aren't very useful for a beginner. And I've also been focusing on the miniboxing plugin lately, which will be ready for use soonish: scala-miniboxing.org.

      Ping me at <first>.<last> on skype and we can decide how to go about it. Btw, I have a scaffolding document, we can use that as a starting point: https://gist.github.com/VladUreche/8396624