I have been struggling with getting the below code excerpt's documentation appear properly with doxygen.
I have searched online for the problem; yet, it seems that the documentation not showing up is mostly due to the member function/variable being private. Even though I seem to be documenting a public member function, which is also non-static, I can't get doxygen working properly. I would appreciate any help of yours.
/**
* #brief Algorithm abstraction.
*
* #tparam float_t `float` or `double`.
* #tparam int_t `int64_t` or similar.
* #tparam StepPolicy Policy for selecting a step-size.
* #tparam OraclePolicy Policy for getting first-order information.
*/
template <class float_t, class int_t, template <class, class> class StepPolicy,
template <class, class> class OraclePolicy>
struct Algorithm : public StepPolicy<float_t, int_t>,
public OraclePolicy<float_t, int_t> {
/**
* #brief Default constructor.
*
*/
Algorithm() = default;
/**
* #brief Constructor with a step-size.
*
* #param[in] step Non-negative step-size value.
*/
Algorithm(float_t step) : StepPolicy<float_t, int_t>{step} {}
/**
* #brief Set the initial step-size of the algorithm.
*
* #param[in] step Non-negative step-size value.
*/
void set_stepsize(float_t step) { StepPolicy<float_t, int_t>::set(step); }
/**
* #brief Get the current step-size of the algorithm.
*
* This does *not* change the state of StepPolicy.
*
* #return float_t Current step-size.
*/
float_t get_stepsize() const { return StepPolicy<float_t, int_t>::get(); }
/**
* #brief Get current step-size based on the algorithm's state.
*
* #param[in] k Current iteration count.
* #param[in] N Dimension of `x` and `dx`.
* #param[in] x Current decision vector.
* #param[in] dx Current first-order information.
* #return float_t Current step-size.
*/
float_t get_stepsize(const int_t k, const int_t N, const float_t *x,
const float_t *dx) {
return StepPolicy<float_t, int_t>::get(k, N, x, dx);
}
private:
int_t k{0};
};
I am not sure if doxygen has anything to do with valid code excerpts, but the above code does indeed compile. Does it have anything to do with templates and inheritance? Am I missing something? I mean, for non-inheriting template classes, doxygen can do its job.
By the way, I do not have any concrete StepPolicy or OraclePolicy somewhere in my directories. Moreover, I can see the constructors getting documented properly. I am just stuck.
I can share my Doxygen file here, which is basically just the defaults overridden in MathJax-related settings.
Thank you, in advance, for your time.
Starting with v1.8.14, there is no such a problem. Apparently, the question was a bug, which has been fixed by the maintainers of doxygen.
Related
I'm trying to get jsdoc (version 3.6.7, using node 16) to turn my documented js code into actual documentation, but no matter what I do it just generates an out directory with an index.html that is primarily empty lines, rather than documentation. I've asked about this over on the issue tracker (after I searched the docs and the web for information on what one might be doing wrong to get jsdoc to generate empty files, but I can't for the life of me find anything useful that addresses that) but since it's been a few days, it feels useful to ask here as well, so that an answer in either place can be cross posted.
Running the jsdoc command does not flag any errors with the input, and completes with a normal zero exit code but generates nothing useful, so hopefully someone here's run into his before and can explain what is necessary in addition to the follow code to actually get jsdoc to generate docs.
An example of code that has no errors according to jsdoc, but also yields no docs whatsoever:
import { Errors } from "../errors.js";
import { Models } from "./models.js";
/**
* Several paragraphs of text that explain this class
*
* #class
* #namespace model
*/
export class Model {
/**
* #ignore
*/
static ALLOW_INCOMPLETE = Symbol();
/**
* Also several paragraphs explaining the use of this function.
*
* #static
* #param {*} data
* #param {*} allowIncomplete (must be Model.ALLOW_INCOMPLETE to do anything)
* #returns {*} a model instance
* #throws {*} one of several errors
*/
static create = function (data = undefined, allowIncomplete) {
return Models.create(
this,
data,
allowIncomplete === Model.ALLOW_INCOMPLETE
);
};
/**
* code comment that explains that if you're reading
* this source, you should not be using the constructor,
* but should use the .create factory function instead.
*
* #ignore
*/
constructor(caller, when) {
if (!caller || typeof when !== "number") {
const { name } = this.__proto__.constructor;
throw Errors.DO_NOT_USE_MODEL_CONSTRUCTOR(name);
}
}
}
Running this with jsdoc test.js yields an out dir with an index.html and test.js.html file, the first containing some thirty newlines of "no docs here" with boilerplate wrapper HTML code, and the second containing the original source code with nothing else useful either.
What else does one need to do to get jsdoc to actually generate documentation here?
I have fixed it by not using export infront of classes, instead exporting them at the end of the file. like this:
import { Errors } from "../errors.js";
import { Models } from "./models.js";
/**
* Several paragraphs of text that explain this class
*
* #class
* #namespace model
*/
class Model {
/**
* #ignore
*/
static ALLOW_INCOMPLETE = Symbol();
/**
* Also several paragraphs explaining the use of this function.
*
* #static
* #param {*} data
* #param {*} allowIncomplete (must be Model.ALLOW_INCOMPLETE to do anything)
* #returns {*} a model instance
* #throws {*} one of several errors
*/
static create = function (data = undefined, allowIncomplete) {
return Models.create(
this,
data,
allowIncomplete === Model.ALLOW_INCOMPLETE
);
};
/**
* code comment that explains that if you're reading
* this source, you should not be using the constructor,
* but should use the .create factory function instead.
*
* #ignore
*/
constructor(caller, when) {
if (!caller || typeof when !== "number") {
const { name } = this.__proto__.constructor;
throw Errors.DO_NOT_USE_MODEL_CONSTRUCTOR(name);
}
}
}
export {Model}
Turns out this was posted too early: taking the time to start at the official documentation for classes over on https://jsdoc.app/tags-class.html and running that example through jsdoc works perfectly fine, and subsequently building out that example to match the actual file's code yields working documentation just fine, too.
And in this specific case, there were several problems:
adding #namespace paired with #class was the main problem. Neither were necessary, but the #namespace entry changes how jsdoc parses the rest of a file's documentation, where if methods are to show up, they must use a #name property that includes that namespace. As that was not the case here, nothing ended up showing in the documentation.
having an #ignore on the constructor function, rather than using the #hideconstructor property on the class meant that even with #namespace removed, no documentation got written. JSdoc treats the class docs heading and the constructor as the same thing, so #ignoreing the constructor is treated the same as ignoring the entire class.
Fixing both mistakes, and removing the unnecessary #class at the top, gives perfectly fine documentation:
import { Errors } from "../errors.js";
import { Models } from "./models.js";
/**
* Several paragraphs of text that explain this class
*
* #hideconstructor
*/
export class Model {
/**
* #ignore
*/
static ALLOW_INCOMPLETE = Symbol();
/**
* Also several paragraphs explaining the use of this function.
*
* #static
* #param {*} data
* #param {*} allowIncomplete (must be Model.ALLOW_INCOMPLETE to do anything)
* #returns {*} a model instance
* #throws {*} one of several errors
*/
static create = function (data = undefined, allowIncomplete) {
return Models.create(
this,
data,
allowIncomplete === Model.ALLOW_INCOMPLETE
);
};
/**
* code comment that explains that if you're reading
* this source, you should not be using the constructor,
* but should use the .create factory function instead.
*/
constructor(caller, when) {
if (!caller || typeof when !== "number") {
const { name } = this.__proto__.constructor;
throw Errors.DO_NOT_USE_MODEL_CONSTRUCTOR(name);
}
}
}
I am trying to document C interface of my library with doxygen. All functions are grouped within a virtual classes and the assigned with operator \memberof. Since there are a lot of functions, I would like to assign multiple functions with group operator #{.
/**
* \class Base
*/
/**
* \class Derived
* \extends Base
*/
/**
* \memberof Base
* #{
*/
/**
* \brief Function A
*/
void Base_A();
/**
* \brief Function B
*/
void Base_B();
/** #} */
This creates page for derived class as following:
For some reason, there are two sections for inherited members - public inherited and related. In my opinion, both functions should be in the same category.
Adding \memberof command to every single function seems to solve the problem.
/**
* \class Base
*/
/**
* \class Derived
* \extends Base
*/
/**
* \brief Function A
* \memberof Base
*/
void Base_A();
/**
* \brief Function B
* \memberof Base
*/
void Base_B();
Can someone confirm this being a bug?
Can someone provide a working group assignment of multiple functions to a class? I have hundreds of functions and adding so many commands is not viable.
I hesitate to call this a bug. The \{ \} commands are intended to be used for grouping together with grouping commands like \ingroup, \defgroup, \addtogroup, \weakgroup and in this case it is used together with \memberof.
It sees the \memberof command and 'assigns' the next function to 'Base' conform:
This command makes a function a member of a class in a similar way as \relates does, only with this command the
function is represented as a real member of the class. This can be useful when the programming language does
not support the concept of member functions natively (e.g. C).
It looks like it ignores the \{ and\}.
I have a function with a huge list of options:
/**
* Show dialog in a blocking manner.
*
* #param {object} opts
* #param {string} opts.msg "Body" of the dialog.
* #param {number} opts.timeout Seconds - floating point values are rounded. (ActiveX imposes this)
* #param {string} opts.title Title of the dialog.
* #param {number} opts.icon Use constants for this. (See docs)
* #param {number} opts.buttons Use constants for this. (See docs)
* #param {number} opts.defaultButton Use constants for this. (See docs)
* #returns {number} Use our constants to check for what the user chose.
*/
const showSync = (opts) => {
...
}
But I also have a non-blocking version of this function obviously takes the same options and returns a Promise. It seems quite dirty to copy/paste the docs, as this will decrease maintainability and likelihood for accidental inconsistency.
So what would be great is something like the following:
/**
* Shows dialog in a non-blocking manner.
*
* #inheritdoc showSync
* #returns {Promise<number>} Use our constants to check for what the user chose.
*/
const show = (opts) => {
...
}
Is this possible somehow?
[UPDATE]
This is not a duplicate of JSDoc for reused Function interface because that question is merely about reusing the same definition, while this one is about reusing but also partly overwriting that definition. And hence, the answer there does not answer the question here.
I think the best way to do that with jsdoc is something like this:
/**
* Options for showing a dialog.
* #typedef {Object} ShowOptions
* #property {string} msg "Body" of the dialog.
* #property {number} timeout Seconds - floating point values are rounded. (ActiveX imposes this)
* #property {string} title Title of the dialog.
* #property {number} icon Use constants for this. (See docs)
* #property {number} buttons Use constants for this. (See docs)
* #property {number} defaultButton Use constants for this. (See docs)
*/
/**
* Show dialog in a blocking manner.
*
* #param {ShowOptions} opts
* #returns {number} Use our constants to check for what the user chose.
*/
const showSync = (opts) => {...}
/**
* Shows dialog in a non-blocking manner.
*
* #param {ShowOptions} opts
* #returns {Promise<number>} Use our constants to check for what the user chose.
*/
const show = (opts) => {...}
You could take it a step further and apply a similar concept to the return value as well:
/**
* Use our constants to check for what the user chose.
* #typedef {number} ShowResult
*/
/**
* Show dialog in a blocking manner.
*
* #param {ShowOptions} opts
* #returns {ShowResult}
*/
const showSync = (opts) => {...}
/**
* Shows dialog in a non-blocking manner.
*
* #param {ShowOptions} opts
* #returns {Promise<ShowResult>}
*/
const show = (opts) => {...}
I'm brand new to JSDoc, and I'm trying to figure out the best way to tag my code. For some reason after I label something as a #class, I can't get anything to appear as #inner:
/**
* The logger, to simply output logs to the console (or potentially a variable)
* #class Logger
* #requires 'config/globalConfig'
*/
define(["config/globalConfig"], function (config) {
/**
* Instantiate a new copy of the logger for a class/object
* #constructor
* #param name {string} - The name of the class instantiating the logger
*/
return function (name) {
/**
* #memberOf Logger
* #type {string}
*/
this.name = name;
/**
* Place the message on the console, only for "DEV" level debugging
* #function
* #memberOf Logger
* #param message {string}
*/
this.debug = function (message) {
... some code ...
};
};
});
Right now all the members are appearing as <static>. If I add the #inner tag to any of the attributes/functions they vanish completely from the output.
Edit: I also forgot to mention. The #constructor flag doesn't seem to be working either. If I remove that entire section, it appears the same in the output. The output does not include the #param that I would like to mention with my constructor.
Please let me know if this is completely off, I'm just kind of guessing here since the JSDoc3 documentation is a bit difficult to read.
So I figured it out, still not sure if it's absolutely correct. I had to use "Logger~name" to have it appear correctly as an inner function. According to the JSDoc documentation, this ~ is "rarely used". Seems to be the only thing that works for me.
define(["config/globalConfig"], function (config) {
/**
* The logger, to simply output logs to the console (or potentially a variable)
* #class Logger
* #param name {string} - The name of the class instantiating the logger
*/
return function (name) {
this.name = name;
/**
* Place the message on the console, only for "DEV" level debugging
* #function Logger~debug
* #param message {string}
*/
this.debug = function (message) {
... code ...
};
};
});
*How to Document following function in JSDoc JS-Toolkit *
I want to document try and help method in this main function
but i did not figure it out how to do that.
/** Sample doc
* #class
* #constructor
* #name Sample
*/
var main=function(){
this.value="";
/** help function
* #param {String} Name
*/
this.help=function(name){
console.log('help me'+name);
}
/** help function
* #param {String} Name
*/
this.try=function(name){
console.log('try me'+name);
}
}
I just struggled with this for several hours. I tried:
#member
#augments
#method
#this
From the examples and tutorials I found, member functions and variables should appear in the output simply by having /** description/* comments above them, but I found that was not the case. Like you, I'm using standard JavaScript constructors, where this should be able to be inferred automatically due to the #constructor being in place. Maybe there's some wrinkle I'm not seeing.
In the end, I found two tags that worked for me, #name and#memberof. They both allow you to specify the object that the property is a member of. Using #name in this way is undocumented (at least, I didn't see it anywhere), but very straightforward. You'll also need to use #function.
Here's an example with the #name tag:
/** help function
* #name Sample.try
* #function
* #param {String} Name
*/
this.try=function(name){
console.log('try me'+name);
};
And here's an example with the #memberof tag:
/** help function
* #memberof Sample
* #function
* #param {String} Name
*/
this.try=function(name){
console.log('try me'+name);
};
As you can see the output is almost the same. The only difference that I see is that #memberof includes this. in the method name. For that reason I've settled on using #name.
The remaining issue is that the functions are per-instance, not <static>.
Hope this helps!