Skip to content

Latest commit

 

History

History
238 lines (172 loc) · 7.82 KB

README.md

File metadata and controls

238 lines (172 loc) · 7.82 KB

Getdocs

Getdocs is like JSDoc or documentation.js, running over ES6 code to extract information and inline documentation in order to generate docs, but without all the @s. It takes source files and outputs JSON.

For example, if you have this file, foo.js:

// :: (number, number) → number
// Add two numbers
export function plus(a, b = 2) {
  return a + b
}

You can say getdocs foo.js to get this JSON:

{
  "plus": {
    "type": "Function",
    "params": [
      {
        "type": "number",
        "name": "a"
      },
      {
        "type": "number",
        "default": "2",
        "optional": true,
        "name": "b"
      }
    ],
    "returns": { "type": "number" },
    "description": "Add two numbers",
    "exported": true
  }
}

The idea is to then feed this into a system (can be a simple set of templates) that massages it into actual human-readable documention files.

A getdocs doc comment starts with a double colon, optionally prefixed with a name (foo::) and followed by a type. It can be either a block comment or a continuous sequence of line comments. When you don't want to specify a type, for example because the type can be inferred from the code (as with a class declaration), you can write a single dash after the colons, instead of a type.

When no name is given, such a doc comment applies to the next program element after it. That element should be something with a name, like a variable, function, or class declaration, or an assignment that can be statically resolved.

The documented items found in the files passed to getdocs will be returned as part of a big JSON object. Nesting is only applied for class and object properties, where the properties are moved under the properties object of the item they are part of. A single namespace is assumed for the documented identifiers in the group of files.

Inside a doc comment, properties of the thing being defined can be added by writing nested, indented doc comments. For example:

// Plugin:: interface
//
// Objects conforming to the plugin interface can be plugged into a
// Foo
//
//   mount:: (Foo) → bool
//   Mount the plugin in this Foo. The return value indicates whether
//   the mount succeeded.
//
//   unmount:: (Foo)
//   Unmount the plugin from a Foo.

Further nesting below such a property (by adding more indentation) is supported.

Type syntax

A type can be:

  • A JavaScript identifier, optionally followed by any number of properties, which are a dot character followed by a JavaScript identifier. A type name can be followed by a list of type parameters, between angle brackets, as in Object<string> (an object whose properties hold string values).

  • An array type, which is a type wrapped in [ and ]. [x] is equivalent to Array<x>.

  • A function type, which is written as a parenthesized list of argument types. Each argument type may optionally be prefixed with an argument name, which is an identifier followed by a colon. When an argument is prefixed by the string ..., it is marked as a rest argument. After the closing parenthesis, an optional return type may appear after an arrow, written either or ->.

  • A nullable type, written as a question mark followed by a type.

  • An unspecified or “any” type, written as an asterisk *.

  • An object type, written as a list of properties wrapped in { and } braces. Each property must start with an identifier, followed by a colon, followed by a type.

  • A string literal, enclosed by double quotes, or a number literal.

  • A type followed by extends followed by another type, to indicate a sub-type.

Here are some examples of types:

  • Math.pow: (base: number, exponent: number) → number

  • Element.insertBefore: (newNode: Node, before: ?Node) → Node

  • console.log: (...data: *)

  • A pair of coordinates: {x: number, y: number}

  • An array of strings: [string]

  • An array of numbers or a string: union<[number], string> (what the name union means isn't something getdocs is aware of, but you could use it for union types, and maybe render it as [number] | string in your output).

Tags

It is possible to add tags to a documented item. These are words prefixed with a # character, appearing at the start of the comment — that is, immediately after the type.

A tag like #deprecated, for example, will result in a $deprecated: "true" property on the given item. The property is named by prepending the tag's name with a dollar sign.

You can give tags an explicit value other than "true" by writing an = character followed either by a word (a sequence of characters without whitespace) or a quoted JavaScript-style string. For example #chapter=selection or #added="2.1.0".

The #static tag can be used to indicate that a given class member is static (which is only necessary for doc comments that aren't tied to a syntactic element in the code).

Output JSON

The returned object maps item names to item descriptions. The following properties can appear in a description for a documented item:

  • description: The doc comment for the item.

  • loc: A {line, column, file} object pointing at the start of the item.

  • exported: Set if the item is exported using ES6 module syntax.

  • constructor: For classes with a documented constructor, this points at the constructor function.

  • extends: Holds the type of the supertype of a class or other sub-type.

  • staticProperties: For classes, this holds properties and methods that appear directly on the constructor.

In addition, they may have these properties, which can also appear on nested types:

  • type: The name of the type. Instances of classes should use the (capitalized) class name. Builtin types will have names like Array or Function. Getdocs does not prescribe a naming of primitive types, but for consistency I recommend you use number, string, and bool.

  • properties: An object mapping property names to types.

  • params: For function types, this holds an array of parameter types. Parameter types can have these additional properties:

    • name: The name of the parameter.

    • rest: Set when this is a rest parameter.

    • default: The default value of the parameter (as a raw source string).

  • returns: For function types, this holds the type that is returned.

  • typeParams: For array types or named types with parameters (angle bracket syntax), this holds an array of parameter types.

  • optional: Set for nullable types.

  • id: The path to this type. For a top-level variable foo this'll be "foo", for the type of the property bar under foo, it'll be "foo.bar", and so on.

Interface

The module exports the following function:

gather: (code: string, options: Object) → Object

It takes a code file, extracts the docs, and returns an object describing the documented items.

Options can have the following properties:

  • filename: string The filename of the given code. Required.

  • items: ?Object An existing items object to add the items found in the given code to.

  • onComment: ?(block: bool, text: string, start: number, end: number, startPos: Object, endPos: Object) Will be called for each comment in the code, if given.

parseType: (input: string, start: number, loc: {file: string, line: number}) → {type: Object, end: number}

Parse a type in getdocs syntax into its object representation. start indicates where in the string the parsing should start. The returned object tells you where the type ended.

Will throw a SyntaxError when the type isn't valid.

stripComment: (comment: string) → string

Strips leading indentation and asterisks (as in the common block comment style where each line gets an asterisk) from a string.