bio-dts 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/parsers/jsdoc.js +159 -0
- package/lib/post-transform.js +94 -14
- package/lib/pre-transform.js +29 -10
- package/package.json +1 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
function skipWhitespace(str, pos) {
|
|
2
|
+
let i = pos;
|
|
3
|
+
|
|
4
|
+
let char;
|
|
5
|
+
for (; (char = str.charAt(i)) && char !== '\n' && /\s/.test(char); i++) {
|
|
6
|
+
|
|
7
|
+
// ignore
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return i;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function skipText(str, pos) {
|
|
14
|
+
let i = pos;
|
|
15
|
+
let char;
|
|
16
|
+
|
|
17
|
+
for (; (char = str.charAt(i)) && /\S/.test(char); i++) {
|
|
18
|
+
|
|
19
|
+
// ignore
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return i;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function findClose(str, pos, openChar, closeChar) {
|
|
26
|
+
|
|
27
|
+
if (str.charAt(pos) !== openChar) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let char;
|
|
32
|
+
|
|
33
|
+
let i = pos;
|
|
34
|
+
|
|
35
|
+
let open = 0;
|
|
36
|
+
|
|
37
|
+
while ((char = str.charAt(i++))) {
|
|
38
|
+
switch (char) {
|
|
39
|
+
case openChar:
|
|
40
|
+
open++;
|
|
41
|
+
break;
|
|
42
|
+
case closeChar:
|
|
43
|
+
if (--open === 0) {
|
|
44
|
+
return {
|
|
45
|
+
start: pos,
|
|
46
|
+
end: i,
|
|
47
|
+
value: str.substring(pos, i)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function findNewline(str, pos) {
|
|
56
|
+
|
|
57
|
+
let i = pos;
|
|
58
|
+
let char;
|
|
59
|
+
|
|
60
|
+
for (; (char = str.charAt(i)) && /[^\n]/.test(char); i++) {
|
|
61
|
+
|
|
62
|
+
// ignore
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return i;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function parse(str) {
|
|
69
|
+
|
|
70
|
+
var i = 0, j;
|
|
71
|
+
|
|
72
|
+
var tags = [];
|
|
73
|
+
var tag;
|
|
74
|
+
|
|
75
|
+
while ((i = str.indexOf('@', i)) && i !== -1) {
|
|
76
|
+
j = i + 1;
|
|
77
|
+
tag = {
|
|
78
|
+
start: i
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// parse tag name
|
|
82
|
+
j = skipText(str, i);
|
|
83
|
+
|
|
84
|
+
tag.name = str.substring(i + 1, j);
|
|
85
|
+
|
|
86
|
+
i = skipWhitespace(str, j);
|
|
87
|
+
|
|
88
|
+
// parse type
|
|
89
|
+
if ([ 'param', 'return', 'returns', 'typedef' ].includes(tag.name)) {
|
|
90
|
+
|
|
91
|
+
let match = findClose(str, i, '{', '}');
|
|
92
|
+
|
|
93
|
+
if (match) {
|
|
94
|
+
tag.type = match;
|
|
95
|
+
|
|
96
|
+
i = skipWhitespace(str, match.end);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// parse param
|
|
101
|
+
if ([ 'param', 'typedef' ].includes(tag.name)) {
|
|
102
|
+
|
|
103
|
+
let match = tag.name === 'param' && findClose(str, i, '[', ']');
|
|
104
|
+
|
|
105
|
+
if (match) {
|
|
106
|
+
tag.param = match;
|
|
107
|
+
|
|
108
|
+
const contents = tag.param.contents = str.substring(match.start + 1, match.end - 1);
|
|
109
|
+
const idxEq = contents.indexOf('=');
|
|
110
|
+
|
|
111
|
+
tag.param.name = idxEq !== -1 ? contents.substring(0, idxEq) : contents;
|
|
112
|
+
} else {
|
|
113
|
+
j = skipText(str, i);
|
|
114
|
+
|
|
115
|
+
tag.param = {
|
|
116
|
+
start: i,
|
|
117
|
+
end: j,
|
|
118
|
+
name: str.substring(i, j),
|
|
119
|
+
value: str.substring(i, j)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
i = skipWhitespace(str, tag.param.end);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
j = findNewline(str, i);
|
|
127
|
+
|
|
128
|
+
tag.description = i !== j ? {
|
|
129
|
+
start: i,
|
|
130
|
+
end: j,
|
|
131
|
+
value: str.substring(i, j)
|
|
132
|
+
} : null;
|
|
133
|
+
|
|
134
|
+
tag.end = j;
|
|
135
|
+
|
|
136
|
+
tags.push(tag);
|
|
137
|
+
|
|
138
|
+
i = j + 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return tags;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function dbg(str, pos) {
|
|
145
|
+
|
|
146
|
+
const arr = Array.from(str);
|
|
147
|
+
|
|
148
|
+
arr.splice(pos, 0, '|');
|
|
149
|
+
|
|
150
|
+
return arr.join('');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function replace(str, range, contents) {
|
|
154
|
+
const arr = Array.from(str);
|
|
155
|
+
|
|
156
|
+
arr.splice(range.start, range.end - range.start, contents);
|
|
157
|
+
|
|
158
|
+
return arr.join('');
|
|
159
|
+
}
|
package/lib/post-transform.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { isArray, isNode, keys, parseDts, path, print } from './util.js';
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
builders as b
|
|
5
|
+
} from 'ast-types';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
parse as parseJSDoc,
|
|
9
|
+
replace as replaceJSDoc
|
|
10
|
+
} from './parsers/jsdoc.js';
|
|
11
|
+
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* @param { { name: string, comments?: any[] } }
|
|
@@ -28,35 +37,106 @@ export default function transform(src) {
|
|
|
28
37
|
const ast = parseDts(src);
|
|
29
38
|
const body = path(ast).get('program', 'body');
|
|
30
39
|
|
|
40
|
+
const replacements = [];
|
|
41
|
+
|
|
42
|
+
function replace(path, ...args) {
|
|
43
|
+
replacements.push([ path, args ]);
|
|
44
|
+
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
31
48
|
traverse(body, function(path) {
|
|
32
49
|
|
|
50
|
+
const {
|
|
51
|
+
value
|
|
52
|
+
} = path;
|
|
53
|
+
|
|
33
54
|
// filter private members
|
|
34
|
-
if (!isPublic(
|
|
35
|
-
|
|
55
|
+
if (!isPublic(value)) {
|
|
56
|
+
return replace(path);
|
|
36
57
|
}
|
|
37
58
|
|
|
38
59
|
// TODO(nikku): transform illegal typescript methods into override calls
|
|
60
|
+
|
|
61
|
+
// TODO(nikku): remove annotations
|
|
62
|
+
//
|
|
63
|
+
// * @typedef
|
|
64
|
+
// * @class
|
|
65
|
+
// * @constructor
|
|
66
|
+
// * @template
|
|
67
|
+
// * @method
|
|
68
|
+
|
|
69
|
+
const comments = path.get('comments') || { value: [] };
|
|
70
|
+
|
|
71
|
+
for (const key of keys(comments.value || []).reverse()) {
|
|
72
|
+
|
|
73
|
+
const comment = comments.get(key);
|
|
74
|
+
|
|
75
|
+
const replacements = [];
|
|
76
|
+
|
|
77
|
+
const doc = comment.value.value.replace(/\n\s+/g, '\n ');
|
|
78
|
+
const tags = parseJSDoc(doc);
|
|
79
|
+
|
|
80
|
+
for (const tag of tags) {
|
|
81
|
+
if (/class|constructor|template|method|typedef/.test(tag.name)) {
|
|
82
|
+
replacements.push([ { start: tag.start - 4, end: tag.end } ]);
|
|
83
|
+
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (tag.type) {
|
|
88
|
+
replacements.push([ { start: tag.type.start - 1, end: tag.type.end }, '' ]);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (tag.param) {
|
|
92
|
+
replacements.push([ tag.param, tag.param.name ]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const newDoc = replacements.slice().reverse().reduce((newDoc, r) => {
|
|
97
|
+
|
|
98
|
+
const [ { start, end }, replacement = '' ] = r;
|
|
99
|
+
|
|
100
|
+
return replaceJSDoc(newDoc, { start, end }, replacement);
|
|
101
|
+
}, doc);
|
|
102
|
+
|
|
103
|
+
// remove entirely, if empty
|
|
104
|
+
if (!newDoc.replace(/[/*\s]/g, '')) {
|
|
105
|
+
replace(comment);
|
|
106
|
+
} else {
|
|
107
|
+
replace(comment, b.commentBlock.from({
|
|
108
|
+
type: 'CommentBlock',
|
|
109
|
+
leading: true,
|
|
110
|
+
value: newDoc
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
39
115
|
});
|
|
40
116
|
|
|
117
|
+
for (const [ path, args ] of replacements) {
|
|
118
|
+
path.replace(...args);
|
|
119
|
+
}
|
|
120
|
+
|
|
41
121
|
return print(ast).code;
|
|
42
122
|
}
|
|
43
123
|
|
|
44
124
|
function traverse(path, cb) {
|
|
45
|
-
|
|
125
|
+
const val = path.value;
|
|
46
126
|
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!isNode(val) && !isArray(val)) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
127
|
+
if (!isNode(val) && !isArray(val)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
53
130
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
131
|
+
if (cb(path) === false) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
58
134
|
|
|
59
|
-
|
|
135
|
+
for (const key of keys(val).reverse()) {
|
|
136
|
+
if ([ 'loc', 'start', 'end' ].includes(key)) {
|
|
137
|
+
continue;
|
|
60
138
|
}
|
|
139
|
+
|
|
140
|
+
traverse(path.get(key), cb);
|
|
61
141
|
}
|
|
62
142
|
}
|
package/lib/pre-transform.js
CHANGED
|
@@ -146,19 +146,31 @@ export default function transform(src) {
|
|
|
146
146
|
const ast = parse(src);
|
|
147
147
|
const body = path(ast).get('program', 'body');
|
|
148
148
|
|
|
149
|
+
const inheritsImports = findInheritsImports(body);
|
|
150
|
+
|
|
149
151
|
const classes = findConstructors(body);
|
|
150
152
|
|
|
153
|
+
// query
|
|
151
154
|
for (const cls of classes) {
|
|
152
|
-
|
|
155
|
+
cls.members = [
|
|
153
156
|
...findEmbeddedMethods(cls),
|
|
154
157
|
...findProtoMethods(cls, body)
|
|
155
158
|
];
|
|
156
159
|
|
|
157
|
-
|
|
160
|
+
cls.staticMembers = [
|
|
158
161
|
...findStaticMembers(cls, body)
|
|
159
162
|
];
|
|
160
163
|
|
|
161
|
-
|
|
164
|
+
cls.superDeclaration = findSuperDeclarations(cls, body, inheritsImports);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// transform
|
|
168
|
+
for (const cls of classes) {
|
|
169
|
+
const {
|
|
170
|
+
members,
|
|
171
|
+
staticMembers,
|
|
172
|
+
superDeclaration
|
|
173
|
+
} = cls;
|
|
162
174
|
|
|
163
175
|
if (superDeclaration) {
|
|
164
176
|
cls.ctor.get('body', 'body').unshift(superCall());
|
|
@@ -187,26 +199,34 @@ export default function transform(src) {
|
|
|
187
199
|
});
|
|
188
200
|
|
|
189
201
|
if (superDeclaration) {
|
|
190
|
-
superDeclaration.importDeclarations.forEach(m => m.node.replace());
|
|
191
202
|
superDeclaration.inheritsExpression.node.replace();
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
|
|
206
|
+
inheritsImports.forEach(m => m.node.replace());
|
|
207
|
+
|
|
195
208
|
return print(ast).code;
|
|
196
209
|
}
|
|
197
210
|
|
|
198
|
-
function
|
|
199
|
-
|
|
211
|
+
function findInheritsImports(nodes) {
|
|
200
212
|
const importsMatches = matcher`
|
|
201
213
|
import $1 from 'inherits-browser';
|
|
202
214
|
`;
|
|
203
215
|
|
|
204
|
-
|
|
216
|
+
return importsMatches(nodes).map(m => {
|
|
217
|
+
return {
|
|
218
|
+
node: m[0],
|
|
219
|
+
name: m[1].value.name
|
|
220
|
+
};
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function findSuperDeclarations(cls, nodes, importDeclarations) {
|
|
205
225
|
|
|
206
|
-
for (const
|
|
226
|
+
for (const { name: inheritsName } of importDeclarations) {
|
|
207
227
|
|
|
208
228
|
const inheritsMatches = matcher`
|
|
209
|
-
${
|
|
229
|
+
${inheritsName}(${cls.name}, $1);
|
|
210
230
|
`;
|
|
211
231
|
|
|
212
232
|
const inheritsExpressions = inheritsMatches(nodes);
|
|
@@ -230,7 +250,6 @@ function findSuperDeclarations(cls, nodes) {
|
|
|
230
250
|
const superCalls = superCallMatches(cls.ctor.get('body', 'body'));
|
|
231
251
|
|
|
232
252
|
return {
|
|
233
|
-
importDeclarations: importDeclarations.map(m => ({ node: m[0] })),
|
|
234
253
|
superCalls: superCalls.map(m => ({ node: m[0] })),
|
|
235
254
|
clazz,
|
|
236
255
|
inheritsExpression
|