Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class Methods in CommonJS modules not displayed #121

Closed
esatterwhite opened this issue May 30, 2012 · 7 comments
Closed

Class Methods in CommonJS modules not displayed #121

esatterwhite opened this issue May 30, 2012 · 7 comments

Comments

@esatterwhite
Copy link

Currently, it doesn't seem possible to get class methods to be displayed property if the class is defined inside of a module.

I have tried a number of different combinations of tags.

I have to declare a modules with /* @module */

I have to define a class as a property of the exports objects with /** @constructor */

This will display and link the class from the module page, however the class page will not have any of the defined methods.

I have tried defining the methdos with @function name / @method name and without. I have used the @memberof tag, and in a variety of combinations. Only the constructor for the Class is ever documented.

Alternatively, you can define and document the Class as a variable and assign it to the exports object later. The class methods will be documented, however the class will be assumed to be a global and not a member of the module.

@micmath
Copy link
Contributor

micmath commented May 30, 2012

A small example demonstrating the code you are trying to document would be instructive. I'm guessing what you are trying to document, but if it is like this then it should work as expected.

/** @module MyModule */

/** @constructor */
exports.MyConstructor = function() {
    /** Describe me. */
    this.myMethod1 = function() { }
}

/** Describe me. */
exports.MyConstructor.prototype.myMethod2 = function() { }

@esatterwhite
Copy link
Author

We have a Class system the hide the prototype style. We're were previously using YUIDoc, But our latest project does everything with modules and are moving to JSDoc3 because of the module support.

/**
 * This does some stuff
 * @module foobar
 * @requires stuff
 */



        /**
         * A Class definition
         * @class Foo
         * @param {String} type ...
         * @see #set
         * @param {Object} options ...
         * @meenberof stuf
         */
        exports.Foo= Foo = new Class({
            /**
             * @constructor
             * @param {String} baz
             * @param {Object} options
             */
            ,initialize: function( baz, options ){

            }
            /**
             * This get a new Bar
             * @method getBar
             * @memberof stuff
             * @param {String} bar
             * @return {Bar} 
             */
            , getBar: function getElements(expression) {
                             return new Bar();
            }
        });

@micmath
Copy link
Contributor

micmath commented Jun 3, 2012

This isn't really a bug report or feature request, rather a support question, so probably should have been addressed to the jsdoc-users mailing list. However, since we are here...

Two points that may help: 1) if you are using a non-standard (meaning one that JSDoc doesn't know :) class construction pattern, like "new Class()" you will probably want to use the @lends tag, since it gives you a shortcut to having to say @memberof all the time. 2) modules can have the same name as classes, so to disambiguate a module from a class, when you refer to a module in places where it isn't obvious that you mean a module, you should prefix the name of the module with "module:", like "module:foo".

Considering that, I'd document your pattern like so:

/**
 * Describe me.
 * @module mymodule
 */

exports.Foo = Foo = new Class( /** @lends module:mymodule.Foo */ {
    /**
     * Describe me.
     * @constructs
     * @param {String} baz
     * @param {Object} options
     */
    initialize: function( baz, options ) {
        /** Describe me. */
        this.someproperty = 1;
    },

    /**
     * Describe me.
     * @param {String} expression
     * @returns {Bar} 
     */
    getBar: function(expression) {
        return new Bar();
    }
});

Notice I moved the leading commas in the object-literal. If you're willing to do that it makes life a bit easier for you, because JSDoc can understand more about you code if you put the doc comments immediately before the thing being commented on (and you are not commenting on those commas, right?). If you are not able to shift your commas, then JSDoc can still be used to document your code, but it requires more work from you -- just say so and I'll show you that way too if you wish.

@micmath
Copy link
Contributor

micmath commented Jun 3, 2012

Here's a ref to the user guide for @lends from JSDoc 2. Nothing has changed with regard to this tag in JSDoc 3, so you can still use this to learn more about @lends.

http://code.google.com/p/jsdoc-toolkit/wiki/TagLends

@esatterwhite
Copy link
Author

Thanks for the pointers, that does help a bit. I moved the commas and got it to mostly work as I would like. I would like to see how to do this while keeping the leading commas if you wouldn't mind. Thanks again.

@micmath
Copy link
Contributor

micmath commented Jun 4, 2012

JSDoc can do static analysis on your source code, and thus make an educated guess about what things will be called when your code runs. That's why, in my previous example, you did not have to tell JSDoc what "this" meant in the line this.someproperty. JSDoc could predict that it would be "module:mymodule.Foo#someproperty" so you didn't have to add any @name tag -- this will save you some typing.

However, if you do add the @name tags, then you are free to write your source code in ways that cannot be analysed by JSDoc. In fact, JSDoc will ignore the source code surrounding the named doc comment.

So, the answer is simply that you must provide the name for every symbol in your documentation. If you are able to do this, then you can write any JavaScript you wish, with commas wherever you want.

JSDoc 3 has a shortcut so that instead of having to write:

/**
    @name foo
    @function
*/

(remember, JSDoc is ignoring the code, so you have to tell it that you're documenting a "function" right?)

In JSDoc 3, you can shorten that to just:

/**
    @function foo
*/

The @named version of your code, with the leading commas left in would be:

/**
 * Describe me.
 * @module mymodule
 */

exports.Foo = Foo = new Class( {
    /**
     * Describe me.
     * @constructor module:mymodule.Foo
     * @param {String} baz
     * @param {Object} options
     */
    initialize: function( baz, options ) {
        /**
         * Describe me.
         * @member module:mymodule.Foo#someproperty
         * @type number
         * @defaultvalue 1
         */
        this.someproperty = 1;
    }

    /**
     * Describe me.
     * @method module:mymodule.Foo#getBar
     * @param {String} expression
     * @returns {Bar} 
     */
    , getBar: function(expression) {
        return new Bar();
    }
});

I personally prefer this style of documentation because it gives me total control over what will appear in my docs. On the other hand you give up JSDoc's somewhat handy static code analysis features, so it is a trade-off. JSDoc 3 has yet another improvement that allows you to provide a @name and still does static code analysis on the surrounding code, using the new @alias tag: this allows you to mix the two styles of documenting together, to get the best of both worlds.

NB you can refer to the version 2 docs for more information about the name tag and namepaths.

@esatterwhite
Copy link
Author

Thank you kind sir!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants