diff options
| author | Xavier Morel <xmo@openerp.com> | 2011-03-27 14:05:15 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@openerp.com> | 2011-03-27 14:05:15 +0200 |
| commit | bdddf2269d4990df5df8d04cf4f3eca46c5de3e6 (patch) | |
| tree | 7e9951223275a8067c1ddb0666b5ec781ace3e03 /doc | |
| parent | ab43c4ee485e5071dd32bcd7d16cc70a1fa03998 (diff) | |
[ADD] document documentation (esp. JS APIDoc via JsDoc, which is actually a fairly complex endeavour)
bzr revid: xmo@openerp.com-20110327120515-wdcxc19j4exuu2zu
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/source/project.rst | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/doc/source/project.rst b/doc/source/project.rst index 78beae9dedb..5ef06a7280a 100644 --- a/doc/source/project.rst +++ b/doc/source/project.rst @@ -19,6 +19,193 @@ Merge proposals Writing documentation +++++++++++++++++++++ +The OpenERP Web project documentation uses Sphinx_ for the literate +documentation (this document for instance), the development guides +(for Python and Javascript alike) and the Python API documentation +(via autodoc_). + +For the Javascript API, documentation should be written using the +`JsDoc Toolkit`_. + +Guides and main documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The meat and most important part of all documentation. Should be +written in plain english, using reStructuredText_ and taking advantage +of `Sphinx's extensions`_, especially `cross-references`_. + +Python API Documentation +~~~~~~~~~~~~~~~~~~~~~~~~ + +All public objects in Python code should have a docstring written in +RST, using Sphinx's `Python domain`_ [#]_: + +* Functions and methods documentation should be in their own + docstring, using Sphinx's `info fields`_ + + For parameters types, built-in and stdlib types should be using the + combined syntax:: + + :param dict foo: what the purpose of foo is + + unless a more extensive explanation needs to be given (e.g. the + specification that the input should be a list of 3-tuple needs to + use ``:type:`` even though all types involved are built-ins). Any + other type should be specified in full with a cross-reference using + the ``:type:`` field:: + + :param foo: what the purpose of foo is + :type foo: :class:`some.addon.Class` + + Likewise, mentions of other methods (including within the same + class), modules or types should be cross-referenced. + +* Classes should likewise be documented using their own docstring, and + should include the documentation of their construction (``__init__`` + and ``__new__``), using the `info fields`_ as well. + +* Attributes (class and instance) should be documented in their + class's docstrin via the ``.. attribute::`` directiveg, following + the class's own documentation. + +* The relation between modules and module-level attributes is similar: + modules should be documented in their own docstring, public module + attributes should be documented in the module's docstring using the + ``.. data::`` directive. + +Javascript API documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Javascript API documentation uses JsDoc_, a javascript documentation +toolkit with a syntax similar to (and inspired by) JavaDoc's. + +Due to limitations of JsDoc, the coding patterns in OpenERP Web and +the Sphinx integration, there are a few peculiarities to be aware of +when writing javascript API documentation: + +* Namespaces and classes *must* be explicitly marked up even if they + are not documented, or JsDoc will not understand what they are and + will not generate documentation for their content. + + As a result, the bare minimum for a namespace is:: + + /** @namespace */ + foo.bar.baz = {}; + + while for a class it is:: + + /** @class */ + foo.bar.baz.Qux = [...] + +* Because the OpenERP Web project uses `John Resig's Class + implementation`_ instead of direct prototypal inheritance [#]_, + JsDoc fails to infer class scopes (and constructors or super + classes, for that matter) and has to be told explicitly. + + See :ref:`js-class-doc` for the complete rundown. + +* Much like the JavaDoc, JsDoc does not include a full markup + language. Instead, comments are simply marked up in HTML. + + This has a number of inconvenients: + + * Complex documentation comments become nigh-unreadable to read in + text editors (as opposed to IDEs, which may handle rendering + documentation comments on the fly) + + * Though cross-references are supported by JsDoc (via ``@link`` and + ``@see``), they only work within the JsDoc + + * More general impossibility to integrate correctly with Sphinx, and + e.g. reference JavaScript objects from a tutorial, or have all the + documentation live at the same place. + + As a result, JsDoc comments should be marked up using RST, not + HTML. They may use Sphinx's cross-references as well. + +.. _js-class-doc: + +Documenting a Class +******************* + +The first task when documenting a class using JsDoc is to *mark* that +class, so JsDoc knows it can be used to instantiate objects (and, more +importantly as far as it's concerned, should be documented with +methods and attributes and stuff). + +This is generally done through the ``@class`` tag, but this tag has a +significant limitation: it "believes" the constructor and the class +are one and the same [#]_. This will work for constructor-less +classes, but because OpenERP Web uses Resig's class the constructor is +not the class itself but its ``init()`` method. + +Because this pattern is common in modern javascript code bases, JsDoc +supports it: it is possible to mark an arbitrary instance method as +the *class specification* by using the ``@constructs`` tag. + +.. warning:: ``@constructs`` is a class specification in and of + itself, it *completely replaces* the class documentation. + + Using both a class documentation (even without ``@class`` itself) + and a constructor documentation is an *error* in JsDoc and will + result in incorrect behavior and broken documentation. + +The second issue is that Resig's class uses an object literal to +specify instance methods, and because JsDoc does not know anything +about Resig's class, it does not know about the role of the object +literal. + +As with constructors, though, JsDoc provides a pluggable way to tell +it about methods: the ``@lends`` tag. It specifies that the object +literal "lends" its properties to the class being built. + +``@lends`` must be specified right before the opening brace of the +object literal (between the opening paren of the ``#extend`` call and +the brace), and takes the full qualified name of the class being +created as a parameter, followed by the character ``#`` or by +``.prototype``. This latter part tells JsDoc these are instance +methods, not class (static) methods.. + +Finally, specifying a class's superclass is done through the +``@extends`` tag, which takes a fully qualified class name as a +parameter. + +Here are a class without a constructor, and a class with one, so that +everything is clear (these are straight from the OpenERP Web source, +with the descriptions and irrelevant atttributes stripped): + +.. code-block:: javascript + + /** + * <Insert description here, not below> + * + * @class + * @extends openerp.base.search.Field + */ + openerp.base.search.CharField = openerp.base.search.Field.extend( + /** @lends openerp.base.search.CharField# */ { + // methods here + }); + +.. code-block:: javascript + + + openerp.base.search.Widget = openerp.base.Controller.extend( + /** @lends openerp.base.search.Widget# */{ + /** + * <Insert description here, not below> + * + * @constructs + * @extends openerp.base.Controller + * + * @param view the ancestor view of this widget + */ + init: function (view) { + // construction of the instance + }, + // bunch of other methods + }); + OpenERP Web over time --------------------- @@ -30,3 +217,35 @@ Roadmap Release notes +++++++++++++ + +.. [#] because Python is the default domain, the ``py:`` markup prefix + is optional and should be left out. + +.. [#] Resig's Class still uses prototypes under the hood, it doesn't + reimplement its own object system although it does add several + helpers such as the ``_super()`` instance method. + +.. [#] Which is the case in normal Javascript semantics. Likewise, the + ``.prototype`` / ``#`` pattern we will see later on is due to + JsDoc defaulting to the only behavior it can rely on: "normal" + Javascript prototype-based type creation. + +.. _reStructuredText: + http://docutils.sourceforge.net/rst.html +.. _Sphinx: + http://sphinx.pocoo.org/index.html +.. _Sphinx's extensions: + http://sphinx.pocoo.org/markup/index.html +.. _Python domain: + http://sphinx.pocoo.org/domains.html#the-python-domain +.. _info fields: + http://sphinx.pocoo.org/domains.html#info-field-lists +.. _autodoc: + http://sphinx.pocoo.org/ext/autodoc.html?highlight=autodoc#sphinx.ext.autodoc +.. _cross-references: + http://sphinx.pocoo.org/markup/inline.html#xref-syntax +.. _JsDoc: +.. _JsDoc Toolkit: + http://code.google.com/p/jsdoc-toolkit/ +.. _John Resig's Class implementation: + http://ejohn.org/blog/simple-javascript-inheritance/ |
