1. Introduction

Good documentation is an important factor in software development. It makes a project more maintainable in the long run.

Scaladoc is a documentation generation system that reads specially formatted comments in Scala source code and generates compiled documentation. It is similar to Javadoc in Java.

In this tutorial, we’ll learn how to add Scaladoc to code for a Scala project. Then, we’ll generate the Scaladoc from the added code. Finally, we’ll examine the generated output.

2. Adding Scaladoc to Code

To add Scaladoc, we can use a special comment block called a Scaladoc comment. Scaladoc comment structure looks very similar to a regular multi-line comment, but the key difference is the extra asterisk at the beginning.

Let’s compare a Scaladoc with regular comments:

// This is a single line comment

/*
 * This is a regular multi-line comment
 */

/** This is a Scaladoc.
  * 
  */

We can put Scaladoc comments above any packages, classes, methods, traits, or objects. In the next subsections, we’ll explore these options.

2.1. Packages

A package’s documentation should contain what the package is about and what classes it includes.

First, we need to create a package object in the file package.scala. Scala will use this object to generate the documentation.

Now, let’s add the Scaladoc into our package:

package com.baeldung.scala

/** Package for Scaladoc tutorial.
  * Provides examples of Scaladoc and their elements such as tags and formattings.
  *
  * Class implemented in this package is [[com.baeldung.scala.scaladoc.IntervalTimer]].
  */
package object scaladoc {}

Notice, we referenced a class in this package – in this case, IntervalTimer –with double square-bracket notation.

2.2. Classes

In class documentation, we should write the functionality of the class and how to use it.

Let’s write a Scaladoc for our IntervalTimer class:

package com.baeldung.scala.scaladoc

/** Represents a timer with interval.
  *
  * Specify how many `reps` desired for the timer and the `interval` between `reps`
  *
  * @constructor Create a timer with a specified `reps` and `interval`
  * @param reps Number of repetitions the timer will run.
  * @param interval Time between repetitions, in seconds. The default is 30 seconds.
  */
class IntervalTimer(val reps: Int, val interval: Int = 30) { }

The @constructor tag is used to explain what the constructor does, while @param is used to explain the parameters used in the constructors.

2.3. Methods

In method documentation, we should describe what the method will do if we use it.

Let’s create a method start for the class IntervalTimer along with its Scaladoc:

/** Start this timer based on defined `reps` and `interval`.
  *
  * Print one message every second and another when each repetition is completed.
  * It cannot be stopped.
  */
def start(): Unit = {
  Array.range(1, reps + 1).foreach { rep =>
    Array.range(1, interval + 1).foreach { second =>
      Thread.sleep(1000)
      println(s"tic toc $second")
    }
    println(s"rep $rep is finished.")
  }
}

If we define a return value for a method, we should explain what it returns with @return tag:

/** Get total time, in seconds, that will be counted for this timer.
  *
  * @return The total number of seconds elapsed for this timer.
  */
def getTotalSeconds: Int = {
  interval * reps
}

2.4. Traits

We need to document the overview of a trait and methods that must be specified in classes using the trait. If possible, we should also write the classes using the trait.

Let’s take a look at trait Carnivore:

/** Defines a meat eater.
  *
  * movement must be specified in class using this.
  * Used by [[com.baeldung.scala.scaladoc.TasmanianDevil]]
  */
trait Carnivore {
  def food: String = "meat"
  def movement: String
}

2.5. Objects

For objects, we need to document the purpose of the object (e.g. as a factory, for implicit methods). We should also document methods implemented there, if available.

Let’s take a look at a factory object TasmanianDevil:

package com.baeldung.scala.scaladoc

/** Factory for [[com.baeldung.scala.scaladoc.TasmanianDevil]] instances.
  *
  * Extends [[com.baeldung.scala.scaladoc.Carnivore]].
  */
object TasmanianDevil extends Carnivore {
  /** Creates a tasmanian devil with a given length.
    *
    * @param length the length of tasmanian devil in cm.
    */
  def apply(length: Int) = {}
  def movement: String = "Walk"
}

3. Formatting and Tags

In Scaladoc, we can use wiki-style markup and tags to convey different kinds of information.

3.1. Wiki-Style Markup

Let’s go over some basic formatting in wiki-style markup:

/** Formatting examples for Scaladoc:
  *
  * =Heading=
  * ==Sub-Heading==
  * `monospace`
  * ''italic text''
  * '''bold text'''
  * __underline__
  * ^superscript^
  * ,,subscript,,
  */

To create a link, we can use double square brackets:

/** [[entity link]], e.g. [[scala.collection.Seq]]
  * [[https://external.link External Link]],
  *   e.g. [[https://scala-lang.org Scala Language Site]]
  */

If our documentation needs an example code, we can use triple curly brackets to create a code block:

/** {{{
  * val example = 1
  * }}}
  */

List blocks are a sequence of list items with the same style and level, with no interruptions from other block styles. We can create both unordered and ordered lists in Scaladoc.

To create an unordered list, we can use the “” symbol before each item:

/** Here is an unordered list:
  *
  *  - First item
  *  - Second item
  *    - Sub-item to the second
  *    - Another sub-item
  *  - Third item
  */

If we need an ordered list, we can use “1.“, “i.“, “I.“, or “a.” to denote various enumerating styles:

/** Here is an ordered list:
  *
  *  1. First numbered item
  *  1. Second numbered item
  *    i. Sub-item to the second
  *    i. Another sub-item
  *  1. Third item
  */

In both cases, we have to use space at the front. More space will make a sub-level.

3.2. Tags

To include different kinds of information in Scaladoc, we can use pre-defined tags:

  • @author specifies the author of the class
  • @constructor provides an explanation for the constructor
  • @param provides any useful description about a method’s parameter or input it should expect
  • @return provides a description of what a method will or can return
  • @since specifies which version the class, field, or method was added to the project
  • @version specifies the version of the software, commonly used with %I% and %G% macros
  • @throws is used to further explain the cases in which the software may expect an exception
  • @deprecated gives an explanation of why code was deprecated, when it may have been deprecated, and what the alternatives are
  • @todo is used to document pending items for a method or class

4. Generating Scaladoc

After adding Scaladoc comments in our code, we can generate it from the command line in our sbt project’s directory:

[email protected]:~$ sbt doc

This will generate documentation at target/scala-{version}/api/index.html.

Let’s go over there and examine what is generated by Scaladoc:

We can see the left side of the page shows the documentation we created for package com.baeldung.scala.scaladoc. On the right side, it shows packages and classes available in the Scaladoc.

Let’s click on IntervalTimer to see a detailed view of our class documentation:

We can see the explanation of the class on the upper part of the page, while the constructor and class members appear on the lower part. We can click on the methods to show their explanations.

5. Conclusion

In this tutorial, we’ve explored how to create documentation for Scala code using Scaladoc. We also saw how to generate Scaladoc documentation from the command line, and we had a look at the rendered result.

As usual, all the examples used in this tutorial are available over on GitHub.

Comments are closed on this article!