-
Notifications
You must be signed in to change notification settings - Fork 1
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
How to document dynamically generated methods? #31
Comments
Can you provide a minimal example code? It would help to check how the parser processes it. |
Here you are: /**
* Test class
*/
class Test {
/**
* Foo function.
*/
foo(str) {
return str + '!';
}
}
['bar', 'baz'].forEach(name => {
Test.prototype[name] = function() {
return this.foo(name);
}
});
// With JSDoc or other tools, I would've documented the functions like this:
// (Maybe with a @memberof, when the comments are outside of the class.)
/**
* @name #bar
* @function
* @description ...
* @returns ...
*/
/**
* @name #baz
* @function
* @description ...
* @returns ...
*/ |
So I did some research into what can be done, and to not let you wait for too long, this is what I found:
Unfortunately ESDoc is old, from ES5- era, and it shows. My fork updates dependencies, replaces unsupported packages, puts all in single monorepo and allows use of modern JS, If you have project, which used ESDoc, you can replace old ESDoc with my fork and it "should work"™. If you are looking for proper documentation generator, I recommend checking other tools and not waste your precious time with ESDoc. I have plans how to make ESDoc better, but I won't lie, I'm slow and few features I work on are in various states of completion and I'm not ready to trust them for retail use... That's TL;DR, I'm sorry I don't have a solution for you. I'm including some more info on why it's not quick hacking to implement ESDoc is abandoned, so I forked it, updated dependencies, replaced unsupported dependencies, added some new functionality here and there... The whole process of how ESDoc works can be divided into three places (phases):
(phase 1) and (phase 2) are done by core ESDoc, (phase 3) is done by So we take file, get AST tree from it, and we traverse this tree, trying to recognize known patters - this is class declaration, this is member declaration, this is function declaration, this is exported etc. For each recognized pattern a This is where first obstacle is found, "extracted tags": There is no JSDoc parsing/lexing done. ESDoc just looks if there is
So
Let's talk more about comments. AST node has comments attached as /**
* Leading comment
*/
{
// Block AST node
}
/**
* Trailing comment
*/ In (phase 1) comments are checked for In (phase 1) comments are chopped by /**
* An example function with `useless` parameter, returning **true**.
* And look,
* It's on multiple lines...
* @param {boolean} [useless=true] - better not be false
* @returns {true}
* @see {link-to-something-more-interesting-here}
*/
function foo(useless = true) {
returns true;
} will create an array with: [
{"tagName": "@desc", "tagValue": "An example function with `useless` parameter, returning **true**.\nAnd look,\nit's on multiple lines..."},
{"tagName": "@param", "tagValue": "{boolean} [useless=true] - better not be false"},
{"tagName": "@returns", "tagValue": "{true}"},
{"tagName": "@see", "tagValue": "{link-to-something-more-interesting-here}"}
]
So ESDoc, in it's two phases, deals with comments like this: /**
* class node leading comment
* - (phase 1) checks for @external, @extend needing special treatment
* - all tags for class must be here, because ClassDoc will be looking here in (phase 2)
*/
class TestClass {
/**
* method node leading comment
* - (phase 1) checks for @external, @extend needing special treatment
* - all tags for foo must be here, because MethodDoc will be looking here in (phase 2)
*/
foo(str) {
return `${str}!`;
}
/**
* Trailing comment
* - is checked in (phase 1)
*/
}
/**
* Trailing comment
* - is checked in (phase 1)
*/ Now to our slightly expanded code example: /**
* Test class
*/
class Test {
/**
* Foo function.
*/
foo(str) {
return str + '!';
}
}
/**
* @name #bar
* @function
* @description ...
* @returns ...
*/
['bar', 'baz'].forEach(name => {
Test.prototype[name] = function() {
return this.foo(name);
}
});
/**
* @function #quax
* @memberof TestClass
*/
TestClass['quax'] = function() {
return this.foo('quax');
}
/**
* @function
*/
const obviouslyNotAFunction = null;
/**
* @function
* @memberof ThisIsNotWhereIDidParkMyClass
*/
const thisIsNotTheFunctionYouAreLookingFor = 42;
// With JSDoc or other tools, I would've documented the functions like this:
// (Maybe with a @memberof, when the comments are outside of the class.)
/**
* @name #baz
* @function
* @description ...
* @returns ...
*/ Let's implement First, let's look at what ESDoc finds: These are the 4 Where can
There's one more place we can find Now more about
If it's present in If If Yes, I know, we're telling ESDoc that those two variables are functions, but that's our order, ESDoc might warn something is fishy, but ultimately document them as global functions... I think we found our place - (phase 1)! It visits leading and trailing comments and we can make it to look at all comments, not only those of detected nodes! If we are clever we can also gather more info ahead of creating It kinda works - we can replace normal But the data we fed to Method not pointing to correct class? Let me take Hmm, this class, which doesn't exist, is not shown, let's try to simulate it and create virtual... What if it exist in other file, which is processed by ESDoc? What do I use as location of the function if it's virtual? Let's point to the place So this way we cannot "create" functions and methods which are not detected by ESDoc in the first place. Ok, then let's teach ESDoc to detect: That's easy, we have Oh, if I create Ok, this is not simple hacking, this is where multiple test cases, not just unit tests needs to be made, and breaking something in (phase 2) and (phase 3) not recognizing changes is highly possible. We didn't even talked about (phase 3). The This short (pun intended) text is explanation why change needs to be done instead of hacking in the support for @function.
|
Thank you for this detailed response!
Do you know any? I've looked at so many but none could handle modern code. Or Node.js' |
Sorry for taking two weeks, well apart from JSDoc itself, which seems more like exporter than a documentation generator "suite", one interesting application seems to be documentation.js. That's all I know of. |
Since there is no
@function
tag, there's currently no way to document dynamically added methods. Or have I missed something?The text was updated successfully, but these errors were encountered: