Skip to content

Commit

Permalink
fix: prevent circular refs when params have the same type expression
Browse files Browse the repository at this point in the history
Catharsis caches parse results by default; if you parse the same type expression twice, with the same options, you get the same object each time.

When the user passes the `--debug` flag, we expose the parsed type for each parameter as an enumerable property of the doclet. If two parameters used the same type expression, the resulting doclet could contain a circular reference.

This change disables the Catharsis cache, so that Catharsis returns a new object for each parsed type, which prevents circular references. As a result, this change fixes an issue with the `-X` flag, and with some JSDoc templates.
  • Loading branch information
hegemonic committed Jul 22, 2020
1 parent 8d0fce6 commit a59b5cd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/jsdoc/tag/type.js
Expand Up @@ -241,7 +241,10 @@ function parseTypeExpression(tagInfo) {
}

try {
parsedType = catharsis.parse(tagInfo.typeExpression, {jsdoc: true});
parsedType = catharsis.parse(tagInfo.typeExpression, {
jsdoc: true,
useCache: false
});
}
catch (e) {
// always re-throw so the caller has a chance to report which file was bad
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/paramtagsametype.js
@@ -0,0 +1,16 @@
const foo = {
bar: {}
};

/**
* Baz class.
*/
foo.bar.Baz = class {
/**
* Creates a Baz.
*
* @param {string=} first - First parameter.
* @param {string=} second - Second parameter.
*/
constructor(first, second) {}
};
28 changes: 28 additions & 0 deletions test/specs/documentation/paramtagsametype.js
@@ -0,0 +1,28 @@
const env = require('jsdoc/env');

describe('multiple @param tags with the same type expression', () => {
const debug = Boolean(env.opts.debug);

afterEach(() => {
env.opts.debug = debug;
});

it('does not have circular references when type.parsedType is enumerable', () => {
let docSet;
let params;
let stringified;

// Force type.parsedType to be enumerable.
env.opts.debug = true;
docSet = jasmine.getDocSetFromFile('test/fixtures/paramtagsametype.js');
params = docSet.getByLongname('foo.bar.Baz').filter(d => !d.undocumented)[0].params;
stringified = JSON.stringify(params);

expect(stringified).toContain('"parsedType":');
expect(stringified).not.toContain('<CircularRef>');

// Prevent the schema validator from complaining about `parsedType`. (The schema _should_
// allow that property, but for some reason, that doesn't work correctly.)
params.forEach(p => delete p.type.parsedType);
});
});

0 comments on commit a59b5cd

Please sign in to comment.