hegemonic / jsdoc-baseline

An experimental, extensible template for JSDoc.
Other
61 stars 32 forks source link

TypeError caused by plugin-provided comments #171

Closed craig0990 closed 9 years ago

craig0990 commented 9 years ago

I've been writing a plugin for JSDoc over the last few weeks (in between an ever-growing list of things to do) and I have succeeded in auto-detecting classes in our framework (JavaScriptMVC 3.2).

However, I am now running into a couple of issues with the jsdoc-baseline template (which is *** amazing by the way). I am using the visitNode functionality to set e.comment and e.event properties as explained by the Making things happen sub-section.

If I set e.comment = '@class ' + longname, then JSDoc happily ignores my modifications. This appears to be caused by the createSymbolDoclet() function in lib/jsdoc/src/handlers.js. My modification causes a name property to be set correctly, then when the method "tries again" it decides to ignore the comment.

I've worked around this issue by using @alias instead, but this then causes a failure in the prefixReducer() of lib/jsdoc/path.js (called by doclethelper.js in Baseline), because ultimately, the meta property of the doclet reaching Baseline does not have a filename set.

Here is the stack trace for the latter error:

path.js:439
      throw new TypeError('Arguments to path.resolve must be strings');
            ^
TypeError: Arguments to path.resolve must be strings
    at Object.posix.resolve (path.js:439:13)
    at prefixReducer (/mnt/data/code/web/localhost/httpdocs/public/node_modules/grunt-jsdoc/node_modules/jsdoc/lib/jsdoc/path.js:23:24)
    at Array.reduce (native)
    at Object.exports.commonPrefix (/mnt/data/code/web/localhost/httpdocs/public/node_modules/grunt-jsdoc/node_modules/jsdoc/lib/jsdoc/path.js:75:26)
    at FrogDocletHelper.DocletHelper.findShortPaths (/mnt/data/code/web/localhost/httpdocs/public/node_modules/jsdoc-baseline/lib/doclethelper.js:392:29)
    at FrogDocletHelper.DocletHelper.addDoclets (/mnt/data/code/web/localhost/httpdocs/public/node_modules/jsdoc-baseline/lib/doclethelper.js:225:10)
    at exports.publish (/mnt/data/code/web/localhost/httpdocs/public/node_modules/jsdoc-baseline/publish.js:54:18)
    at Object.exports.publish (/mnt/data/code/web/localhost/httpdocs/public/app/jsdoc/template/publish.js:19:10)
    at Object.module.exports.cli.generateDocs (/mnt/data/code/web/localhost/httpdocs/public/node_modules/grunt-jsdoc/node_modules/jsdoc/cli.js:443:18)
    at Object.module.exports.cli.processParseResults (/mnt/data/code/web/localhost/httpdocs/public/node_modules/grunt-jsdoc/node_modules/jsdoc/cli.js:394:13)

I have dug around a little bit, and the error is that it is attempting to resolve undefined.

I have tried:

exports.astNodeVisitor = {
    visitNode: function(node, e, parser, currentSourceName) {
        // <code to determine if node (function call) is a class goes here>
        var longname = node.arguments[0].value;
        e.comment = '@alias ' + longname;
        // Tell JSDoc we found a new doclet
        // e.event = 'newDoclet';
        // Tell JSDoc we found a new symbol
        e.event = 'symbolFound';
        // Now we can fill out our doclet
        e.code = {
            // JSDoc seems to ignore anything without this attribute
            name: longname,
            filename: currentSourceName
        };
        // Abandon all hope, ye who enter here
        e.filename = currentSourceName;
        e.meta = {
            code: {},
            range: node.range,
            filename: currentSourceName,
            lineno: node.loc.start.line,
        };
        e.doclet = {
            kind: 'class',
            undocumented: false,
            name: longname.split('.').pop(),
            longname: longname,
        };
        e.code = node;
    }
}

So I have two questions:

I can share the plugin (and would ultimately like to do so on GitHub), but I will need to remove the cursing from the inline comments first ;)

craig0990 commented 9 years ago

Somehow I knew that after filing this issue, I would find a way to solve my issue, if not the root cause of it. I started again, by cloning both jsdoc and jsdoc-baseline locally, running npm link (plus some symbolic links for nested dependencies with grunt-jsdoc) and modifying JSDoc directly to output more verbose logging information.

I have now managed to reduce the above code to it's absolute minimum:

exports.astNodeVisitor = {
    visitNode: function(node, e, parser, currentSourceName) {
        // <code to determine if node (function call) is a class goes here>
        var longname = node.arguments[0].value;
        e.event = 'jsdocCommentFound';
        e.comment = '@class ' + longname;
        e.filename = currentSourceName;
        e.lineno = node.loc.start.line;
    }
}

Just in case this is useful to anyone in future.

Thanks again for an awesome set of tooling!