Skip to content

Commit

Permalink
Merge pull request #76 from ekhaled/es6-assignment-pattern
Browse files Browse the repository at this point in the history
fix #75: support for ES6 assignment pattern in methods
  • Loading branch information
alexprey authored Aug 30, 2021
2 parents 29eb5f3 + 45777c2 commit 4e02b7d
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
38 changes: 36 additions & 2 deletions lib/v3/v3-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const {
parseTypeKeyword
} = require('../jsdoc');

const { inferTypeFromVariableDeclaration } = require('../utils');

class InvalidNodeTypeError extends TypeError {
constructor(expected, actual = '', ...args) {
super(expected, actual, ...args);
Expand Down Expand Up @@ -63,7 +65,22 @@ function parseFunctionDeclaration(node) {
node.params.forEach((param) => {
if (param.type === 'Identifier') {
params.push({
name: param.name,
name: param.name
});
}
if (param.type == 'AssignmentPattern') {
let inferred_type = inferTypeFromVariableDeclaration({
//fake variable declarator block
declarator: {
init: param.right
}
});
params.push({
name: param.left.name,
type: inferred_type,
description: null,
optional: true,
defaultValue: param.right.raw
});
}
});
Expand Down Expand Up @@ -178,7 +195,24 @@ function parseAndMergeKeywords(keywords = [], event, allowToParseReturn = true)
* present from parsing the AST node.
*/
if (pIndex >= 0) {
event.params[pIndex] = parsedParam;
if(
parsedParam.type &&
event.params[pIndex].type &&
parsedParam.type.text == '*'
){
/**
* Only `getDefaultJSDocType()` has type.text = "*"
* so, if parsedParams contain that, we can be sure that
* type information was not found in the keyword description
*
* When that happens, we check if type data is already present
* from parsing the assignment pattern in the FunctionDeclaration
*/
parsedParam.type = event.params[pIndex].type;
parsedParam.optional = event.params[pIndex].optional;
}

event.params[pIndex] = Object.assign(event.params[pIndex], parsedParam);
} else {
/*
* This means @param does not match an actual param
Expand Down
21 changes: 21 additions & 0 deletions test/svelte3/integration/methods/method.typeInference.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script>
/**
* The method comment.
* @param {string} param1 - the first parameter
* @param {boolean} [param2=false] - the second parameter
* @param param3 - the third parameter of type number
* @param {any} param7
* @returns {number} - return value description
*/
export function publicMethod(
param1, //this should use jsdoc from above
param2, //this should use jsdoc from above
param3 = 1, //type and default should be inferred, description from jsdoc
param4 = [], //type should be inferred, no description
param5 = {}, //type should be inferred, no description
param6 = true, //type and default should be inferred, no description
param7 // this should use jsdoc from above
) {
return 0;
};
</script>
91 changes: 91 additions & 0 deletions test/svelte3/integration/methods/methods.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,95 @@ describe('SvelteDoc v3 - Methods', () => {
done(e);
});
});

it('Method argument types should be inferred from assignment patterns, and enhanced with additional metadata', (done) => {
parser.parse({
version: 3,
filename: path.resolve(__dirname, 'method.typeInference.svelte'),
features: ['methods', 'description'],
ignoredVisibilities: []
}).then((doc) => {
expect(doc, 'Document should be provided').to.exist;

expect(doc.methods, 'Document methods should be parsed').to.exist;
expect(doc.methods.length).to.equal(1);

const method = doc.methods[0];

expect(method.name).to.equal('publicMethod');
expect(method.visibility).to.equal('public');
expect(method.static).to.be.false;
expect(method.description).to.equal('The method comment.');

// @param keywords
expect(method.params, 'Method arguments should be parsed').to.exist;
expect(method.params.length).to.equal(7);

const param0 = method.params[0];

expect(param0.name).to.equal('param1');
expect(param0.description).to.equal('the first parameter');
expect(param0.type.type).to.equal('string');
expect(param0.defaultValue).to.be.undefined;
expect(param0.optional).to.be.false;

const param1 = method.params[1];

expect(param1.name).to.equal('param2');
expect(param1.description).to.equal('the second parameter');
expect(param1.type.type).to.equal('boolean');
expect(param1.defaultValue).to.equal('false');
expect(param1.optional).to.be.true;

const param2 = method.params[2];

expect(param2.name).to.equal('param3');
expect(param2.description).to.equal('the third parameter of type number');
expect(param2.type.type).to.equal('number');
expect(param2.defaultValue).to.equal('1');
expect(param2.optional).to.be.true;

const param3 = method.params[3];

expect(param3.name).to.equal('param4');
expect(param3.description).to.be.null;
expect(param3.type.type).to.equal('array');
expect(param3.defaultValue).to.be.undefined;
expect(param3.optional).to.be.true;

const param4 = method.params[4];

expect(param4.name).to.equal('param5');
expect(param4.description).to.be.null;
expect(param4.type.type).to.equal('object');
expect(param4.defaultValue).to.be.undefined;
expect(param4.optional).to.be.true;

const param5 = method.params[5];

expect(param5.name).to.equal('param6');
expect(param5.description).to.be.null;
expect(param5.type.type).to.equal('boolean');
expect(param5.defaultValue).to.equal('true');
expect(param5.optional).to.be.true;

const param6 = method.params[6];

expect(param6.name).to.equal('param7');
expect(param6.description).to.be.null;
expect(param6.type.type).to.equal('any');
expect(param6.defaultValue).to.be.undefined;
expect(param6.optional).to.be.false;

// @returns keyword
expect(method.return, 'Method return keyword should be parsed').to.exist;
expect(method.return.type).to.exist;
expect(method.return.type.type).to.equal('number');
expect(method.return.description).to.equal('return value description');

done();
}).catch(e => {
done(e);
});
});
});

0 comments on commit 4e02b7d

Please sign in to comment.