Skip to content

Commit

Permalink
Methods and imported data parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
ArdenIvanov committed Aug 5, 2019
1 parent ec5de3d commit 23514d8
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 14 deletions.
87 changes: 73 additions & 14 deletions lib/v3/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ const DEFAULT_OPTIONS = {};

const SUPPORTED_FEATURES = [
'name',
'data',
'computed',
// 'methods',
// 'actions',
// 'helpers',
'components',
// 'description',
'events',
'slots',
// 'transitions',
'data',
'computed',
'methods',
// 'actions',
// 'helpers',
'components',
// 'description',
'events',
'slots',
// 'transitions',
// 'store'
];

Expand Down Expand Up @@ -114,6 +114,16 @@ class Parser extends EventEmitter {
this.emit('data', item);
}

emitMethodItem(method, isStaticScope, defaultVisibility) {
const item = Object.assign({}, utils.getComment(method.node, defaultVisibility), {
name: method.name,
args: method.args,
static: isStaticScope
});

this.emit('method', item);
}

emitComputedItem(computed, isStaticScope, defaultVisibility) {
const item = Object.assign({}, utils.getComment(computed.node, defaultVisibility), {
name: computed.name,
Expand Down Expand Up @@ -158,6 +168,12 @@ class Parser extends EventEmitter {
return;
}

if (node.type === 'FunctionDeclaration') {
this.emitMethodItem(this.parseFunctionDeclaration(node), isStaticScope, 'private');

return;
}

if (node.type === 'ExportNamedDeclaration') {
const declaration = node.declaration;
if (declaration) {
Expand All @@ -169,6 +185,11 @@ class Parser extends EventEmitter {

return;
}

if (declaration.type === 'FunctionDeclaration') {
this.emitMethodItem(this.parseFunctionDeclaration(declaration), isStaticScope, 'public');
return;
}
}
}

Expand Down Expand Up @@ -207,13 +228,30 @@ class Parser extends EventEmitter {
if (!this.imports.hasOwnProperty(importEntry.identifier)) {
this.imports[importEntry.identifier] = importEntry;

if (importEntry.identifier && importEntry.identifier[0] === importEntry.identifier[0].toUpperCase()) {
this.emitImportedComponentItem(node, importEntry.identifier, importEntry.sourceFilename);

return;
if (importEntry.identifier) {
if (importEntry.identifier[0] === importEntry.identifier[0].toUpperCase()) {
this.emitImportedComponentItem(node, importEntry.identifier, importEntry.sourceFilename);
return;
} else {
this.emitDataItem({
node,
name: importEntry.identifier,
kind: 'const'
}, isStaticScope, 'private');
}
}
}
}
} else if (node.specifiers.length > 0) {
node.specifiers.forEach((specifier) => {
if (specifier.type === 'ImportSpecifier') {
this.emitDataItem({
node: specifier,
name: specifier.local.name,
kind: 'const'
}, isStaticScope, 'private');
}
});
}
}

Expand Down Expand Up @@ -253,6 +291,27 @@ class Parser extends EventEmitter {
return result;
}

parseFunctionDeclaration(node) {
if (node.type !== 'FunctionDeclaration') {
throw new Error('Node should have a FunctionDeclarationType, but is ' + node.type);
}

const args = [];
node.params.forEach(param => {
if (param.type === 'Identifier') {
args.push({
name: param.name,
});
}
});

return {
node: node,
name: node.id.name,
args: args
};
}

parseObjectProperty(node) {
if (node.type !== 'Property') {
throw new Error('Node should have a Property, but is ' + node.type);
Expand Down
8 changes: 8 additions & 0 deletions test/svelte3/integration/data/data.import.default.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
/**
* The import comment.
*/
import x from "./importable.js";
import X from "./importable.js";
</script>
8 changes: 8 additions & 0 deletions test/svelte3/integration/data/data.import.many.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
/**
* The import comment.
*/
import {y, z} from "./importable.js";
import X from "./importable.js";
</script>
56 changes: 56 additions & 0 deletions test/svelte3/integration/data/data.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,60 @@ describe('SvelteDoc v3 - Props', () => {
done(e);
});
});

it('Imported default data should be parsed with comment', (done) => {
parser.parse({
version: 3,
filename: path.resolve(__dirname, 'data.import.default.svelte'),
features: ['data'],
ignoredVisibilities: []
}).then((doc) => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.data, 'Document data should be parsed').to.exist;

expect(doc.data.length).to.equal(1);
const prop = doc.data[0];
expect(prop.name).to.equal('x');
expect(prop.visibility).to.equal('private');
expect(prop.static).to.be.false;

expect(prop.description).to.equal('The import comment.');

expect(prop.type).to.equal('any');

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

it('Imported many data should be parsed', (done) => {
parser.parse({
version: 3,
filename: path.resolve(__dirname, 'data.import.many.svelte'),
features: ['data'],
ignoredVisibilities: []
}).then((doc) => {
expect(doc, 'Document should be provided').to.exist;
expect(doc.data, 'Document data should be parsed').to.exist;

expect(doc.data.length).to.equal(2);

const prop1 = doc.data[0];
expect(prop1.name).to.equal('y');
expect(prop1.visibility).to.equal('private');
expect(prop1.static).to.be.false;
expect(prop1.type).to.equal('any');

const prop2 = doc.data[1];
expect(prop2.name).to.equal('z');
expect(prop2.visibility).to.equal('private');
expect(prop2.static).to.be.false;
expect(prop2.type).to.equal('any');

done();
}).catch(e => {
done(e);
});
});
});
3 changes: 3 additions & 0 deletions test/svelte3/integration/data/importable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default x = 1;
export let y = 1;
export let z = 1;
8 changes: 8 additions & 0 deletions test/svelte3/integration/methods/method.private.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
/**
* The method comment.
*/
function privateMethod(param1, param2) {
return 0;
};
</script>
8 changes: 8 additions & 0 deletions test/svelte3/integration/methods/method.public.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
/**
* The method comment.
*/
export function publicMethod(param1, param2) {
return 0;
};
</script>
62 changes: 62 additions & 0 deletions test/svelte3/integration/methods/methods.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const path = require('path');
const chai = require('chai');
const expect = chai.expect;

const parser = require('../../../../index');

describe('SvelteDoc v3 - Methods', () => {
it('Private method should be parsed with comment and additional metadata', (done) => {
parser.parse({
version: 3,
filename: path.resolve(__dirname, 'method.private.svelte'),
features: ['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.length).to.equal(1);
const method = doc.methods[0];
expect(method.name).to.equal('privateMethod');
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.description).to.equal('The method comment.');
done();
}).catch(e => {
done(e);
});
});

it('Public method should be parsed with comment and additional metadata', (done) => {
parser.parse({
version: 3,
filename: path.resolve(__dirname, 'method.public.svelte'),
features: ['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.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.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');

done();
}).catch(e => {
done(e);
});
});
});
7 changes: 7 additions & 0 deletions typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ export interface SvelteMethodArgumentItem {
* The description of the parameter.
*/
description?: string;
/**
* Indicates that this data item of component located in static context.
* Variable should be declared in `<script scope="module" />` block.
* @since Svelte V3
* @since {2.0.0}
*/
static?: boolean;
}

export interface SvelteMethodItem extends ISvelteItem {
Expand Down

0 comments on commit 23514d8

Please sign in to comment.