I have the following JavaScript.
It is a RequireJS module that has its functions namespaced into an object literal. I referred to: How do I JSDoc A Nested Object's Methods? to find out how to mark up the JSDoc notations.
I run JSDocs 3.3.0-beta3 with private: true in a grunt task but on the modules page there are no private methods or arguments for the publich method.
/**
* A module doing a lot of Foo.
* #module Foo
* #requires jquery
* #author Markus Falk
*/
define(['jquery'], function($) {
'use strict';
/**
* #property {Object} Container
*/
var Foo = {
/**
* Caches all jQuery Objects for later use
* #function
* #private
*/
_cacheElements: function() {
this.$foo = $('.foo');
},
/**
* inits the app and returns the Message Text
* #function
* #public
* #param {Object} msg - The message.
* #param {string} msg.text - The message's Text.
* #param {string} msg.author - The message's author.
* #returns {String} Sentence with given message.text
*/
init: function(msg) {
this._cacheElements();
return "Say " + msg.text;
}
};
return /** #alias module:Foo */ {
/** init */
init: Foo.init
};
});
Here is the output of this JSDoc code:
Try #function init and #function _cacheElements
/**
* A module representing a Foo.
* #module Foo
* #requires jquery
* #author Markus Falk
*/
define(['jquery'], function($) {
'use strict';
/**
* #property {Object} Container
*/
var Foo = {
/**
* Caches all jQuery Objects for later use
* #function _cacheElements
* #private
*/
_cacheElements: function() {
this.$foo = $('.foo');
},
/**
* inits the app and returns the Message Text
* #function init
* #public
* #param {Object} msg - The message.
* #param {string} msg.text - The message's Text.
* #param {string} msg.author - The message's author.
* #returns {String} Sentence with given message.text
*/
init: function(msg) {
this._cacheElements();
return "Say " + msg.text;
}
};
return /** #alias module:Foo */ {
/** init */
init: Foo.init
};
});
Related
I'm trying to document some old code with JSDoc3, and I'm stuck trying to get it to include in the documentation the parameters to instance methods - or to show anything as an instance property at all. I suspect the problem is that the code does not follow the expected idiom for faking classes in javascript, but I want to get everything documented before I start rewriting anything. I've tried to make a small example of the problem, with the structure of the actual code:
/**
* Global function
* #param {Object} v Stuff that they're trying to avoid making global
* #return {Object} Updated v
*/
jsdoc_test = function( v ) {
/**
* Some stuff is defined in this namespace
* #namespace space
*/
var space = {};
/**
* Something that acts like a class
* #name space.someclass
* #memberOf space
* #constructor
* #type {function}
* #param {any} y blah blah
* #return {Object} The constructed object
*/
space.someclass = function( w ) {
var obj = {
source: w, // might need this again
derived: foo( w ), // what we usually need
etc: "etc" // and so on
};
/**
* This should be a member function, but it appears as a static property
* #name space.someclass.methodA
* #memberOf space.someclass
* #type {function}
* #instance
* #param {any} x Parameters do not appear in documentation
* #return {Object} this
*/
obj.methodA = function( x ) {
bar( x ); // or whatever methodA does
return this;
}
/**
* This should be a member function, but it doesn't show up at all
* #name space.someclass.methodB
* #memberOf space.someclass#
* #type {function}
* #param {any} y Parameters do not appear in documentation
* #return {Object} this
*/
obj.methodB = function( y ) {
baz( y ); // or whatever methodB does
return this;
}
return obj;
/**
* This should be a member function, but it doesn't show up at all
* #name space.someclass.methodC
* #memberOf space.someclass.prototype
* #type {function}
* #param {any} z Parameters do not appear in documentation
* #return {Object} this
*/
obj.methodC = function( z ) {
qux( z ); // or whatever methodC does
return this;
}
return obj;
}
// ...
}
I want all three methods to appear in the generated documentation as instance methods. As it is, methodA appears as a static property, while methodB and methodC (which follow suggestions from here) do not appear at all
How do I get JSDoc3 to document instance methods, with their parameters, without rewriting the code?
A combination of #instance, #memberOf & #method should do it:
/**
* This should now be a member function.
* #instance
* #memberOf space.someclass
* #method methodA
* #param {*} x Some parameter of any type.
* #return {Object} this.
*/
Looks like you're using too many tags on your code. When you use #constructor, you shouldn't need #name or #type, since those are covered by using constructor.
So, you've got two options, I think.
Use #constructor and remove the redundant (conflicting) tags:
/**
* Something that acts like a class
* #constructor space.someclass
* #memberOf space
* #param {any} y blah blah
* #return {Object} The constructed object
*/
Or, if you don't want to use the #constructor tag, add the appropriate hinting yourself:
/**
* Something that acts like a class
* #name space.someclass
* #memberOf space
* #kind class
* #param {any} y blah blah
* #return {Object} The constructed object
*/
In both cases, #type is redundant since you're documenting a class; the type would technically be the full name of your function (i.e., #type {space.someclass}).
I have the following AMD structure for my modules.
/* globals define */
define([""], function() {
'use strict';
var module = {};
function _somePrivateFunc() {}
function somePublicFunc() {}
module.somePublicFunc = somePublicFunc;
return module;
});
I'm struggling with JSDoc to make it work with my modules. Until now, I could make it work like
/* globals define */
/**
* Module description here
* #module some/module/name
*/
define([""], function() {
'use strict';
/**
* #alias module:some/module/name
*/
var module = {};
function _somePrivateFunc() {}
function somePublicFunc() {}
/**
* Some property description here
* #itWorks
*/
module.somePublicFunc = somePublicFunc;
return module;
});
As you can see, it's working. But I want my doc comments to be defined on the function declarations instead where I add them to the module. I want to achieve this:
/* globals define */
/**
* Module description here
* #module some/module/name
*/
define([""], function() {
'use strict';
/**
* #alias module:some/module/name
*/
var module;
/**
* Somehow make this appear in JSDoc
* #extend module:some/module/name
* #private
*/
function _somePrivateFunc() {}
/**
* Make this appear in JSDoc for sure.
*/
function somePublicFunc() {}
// I want this to NOT annotate, and I want the property to gather JSDoc
// from the func. declaration
module = {
somePublicFunc: somePublicFunc
};
return module;
});
The latter one is what I would like to achieve, but sadly it's not working :(
Any ideas?
Cheers
Edit:
I made some progress. Mind, that if I write only this:
define('dep', function(require) {
/**
* #exports dep
*/
var module = {};
/**
* Adds two numbers together.
* #param {Number} a the first number
* #param {Number} b the second number
* #return {Number} the sum of a and b
*/
function sum(a, b) {
return a + b;
}
module.sum = sum;
return module;
});
then the output is empty. JSDoc can't generate the documentation properly. Although if I add a #method <name> annotation to my function, then it automagically works great. Interesting, but adding only a #method annotation without a name is not sufficient enough. My final working solution looks like:
define('dep', function(require) {
/**
* #exports dep
*/
var module = {};
/**
* Adds two numbers together.
* #func sum
* #param {Number} a the first number
* #param {Number} b the second number
* #return {Number} the sum of a and b
*/
function sum(a, b) {
return a + b;
}
/**
* Creates a closure. Adds two numbers together
* #func _add
* #param {Number} a the closure variable to add statically
* #return {Function} the closure
* #private
*/
function _add(a) {
return function(b) {
return a + b;
};
}
module.sum = sum;
return module;
});
The CLI flag -p makes the private members to appear in the documentation.
Additional info
I was able to make inner links only one way through my sample code:
/**
* Adds two numbers together.
* #func sum
* #param {Number} a the first number
* #param {Number} b the second number
* #return {Number} the sum of a and b
* #see {#link module:dep~_add|_add}
*/
function sum(a, b) {
return a + b;
}
I'm trying to use jsDoc on my js code in which I want to define:
- A Namespace.
- A Class.
- A Static Method.
Note that the code does exactly what I expect at runtime, but I have problems to getting started with jsDoc, so I question myself if code is correct...
/** #namespace
* #name myNamespace
* #description myNamespace description.
*/
if (typeof (myNamespace) == "undefined") myNamespace = { };
/** #class
* #name myClass
* #description myClass description.
* #memberof myNamespace
* #inner
*/
myNamespace.myClass = function () { };
/** #method
* #name myStaticMethod
* #description myStaticMethod description.
* #param {String} myParam. Required. myParam description.
* #return myReturnValue description.
* #remarks remarks description.
* #memberof myNamespace.myClass
* #inner
*/
myNamespace.myClass.myStaticMethod = function (myParam) {
var myReturnValue = myParam;
return myReturnValue;
};
When I generate with jsDoc I see in the index:
- Correct myNamespace definition.
- Correct myClass definition.
When I go inside myClass I cannot see myStaticMethod...
myStaticMethod is not present anywhere.
My JS is coded correctly?
If is correctly coded... Is the comments correctly written?
What's wrong?
Thanks a lot...
If you're going to use #name, you need to tell JsDoc what the member is; using #name tells JsDoc to completely ignore context.
In your case, I think you need to add #static (you already have #memberof, so that's good).
T.J. Crowder was right, I cannot vote becouse I'm young in community, this is the corrected code comments for jsDoc if someone need:
/** #namespace
* #name myNamespace
* #description myNamespace description.
*/
if (typeof (myNamespace) == "undefined") myNamespace = { };
/** #class
* #name myNamespace.myClass
* #description myClass description.
* #memberof myNamespace
* #inner
*/
myNamespace.myClass = function () { };
/** #function
* #static
* #name myNamespace.myClass.myStaticMethod
* #description myStaticMethod description.
* #param {String} myParam. Required. myParam description.
* #return myReturnValue description.
* #remarks remarks description.
* #memberof myNamespace.myClass
* #inner
*/
myNamespace.myClass.myStaticMethod = function (myParam) {
var myReturnValue = myParam;
return myReturnValue;
};
I'm trying to create documentation based on the following structure:
/**
* #ngdoc service
*
* #name module:resource
* #module module
* # return {Object} The returned object
*/
angular.module('module').factory('resource', [
function () {
function Foo (param1) {
//Do something with param1
}
return {
Test: {
/**
* #ngdoc function
* #name resource#theTest
* #methodOf module:resource
*
* #description
* Search to see if a study exists with the given protocol identifier
* #param {Object} params The param
* #return {Object} A Promise
*/
theTest: function(param) {
return functionFoo (param);
},
/**
* #ngdoc function
* #name resource#theTest1
* #methodOf module:resource
*
* #description
* Search to see if a study exists with the given protocol identifier
* #param {Object} params The param
* #return {Object} A Promise
*/
theTest1: function(param) {
return functionFoo (param)
}
}
};
}
]);
What I would like to say in the documentation is that the service 'resource' returns an object that returns a collection of functions, but I cannot find the way of doing this with ngdocs. Is it supported?
Thank you
I don't think you could specify a 'map of function' the only type that are supported are Function, object, string, number, ...
But you could instead add a description in your class like:
/*
* #description
* This class return 2 functions as describe below:
* ```js
* {
* theTest {Function} This function do (...)
* theTest1 {Function} This function do (...)
* };
* ```
*/
function Foo (param1) {
Hope this will help
I've been trying to use JSDoc3 to generate documentation on a file, but I'm having some difficulty. The file (which is a Require.js module) basically looks like this:
define([], function() {
/*
* #exports mystuff/foo
*/
var foo = {
/**
* #member
*/
bar: {
/**
* #method
*/
baz: function() { /*...*/ }
}
};
return foo;
}
The problem is, I can't get baz to show up in the generated documentation. Instead I just get a documentation file for a foo/foo module, which lists a bar member, but bar has no baz (just a link to foo's source code).
I've tried changing bar's directive to #property instead, and I've tried changing baz's directive to #member or #property, but none of that helps. No matter what I do, baz just doesn't seem to want to show up.
Does anyone know what directive structure I could use to get baz to appear in the generated documentation?
P.S. I've tried reading pages like this one on the JSDoc site http://usejsdoc.org/howto-commonjs-modules.html, but it only describes cases of foo.bar, not foo.bar.baz.
You can use a combination of #module or #namespace along with #memberof.
define([], function() {
/**
* A test module foo
* #version 1.0
* #exports mystuff/foo
* #namespace foo
*/
var foo = {
/**
* A method in first level, just for test
* #memberof foo
* #method testFirstLvl
*/
testFirstLvl: function(msg) {},
/**
* Test child object with child namespace
* #memberof foo
* #type {object}
* #namespace foo.bar
*/
bar: {
/**
* A Test Inner method in child namespace
* #memberof foo.bar
* #method baz
*/
baz: function() { /*...*/ }
},
/**
* Test child object without namespace
* #memberof foo
* #type {object}
* #property {method} baz2 A child method as property defination
*/
bar2: {
/**
* A Test Inner method
* #memberof foo.bar2
* #method baz2
*/
baz2: function() { /*...*/ }
},
/**
* Test child object with namespace and property def.
* #memberof foo
* #type {object}
* #namespace foo.bar3
* #property {method} baz3 A child method as property defination
*/
bar3: {
/**
* A Test Inner method in child namespace
* #memberof foo.bar3
* #method baz3
*/
baz3: function() { /*...*/ }
},
/**
* Test child object
* #memberof foo
* #type {object}
* #property {method} baz4 A child method
*/
bar4: {
/**
* The #alias and #memberof! tags force JSDoc to document the
* property as `bar4.baz4` (rather than `baz4`) and to be a member of
* `Data#`. You can link to the property as {#link foo#bar4.baz4}.
* #alias bar4.baz4
* #memberof! foo#
* #method bar4.baz4
*/
baz4: function() { /*...*/ }
}
};
return foo;
});
EDIT as per Comment: (Single page solution for module)
bar4 without that ugly property table. ie #property removed from bar4.
define([], function() {
/**
* A test module foo
* #version 1.0
* #exports mystuff/foo
* #namespace foo
*/
var foo = {
/**
* A method in first level, just for test
* #memberof foo
* #method testFirstLvl
*/
testFirstLvl: function(msg) {},
/**
* Test child object
* #memberof foo
* #type {object}
*/
bar4: {
/**
* The #alias and #memberof! tags force JSDoc to document the
* property as `bar4.baz4` (rather than `baz4`) and to be a member of
* `Data#`. You can link to the property as {#link foo#bar4.baz4}.
* #alias bar4.baz4
* #memberof! foo#
* #method bar4.baz4
*/
baz4: function() { /*...*/ },
/**
* #memberof! for a memeber
* #alias bar4.test
* #memberof! foo#
* #member bar4.test
*/
test : true
}
};
return foo;
});
References -
Another Question about nested namespaces
For alternative way of using Namespaces
Documenting literal objects
*Note I haven't tried it myself. Please try and share the results.
Here's a simple way to do it:
/**
* #module mystuff/foo
* #version 1.0
*/
define([], function() {
/** #lends module:mystuff/foo */
var foo = {
/**
* A method in first level, just for test
*/
testFirstLvl: function(msg) {},
/**
* #namespace
*/
bar4: {
/**
* This is the description for baz4.
*/
baz4: function() { /*...*/ },
/**
* This is the description for test.
*/
test : true
}
};
return foo;
});
Note that jsdoc can infer the types baz4.baz4 and test without having to say #method and #member.
As far as having jsdoc3 put documentation for classes and namespaces on the same page as the module that defines them, I don't know how to do it.
I've been using jsdoc3 for months, documenting a small library and a large application with it. I prefer to bend to jsdoc3's will in some areas than have to type reams of #-directives to bend it to my will.
You can't document nested functions directly. I didn't like Prongs solution, so I used a different implementation without namespaces (it's JS, not Java!).
Update:
I updated my answer to reflect the exact use case given by the OP (which is fair, since JSdoc is pretty painful to use). Here is how it would work:
/** #module foobar */
/** #function */
function foobarbaz() {
/*
* You can't document properties inside a function as members, like you
* can for classes. In Javascript, functions are first-class objects. The
* workaround is to make it a #memberof it's closest parent (the module).
* manually linking it to the function using (see: {#link ...}), and giving
* it a #name.
*/
/**
* Foo object (see: {#link module:foobar~foobarbaz})
* #name foo
* #inner
* #private
* #memberof module:foobar
* #property {Object} foo - The foo object
* #property {Object} foo.bar - The bar object
* #property {function} foo.bar.baz - The baz function
*/
var foo = {
/*
* You can follow the same steps that was done for foo, with bar. Or if the
* #property description of foo.bar is enough, leave this alone.
*/
bar: {
/*
* Like the limitation with the foo object, you can only document members
* of #classes. Here I used the same technique as foo, except with baz.
*/
/**
* Baz function (see: {#link module:foobar~foo})
* #function
* #memberof module:foobar
* #returns {string} Some string
*/
baz: function() { /*...*/ }
}
};
return foo;
}
Unfortunately JSdoc is a port of Java, so it has a lot of features that make sense for Java but not for JS, and vice-versa. For example, since in JS functions are first-class objects, they can be treated as objects or functions. So doing something like this should work:
/** #function */
function hello() {
/** #member {Object} */
var hi = {};
}
But it won't, because JSdoc recognizes it as a function. You would have to use namespaces, my technique with #link, or to make it a class:
/** #class */
function Hello() {
/** #member {Object} */
var hi = {};
}
But then that doesn't make sense either. Do classes exist in JS? no, they don't.
I think we really need to find a better documentation solution. I've even seen inconsistencies in the documentation for with how types should be displayed (e.g. {object} vs {Object}).
You can also use my technique to document closures.
Just to improve on Prongs's answer a bit for JSDoc3, I was only able to get it to work when I used the #instance annotation in lieu of #member.
ES6 example code follows:
class Test
{
/**
* #param {object} something
*/
constructor(something)
{
this.somethingElse = something;
/**
* This sub-object contains all sub-class functionality.
*
* #type {object}
*/
this.topology = {
/**
* Informative comment here!
*
* #alias topology.toJSON
* #memberof! Test#
* #instance topology.toJSON
*
* #returns {object} JSON object
*/
toJSON()
{
return deepclone(privatesMap.get(this).innerJSON);
},
...
}
}
}