-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathparseComment.js
117 lines (103 loc) · 3.04 KB
/
parseComment.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Todo: We ideally would use comment-parser's es6 directory, but as the repo
// is CommonJS, it will not be properly treated as ESM from here
/* eslint-disable prefer-named-capture-group -- Temporary */
import {
// eslint-disable-next-line import/no-named-default -- Both together
default as descriptionTokenizer,
getJoiner
} from 'comment-parser/lib/parser/tokenizers/description.js';
import {
seedBlock,
seedTokens
} from 'comment-parser/lib/util.js';
import {parse as commentParser} from 'comment-parser';
import nameTokenizer from 'comment-parser/lib/parser/tokenizers/name.js';
import tagTokenizer from 'comment-parser/lib/parser/tokenizers/tag.js';
import typeTokenizer from 'comment-parser/lib/parser/tokenizers/type.js';
const hasSeeWithLink = (spec) => {
return spec.tag === 'see' && (/\{@link.+?\}/u).test(spec.source[0].source);
};
const getTokenizers = () => {
// trim
return [
// Tag
tagTokenizer(),
// Type
(spec) => {
if (['default', 'defaultvalue', 'see'].includes(spec.tag)) {
return spec;
}
return typeTokenizer()(spec);
},
// Name
(spec) => {
if (spec.tag === 'template') {
// const preWS = spec.postTag;
const remainder = spec.source[0].tokens.description;
const pos = remainder.search(/(?<![\s,])\s/u);
const name = pos === -1 ? remainder : remainder.slice(0, pos);
const extra = remainder.slice(pos + 1);
let postName = '', description = '';
if (pos > -1) {
[, postName, description] = extra.match(/(\s*)(.*)/u);
}
spec.name = name;
spec.optional = false;
const {tokens} = spec.source[0];
tokens.name = name;
tokens.postName = postName;
tokens.description = description;
return spec;
}
if ([
'example', 'return', 'returns', 'throws', 'exception',
'access', 'version', 'since', 'license', 'author',
'default', 'defaultvalue', 'variation'
].includes(spec.tag) || hasSeeWithLink(spec)) {
return spec;
}
return nameTokenizer()(spec);
},
// Description
(spec) => {
return descriptionTokenizer(getJoiner('preserve'))(spec);
}
];
};
/**
*
* @param {PlainObject} commentNode
* @param {string} indent Whitespace
* @returns {PlainObject}
*/
const parseComment = (commentNode, indent) => {
// Preserve JSDoc block start/end indentation.
return commentParser(`/*${commentNode.value}*/`, {
// @see https://github.com/yavorskiy/comment-parser/issues/21
tokenizers: getTokenizers()
})[0] || seedBlock({
source: [
{
number: 0,
tokens: seedTokens({
delimiter: '/**',
description: '',
end: '',
postDelimiter: '',
start: ''
})
},
{
number: 1,
tokens: seedTokens({
delimiter: '',
description: '',
end: '*/',
postDelimiter: '',
start: indent + ' '
})
}
]
});
};
export {getTokenizers, parseComment};