Doc Block style guide

Doc Block style guide

Submitted by paddy on Sun, 12/11/2016 - 17:50

Style guide for writing docblock comments.How to Write Doc Comments

 

This document describes the style guide and tag conventions used in documentation comments for this site.

Writing Programming Guide Documentation

What separates API specifications from a programming guide are examples, definitions of common programming terms, certain conceptual overviews (such as metaphors), and descriptions of implementation bugs and workarounds. There is no dispute that these contribute to a developer's understanding and help a developer write reliable applications more quickly. However, because these do not contain API "assertions", they are not necessary in an API specification.

It's useful to go into further detail about how to document bugs and workarounds. There is sometimes a discrepancy between how code  should work and how it actually works. This can take two different forms: API spec bugs and code bugs. It's useful to decide up front whether you want to document these in the doc comments. 

API spec bugs are bugs that are present in the method declaration or in the doc comment that affects the syntax or semantics. An example of such a spec bug is a method that is specified to throw a NullPointerException when  null is passed in, but  null is actually a useful parameter that should be accepted (and was even implemented that way). If a decision is made to correct the API specification, it would be useful to state that either in the API specification itself, or in a list of changes to the spec, or both. Documenting an API difference like this in a doc comment, along with its workaround, alerts a developer to the change where they are most likely to see it. Note that an API specification with this correction would still maintain its implementation-independence.

Code bugs are bugs in the implementation rather than in the API specification. Code bugs and their workarounds are often likewise distributed separately in a bug report. It would be quite useful to include this information in the doc comments, suitably separated as a note or by a custom tag (say  @bug).

Writing Doc Comments

Format of a Doc Comment

A doc comment is written in HTML and must precede a class, field, constructor or method declaration. It is made up of two parts -- a description followed by block tags. In this example, the block tags are  @param,  @return, and  @see.

/**
 * Returns an Image object that can then be painted on the screen.
 * The url argument must specify an absolute <a href="#{@link}">{@link URL}</a>. The name
 * argument is a specifier that is relative to the url argument.
 * &lt;p&gt;
 * This method always returns immediately, whether or not the
 * image exists. When this applet attempts to draw the image on
 * the screen, the data will be loaded. The graphics primitives
 * that draw the image will incrementally paint on the screen.
 *
 * <a href="#@param">@param</a>  url  an absolute URL giving the base location of the image
 * <a href="#@param">@param</a>  name the location of the image, relative to the url argument
 * <a href="#@return">@return</a>      the image at the specified URL
 * <a href="#@see">@see</a>         Image
 */
 function getImage(url, name) {
        try {
            return getImage(new URL(url, name));
        } catch (MalformedURLException e) {
            return null;
        }
 }
 

Notes:

  • The  resulting HTML from running PHPDoc is shown below
  • Each line above is indented to align with the code below the comment.
  • The first line contains the begin-comment delimiter (  /**).
  • Notice the inline tag  {@link URL}, which converts to an HTML hyperlink pointing to the documentation for the URL class. This inline tag can be used anywhere that a comment can be written, such as in the text following block tags.
  • If you have more than one paragraph in the doc comment, separate the paragraphs with a  &lt;p&gt; paragraph tag, as shown.
  • Insert a blank comment line between the description and the list of tags, as shown.
  • The first line that begins with an "@" character ends the description. There is only one description block per doc comment; you cannot continue the description following block tags.
  • The last line contains the end-comment delimiter (  */) Note that unlike the begin-comment delimiter, the end-comment contains only a single asterisk.

So lines won't wrap, limit any doc-comment lines to 80 characters.

Here is what the previous example would look like after running the PHPDoc tool:

getImage

function getImage(url,
             name)

Returns an Image object that can then be painted on the screen. The url argument must specify an absolute URL. The name argument is a specifier that is relative to the url argument.

This method always returns immediately, whether or not the image exists. When this applet attempts to draw the image on the screen, the data will be loaded. The graphics primitives that draw the image will incrementally paint on the screen.

