@vesk/compiler 0.1.14 → 0.2.9
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/dist/api-routes.d.ts +6 -1
- package/dist/api-routes.d.ts.map +1 -1
- package/dist/api-routes.js +52 -7
- package/dist/client-codegen.d.ts +15 -0
- package/dist/client-codegen.d.ts.map +1 -1
- package/dist/client-codegen.js +84 -11
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +25 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +33 -4
- package/dist/ir-generator.d.ts.map +1 -1
- package/dist/ir-generator.js +208 -9
- package/dist/md-inline.d.ts +17 -0
- package/dist/md-inline.d.ts.map +1 -0
- package/dist/md-inline.js +149 -0
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +42 -7
- package/dist/module-imports.d.ts +51 -0
- package/dist/module-imports.d.ts.map +1 -0
- package/dist/module-imports.js +715 -0
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +48 -3
- package/dist/server-codegen.d.ts +1 -1
- package/dist/server-codegen.d.ts.map +1 -1
- package/dist/server-codegen.js +1 -1
- package/dist/server-jsgen.d.ts.map +1 -1
- package/dist/server-jsgen.js +9 -4
- package/dist/server-render.d.ts.map +1 -1
- package/dist/server-render.js +30 -10
- package/dist/server-utils.d.ts +31 -0
- package/dist/server-utils.d.ts.map +1 -1
- package/dist/server-utils.js +478 -52
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +24 -1
- package/dist/typecheck.d.ts +2 -2
- package/dist/typecheck.d.ts.map +1 -1
- package/dist/typecheck.js +71 -27
- package/dist/types.d.ts +4 -129
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/vesk-plugin.d.ts +3 -0
- package/dist/vesk-plugin.d.ts.map +1 -1
- package/dist/vesk-plugin.js +518 -1
- package/dist/vsk-imports.d.ts.map +1 -1
- package/dist/vsk-imports.js +3 -1
- package/dist/vsk-tsx.d.ts.map +1 -1
- package/dist/vsk-tsx.js +27 -5
- package/package.json +2 -1
package/dist/vesk-plugin.js
CHANGED
|
@@ -1,7 +1,136 @@
|
|
|
1
1
|
import * as acorn from 'acorn';
|
|
2
|
+
const VOID_ELEMENTS = new Set([
|
|
3
|
+
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
|
|
4
|
+
'link', 'meta', 'param', 'source', 'track', 'wbr',
|
|
5
|
+
]);
|
|
6
|
+
function getJSXElementName(node) {
|
|
7
|
+
if (!node)
|
|
8
|
+
return null;
|
|
9
|
+
if (node.type === 'JSXIdentifier')
|
|
10
|
+
return node.name;
|
|
11
|
+
if (node.type === 'JSXNamespacedName' && node.namespace && node.name) {
|
|
12
|
+
return `${node.namespace.name}:${node.name.name}`;
|
|
13
|
+
}
|
|
14
|
+
if (node.type === 'JSXMemberExpression') {
|
|
15
|
+
const parts = [];
|
|
16
|
+
let cur = node;
|
|
17
|
+
while (cur && cur.type === 'JSXMemberExpression') {
|
|
18
|
+
if (cur.property && cur.property.name)
|
|
19
|
+
parts.unshift(cur.property.name);
|
|
20
|
+
cur = cur.object;
|
|
21
|
+
}
|
|
22
|
+
if (cur && cur.type === 'JSXIdentifier' && cur.name)
|
|
23
|
+
parts.unshift(cur.name);
|
|
24
|
+
return parts.join('.') || null;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function isIdentStartCode(code) {
|
|
29
|
+
return (code >= 65 && code <= 90) || (code >= 97 && code <= 122) || code === 95 || code === 36;
|
|
30
|
+
}
|
|
31
|
+
function isIdentCharCode(code) {
|
|
32
|
+
return isIdentStartCode(code) || (code >= 48 && code <= 57);
|
|
33
|
+
}
|
|
34
|
+
function getQualifiedJSXName(object) {
|
|
35
|
+
if (!object)
|
|
36
|
+
return object;
|
|
37
|
+
if (object.type === 'JSXIdentifier')
|
|
38
|
+
return object.name;
|
|
39
|
+
if (object.type === 'JSXNamespacedName')
|
|
40
|
+
return object.namespace.name + ':' + object.name.name;
|
|
41
|
+
if (object.type === 'JSXMemberExpression') {
|
|
42
|
+
return getQualifiedJSXName(object.object) + '.' + getQualifiedJSXName(object.property);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function looksLikeGenericArrowAt(input, pos) {
|
|
47
|
+
let i = pos + 1;
|
|
48
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
49
|
+
i++;
|
|
50
|
+
if (i >= input.length || !isIdentStartCode(input.charCodeAt(i)))
|
|
51
|
+
return false;
|
|
52
|
+
while (i < input.length && isIdentCharCode(input.charCodeAt(i)))
|
|
53
|
+
i++;
|
|
54
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
55
|
+
i++;
|
|
56
|
+
if (input.charCodeAt(i) !== 44)
|
|
57
|
+
return false; // ','
|
|
58
|
+
i++;
|
|
59
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
60
|
+
i++;
|
|
61
|
+
if (input.charCodeAt(i) !== 62)
|
|
62
|
+
return false; // '>'
|
|
63
|
+
i++;
|
|
64
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
65
|
+
i++;
|
|
66
|
+
if (input.charCodeAt(i) !== 40)
|
|
67
|
+
return false; // '('
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
const TS_PRIMITIVE_TYPES = new Set(['number', 'string', 'boolean', 'any', 'unknown', 'never', 'void', 'object', 'symbol', 'bigint', 'undefined', 'null']);
|
|
71
|
+
const HTML_TAGS = new Set(['a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'menu', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'slot', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
72
|
+
function looksLikeTypeAssertionAt(input, pos) {
|
|
73
|
+
let i = pos + 1;
|
|
74
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
75
|
+
i++;
|
|
76
|
+
const nameStart = i;
|
|
77
|
+
if (i >= input.length || !isIdentStartCode(input.charCodeAt(i)))
|
|
78
|
+
return false;
|
|
79
|
+
while (i < input.length && isIdentCharCode(input.charCodeAt(i)))
|
|
80
|
+
i++;
|
|
81
|
+
const name = input.slice(nameStart, i);
|
|
82
|
+
// If it's a known HTML tag (lowercase), it's JSX, not a type assertion
|
|
83
|
+
if (HTML_TAGS.has(name) || VOID_ELEMENTS.has(name))
|
|
84
|
+
return false;
|
|
85
|
+
// Only treat as type assertion if name is a TS primitive or capitalized type
|
|
86
|
+
const isPrimitive = TS_PRIMITIVE_TYPES.has(name);
|
|
87
|
+
const isCapitalized = name[0] >= 'A' && name[0] <= 'Z';
|
|
88
|
+
if (!isPrimitive && !isCapitalized)
|
|
89
|
+
return false;
|
|
90
|
+
// allow qualified type like `ns.Type` or `Array<string>`? For now only single identifier, skip generics check
|
|
91
|
+
// If next is '<', skip balanced <...>
|
|
92
|
+
if (input.charCodeAt(i) === 60) {
|
|
93
|
+
let depth = 0;
|
|
94
|
+
let j = i;
|
|
95
|
+
while (j < input.length) {
|
|
96
|
+
const c = input.charCodeAt(j);
|
|
97
|
+
if (c === 60)
|
|
98
|
+
depth++;
|
|
99
|
+
else if (c === 62) {
|
|
100
|
+
depth--;
|
|
101
|
+
if (depth === 0) {
|
|
102
|
+
i = j + 1;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
j++;
|
|
107
|
+
if (j - i > 100)
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
112
|
+
i++;
|
|
113
|
+
if (input.charCodeAt(i) !== 62)
|
|
114
|
+
return false; // '>'
|
|
115
|
+
i++;
|
|
116
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
117
|
+
i++;
|
|
118
|
+
if (i >= input.length)
|
|
119
|
+
return false;
|
|
120
|
+
const c = input.charCodeAt(i);
|
|
121
|
+
// expression start: identifier, (, [, {, ", ', `, !, ~, +, -, number, this/super etc.
|
|
122
|
+
if (isIdentStartCode(c) || c === 40 || c === 91 || c === 123 || c === 34 || c === 39 || c === 96 || c === 33 || c === 126 || c === 43 || c === 45 || (c >= 48 && c <= 57))
|
|
123
|
+
return true;
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
2
126
|
function isWsChar(code) {
|
|
3
127
|
return code === 32 || code === 9 || code === 10 || code === 13 || code === 12;
|
|
4
128
|
}
|
|
129
|
+
function skipWs(input, i) {
|
|
130
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
131
|
+
i++;
|
|
132
|
+
return i;
|
|
133
|
+
}
|
|
5
134
|
function isStyleBoundary(code) {
|
|
6
135
|
return isWsChar(code) || code === 62 || code === 47 || code === 123;
|
|
7
136
|
}
|
|
@@ -36,6 +165,9 @@ export function VeskParserPlugin(config = {}) {
|
|
|
36
165
|
#closeTagName = null;
|
|
37
166
|
#jsxStartsStatement = false;
|
|
38
167
|
#inTSTypeDecl = false;
|
|
168
|
+
#pendingChildStatement = false;
|
|
169
|
+
/** per-statement context-stack depths (LIFO — child statements may nest) */
|
|
170
|
+
#jsxChildDepthStack = [];
|
|
39
171
|
constructor(options, input) {
|
|
40
172
|
super(options, input);
|
|
41
173
|
}
|
|
@@ -43,7 +175,292 @@ export function VeskParserPlugin(config = {}) {
|
|
|
43
175
|
const ctx = this.curContext();
|
|
44
176
|
return ctx && (ctx.token === '{' || ctx.token === 'function');
|
|
45
177
|
}
|
|
178
|
+
#isJsxChildrenContext() {
|
|
179
|
+
const ctx = this.curContext();
|
|
180
|
+
return !!ctx && ctx.token === '<tag>...</tag>';
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Determines whether the text starting at `this.pos` opens a
|
|
184
|
+
* statement-mode control-flow header (`if (`, `for (`, `while (`,
|
|
185
|
+
* `switch (`, `try {`, `do {`) among JSX children. Scans chars only —
|
|
186
|
+
* the paren body must balance and be followed by a `{` block.
|
|
187
|
+
*/
|
|
188
|
+
#scansChildStatement() {
|
|
189
|
+
const input = this.input;
|
|
190
|
+
let i = this.pos;
|
|
191
|
+
while (i < input.length && isWsChar(input.charCodeAt(i)))
|
|
192
|
+
i++;
|
|
193
|
+
if (i >= input.length || !isIdentStartCode(input.charCodeAt(i)))
|
|
194
|
+
return false;
|
|
195
|
+
const wordStart = i;
|
|
196
|
+
while (i < input.length && isIdentCharCode(input.charCodeAt(i)))
|
|
197
|
+
i++;
|
|
198
|
+
const word = input.slice(wordStart, i);
|
|
199
|
+
// Declaration statements (`const`/`let`/`var …;`) are also valid
|
|
200
|
+
// statement-mode element children. Recognise them by a `=` of
|
|
201
|
+
// assignment plus either a top-level `;` or a newline at depth 0
|
|
202
|
+
// (ASI-style). Bail out (stay text) when a closing JSX tag `</` is
|
|
203
|
+
// seen before a terminator: a real element-child statement never
|
|
204
|
+
// contains its parent's closing tag, while prose text like
|
|
205
|
+
// `<p>const value = 5 apples</p>` does.
|
|
206
|
+
if (word === 'const' || word === 'let' || word === 'var') {
|
|
207
|
+
let depth = 0;
|
|
208
|
+
let seenAssign = false;
|
|
209
|
+
let q = i;
|
|
210
|
+
while (q < input.length) {
|
|
211
|
+
const c = input.charCodeAt(q);
|
|
212
|
+
if (c === 34 || c === 39 || c === 96) { // " ' `
|
|
213
|
+
const quote = c;
|
|
214
|
+
let tplDepth = 0;
|
|
215
|
+
q++;
|
|
216
|
+
while (q < input.length) {
|
|
217
|
+
const ch = input.charCodeAt(q);
|
|
218
|
+
if (ch === 92) {
|
|
219
|
+
q += 2;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (quote === 96 && ch === 36 && input.charCodeAt(q + 1) === 123) {
|
|
223
|
+
tplDepth++;
|
|
224
|
+
q += 2;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (quote === 96 && ch === 125 && tplDepth > 0) {
|
|
228
|
+
tplDepth--;
|
|
229
|
+
q++;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (ch === quote && tplDepth === 0) {
|
|
233
|
+
q++;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
q++;
|
|
237
|
+
}
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (c === 60 && input.charCodeAt(q + 1) === 47)
|
|
241
|
+
return false; // '</' -> it's JSX text, not a statement
|
|
242
|
+
if (c === 40 || c === 91 || c === 123)
|
|
243
|
+
depth++;
|
|
244
|
+
else if (c === 41 || c === 93 || c === 125)
|
|
245
|
+
depth--;
|
|
246
|
+
else if (c === 61 && depth === 0) { // '='
|
|
247
|
+
const n2 = input.charCodeAt(q + 1);
|
|
248
|
+
const n1 = q > 0 ? input.charCodeAt(q - 1) : 0;
|
|
249
|
+
if (n2 !== 61 && n2 !== 62 && n1 !== 33 && n1 !== 60 && n1 !== 61)
|
|
250
|
+
seenAssign = true; // not ==, =>, !=, <=, >=
|
|
251
|
+
}
|
|
252
|
+
else if (c === 59 && depth === 0)
|
|
253
|
+
return true; // ';'
|
|
254
|
+
else if ((c === 10 || c === 13) && depth === 0 && seenAssign)
|
|
255
|
+
return true; // ASI at end of line
|
|
256
|
+
q++;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
// Bare expression statements (`console.log(x)`, `alert('hi')`,
|
|
261
|
+
// `doSomething(args)`) are also valid statement-mode element children.
|
|
262
|
+
// They are ambiguous with prose, so only treat them as code when they
|
|
263
|
+
// read like a standalone line of code — not a sentence:
|
|
264
|
+
// * an identifier call chain (`console.log`, `foo?.bar`) with NO
|
|
265
|
+
// whitespace before the `(` (prose writes `word (`, code writes
|
|
266
|
+
// `word(`),
|
|
267
|
+
// * a balanced `(...)` call,
|
|
268
|
+
// * then a terminator — a top-level `;` or ASI newline — with no
|
|
269
|
+
// bare word after the `)` before it (`doSomething(x) then more`
|
|
270
|
+
// is prose; `doSomething(x)` on its own line is code).
|
|
271
|
+
// Bail out (stay text) when a closing JSX tag `</` is seen first, as
|
|
272
|
+
// a real child statement never contains its parent's closing tag.
|
|
273
|
+
if (isIdentStartCode(input.charCodeAt(wordStart))) {
|
|
274
|
+
let q = i; // position just after the first identifier
|
|
275
|
+
// member chain: `.foo` / `?.bar`, no surrounding whitespace
|
|
276
|
+
while (q < input.length) {
|
|
277
|
+
const c = input.charCodeAt(q);
|
|
278
|
+
if (c === 46 /* . */) {
|
|
279
|
+
q++;
|
|
280
|
+
}
|
|
281
|
+
else if (c === 63 /* ? */ && input.charCodeAt(q + 1) === 46) {
|
|
282
|
+
q += 2;
|
|
283
|
+
}
|
|
284
|
+
else
|
|
285
|
+
break;
|
|
286
|
+
if (q >= input.length || !isIdentStartCode(input.charCodeAt(q)))
|
|
287
|
+
return false;
|
|
288
|
+
q++;
|
|
289
|
+
while (q < input.length && isIdentCharCode(input.charCodeAt(q)))
|
|
290
|
+
q++;
|
|
291
|
+
}
|
|
292
|
+
// must be a call: `(` with no whitespace before it
|
|
293
|
+
if (input.charCodeAt(q) === 40 /* ( */) {
|
|
294
|
+
let depth = 0;
|
|
295
|
+
let callClosed = false;
|
|
296
|
+
let s = q;
|
|
297
|
+
while (s < input.length) {
|
|
298
|
+
const c = input.charCodeAt(s);
|
|
299
|
+
if (c === 34 || c === 39 || c === 96) { // " ' `
|
|
300
|
+
const quote = c;
|
|
301
|
+
let tplDepth = 0;
|
|
302
|
+
s++;
|
|
303
|
+
while (s < input.length) {
|
|
304
|
+
const ch = input.charCodeAt(s);
|
|
305
|
+
if (ch === 92) {
|
|
306
|
+
s += 2;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (quote === 96 && ch === 36 && input.charCodeAt(s + 1) === 123) {
|
|
310
|
+
tplDepth++;
|
|
311
|
+
s += 2;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (quote === 96 && ch === 125 && tplDepth > 0) {
|
|
315
|
+
tplDepth--;
|
|
316
|
+
s++;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (ch === quote && tplDepth === 0) {
|
|
320
|
+
s++;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
s++;
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (c === 60 && input.charCodeAt(s + 1) === 47)
|
|
328
|
+
return false; // '</'
|
|
329
|
+
if (c === 40 || c === 91 || c === 123)
|
|
330
|
+
depth++;
|
|
331
|
+
else if (c === 41 || c === 93 || c === 125) {
|
|
332
|
+
depth--;
|
|
333
|
+
if (c === 41 && depth === 0) {
|
|
334
|
+
callClosed = true;
|
|
335
|
+
s++;
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
s++;
|
|
340
|
+
}
|
|
341
|
+
if (!callClosed)
|
|
342
|
+
return false;
|
|
343
|
+
// After the call, walk forward treating each character in turn so
|
|
344
|
+
// we can tell "standalone statement ending in `;` / newline" from
|
|
345
|
+
// "trailing prose on the same line". Chained member calls
|
|
346
|
+
// (`.foo(...)`) and paren-groups are consumed; a bare word on the
|
|
347
|
+
// same line before a newline/`;` means the child is a sentence.
|
|
348
|
+
let d = 0;
|
|
349
|
+
for (;;) {
|
|
350
|
+
if (s >= input.length)
|
|
351
|
+
return false;
|
|
352
|
+
const c = input.charCodeAt(s);
|
|
353
|
+
if (c === 60 && input.charCodeAt(s + 1) === 47)
|
|
354
|
+
return false; // '</' -> prose
|
|
355
|
+
if (c === 34 || c === 39 || c === 96) { // " ' `
|
|
356
|
+
const quote = c;
|
|
357
|
+
let tplDepth = 0;
|
|
358
|
+
s++;
|
|
359
|
+
while (s < input.length) {
|
|
360
|
+
const ch = input.charCodeAt(s);
|
|
361
|
+
if (ch === 92) {
|
|
362
|
+
s += 2;
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (quote === 96 && ch === 36 && input.charCodeAt(s + 1) === 123) {
|
|
366
|
+
tplDepth++;
|
|
367
|
+
s += 2;
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (quote === 96 && ch === 125 && tplDepth > 0) {
|
|
371
|
+
tplDepth--;
|
|
372
|
+
s++;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (ch === quote && tplDepth === 0) {
|
|
376
|
+
s++;
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
s++;
|
|
380
|
+
}
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (c === 40 || c === 91 || c === 123)
|
|
384
|
+
d++;
|
|
385
|
+
else if (c === 41 || c === 93 || c === 125)
|
|
386
|
+
d--;
|
|
387
|
+
else if (c === 59 && d === 0)
|
|
388
|
+
return true; // ';' -> statement
|
|
389
|
+
else if ((c === 10 || c === 13) && d === 0)
|
|
390
|
+
return true; // ASI newline -> standalone
|
|
391
|
+
else if (c === 46) { // member access `.foo`; may lead to another call
|
|
392
|
+
s++;
|
|
393
|
+
while (s < input.length && isIdentCharCode(input.charCodeAt(s)))
|
|
394
|
+
s++;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
else if (isIdentCharCode(c) || isIdentStartCode(c))
|
|
398
|
+
return false; // bare word -> prose
|
|
399
|
+
s++;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (word !== 'if' && word !== 'for' && word !== 'while' && word !== 'switch' && word !== 'try' && word !== 'do')
|
|
404
|
+
return false;
|
|
405
|
+
let p = i;
|
|
406
|
+
while (p < input.length && isWsChar(input.charCodeAt(p)))
|
|
407
|
+
p++;
|
|
408
|
+
if (word === 'try' || word === 'do') {
|
|
409
|
+
return input.charCodeAt(p) === 123; // '{'
|
|
410
|
+
}
|
|
411
|
+
if (input.charCodeAt(p) !== 40)
|
|
412
|
+
return false; // '('
|
|
413
|
+
let depth = 1;
|
|
414
|
+
let q = p + 1;
|
|
415
|
+
while (q < input.length) {
|
|
416
|
+
const c = input.charCodeAt(q);
|
|
417
|
+
if (c === 34 || c === 39 || c === 96) {
|
|
418
|
+
const quote = c;
|
|
419
|
+
q++;
|
|
420
|
+
while (q < input.length) {
|
|
421
|
+
const ch = input.charCodeAt(q);
|
|
422
|
+
if (ch === 92) {
|
|
423
|
+
q += 2;
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
if (ch === quote) {
|
|
427
|
+
q++;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
q++;
|
|
431
|
+
}
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (c === 40 || c === 91 || c === 123)
|
|
435
|
+
depth++;
|
|
436
|
+
else if (c === 41 || c === 93 || c === 125) {
|
|
437
|
+
depth--;
|
|
438
|
+
if (c === 41 && depth === 0)
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
q++;
|
|
442
|
+
}
|
|
443
|
+
if (q >= input.length)
|
|
444
|
+
return false;
|
|
445
|
+
let r = q + 1;
|
|
446
|
+
while (r < input.length && isWsChar(input.charCodeAt(r)))
|
|
447
|
+
r++;
|
|
448
|
+
return input.charCodeAt(r) === 123; // '{'
|
|
449
|
+
}
|
|
46
450
|
readToken(code) {
|
|
451
|
+
if (this.#componentDepth > 0 && this.#isJsxChildrenContext() && this.#scansChildStatement()) {
|
|
452
|
+
this.#pendingChildStatement = true;
|
|
453
|
+
this.#jsxChildDepthStack.push(this.context.length);
|
|
454
|
+
this.context.push(acorn.tokContexts.b_stat);
|
|
455
|
+
if (isWsChar(code)) {
|
|
456
|
+
this.skipSpace();
|
|
457
|
+
this.start = this.pos;
|
|
458
|
+
if (this.options.locations && typeof this.curPosition === 'function') {
|
|
459
|
+
this.startLoc = this.curPosition();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return super.readToken(this.input.codePointAt(this.pos));
|
|
463
|
+
}
|
|
47
464
|
if (this.#componentDepth > 0 && code === 60 && this.#isBlockContext()) {
|
|
48
465
|
const next = this.input.charCodeAt(this.pos + 1);
|
|
49
466
|
if (next === 47 || (next >= 65 && next <= 90) || (next >= 97 && next <= 122)) {
|
|
@@ -58,6 +475,10 @@ export function VeskParserPlugin(config = {}) {
|
|
|
58
475
|
};
|
|
59
476
|
if (inType) {
|
|
60
477
|
if (startsNewStatement) {
|
|
478
|
+
if (looksLikeGenericArrowAt(this.input, this.pos) || looksLikeTypeAssertionAt(this.input, this.pos)) {
|
|
479
|
+
this.#jsxStartsStatement = false;
|
|
480
|
+
return super.readToken(code);
|
|
481
|
+
}
|
|
61
482
|
this.#jsxStartsStatement = true;
|
|
62
483
|
++this.pos;
|
|
63
484
|
return this.finishToken(tstt.jsxTagStart);
|
|
@@ -70,6 +491,10 @@ export function VeskParserPlugin(config = {}) {
|
|
|
70
491
|
prev === tt._this || prev === tt._super || prev === tt._true || prev === tt._false ||
|
|
71
492
|
prev === tt._null || prev === tt.jsxTagEnd;
|
|
72
493
|
if (!canEndExpr || startsNewStatement) {
|
|
494
|
+
if (looksLikeGenericArrowAt(this.input, this.pos) || looksLikeTypeAssertionAt(this.input, this.pos)) {
|
|
495
|
+
this.#jsxStartsStatement = false;
|
|
496
|
+
return super.readToken(code);
|
|
497
|
+
}
|
|
73
498
|
this.#jsxStartsStatement = true;
|
|
74
499
|
return forceJsx();
|
|
75
500
|
}
|
|
@@ -377,7 +802,99 @@ export function VeskParserPlugin(config = {}) {
|
|
|
377
802
|
if (prefix.startsWith('<style') && isStyleBoundary(prefix.charCodeAt(6))) {
|
|
378
803
|
return this.parseStyleElement(startPos, startLoc);
|
|
379
804
|
}
|
|
380
|
-
return
|
|
805
|
+
return this.#parseElementWithStatements(startPos, startLoc);
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Parses an entire JSX element (or fragment) starting after `<`,
|
|
809
|
+
* mirroring the vendored acorn-jsx `jsx_parseElementAt` with an added
|
|
810
|
+
* statement-mode branch: when `#pendingChildStatement` is set (a
|
|
811
|
+
* control-flow header like `if (…) {` appeared where JSX children
|
|
812
|
+
* expect text), a real statement is parsed into the children array.
|
|
813
|
+
*/
|
|
814
|
+
#parseElementWithStatements(startPos, startLoc) {
|
|
815
|
+
const node = this.startNodeAt(startPos, startLoc);
|
|
816
|
+
const children = [];
|
|
817
|
+
const openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc);
|
|
818
|
+
let closingElement = null;
|
|
819
|
+
if (!openingElement.selfClosing) {
|
|
820
|
+
contents: for (;;) {
|
|
821
|
+
if (this.#pendingChildStatement) {
|
|
822
|
+
this.#pendingChildStatement = false;
|
|
823
|
+
const stmt = this.parseStatement(null);
|
|
824
|
+
children.push(stmt);
|
|
825
|
+
// Restore the JSX-children tokenizer and re-lex the trailing
|
|
826
|
+
// token (lexed under the temporary b_stat context) as a JSX child.
|
|
827
|
+
this.context.length = this.#jsxChildDepthStack.pop() ?? this.context.length;
|
|
828
|
+
this.exprAllowed = true;
|
|
829
|
+
this.pos = this.start;
|
|
830
|
+
this.next();
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
switch (this.type) {
|
|
834
|
+
case tstt?.jsxTagStart:
|
|
835
|
+
startPos = this.start;
|
|
836
|
+
startLoc = this.startLoc;
|
|
837
|
+
this.next();
|
|
838
|
+
if (this.eat(tt.slash)) {
|
|
839
|
+
closingElement = this.jsx_parseClosingElementAt(startPos, startLoc);
|
|
840
|
+
break contents;
|
|
841
|
+
}
|
|
842
|
+
children.push(this.jsx_parseElementAt(startPos, startLoc));
|
|
843
|
+
break;
|
|
844
|
+
case tstt?.jsxText:
|
|
845
|
+
children.push(this.parseExprAtom());
|
|
846
|
+
break;
|
|
847
|
+
case tt.braceL:
|
|
848
|
+
children.push(this.jsx_parseExpressionContainer());
|
|
849
|
+
break;
|
|
850
|
+
default:
|
|
851
|
+
this.unexpected();
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
|
|
855
|
+
this.raise(closingElement.start, "Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">");
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
const fragmentOrElement = openingElement.name ? "Element" : "Fragment";
|
|
859
|
+
node["opening" + fragmentOrElement] = openingElement;
|
|
860
|
+
node["closing" + fragmentOrElement] = closingElement;
|
|
861
|
+
node.children = children;
|
|
862
|
+
if (this.type === tt.relational && this.value === "<") {
|
|
863
|
+
this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
|
|
864
|
+
}
|
|
865
|
+
return this.finishNode(node, "JSX" + fragmentOrElement);
|
|
866
|
+
}
|
|
867
|
+
jsx_parseOpeningElementAt(startPos, startLoc) {
|
|
868
|
+
// Manual implementation that treats HTML void elements as
|
|
869
|
+
// self-closing even without `/>`. Delegating to super would leave
|
|
870
|
+
// a stale tc_expr context (the `>` updateContext only pops the
|
|
871
|
+
// extra level when a `/` was present), so the following `}` is
|
|
872
|
+
// mis-read as JSX text: "Unexpected token `}`".
|
|
873
|
+
const node = this.startNodeAt(startPos, startLoc);
|
|
874
|
+
node.attributes = [];
|
|
875
|
+
const nodeName = this.jsx_parseElementName();
|
|
876
|
+
if (nodeName)
|
|
877
|
+
node.name = nodeName;
|
|
878
|
+
const nameStr = getJSXElementName(nodeName);
|
|
879
|
+
const isVoid = !!(nameStr && VOID_ELEMENTS.has(nameStr));
|
|
880
|
+
while (this.type !== tt.slash && this.type !== tstt.jsxTagEnd) {
|
|
881
|
+
node.attributes.push(this.jsx_parseAttribute());
|
|
882
|
+
}
|
|
883
|
+
const hasSlash = this.eat(tt.slash);
|
|
884
|
+
node.selfClosing = hasSlash || isVoid;
|
|
885
|
+
if (this.type !== tstt.jsxTagEnd)
|
|
886
|
+
this.unexpected();
|
|
887
|
+
if (isVoid && !hasSlash) {
|
|
888
|
+
const stack = this.context;
|
|
889
|
+
if (stack.length > 0 && stack[stack.length - 1].token === '<tag>...</tag>') {
|
|
890
|
+
stack.pop();
|
|
891
|
+
this.exprAllowed = true;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
// Consume `>`. For void `>` we already popped tc_expr above so the
|
|
895
|
+
// following `}` is read as a normal JS token, not JSX text.
|
|
896
|
+
this.next();
|
|
897
|
+
return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment');
|
|
381
898
|
}
|
|
382
899
|
parseStyleElement(startPos, startLoc) {
|
|
383
900
|
const el = this.startNodeAt(startPos, startLoc);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vsk-imports.d.ts","sourceRoot":"","sources":["../src/vsk-imports.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAahE;AA0BD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAUrF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"vsk-imports.d.ts","sourceRoot":"","sources":["../src/vsk-imports.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAahE;AA0BD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAUrF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsBhE"}
|
package/dist/vsk-imports.js
CHANGED
|
@@ -127,7 +127,9 @@ export function stripTypeImport(importSrc) {
|
|
|
127
127
|
return null;
|
|
128
128
|
const specs = stmt.specifiers || [];
|
|
129
129
|
const kept = specs.filter((s) => s.importKind !== 'type');
|
|
130
|
-
|
|
130
|
+
// A side-effect import (`import './x'`) has no specifiers at all — it is NOT
|
|
131
|
+
// type-only and must survive so both bundles run its module-level code.
|
|
132
|
+
if (specs.length > 0 && kept.length === 0)
|
|
131
133
|
return null;
|
|
132
134
|
if (kept.length === specs.length)
|
|
133
135
|
return importSrc;
|
package/dist/vsk-tsx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vsk-tsx.d.ts","sourceRoot":"","sources":["../src/vsk-tsx.ts"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3E,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;KAAE,CAAC;IACtG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"vsk-tsx.d.ts","sourceRoot":"","sources":["../src/vsk-tsx.ts"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AAEH,MAAM,WAAW,QAAQ;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAClD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC3E,UAAU,CAAC,EAAE,OAAO,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;KAAE,CAAC;IACtG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AA++BD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CA0ChG;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/C;AAWD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmDrD"}
|
package/dist/vsk-tsx.js
CHANGED
|
@@ -388,7 +388,17 @@ function emitJSXElement(g, source, el, opts) {
|
|
|
388
388
|
emitJSXAttr(g, source, attr);
|
|
389
389
|
prev = attr.end;
|
|
390
390
|
}
|
|
391
|
-
|
|
391
|
+
const tail = source.slice(prev, op.end);
|
|
392
|
+
if (op.selfClosing && !tail.includes('/')) {
|
|
393
|
+
const gt = tail.lastIndexOf('>');
|
|
394
|
+
const head = gt === -1 ? tail : tail.slice(0, gt);
|
|
395
|
+
if (head)
|
|
396
|
+
g.add(head, prev, prev + head.length);
|
|
397
|
+
g.addRaw('/>');
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
g.add(tail, prev, op.end);
|
|
401
|
+
}
|
|
392
402
|
if (op.selfClosing)
|
|
393
403
|
return;
|
|
394
404
|
emitJSXChildren(g, source, el.children ?? [], opts);
|
|
@@ -559,6 +569,18 @@ function emitJSXChildren(g, source, children, opts) {
|
|
|
559
569
|
emitJSXFragment(g, source, child, opts);
|
|
560
570
|
i++;
|
|
561
571
|
}
|
|
572
|
+
else if (child.type === 'IfStatement' || child.type === 'ForOfStatement' ||
|
|
573
|
+
child.type === 'ForStatement' || child.type === 'ForInStatement' ||
|
|
574
|
+
child.type === 'WhileStatement' || child.type === 'DoWhileStatement' ||
|
|
575
|
+
child.type === 'SwitchStatement' || child.type === 'TryStatement' ||
|
|
576
|
+
child.type === 'VariableDeclaration' || child.type === 'ExpressionStatement') {
|
|
577
|
+
// Statement-mode control flow nested among JSX children: TSX has no
|
|
578
|
+
// statement children, so wrap each in an IIFE expression container.
|
|
579
|
+
g.addRaw('{(() => { ');
|
|
580
|
+
emitBody(g, source, [child], '', opts);
|
|
581
|
+
g.addRaw(' })()}');
|
|
582
|
+
i++;
|
|
583
|
+
}
|
|
562
584
|
else {
|
|
563
585
|
i++;
|
|
564
586
|
}
|
|
@@ -1008,7 +1030,7 @@ export function compileVskCodegen(source, opts = {}) {
|
|
|
1008
1030
|
g.add(clean.slice(pos), pos, source.length);
|
|
1009
1031
|
let code = g.code;
|
|
1010
1032
|
if (isModuleAst(ast) && containsIdentifier(code, 'Head') && !isIdentifierImported(code, 'Head')) {
|
|
1011
|
-
g.prepend('declare const Head: (props: { children?:
|
|
1033
|
+
g.prepend('declare const Head: (props: { children?: Component }) => Component;\n');
|
|
1012
1034
|
code = g.code;
|
|
1013
1035
|
}
|
|
1014
1036
|
return { code, mappings: g.mappings, styleRegions: g.styleRegions, errors: [] };
|
|
@@ -1057,7 +1079,7 @@ export function generateVskDts(source) {
|
|
|
1057
1079
|
const hasType = propsType !== null && propsType !== undefined;
|
|
1058
1080
|
const collision = typeDeclNames.has(typeName);
|
|
1059
1081
|
const signature = hasType
|
|
1060
|
-
? (collision ? propsType : typeName) + ' & { children?:
|
|
1082
|
+
? (collision ? propsType : typeName) + ' & { children?: Component }'
|
|
1061
1083
|
: 'any';
|
|
1062
1084
|
if (hasType && !collision) {
|
|
1063
1085
|
lines.push(`export type ${typeName} = ${propsType};`, '');
|
|
@@ -1066,10 +1088,10 @@ export function generateVskDts(source) {
|
|
|
1066
1088
|
lines.push(`export type ${typeName} = any;`, '');
|
|
1067
1089
|
}
|
|
1068
1090
|
if (defaultExport) {
|
|
1069
|
-
lines.push(`export default function ${name}(props: ${signature}):
|
|
1091
|
+
lines.push(`export default function ${name}(props: ${signature}): Component;`, '');
|
|
1070
1092
|
}
|
|
1071
1093
|
else {
|
|
1072
|
-
lines.push(`export declare function ${name}(props: ${signature}):
|
|
1094
|
+
lines.push(`export declare function ${name}(props: ${signature}): Component;`, '');
|
|
1073
1095
|
}
|
|
1074
1096
|
}
|
|
1075
1097
|
return lines.join('\n');
|