Skip to content

Commit 9f1abb6

Browse files
committed
Added Vue support, waiting for a test and dependencies
1 parent 542031e commit 9f1abb6

File tree

4 files changed

+174
-2
lines changed

4 files changed

+174
-2
lines changed

__tests__/fixture/simple.input.vue

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<template>
2+
<div>not relevant</div>
3+
</template>
4+
5+
<script>
6+
7+
/**
8+
* This Vue Component is a test
9+
* @returns {vue-tested} vue-tested component
10+
*/
11+
export default {
12+
13+
props: {
14+
15+
/**
16+
* This is a number
17+
*
18+
* @property
19+
*/
20+
myNumber: {
21+
default: 42,
22+
type: Number
23+
}
24+
}
25+
}
26+
</script>
27+
28+
<style>
29+
30+
</style>

src/index.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const filterAccess = require('./filter_access');
66
const dependency = require('./input/dependency');
77
const shallow = require('./input/shallow');
88
const parseJavaScript = require('./parsers/javascript');
9+
const parseVueScript = require('./parsers/vue');
910
const github = require('./github');
1011
const hierarchy = require('./hierarchy');
1112
const inferName = require('./infer/name');
@@ -102,8 +103,13 @@ function buildInternal(inputsAndConfig) {
102103
if (!sourceFile.source) {
103104
sourceFile.source = fs.readFileSync(sourceFile.file, 'utf8');
104105
}
106+
var extension = sourceFile.file.substr(sourceFile.file.length - 4);
105107

106-
return parseJavaScript(sourceFile, config).map(buildPipeline);
108+
if (extension === '.vue') {
109+
return parseVueScript(sourceFile, config).map(buildPipeline);
110+
} else {
111+
return parseJavaScript(sourceFile, config).map(buildPipeline);
112+
}
107113
}).filter(Boolean);
108114

109115
return filterAccess(

src/merge_config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ function mergeConfig(config: Object): Promise<DocumentationConfig> {
8888
'js',
8989
'jsx',
9090
'es5',
91-
'es6'
91+
'es6',
92+
'vue'
9293
]);
9394

9495
return mergeConfigFile(config).then(mergePackage);

src/parsers/vue.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* @flow */
2+
3+
const _ = require('lodash');
4+
const t = require('babel-types');
5+
const parse = require('../parse');
6+
const walkComments = require('../extractors/comments');
7+
const walkExported = require('../extractors/exported');
8+
const util = require('util');
9+
const debuglog = util.debuglog('documentation');
10+
const findTarget = require('../infer/finders').findTarget;
11+
const vuecompiler = require('vue-template-compiler');
12+
13+
import { parseToAst } from './parse_to_ast';
14+
15+
/**
16+
* Left-pad a string so that it can be sorted lexicographically. We sort
17+
* comments to keep them in order.
18+
* @param {string} str the string
19+
* @param {number} width the width to pad to
20+
* @returns {string} a padded string with the correct width
21+
* @private
22+
*/
23+
function leftPad(str, width) {
24+
str = str.toString();
25+
while (str.length < width) {
26+
str = '0' + str;
27+
}
28+
return str;
29+
}
30+
31+
/**
32+
* Receives a module-dep item,
33+
* reads the file, parses the JavaScript, and parses the JSDoc.
34+
*
35+
* @param {Object} data a chunk of data provided by module-deps
36+
* @param {Object} config config
37+
* @returns {Array<Object>} an array of parsed comments
38+
*/
39+
function parseJavaScript(data: Object, config: DocumentationConfig) {
40+
const visited = new Set();
41+
const commentsByNode = new Map();
42+
43+
const component = vuecompiler.parseComponent(data.source);
44+
45+
const ast = parseToAst(component.script.content);
46+
const addComment = _addComment.bind(null, visited, commentsByNode);
47+
48+
return _.flatMap(
49+
config.documentExported
50+
? [walkExported]
51+
: [
52+
walkComments.bind(null, 'leadingComments', true),
53+
walkComments.bind(null, 'innerComments', false),
54+
walkComments.bind(null, 'trailingComments', false)
55+
],
56+
fn => fn(ast, data, addComment)
57+
).filter(comment => comment && !comment.lends);
58+
}
59+
60+
function _addComment(
61+
visited,
62+
commentsByNode,
63+
data,
64+
commentValue,
65+
commentLoc,
66+
path,
67+
nodeLoc,
68+
includeContext
69+
) {
70+
// Avoid visiting the same comment twice as a leading
71+
// and trailing node
72+
const key =
73+
data.file + ':' + commentLoc.start.line + ':' + commentLoc.start.column;
74+
if (!visited.has(key)) {
75+
visited.add(key);
76+
77+
const context /* : {
78+
loc: Object,
79+
file: string,
80+
sortKey: string,
81+
ast?: Object,
82+
code?: string
83+
}*/ = {
84+
loc: nodeLoc,
85+
file: data.file,
86+
sortKey: data.sortKey + ' ' + leftPad(nodeLoc.start.line, 8)
87+
};
88+
89+
if (includeContext) {
90+
// This is non-enumerable so that it doesn't get stringified in
91+
// output; e.g. by the documentation binary.
92+
Object.defineProperty(context, 'ast', {
93+
configurable: true,
94+
enumerable: false,
95+
value: path
96+
});
97+
98+
if (path.parentPath && path.parentPath.node) {
99+
const parentNode = path.parentPath.node;
100+
context.code = data.source.substring(parentNode.start, parentNode.end);
101+
}
102+
}
103+
const comment = parse(commentValue, commentLoc, context);
104+
if (includeContext) {
105+
commentsByNode.set((findTarget(path) || path).node, comment);
106+
107+
if (t.isClassMethod(path) && path.node.kind === 'constructor') {
108+
// #689
109+
if (
110+
comment.tags.some(
111+
tag => tag.title !== 'param' && tag.title !== 'hideconstructor'
112+
)
113+
) {
114+
debuglog(
115+
'A constructor was documented explicitly: document along with the class instead'
116+
);
117+
}
118+
119+
const parentComment = commentsByNode.get(
120+
path.parentPath.parentPath.node
121+
);
122+
if (parentComment) {
123+
parentComment.constructorComment = comment;
124+
return;
125+
}
126+
if (comment.hideconstructor) {
127+
return;
128+
}
129+
}
130+
}
131+
return comment;
132+
}
133+
}
134+
135+
module.exports = parseJavaScript;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy