Toggle Menu

Introduction

This document is an introductory guide on documenting your source code using short-jsdoc.

short-jsdoc defines a language very similar to jsdoc with a strong emphasis in types and other advanced features designed to better express particularities of the semantics of the JavaScript language.

So if you are already familiar with Object Oriented Programming and tools like jsdoc, javadoc, doxygen, etc then using short-jsdoc will be straight forward.

Annotation Index

For the impatiens, here there is a list of main jsdoc annotations. Because short-jsdoc is designed with flezibility/customizability in mind, some relevant things to understand are:

  • Secondary annotations are children of primary annotations
  • You can use any custom annotation you can think of, at any point. They will be treated as secondary annotations
  • You can declare annotation aliases for having custom annotations/semantics

Primary annotations

nameexampledescription
@module
// @module TodoList 
// This module contains the front-end classes that implement 
// the product list user experience from Models, routers and views

Indicates that the block describes a group of related classes. It declares that the following class declarations will be contained by this module.

@class
// @class TodoEntry
// Instance of this class represent an entry in the TODO list. 
// @extends AbstractView

Indicates that the block describes a class. In JavaScript, this is generally an object with a constructor function. Nevertheless @class can be also used to describe plain old JavaScript objects (without constructor functions).

Must be preceded by a @module annotation that contains it.

Parents: @module

Children: @method, @event, @property, @attribute, @contructor

@method
// @method parse it will parse given JavaScript code and return an AST object
// @param {String} jscode the JavaScript code to parse
// @throws {ParserError} thrown if given code is not valid JavaScript
// @returns {ASTNode}

Indicates that the block describes a method for the current class, this is the last parsed class.

Parents: @class

Children: @param, @return, @throw, @public, @private

@property
// @property {Color} color the color of this car.

Indicates that the block describes a method for the current class, this is the last parsed class. A @property tag has the structure @property {type} description. The {type} is optional.

Parents: @class

Children: @public, @private

@event
// @event change
// triggered when the state of this model changed. 
// Handlers accept the property name and new value as parameters

Indicates that the block describes a custom event that the class can fire at some interesting moment of code execution.

Ideally, an @event block should reside above the code that defines the event, even if that code is just a simple string declaration.

A @event tag has the structure @event {type} name description. The {type} is optional but it can be used informally to describe the handler signature.

Parents: @class

Children:@public, @private

@interface
// @interface Throwable @extends IBase @method throw
// @interface SoundMaker @method play @method stop
// @class LittleRadio @extends Radio @implements Throwable @implements SoundMaker

Interfaces are very similar to classes. See Interfaces section. A class can @implement several interfaces and also an interface can @extend another interface.

Parents: @module

Children:@method, @property, @event, etc (same as class)

@function
// @function formatUrl @param {String} base @returns {String} 
// @function visitor @param {Thing} visitable
// @function visit @param collection @param {visitor} visitor

Functions belong to a module. Also, notice that functions can be referenced as types - as if they were classes/interfaces.

Parents: @module

Children:@param, @returns, @throws, etc (same as method)

Secondary annotations

nameexampledescription
@extend or @extends
// @class Apple @extend Fruit
// @interface Component @extend Actionable

classes can inherit from other classes and this is declared by using the @extend annotation. Also, interfaces can inherit from another interface. In both cases, only single inheritance is supported in short-jsdoc. If you need multiple inheritance then you probably want to model your problem defining interfaces.

@implement or @implements
// @class Button 
// @implements Component 
// @implements Actionable

classes can implement one or more interfaces and for declaring that we use @implements annotation.

@return or @returns
// @return {Number} the number of goals this player has submitted. 

Specifies a method's return value. A @return tag has the structure @return {type} description. The {type} is optional.

Parents: @method

Children: @public, @private

@param
// @param {Array<String>} queue the queue objectyou want to process. 

Specifies a method's return value. A @return tag has the structure @return {type} description. The {type} is optional.

Parents: @method

Children: @public, @private

@constructor
// @constructor 
// @param {Config} config the configuration for the new instances. 

constructors are similar to methods but they don't have a name. A class can declare several constructors and they describe the constructor function of the class. @return can be omitted.

Parents: @class

Children: @param, @return, @throw, @public, @private

@attribute
// @attribute {String} name the color of this car.

Several JavaScript frameworks like Backbone.js react, YUI, etc support the concept of class attributes. Attributes are similar to properties but they can be setted/getted using getters and setters methods and also the class could trigger 'change' events when attributes change.

Parents: @class

Children: @public, @private

@throw or @throws
// @throws {UnexpectedError} when an unknown error raises. 

Specifies an error which method throws. A @throws tag has the structure @throws {type} description. The {type} is optional. A method can contain multiple throw declarations, often one for each type of error thrown.

Parents: @method

Children: @public, @private

@public or @private
// @property {Color} color the color of this fruit. 
// @public

You can add @public or @private annotation to any method, property, etc to declare that it is public or private.

Parents: @method, @property, @event

Object Oriented Programming

For documenting our source code with short-jsdoc we will be using the Object Oriented Programming paradigm (OOP). So short-jsdoc will be better suited to document those projects that uses POO than other paradigms, like functional. You should be familiar with POO, but just in case here is a summary:

Software is organized in several Modules which are the first building block for modularization of responsibilities in a project. Modules contains classes that can be instantiated and which instances collaborate to solve a problem. classes which are the main behavior building block in POO:

  • A class might extend another class. For example, the class Car extends from the class Vehicle and this means that a Car is and can do what any other Vehicle is/does and also have some particularities, like it has an engine and four wheels.
  • A class contains properties which defines the state of its instances. For example the class Car has the 'color' property which defines the car's color.
  • A class might contain methods which defines the behavior of classes. For example, the class Car have a method startEngine()
  • Instances of a class could trigger events to notify other objects that something interesting happens. For example, cars could trigger the event 'engine-started' to notify other interested objects that that particular car instance engine's just started.

jsdoc

jsdoc is a technology in which the programmer writes source code comments that contains some special markings to declare and describe its project's Object oriented elements like modules, classes, properties, etc.

These markings have the format @foo and are called annotations

Then a jsdoc tool will parse the source code files and collect all these annotations to form an Abstract Syntax Tree (AST)

Alternatively, another tools will be responsible of showing this AST visually so the user can navigate through classes, modules, methods, etc.

Let's see a little example of JavaScript code that contains a jsdoc comment. It declares a class FileView of module myapp that extends class AbstractView and contains a property file of type FileData and a method deleteFileHandler that accept a Function parameter and returns a Promise object:

// @module myapp
// @class FileView This view shows a single file @extends AbstractView
// @property {FileData} file
// @method deleteFileHandler Handles the delete file action 
// @param {Function} fn 
// @returns {Promise}
                        

Annotation syntax

The tool will be consuming expressions like the following to build the AST. We call these expressions annotations:

// @param {Color} color a description for the color parameter

Annotation parts

  • @param is the annotation and defines the type of node we are declaring. In this case we are declaring a method parameter
  • {Color} is optional. Is a refence of the type of the node we are declaring.
  • color is optional too and it is the name of the node we are declaring.
  • The text a description for the color parameter is associated to the node and documents it

Tree structure

The structure of the generated tree is as follows.

  • A @module contains @class
  • A @class contains @method, @property, and @event
  • A @method contains @param, @return and @throw

In short-jsdoc only certain nodes can contain children and are the following:

@module @method @property @event @class

All other annotations are leaf nodes meaning they can't contain children and always belong to a parent node. Example of leaf nodes:

@param @throws @returns @extends @static

Parsing

The parser will read your files from top to bottom parsing any annotation found in your source code comments.

When a leaf node annotation is found, it is assigned as children of the last parsed parent node.

When a parent node annotation is found it is assigned as children of the last parent node that matches the structure 'modules that contain classes that contains methods, etc'.

Any kind of comment style can be used.

Any @annotation name can be used so you can define your own semantics - they will be parsed as children of the last parent node read.

Source code files must be auto-containable - in other words you cannot make any assumptions about the order of the files being parsed.

Ignored comments

Comments starting with the character '?' will be ignored, even if they contain annotations:

//? @class Something will be ignored b the parser
/*? @method foo also will be ignored */

Class inheritance

short-jsdoc supports class inheritance. Only single class inheritance is supported, this is, a class can only extend only other one class. Also, javascript.Object is the root class, meaning that, if a class doesn't declare any inheritance then the tool will assume it extends from javascript.Object.

