summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2011-03-27 14:05:15 +0200
committerXavier Morel <xmo@openerp.com>2011-03-27 14:05:15 +0200
commitbdddf2269d4990df5df8d04cf4f3eca46c5de3e6 (patch)
tree7e9951223275a8067c1ddb0666b5ec781ace3e03 /doc
parentab43c4ee485e5071dd32bcd7d16cc70a1fa03998 (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.rst219
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/