Chapter 57. JS2Doc Reference

Table of Contents

1. Overview
2. Format of Structured Comments
3. Matching Comments to Declarations
4. Conditional Annotations
5. Supported Comment Fields
6. JS2Doc and LZX files
7. To Do
8. JS2Doc Schema
[Note] Note

This book part is currently being drafted. Stay tuned for more contents!

1. Overview

The js2doc tool extracts reference documentation from ECMAScript (ECMA-262) 3rd Edition source code, with some provision for ECMAScript 4th Edition extensions such as class. (It is intended that eventually js2doc will support the full ES4 language once that standard has been finalized.) The tool generates an XML representation of the declarations in the source, augmented by material extracted from specially-formatted comments found adjacent to the program declarations. This XML output can be used to generate human-readable documentation in a number of different formats, or to extract information about the program source under study.

[Note] Note

The js2doc tool was built to document JavaScript source associated with the OpenLaszlo project, and as such contains several proprietary extensions in support of OpenLaszlo. The intention is to remove these extensions as the ES4 language nears acceptance.

2. Format of Structured Comments

Structured comments generally follow the format defined for javadoc.

3. Matching Comments to Declarations

The js2doc tool works by matching comments to declarations. Generally speaking, the comment immediately preceding the declaration is matched if it has the correct format. The comment must immediately precede the declaration: if an improperly-formatted (or unformatted) comment intervenes between a properly formatted comment and a declaration, there is no match. Note that special rules apply to a structured comment intended to apply to the source file as a whole; see below for details.

Here is a simple example:

/** Whether the process is complete **/
var isdone = false;

And another:

/** class for monitoring process status **/
class foo {
  /** Whether the process is complete **/
  var isdone = false;
}

A comment placed before a multi-term variable declaration is distributed to all variables in the declaration. This is consistent with javadoc's behavior.

/** Whether the process is complete **/
var isdone = false,
    isprivate = false;  Comment is same as for isdone

Separate comments should be placed 'inside' the declaration:

var 
  /** Whether the process is complete **/
  isdone = false,
  /** Whether the process is private **/
  isprivate = false;

Documentation can be provided for an entire source file, by placing a structured comment at the top of the file. Note that there is a potential for ambiguity: a structured comment at the top of a file may also precede a declaration and therefore logically apply to that declaration. To eliminate this ambiguity, the js2doc tool currently requires a whole-file comment to contain a @copyright field, which will typically be the case anyway.

/** Math utilities
   @copyright Copyright 2007 Laszlo Systems, all rights reserved
   */
   
   var pi = 3.14159;  Preceding comment applies to file, not var
   

4. Conditional Annotations

The js2doc tool tracks the use of top-level conditional expressions and automatically annotates its output with information about those conditionals. Two types of constants are tracked: runtime designators, and build types.

In the following example, the js2doc output will annotate the foo variable as if it had an associated comment with the field @runtimes $swf8.

if ($swf8) {
  var foo = 10;
}

Only boolean literals (true or false) or predefined constants are tracked, but complex boolean expressions combining those elements are supported. In the following example, with a set of three known runtime constants ($swf8, $swf8, and $dhtml) foo is annotated as if by @runtimes $swf8 $swf9, and bar is annotated as if by @runtimes $dhtml.

if ($swf8 || $swf9) {
  var foo = 10;
} else {
  var bar = 20;
}

Conditionals that can be proven to evaluate to true or false are automatically compiled away in the expected manner. In the following example, js2doc emits information about the variable bar but not foo.

if (false) {
  var foo = 10;
} else {
  var bar = 20;
}

5. Supported Comment Fields

Standard Comment Fields

topic, subtopic

The topic and subtopic used to organize this declaration within its output book. Valid only for file-level and top-level declarations.

copyright

access

The visibility (private|public|protected) of the declaration.

type

The JavaScript type of the declaration. Will become unnecessary once type declaration support is added to the compiler. May not exist if @lzxtype is given since in that case the JS type can be trivially derived (lz.lzxtype).

modifiers

(final|virtual|deprecated|override|abstract|const|readonly|read-only)

param

Used to describe a particular function or method parameter. Format is @param [jstype] name : description. The description may be multi-line, as with all comment fields. Ignored if not given as part of a function or method comment.

return, returns

Used to describe the return value of a function or method. Format is @param [jstype : ] description. The description may be multi-line, as with all comment fields. Ignored if not given as part of a function or method comment.

keyword, keywords

The keywords field is a mechanism to give various forms of modifiers.

Standard Comment Keywords

public, protected, private

Equivalent to giving @access.

final, virtual, deprecated, override, abstract, const, readonly, read-only

Equivalent to giving @modifiers.

OpenLaszlo-specific Comment Fields

initarg

runtimes

lzxtype

