bio-dts 0.2.1 → 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.
@@ -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
+ }
@@ -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,11 +37,23 @@ 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(path.value)) {
35
- path.replace();
55
+ if (!isPublic(value)) {
56
+ return replace(path);
36
57
  }
37
58
 
38
59
  // TODO(nikku): transform illegal typescript methods into override calls
@@ -42,27 +63,80 @@ export default function transform(src) {
42
63
  // * @typedef
43
64
  // * @class
44
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
+
45
115
  });
46
116
 
117
+ for (const [ path, args ] of replacements) {
118
+ path.replace(...args);
119
+ }
120
+
47
121
  return print(ast).code;
48
122
  }
49
123
 
50
124
  function traverse(path, cb) {
51
- cb(path);
125
+ const val = path.value;
52
126
 
53
- if (path.parentPath) {
54
- const val = path.value;
55
-
56
- if (!isNode(val) && !isArray(val)) {
57
- return;
58
- }
127
+ if (!isNode(val) && !isArray(val)) {
128
+ return;
129
+ }
59
130
 
60
- for (const key of keys(val).reverse()) {
61
- if ([ 'loc', 'start', 'end' ].includes(key)) {
62
- continue;
63
- }
131
+ if (cb(path) === false) {
132
+ return;
133
+ }
64
134
 
65
- traverse(path.get(key), cb);
135
+ for (const key of keys(val).reverse()) {
136
+ if ([ 'loc', 'start', 'end' ].includes(key)) {
137
+ continue;
66
138
  }
139
+
140
+ traverse(path.get(key), cb);
67
141
  }
68
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bio-dts",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Generate sane and clean types from JavaScript sources",
5
5
  "type": "module",
6
6
  "main": "index.js",