AaronNGray / jsdoc-toolkit

Automatically exported from code.google.com/p/jsdoc-toolkit
0 stars 0 forks source link

ENHANCEMENT: Better support for Class.create style documentation #237

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Goal: Document class declarations using the Class.create idiom. Consider the 
following example 
class definition:

    /** Here is my class. It's a real beauty.
     */
    TheClass = Class.create({

        /** This is the constructor!
            @param zebra    An instance of a black and white striped thing.
         */
        constructor: function(zebra)
        {
        },

        /** A function taking two arguments returning nothing.
         */
        foo: function(bar, baz)
        {}

    });

What's in this DIFF?
1. A slight tweak to main.js because it was crashing when I'd pass it a path 
that contained a 
trailing slash.
2. A new plugin, CoherentPlugin, that does some behind the scenes manipulation 
when the 
Class.create function is encountered. It automatically inserts a @lends tag for 
the upcoming 
object literal, and determines whether arg1 represents an existing class. If 
so, it will retroactively 
create an @augments tag for the class being created. It also trims off extra 
white space from the 
beginning of doc comments for folks who don't like to use asterix on each line. 
(This makes 
using markdown in my templates nicer, otherwise my comments become code blocks.)
3. A slight tweak to Symbol.js to prevent re-creating parameters as symbols. 
This is needed 
because my code calls setTags to get the symbol to reset its internal state.
4. Modifications to Walker.js to allow the 'constructor' function to be 
automatically recognised as 
a constructor (seemed logical and is also nice since that's how Coherent 
declares its 
constructors). Also when discovering a constructor (or a function marked with 
@constructs), this 
will fix up an existing symbol if necessary.

I was careful to keep project specific logic in a plugin and only changed the 
jsdoc source where 
absolutely necessary. The changes to Symbol.js and Walker.js are beneficial 
even without the 
CoherentPlugin.js file, because it allows developers to document the class 
where it's defined and 
the constructor where it's defined.

Original issue reported on code.google.com by jwmetrocat@gmail.com on 24 Aug 2009 at 5:33

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by micmath on 12 Sep 2009 at 6:29

GoogleCodeExporter commented 9 years ago
Looks like what @class and @lends 
(http://code.google.com/p/jsdoc-toolkit/wiki/TagLends) are for?

Original comment by wke...@gmail.com on 8 Nov 2009 at 7:05

GoogleCodeExporter commented 9 years ago
This can already be documented quite easily, without any patch, like so:

TheClass = Class.create(
    /** @lends TheClass.prototype */
    {

        /** This is the constructor!
            @constructs
            @class Here is my class. It's a real beauty.
            @param zebra    An instance of a black and white striped thing.
         */
        constructor: function(zebra)
        {
        },

        /** A function taking two arguments returning nothing.
         */
        foo: function(bar, baz)
        {}

    }
);

I would rather not modify walker.js to treat things named "constructor" in a 
special way, but I will investigate 
the bug you reported involving the trailing slash.

Original comment by micmath on 8 Nov 2009 at 9:42

GoogleCodeExporter commented 9 years ago
I'd rather keep the @constructs tag as the official way to indicate a 
constructor function, so I'm not applying the 
changes to walker.js. I have however added the fix to main.js in revision 818. 
I think the existing plugin 
'frameworkPrototype.js' could be modified to do what you want without changes 
to walker.

Original comment by micmath on 8 Nov 2009 at 2:54

GoogleCodeExporter commented 9 years ago
Although it's possible to redefine the constructor, the default language 
behaviour is to expose the original 
constructor using the field 'constructor'. Therefore, I don't feel that the 
modification to walker.js is invalid.

If you have the following code:

    function MyClass() {}
    var m= new MyClass();

The value of m.constructor will be MyClass.

Can you recommend a way to implement this behaviour via a plugin?

Original comment by jeff%met...@gtempaccount.com on 16 Nov 2009 at 7:20

GoogleCodeExporter commented 9 years ago
It's hard to answer your question, without knowing exactly what your goal is. 
At one point you said it was to "Document 
class declarations using the Class.create idiom," and I think I've shown how 
that can be done. It sounds like your new 
goal is to have things named 'constructor' automatically get treated as if they 
had a @constructs tag. There probably isn't 
anyway to do that without modifying the source code of Walker.js, as that is 
where there is already some magic being 
applied to make the @constructs tag work at all. However, as I said, I'd rather 
not have things named 'constructor' 
treated in a special way by the documentation generator, that's what the 
@constructs tag is for: it's more flexible 
because it can be applied to any function regardless of name, it's already a 
known and documented way of doing it, and I 
don't think it's too difficult to add a @constructs tag when documenting a 
function that will be used as the constructor.

For the above reasons I don't want to add any automatic treatment for things 
named "constructor" to Walker, but it 
should be possible for anyone else to add a plugin that will layer this 
behavior on top of the core. To make that possible 
I added a new hook for the plugin manager, named 'onConstructorDefined' 
(committed in revision 825). you would 
register for this by adding a file to the app/plugins folder (named 
anythingYouWant.js) with some code like this:

JSDOC.PluginManager.registerPlugin(
    "JSDOC.constructor", // name it anything unique, maybe "metrocat.thingy"?
    {
        onConstructorDefined: function(doc) {
            doc.parse(doc.src += "\n@constructs");
        }
    }
);

Original comment by micmath on 22 Nov 2009 at 2:08

GoogleCodeExporter commented 9 years ago
OK, I should have been a bit more clear. This plug in makes documenting 
Class.create, Class.extend, and 
Object.extend automatic without the use of @lends or @constructs. The existing 
technique requires 
substantial code changes and does not improve the readability of the code. This 
plug in also permits 
documenting the class separately from documenting the constructor, without 
additional tags.

I respect your desire to minimise special casing identifiers (e.g. 
constructor), so I've reworked the plug in, 
CoherentPlugin.js to perform its magic in onSymbol. This alleviates the need 
for onConstructorDefined.

The one change to the framework that's still required is the patch to 
Symbol.js. This prevents adding 
parameters more than once.

Original comment by jeff%met...@gtempaccount.com on 22 Nov 2009 at 7:50

Attachments:

GoogleCodeExporter commented 9 years ago
Wish granted: Symbol.js modified and committed in  revision 826. The plugin 
looks handy but I'd prefer you 
maintained your own work. You (or I if you like) can announce it on the mailing 
list and I'll happily link to your 
copy of it from the project website or I can post a copy of the file to the 
user's group -- whichever you prefer.

Original comment by micmath on 22 Nov 2009 at 10:40