lzxname

6. JS2Doc and LZX files

Structured comments in LZX files generally follow the same format and conventions as the comments in JavaScript documents. The comments themselves are in XML format, of course:

<!-- A simple button 
    @access private
    -->
<class name="mybutton" extends="view" />

One difference is that documentation can also be given in XML format directly:

<class name="mybutton" extends="view" >
  <doc>
    <tag name="access"><text>private</text></tag>
    <text>A simple button</text>
  </doc>
  </class>

7. To Do

8. JS2Doc Schema

This section gives the schema describing output of the js2doc tool, in Relax-NG Compact notation.

      # js2doc.rnc is in the RELAXNG Compact syntax:
# http://www.thaiopensource.com/relaxng/compact/syntax.html
#
# js2doc.rng is a RELAXNG schema:
# http://www.oasis-open.org/committees/relax-ng/
#
# Note: js2doc.rnc is the master schema. 
#

# * P_LZ_COPYRIGHT_BEGIN ******************************************************
# * Copyright 2006 Laszlo Systems, Inc.  All Rights Reserved.                 *
# * Use is subject to license terms.                                          *
# * P_LZ_COPYRIGHT_END ********************************************************

# Notes
#
# This isn't yet the best structure, according to what we know about ES4.
# (http://developer.mozilla.org/es4/spec/chapter_9_classes.html)
# Better would be to introduce separate traits and methods productions within
# object|function|class and also instancetraits and instancemethods productions
# within class. Properties would only appear at top level. But this would 
# involve a fairly large code change in the js2doc parser, which I'm not 
# willing to make right now.
#
# Another improvement to make would be to get rid of the initarg element and
# add a 'ctors' element containing function/method elements. The initargs can
# be attached as metatadata added to the 'options' parameter conventionally
# used in the openlaszlo object system.

namespace rng = "http://relaxng.org/ns/structure/1.0"
namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"

# Literals & Tags
booleanLiteral = xsd:boolean
optionsTag = string        # was: xsd:string {pattern="[+\-][a-zA-Z0-9\-_:.]*"}

# Attributes
idAttribute = attribute id {token}
modifiersAttribute = attribute modifiers {string}
typeAttribute = ([a:defaultValue="Object"] attribute type {token})
accessAttribute = ([a:defaultValue="public"] attribute access {"public" | "protected" | "private"})

conditionAttributes = (
      attribute runtimes {optionsTag}?
    & attribute includebuilds   {optionsTag}?
    & attribute excludebuilds   {optionsTag}?
    )

topicAttributes = (
      attribute topic {token}?
    & attribute subtopic {token}?
    )

bindingAttributes = (
      idAttribute
    & conditionAttributes
    & accessAttribute?
    & modifiersAttribute?
    )

toplevelAttributes = (
      topicAttributes
    & attribute unitid {token}?
    & bindingAttributes
    )
    
any = (text | element * { attribute * { text }*, any })*
  
# Grammar
start = js2doc

js2doc =
    element js2doc {
        attribute runtimeoptions {optionsTag}?
      & attribute buildoptions {optionsTag}?
      & (propertyElement | unitElement)*
    }

unitElement =
    element unit {
        attribute path {string}
      & toplevelAttributes
      & docElement?
    }
    
propertyElement =
    element property {
        attribute name {token}?
      & toplevelAttributes?
      & typeAttribute?
      # use @value attribute for literals, elements otherwise
      # TODO [jgrandy 2/14/2007] consider removing this abbreviation, just support elements
      & attribute value {token}?
      & (objectElement | functionElement | classElement)?
      & docElement?
    }

objectElement =
    element object {
        attribute type {token}?
      & propertyElement*
    }

classElement =
    element class {
        [a:defaultValue="class"] attribute variant {token}?
      & attribute extends {token}?
      & (propertyElement | initargElement)*
    }

functionElement = 
    element function {
       (parameterElement)*
      & returnsElement?
      & propertyElement*
    }

parameterElement =
    element parameter {
        attribute name {token}
      & typeAttribute?
      & docElement?
    }

returnsElement =
    element returns {
        typeAttribute?
      & docElement?
    }

## this is (sort of) an OpenLaszlo-specific element
## it corresponds to properties passed in the args parameter to the
## class instance constructor that are processed by the constructor rather
## than being used to directly initialize instance properties.
initargElement =
    element initarg {
        attribute name {token}
      & typeAttribute?
      & bindingAttributes
      & docElement?
    }

docElement =
    element doc {
        attribute keywords {string}?
      & docTagElement*
      & docTextElement?
    }

docTagElement =
    element tag {
        attribute name {token}
      & docTextElement?
    }

docTextElement =
    element text { 
        [a:defaultValue="text/html"] 
        attribute content {string}?
      & any }