Skip to content

Commit

Permalink
fix(v3-parser): Export metadata for method.param items (alexprey#39)
Browse files Browse the repository at this point in the history
- Add function getDefaultJSDocType
- Update tests for svelte3/integration/methods
- Fix typings for SvelteMethodItem
- Add example usage
  • Loading branch information
soft-decay committed Nov 29, 2020
1 parent 9282ac5 commit f863a48
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 36 deletions.
14 changes: 11 additions & 3 deletions examples/Button.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
"keywords": [
{
"name": "param",
"description": "{string} question a question about life, the universe, everything"
"description": "{string} [question=Why?] a question about life, the universe, everything"
},
{
"name": "returns",
Expand All @@ -142,9 +142,17 @@
"visibility": "public",
"description": "Computes the answer to your question.",
"name": "computeAnswer",
"args": [
"params": [
{
"name": "question"
"type": {
"kind": "type",
"text": "string",
"type": "string"
},
"name": "question",
"optional": true,
"default": "Why?",
"description": "a question about life, the universe, everything"
}
],
"return": {
Expand Down
4 changes: 2 additions & 2 deletions examples/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
/**
* Computes the answer to your question.
* @param {string} question a question about life, the universe, everything
* @param {string} [question=Why?] a question about life, the universe, everything
* @returns {number} the answer to all your questions
*/
export function computeAnswer(question) {
return question.indexOf("?") >= 0 ? 42 : 23;
return question.indexOf('?') >= 0 ? 42 : 23;
};
</script>

Expand Down
23 changes: 11 additions & 12 deletions lib/jsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ const RETURN_RE = new RegExp(`^\\s*(${TYPE})?(\\s*${TYPE_DESC})?`, 'i');

const DEFAULT_TYPE = 'any';

function getDefaultJSDocType() {
return {
kind: 'type',
text: '*',
type: DEFAULT_TYPE
};
}

function parseType(type, param) {
if (type.indexOf('|') > -1) {
param.type = type.split('|');
Expand Down Expand Up @@ -111,15 +119,10 @@ function parseTypeKeyword(text) {

function parseParamKeyword(text) {
const param = {
type: {
kind: 'type',
text: '*',
type: DEFAULT_TYPE
},
type: getDefaultJSDocType(),
name: null,
optional: false,
default: null,
description: null
default: null
};

const match = PARAM_RE.exec(text);
Expand Down Expand Up @@ -169,11 +172,7 @@ function parseParamKeyword(text) {

function parseReturnKeyword(text) {
const output = {
type: {
kind: 'type',
text: '*',
type: DEFAULT_TYPE
},
type: getDefaultJSDocType(),
description: null
};
const matches = RETURN_RE.exec(text);
Expand Down
39 changes: 32 additions & 7 deletions lib/v3/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class Parser extends EventEmitter {

const item = Object.assign({}, comment, {
name: method.name,
args: method.args,
params: method.params,
return: method.return,
static: parseContext.scopeType === SCOPE_STATIC
});
Expand Down Expand Up @@ -679,11 +679,11 @@ class Parser extends EventEmitter {
throw new Error('Node should have a FunctionDeclarationType, but is ' + node.type);
}

const args = [];
const params = [];

node.params.forEach(param => {
node.params.forEach((param) => {
if (param.type === 'Identifier') {
args.push({
params.push({
name: param.name,
});
}
Expand All @@ -696,7 +696,7 @@ class Parser extends EventEmitter {
start: node.id.start,
end: node.id.end
},
args: args,
params: params,
};

return output;
Expand Down Expand Up @@ -916,15 +916,40 @@ class Parser extends EventEmitter {
parser.end();
}

/**
* Mutates event.
* @param {any[]} keywords
* @param {{ params?: any[] }} event
*/
parseKeywords(keywords = [], event) {
event.params = [];
if (!event.params) event.params = [];

keywords.forEach(({ name, description }) => {
switch (name) {
case 'arg':
case 'param':
case 'argument':
event.params.push(jsdoc.parseParamKeyword(description));
const parsedParam = jsdoc.parseParamKeyword(description);
const pIndex = event.params.findIndex(
p => p.name === parsedParam.name
);

/*
* Replace the param if there is already one present with
* the same name. This will happen with parsed
* FunctionDeclaration because params will already be
* present from parsing the AST node.
*/
if (0 <= pIndex) {
event.params[pIndex] = parsedParam;
} else {
/*
* This means @param does not match an actual param
* in the FunctionDeclaration.
* Should we ignore it or warn about it?
*/
event.params.push(parsedParam);
}
break;

case 'return':
Expand Down
2 changes: 2 additions & 0 deletions test/svelte3/integration/methods/method.public.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script>
/**
* The method comment.
* @param {string} param1 - the first parameter
* @param {boolean} [param2=false] - the second parameter
* @returns {number} - return value description
*/
export function publicMethod(param1, param2) {
Expand Down
30 changes: 20 additions & 10 deletions test/svelte3/integration/methods/methods.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ describe('SvelteDoc v3 - Methods', () => {
expect(method.visibility).to.equal('private');
expect(method.static).to.be.false;

expect(method.args, 'Method arguments should be parsed').to.exist;
expect(method.args.length).to.equal(2);
expect(method.args[0].name).to.equal('param1');
expect(method.args[1].name).to.equal('param2');
expect(method.params, 'Method arguments should be parsed').to.exist;
expect(method.params.length).to.equal(2);
expect(method.params[0].name).to.equal('param1');
expect(method.params[1].name).to.equal('param2');

expect(method.description).to.equal('The method comment.');

Expand Down Expand Up @@ -56,21 +56,31 @@ describe('SvelteDoc v3 - Methods', () => {
ignoredVisibilities: []
}).then((doc) => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.methods, 'Document methods should be parsed').to.exist;

expect(doc.methods, 'Document methods should be parsed').to.exist;
expect(doc.methods.length).to.equal(1);
const method = doc.methods[0];

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.');

expect(method.args, 'Method arguments should be parsed').to.exist;
expect(method.args.length).to.equal(2);
expect(method.args[0].name).to.equal('param1');
expect(method.args[1].name).to.equal('param2');
// @param keywords
expect(method.params, 'Method arguments should be parsed').to.exist;
expect(method.params.length).to.equal(2);

const param0 = method.params[0];
expect(param0.name).to.equal('param1');
expect(param0.description).to.equal('the first parameter');
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.optional).to.be.true;

// @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');
Expand Down
7 changes: 5 additions & 2 deletions typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export interface SvelteComputedItem extends ISvelteItem {
dependencies: string[]
}

export interface SvelteMethodArgumentItem {
export interface SvelteMethodParamItem {
/**
* The name of method parameter.
*/
Expand Down Expand Up @@ -223,6 +223,9 @@ export interface SvelteMethodArgumentItem {
static?: boolean;
}

export type SvelteArgItem = SvelteMethodParamItem;
export type SvelteArgumentItem = SvelteMethodParamItem;

export interface SvelteMethodReturnItem {
/**
* The JSDocType of the return value.
Expand All @@ -238,7 +241,7 @@ export interface SvelteMethodItem extends ISvelteItem {
/**
* The list of parameter items of the method.
*/
args?: SvelteMethodArgumentItem[];
params?: SvelteMethodParamItem[];
/**
* The return item of the method. This exists if an item with 'name' equal
* to 'returns' or 'return' exists in 'keywords'.
Expand Down

0 comments on commit f863a48

Please sign in to comment.