3
3
* @typedef {import('@volar/language-service').Mapping<CodeInformation> } Mapping
4
4
* @typedef {import('@volar/language-service').VirtualFile } VirtualFile
5
5
* @typedef {import('estree').ExportDefaultDeclaration } ExportDefaultDeclaration
6
+ * @typedef {import('estree').Program } Program
6
7
* @typedef {import('mdast').Nodes } Nodes
7
8
* @typedef {import('mdast').Root } Root
8
9
* @typedef {import('mdast-util-mdxjs-esm').MdxjsEsm } MdxjsEsm
11
12
* @typedef {import('vfile-message').VFileMessage } VFileMessage
12
13
*/
13
14
15
+ import { walk } from 'estree-walker'
14
16
import { ScriptSnapshot } from './script-snapshot.js'
15
17
16
18
/**
@@ -31,23 +33,39 @@ const layoutJsDoc = (propsName) => `
31
33
* The MDX content wrapped in the layout.
32
34
*/`
33
35
34
- const componentStart = `
35
36
/**
36
- * Render the MDX contents.
37
+ * @param {boolean } isAsync
38
+ * Whether or not the `_createMdxContent` should be async
39
+ */
40
+ const componentStart = ( isAsync ) => `
41
+ /**
42
+ * @deprecated
43
+ * Do not use.
37
44
*
38
45
* @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props
39
46
* The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.
40
47
*/
41
- export default function MDXContent (props) {
48
+ ${ isAsync ? 'async ' : '' } function _createMdxContent (props) {
42
49
return `
50
+
43
51
const componentEnd = `
44
52
}
45
53
54
+ /**
55
+ * Render the MDX contents.
56
+ *
57
+ * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props
58
+ * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.
59
+ */
60
+ export default function MDXContent(props) {
61
+ return <_createMdxContent {...props} />
62
+ }
63
+
46
64
// @ts-ignore
47
65
/** @typedef {0 extends 1 & Props ? {} : Props} MDXContentProps */
48
66
`
49
67
50
- const fallback = componentStart + '<></>' + componentEnd
68
+ const fallback = componentStart ( false ) + '<></>' + componentEnd
51
69
52
70
/**
53
71
* Visit an mdast tree with and enter and exit callback.
@@ -210,6 +228,38 @@ function processExports(mdx, node, mapping, esm) {
210
228
return esm
211
229
}
212
230
231
+ /**
232
+ * @param {Program | undefined } expression
233
+ * @returns {boolean }
234
+ */
235
+ function hasAwaitExpression ( expression ) {
236
+ let awaitExpression = false
237
+ if ( expression ) {
238
+ walk ( expression , {
239
+ enter ( node ) {
240
+ if (
241
+ awaitExpression ||
242
+ node . type === 'ArrowFunctionExpression' ||
243
+ node . type === 'FunctionDeclaration' ||
244
+ node . type === 'FunctionExpression'
245
+ ) {
246
+ this . skip ( )
247
+ return
248
+ }
249
+
250
+ if (
251
+ node . type === 'AwaitExpression' ||
252
+ ( node . type === 'ForOfStatement' && node . await )
253
+ ) {
254
+ awaitExpression = true
255
+ this . skip ( )
256
+ }
257
+ }
258
+ } )
259
+ }
260
+ return awaitExpression
261
+ }
262
+
213
263
/**
214
264
* @param {string } fileName
215
265
* @param {string } mdx
@@ -280,6 +330,7 @@ function getEmbeddedFiles(fileName, mdx, ast) {
280
330
/** @type {VirtualFile[] } */
281
331
const virtualFiles = [ ]
282
332
333
+ let hasAwait = false
283
334
let esm = ''
284
335
let jsx = ''
285
336
let markdown = ''
@@ -402,12 +453,17 @@ function getEmbeddedFiles(fileName, mdx, ast) {
402
453
case 'mdxFlowExpression' :
403
454
case 'mdxTextExpression' : {
404
455
updateMarkdownFromNode ( node )
456
+ const program = node . data ?. estree
405
457
406
- if ( node . data ?. estree ?. body . length === 0 ) {
458
+ if ( program ?. body . length === 0 ) {
407
459
jsx = addOffset ( jsxMapping , mdx , jsx , start , start + 1 )
408
460
jsx = addOffset ( jsxMapping , mdx , jsx , end - 1 , end )
409
461
esm = addOffset ( esmMapping , mdx , esm , start + 1 , end - 1 ) + '\n'
410
462
} else {
463
+ if ( program ) {
464
+ hasAwait ||= hasAwaitExpression ( program )
465
+ }
466
+
411
467
jsx = addOffset ( jsxMapping , mdx , jsx , start , end )
412
468
}
413
469
@@ -460,7 +516,7 @@ function getEmbeddedFiles(fileName, mdx, ast) {
460
516
)
461
517
462
518
updateMarkdownFromOffsets ( mdx . length , mdx . length )
463
- esm += componentStart
519
+ esm += componentStart ( hasAwait )
464
520
465
521
for ( let i = 0 ; i < jsxMapping . generatedOffsets . length ; i ++ ) {
466
522
jsxMapping . generatedOffsets [ i ] += esm . length
0 commit comments