Parameters:
url - an absolute URL giving the base location of the image.
name - the location of the image, relative to the url argument.
Returns:
the image at the specified URL.
See Also:
Image

Also see  Troubleshooting Curly Quotes (Microsoft Word) at the end of this document.

Descriptions

First Sentence 
The first sentence of each doc comment should be a summary sentence, containing a concise but complete description of the API item. This means the first sentence of each member, class, interface or package description. The PHPDoc tool copies this first sentence to the appropriate member, class/interface or package summary. This makes it important to write crisp and informative initial sentences that can stand on their own.

This sentence ends at the first period that is followed by a blank, tab, or line terminator, or at the first tag (as defined below). For example, this first sentence ends at "Prof.":

   /**
    * This is a simulation of Prof. Knuth's MIX computer.
    */

However, you can work around this by typing an HTML meta-character such as "&" or "<" immediately after the period, such as:

   /**
    * This is a simulation of Prof.&amp;nbsp;Knuth's MIX computer.
    */

or

   /**
    * This is a simulation of Prof.&lt;!-- --&gt; Knuth's MIX computer.
    */

In particular, write summary sentences that distinguish overloaded methods from each other. For example: 

   /**
    * Class constructor.
    */
   foo() {
     ...
 
   /**
    * Class constructor specifying number of objects to create.
    */
   foo(int n) {
     ...

A Style Guide

The following are useful tips and conventions for writing descriptions in doc comments.

  • Use <code> style for keywords and names. 
    Keywords and names are offset by <code>...</code> when mentioned in a description. This includes:

    • PHP keywords
    • package names
    • class names
    • method names
    • interface names
    • field names
    • argument names
    • code examples

     

  • Use in-line links economically 
    You are encouraged to add links for API names (listed immediately above) using the  {@link}  tag. It is not necessary to add links for  all API names in a doc comment. Because links call attention to themselves (by their color and underline in HTML, and by their length in source code doc comments), it can make the comments more difficult to read if used profusely. We therefore recommend adding a link to an API name if:

    • The user might actually want to click on it for more information (in your judgment), and
    • Only for the first occurrence of each API name in the doc comment (don't bother repeating a link)

     

  • Omit parentheses for the general form of methods and constructors 
    When referring to a method or constructor that has multiple forms, and you mean to refer to a specific form, use parentheses and argument types. For example, ArrayList has two add methods: add(Object) and add(int, Object):

    The  add(int, Object) method adds an item at a specified position in this arraylist.

    However, if referring to both forms of the method, omit the parentheses altogether. It is misleading to include empty parentheses, because that would imply a particular form of the method. The intent here is to distinguish the general method from any of its particular forms. Include the word "method" to distinguish it as a method and not a field.

    The add method enables you to insert items. (preferred)

    The add() method enables you to insert items. (avoid when you mean "all forms" of the add method)

     

  • OK to use phrases instead of complete sentences, in the interests of brevity.
    This holds especially in the initial summary and in @param tag descriptions.

     

  • Use 3rd person (descriptive) not 2nd person (prescriptive). 
    The description is in 3rd person declarative rather than 2nd person imperative.

    Gets the label. (preferred)

    Get the label. (avoid)

     

  • Method descriptions begin with a verb phrase. 
    A method implements an operation, so it usually starts with a verb phrase:

    Gets the label of this button. (preferred)

    This method gets the label of this button.

     

  • Class/interface/field descriptions can omit the subject and simply state the object.
    These API often describe things rather than actions or behaviors:

    A button label. (preferred)

    This field is a button label. (avoid)

     

  • Use "this" instead of "the" when referring to an object created from the current class.
    For example, the description of the  getToolkit method should read as follows:

    Gets the toolkit for this component. (preferred)

    Gets the toolkit for the component. (avoid)

     

  • Add description beyond the API name.
    The best API names are "self-documenting", meaning they tell you basically what the API does. If the doc comment merely repeats the API name in sentence form, it is not providing more information. For example, if method description uses only the words that appear in the method name, then it is adding nothing at all to what you could infer. The ideal comment goes beyond those words and should always reward you with some bit of information that was not immediately obvious from the API name.

    Avoid - The description below says nothing beyond what you know from reading the method name. The words "set", "tool", "tip", and "text" are simply repeated in a sentence.

    /**
     * Sets the tool tip text.
     *
     * @param text  the text of the tool tip
     */
    public void setToolTipText(String text) {

    Preferred - This description more completely defines what a tool tip is, in the larger context of registering and being displayed in response to the cursor.

    /**
     * Registers the text to display in a tool tip.   The text
     * displays when the cursor lingers over the component.
     *
     * @param text  the string to display.  If the text is null,
     *              the tool tip is turned off for this component.
     */
    public void setToolTipText(String text) {

  • Be clear when using the term "field".
    Be aware that the word "field" has two meanings:

    • static field, which is another term for "class variable"
    • text field, as in the TextField class. Note that this kind of field might be restricted to holding dates, numbers or any text. Alternate names might be "date field" or "number field", as appropriate.
  • Avoid Latin
    use "also known as" instead of "aka", use "that is" or "to be specific" instead of "i.e.", use "for example" instead of "e.g.", and use "in other words" or "namely" instead of "viz."

Tag Conventions

This section covers:

Order of Tags
Include tags in the following order:

  • @author (classes and interfaces only, required)
  • @version (classes and interfaces only, required.)
  • @param (methods and constructors only)
  • @return (methods only)
  • @exception (@throws is a synonym)
  • @see

Ordering Multiple Tags 
We employ the following conventions when a tag appears more than once in a documentation comment. If desired, groups of tags, such as multiple @see tags, can be separated from the other tags by a blank line with a single asterisk. 

Multiple @author tags should be listed in chronological order, with the creator of the class listed at the top. 

Multiple @param tags should be listed in argument-declaration order. This makes it easier to visually match the list to the declaration. 

Multiple @throws tags (also known as @exception) should be listed alphabetically by the exception names.    

Multiple @see tags should be ordered as follows, which is roughly the same order as their arguments are  searched for by PHPDoc, basically from nearest to farthest access, from least-qualified to fully-qualified, The following list shows this progression. Notice the methods and constructors are in "telescoping" order, which means the "no arg" form first, then the "1 arg" form, then the "2 arg" form, and so forth. Where a second sorting key is needed, they could be listed either alphabetically or grouped logically.

@see $field
@see Class
@see package

Required Tags
An @param tag is "required" (by convention) for every parameter, even when the description is obvious. The @return tag is required for every method that returns something other than  void, even if it is redundant with the method description. (Whenever possible, find something non-redundant (ideally, more specific) to use for the tag comment.)

These principles expedite automated searches and automated processing. Frequently, too, the effort to avoid redundancy pays off in extra clarity.

Tag Comments 

@author (reference page)

You can provide one @author tag, multiple @author tags, or no @author tags. Individual programmers can be assigned to @author at the class level. As this tag can only be applied at the overview, package and class level, the tag applies only to those who make significant contributions to the design or implementation, and so would not ordinarily include technical writers.

The @author tag is not critical, because it is not included when generating the API specification, and so it is seen only by those viewing the source code. (Version history can also be used for determining contributors for internal purposes.)

If the author is unknown, use "unascribed" as the argument to @author. Also see  order of multiple @author tags.

@version (reference page)

The convention for the argument to the @version tag is the SCCS string "%I%, %G%", which converts to something like "  1.39, 02/28/97" (mm/dd/yy) when the file is checked out of SCCS.

The clearest numeric date format would be to have the date formatted with the year first, something like yyyy-mm-dd, as proposed in ISO 8601 and elsewhere (such as http://www.cl.cam.ac.uk/~mgk25/iso-time.html).

@param (reference page)

The @param tag is followed by the name (not data type) of the parameter, followed by a description of the parameter. By convention, the first noun in the description is the data type of the parameter. (Articles like "a", "an", and "the" can precede the noun.) An exception is made for the primitive  int, where the data type is usually omitted. Additional spaces can be inserted between the name and description so that the descriptions line up in a block. Dashes or other punctuation should not be inserted before the description, as the PHPDoc tool inserts one dash.

Parameter names are lowercase by convention. The data type starts with a lowercase letter to indicate an object rather than a class. The description begins with a lowercase letter if it is a phrase (contains no verb), or an uppercase letter if it is a sentence. End the phrase with a period only if another phrase or sentence follows it.

Example:

* @param ch        the character to be tested
* @param observer  the image observer to be notified

Do not bracket the name of the parameter after the @param tag with  &lt;code&gt;...&lt;/code&gt; since PHPDoc automatically does this.

When writing the comments themselves, in general, start with a phrase and follow it with sentences if they are needed.

  • When writing a phrase, do not capitalize and do not end with a period:

    @param x  the x-coordinate, measured in pixels

  • When writing a phrase followed by a sentence, do not capitalize the phrase, but end it with a period to distinguish it from the start of the next sentence:

    @param x  the x-coordinate. Measured in pixels.

  • If you prefer starting with a sentence, capitalize it and end it with a period:

      @param x  Specifies the x-coordinate, measured in pixels.

  • When writing multiple sentences, follow normal sentence rules:

      @param x  Specifies the x-coordinate. Measured in pixels.

Also see order of multiple @param tags.

@return (reference page)

Omit @return for methods that return void and for constructors; include it for all other methods, even if its content is entirely redundant with the method description. Having an explicit @return tag makes it easier for someone to find the return value quickly. Whenever possible, supply return values for special cases (such as specifying the value returned when an out-of-bounds argument is supplied).

Use the same capitalization and punctuation as you used in @param.

@throws (@exception was the original tag) (reference page)

A @throws tag should be included for any checked exceptions (declared in the throws clause), as illustrated below, and also for any unchecked exceptions that the caller might reasonably want to catch, with the exception of  NullPointerException. Errors should not be documented as they are unpredictable. For more details, please see  Documenting Exceptions with the @throws Tag.

/**
 * @throws IOException  If an input or output
 *                      exception occurred
 */
public void f() throws IOException {
    // body
}

@see (reference page)

Also see  order of multiple @see tags.

{@link} (reference page)

For conventions, see  Use In-Line Links Economically.

Documenting Anonymous Inner Classes

PHPDoc does not directly document anonymous classes -- that is, their declarations and doc comments are ignored. If you want to document an anonymous class, the proper way to do so is in a doc comment of its outer class, or another closely associated class.

For example, if you had an anonymous  TreeSelectionListener inner class in a method  makeTree that returns a  JTree object that users of this class might want to override, you could document in the method comment that the returned  JTree has a  TreeSelectionListener attached to it:

    /**
     * The method used for creating the tree. Any structural
     * modifications to the display of the Jtree should be done
     * by overriding this method.
     * &lt;p&gt;
     * This method adds an anonymous TreeSelectionListener to
     * the returned JTree.  Upon receiving TreeSelectionEvents,
     * this listener calls refresh with the selected node as a
     * parameter.
     */
    public JTree makeTree(AreaInfo ai){
    }

Examples of Doc Comments

/**
 * Graphics is the abstract base class for all graphics contexts
 * which allow an application to draw onto components realized on
 * various devices or onto off-screen images.
 * A Graphics object encapsulates the state information needed
 * for the various rendering operations that Java supports.  This
 * state information includes:
 * &lt;ul&gt;
 * &lt;li&gt;The Component to draw on
 * &lt;li&gt;A translation origin for rendering and clipping coordinates
 * &lt;li&gt;The current clip
 * &lt;li&gt;The current color
 * &lt;li&gt;The current font
 * &lt;li&gt;The current logical pixel operation function (XOR or Paint)
 * &lt;li&gt;The current XOR alternation color
 *     (see &lt;a href="#setXORMode"&gt;setXORMode&lt;/a&gt;)
 * &lt;/ul&gt;
 * &lt;p&gt;
 * Coordinates are infinitely thin and lie between the pixels of the
 * output device.
 * Operations which draw the outline of a figure operate by traversing
 * along the infinitely thin path with a pixel-sized pen that hangs
 * down and to the right of the anchor point on the path.
 * Operations which fill a figure operate by filling the interior
 * of the infinitely thin path.
 * Operations which render horizontal text render the ascending
 * portion of the characters entirely above the baseline coordinate.
 * &lt;p&gt;
 * Some important points to consider are that drawing a figure that
 * covers a given rectangle will occupy one extra row of pixels on
 * the right and bottom edges compared to filling a figure that is
 * bounded by that same rectangle.
 * Also, drawing a horizontal line along the same y coordinate as
 * the baseline of a line of text will draw the line entirely below
 * the text except for any descenders.
 * Both of these properties are due to the pen hanging down and to
 * the right from the path that it traverses.
 * &lt;p&gt;
 * All coordinates which appear as arguments to the methods of this
 * Graphics object are considered relative to the translation origin
 * of this Graphics object prior to the invocation of the method.
 * All rendering operations modify only pixels which lie within the
 * area bounded by both the current clip of the graphics context
 * and the extents of the Component used to create the Graphics object.
 *
 * <a href="#@author">@author</a>      Sami Shaio
 * @author      Arthur van Hoff
 * <a href="#@version">@version</a>     %I%, %G%
 * <a href="#@since">@since</a>       1.0
 */
public abstract class Graphics {
 
    /**
     * Draws as much of the specified image as is currently available
     * with its northwest corner at the specified coordinate (x, y).
     * This method will return immediately in all cases, even if the
     * entire image has not yet been scaled, dithered and converted
     * for the current output device.
     * &lt;p&gt;
     * If the current output representation is not yet complete then
     * the method will return false and the indicated
     * {@link ImageObserver} object will be notified as the
     * conversion process progresses.
     *
     * <a href="#@param">@param</a> img       the image to be drawn
     * @param x         the x-coordinate of the northwest corner
     *                  of the destination rectangle in pixels
     * @param y         the y-coordinate of the northwest corner
     *                  of the destination rectangle in pixels
     * @param observer  the image observer to be notified as more
     *                  of the image is converted.  May be
     *                  &lt;code&gt;null&lt;/code&gt;
     * <a href="#@return">@return</a>          &lt;code&gt;true&lt;/code&gt; if the image is completely
     *                  loaded and was painted successfully;
     *                  &lt;code&gt;false&lt;/code&gt; otherwise.
     * <a href="#@see">@see</a>             Image
     * @see             ImageObserver
     * <a href="#@since">@since</a>           1.0
     */
    public abstract boolean drawImage(Image img, int x, int y,
                                      ImageObserver observer);
 
 
    /**
     * Dispose of the system resources used by this graphics context.
     * The Graphics context cannot be used after being disposed of.
     * While the finalization process of the garbage collector will
     * also dispose of the same system resources, due to the number
     * of Graphics objects that can be created in short time frames
     * it is preferable to manually free the associated resources
     * using this method rather than to rely on a finalization
     * process which may not happen for a long period of time.
     * &lt;p&gt;
     * Graphics objects which are provided as arguments to the paint
     * and update methods of Components are automatically disposed
     * by the system when those methods return.  Programmers should,
     * for efficiency, call the dispose method when finished using
     * a Graphics object only if it was created directly from a
     * Component or another Graphics object.
     *
     * @see       #create(int, int, int, int)
     * @see       #finalize()
     * @see       Component#getGraphics()
     * @see       Component#paint(Graphics)
     * @see       Component#update(Graphics)
     * @since     1.0
     */
    public abstract void dispose();
 
    /**
     * Disposes of this graphics context once it is no longer
     * referenced.
     *
     * @see       #dispose()
     * @since     1.0
     */
    public void finalize() {
        dispose();
    }
}