For declaring inheritance we use the class-level annotations @extend or @extends. In the following example we declare that class Dog extends from class Animal:

// @class Animal lorem ipsum @property {Number} age
// @class Dog @extends Animal @method bark @return {Sound}

Important: you can only extend simple types, for example the following won't work: @class Apples @extends Array<Fruit>

Interfaces

short-jsdoc supports the concept of class's interfaces. An interface is a well known concept in Object oriented programming for describing contracts that classes/objects must respect. A class can 'implement' several interfaces and, for declaring that, we use the annotation @implement or @implements at the class level.

For declaring an interface we use the annotation @interface that is very very similar to @class annotation. interfaces can contain just the same things as classes like methods, properties, events, etc.

Also interfaces can inherit from other interfaces by using @extend or @extends, just as classes.

In the following code we declare a class LittleRadio that implements two interfaces Throwable and SoundMaker. Also interface Throwable extends interface IBase:

// @interface Throwable @extends IBase @method throw
// @interface SoundMaker @method play @method stop
// @class LittleRadio @extends Radio @implements Throwable @implements SoundMaker

Types

Types are optional, always

Some nodes like parameters or returns can declare a type, which is a reference to class nodes. short-jsdoc heavily support types and can be of the following kinds:

Simple types

Are just a reference to a class by name, for example:

// @method getModel @returns {Banana}

Native types

If you reference a JavaScript native type like String, Array, Object, etc., they will be binded to the Mozilla JavaScript Types Reference. Some native types are:

Object, Number, Boolean, String, Array, Function, Error, etc

Alternative you can instruct short-jsdoc parser to also include build in natives types documentation. In that case instead an external link you can navigate to the type as with any other types and the inherited information will be available.

Generic types

These are inspired in Java or C# generics. For example we can say that a parameter is an Array but we can also say it is an Array of Bananas :

// @method addFruit @param {Array<Banana>} fruits

Generic types support arbitrary nesting:

// @method groupWires @returns {Object<String,Array<Wire>>} a map of wires by name.

Multiple types - (OR)

Imagine a method in which its first param can be both a String or an Array. Then we can say so in jsdocs like this:

@method foo @param {String|Array} p

Literal Object

Because in JavaScript is very common to define Objects on the fly shortjsdoc supports an object literal type definition:

@method foo @returns {id:String,colors:Array<Color>,execute:Function}

That means that the method foo returns an object with the properties id of type String, color of type Array of Color and execute of type Function.

Text Markings

Marks inside a node text can be defined using the syntax @?something. This is mostly used for defining references to other nodes or to external links from within the text. It is similar to java's @see annotation.

We can use @?class AClass or @?method module.Class.method1 or @?property, @?event, etc. These markings will create a link to the referenced node in the output. Example:

// @module client
// @class CustomerModel This model represent a single customer. 
// The attributes of this model are defined by the @?class server.CustomerService service 
// @extends Backbone.Model

Also, there is a @?ref that will accept any kind of node. For classes is intelligent and you can use the class' simple name, but for referencing other types like methods, properties, events, etc you need to reference them by absolute name, this is $module.$className.$methodName.

Aliases

Type alias

There is a very powerful annotation @alias that let declare alias for types and even for annotations.

Suppose you want to integrate an external jsdoc file in which the type 'float' is used instead of Number. You want the tool to replace each 'float' type with 'Number', so you would add the following (before):

// @alias class float Number

Even more interesting, you want to create shortcuts to common js types, so instead writing Object < String, < Array < Number>>> you can just write O < S, < A < N>>>, well that can be done by just defining class alias:

// @alias class O Object
// @alias class A Array
// @alias class S String
// @alias class N NUmber
                        

Then when the type 'A' is found it will be replaced by 'Array'

Annotation alias

the @alias plugin also supports another kind of aliasing that gives the user the power of creating aliases of annotations. For example, suppose that we are not documenting js-doc but another thing, like the grunt/gulp build tasks and we want to use the annotation @gulp-task to be processed as if they were @module, then we can just write:

// @alias annotation gulp-task module

After that declaration, all annotations @gulp-task will be treated as if they were @module.