From 000db8cd1a15e7ed2723bd75a2871a92da1955aa Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 19 Dec 2023 14:08:55 +0100 Subject: [PATCH] Support await expressions (#377) To support await expressions, the `_createMdxContent` function is generated. It is marked as deprecated to discourage the user from using it. This pushes the function to the bottom of TypeScript autocompletion and renders it with a strike through effect. --- .changeset/odd-fireants-smell.md | 7 + packages/language-service/lib/virtual-file.js | 68 +++- packages/language-service/package.json | 1 + .../language-service/test/language-module.js | 377 ++++++++++++++++-- 4 files changed, 421 insertions(+), 32 deletions(-) create mode 100644 .changeset/odd-fireants-smell.md diff --git a/.changeset/odd-fireants-smell.md b/.changeset/odd-fireants-smell.md new file mode 100644 index 00000000..8a2dfd54 --- /dev/null +++ b/.changeset/odd-fireants-smell.md @@ -0,0 +1,7 @@ +--- +"@mdx-js/language-service": patch +"@mdx-js/language-server": patch +"vscode-mdx": patch +--- + +Support await expressions. diff --git a/packages/language-service/lib/virtual-file.js b/packages/language-service/lib/virtual-file.js index c121c050..30d3c04b 100644 --- a/packages/language-service/lib/virtual-file.js +++ b/packages/language-service/lib/virtual-file.js @@ -3,6 +3,7 @@ * @typedef {import('@volar/language-service').Mapping} Mapping * @typedef {import('@volar/language-service').VirtualFile} VirtualFile * @typedef {import('estree').ExportDefaultDeclaration} ExportDefaultDeclaration + * @typedef {import('estree').Program} Program * @typedef {import('mdast').Nodes} Nodes * @typedef {import('mdast').Root} Root * @typedef {import('mdast-util-mdxjs-esm').MdxjsEsm} MdxjsEsm @@ -11,6 +12,7 @@ * @typedef {import('vfile-message').VFileMessage} VFileMessage */ +import {walk} from 'estree-walker' import {ScriptSnapshot} from './script-snapshot.js' /** @@ -31,23 +33,39 @@ const layoutJsDoc = (propsName) => ` * The MDX content wrapped in the layout. */` -const componentStart = ` /** - * Render the MDX contents. + * @param {boolean} isAsync + * Whether or not the `_createMdxContent` should be async + */ +const componentStart = (isAsync) => ` +/** + * @deprecated + * Do not use. * * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component. */ -export default function MDXContent(props) { +${isAsync ? 'async ' : ''}function _createMdxContent(props) { return ` + const componentEnd = ` } +/** + * Render the MDX contents. + * + * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props + * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component. + */ +export default function MDXContent(props) { + return <_createMdxContent {...props} /> +} + // @ts-ignore /** @typedef {0 extends 1 & Props ? {} : Props} MDXContentProps */ ` -const fallback = componentStart + '<>' + componentEnd +const fallback = componentStart(false) + '<>' + componentEnd /** * Visit an mdast tree with and enter and exit callback. @@ -210,6 +228,38 @@ function processExports(mdx, node, mapping, esm) { return esm } +/** + * @param {Program | undefined} expression + * @returns {boolean} + */ +function hasAwaitExpression(expression) { + let awaitExpression = false + if (expression) { + walk(expression, { + enter(node) { + if ( + awaitExpression || + node.type === 'ArrowFunctionExpression' || + node.type === 'FunctionDeclaration' || + node.type === 'FunctionExpression' + ) { + this.skip() + return + } + + if ( + node.type === 'AwaitExpression' || + (node.type === 'ForOfStatement' && node.await) + ) { + awaitExpression = true + this.skip() + } + } + }) + } + return awaitExpression +} + /** * @param {string} fileName * @param {string} mdx @@ -280,6 +330,7 @@ function getEmbeddedFiles(fileName, mdx, ast) { /** @type {VirtualFile[]} */ const virtualFiles = [] + let hasAwait = false let esm = '' let jsx = '' let markdown = '' @@ -402,12 +453,17 @@ function getEmbeddedFiles(fileName, mdx, ast) { case 'mdxFlowExpression': case 'mdxTextExpression': { updateMarkdownFromNode(node) + const program = node.data?.estree - if (node.data?.estree?.body.length === 0) { + if (program?.body.length === 0) { jsx = addOffset(jsxMapping, mdx, jsx, start, start + 1) jsx = addOffset(jsxMapping, mdx, jsx, end - 1, end) esm = addOffset(esmMapping, mdx, esm, start + 1, end - 1) + '\n' } else { + if (program) { + hasAwait ||= hasAwaitExpression(program) + } + jsx = addOffset(jsxMapping, mdx, jsx, start, end) } @@ -460,7 +516,7 @@ function getEmbeddedFiles(fileName, mdx, ast) { ) updateMarkdownFromOffsets(mdx.length, mdx.length) - esm += componentStart + esm += componentStart(hasAwait) for (let i = 0; i < jsxMapping.generatedOffsets.length; i++) { jsxMapping.generatedOffsets[i] += esm.length diff --git a/packages/language-service/package.json b/packages/language-service/package.json index 68a5493c..df86b96b 100644 --- a/packages/language-service/package.json +++ b/packages/language-service/package.json @@ -35,6 +35,7 @@ "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "@volar/language-service": "2.0.0-alpha.7", + "estree-walker": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", diff --git a/packages/language-service/test/language-module.js b/packages/language-service/test/language-module.js index 9773faf7..e4a3c6db 100644 --- a/packages/language-service/test/language-module.js +++ b/packages/language-service/test/language-module.js @@ -62,13 +62,24 @@ test('create virtual file w/ mdxjsEsm', () => { 'import {Planet} from "./Planet.js"', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -154,13 +165,24 @@ test('create virtual file w/o MDX layout in case of named re-export', () => { 'export {named} from "./Layout.js"', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -249,13 +271,24 @@ test('create virtual file w/ MDX layout in case of default re-export', () => { 'export {} from "./Layout.js"', 'import {default as MDXLayout} from "./Layout.js"', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -344,13 +377,24 @@ test('create virtual file w/ MDX layout in case of named and default re-export', 'export {named, } from "./Layout.js"', 'import {default as MDXLayout} from "./Layout.js"', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -439,13 +483,24 @@ test('create virtual file w/ MDX layout in case of default and named re-export', 'export { named} from "./Layout.js"', 'import {default as MDXLayout} from "./Layout.js"', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -545,13 +600,24 @@ test('create virtual file w/ MDX layout in case of a default exported arrow func 'const MDXLayout = () => {}', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -654,13 +720,24 @@ test('create virtual file w/ MDX layout in case of a default exported function d 'const MDXLayout = function MDXLayout() {}', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -747,13 +824,24 @@ test('create virtual file w/ MDX layout in case of a default exported constant', 'const MDXLayout = "main"', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -856,13 +944,24 @@ test('create virtual file w/ MDX layout and matching argument name', () => { 'const MDXLayout = function MDXLayout(properties) {}', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -967,13 +1066,24 @@ test('create virtual file w/ MDX layout in case of a default export followed by 'export function named() {}', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1078,13 +1188,24 @@ test('create virtual file w/ MDX layout in case of a default export preceded by 'const MDXLayout = function MDXLayout() {}', '', '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', + '', + '/**', ' * Render the MDX contents.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1154,7 +1275,7 @@ test('create virtual file w/ mdxFlowExpression', () => { mappings: [ { sourceOffsets: [0], - generatedOffsets: [275], + generatedOffsets: [271], lengths: [9], data: { completion: true, @@ -1167,6 +1288,17 @@ test('create virtual file w/ mdxFlowExpression', () => { } ], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>{Math.PI}', + '}', '', '/**', ' * Render the MDX contents.', @@ -1175,7 +1307,7 @@ test('create virtual file w/ mdxFlowExpression', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>{Math.PI}', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1252,7 +1384,7 @@ test('create virtual file w/ mdxJsxFlowElement w/ children', () => { mappings: [ { sourceOffsets: [0, 57], - generatedOffsets: [275, 293], + generatedOffsets: [271, 289], lengths: [9, 8], data: { completion: true, @@ -1267,12 +1399,13 @@ test('create virtual file w/ mdxJsxFlowElement w/ children', () => { snapshot: snapshotFromLines( '', '/**', - ' * Render the MDX contents.', + ' * @deprecated', + ' * Do not use.', ' *', ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', - 'export default function MDXContent(props) {', + 'function _createMdxContent(props) {', ' return <>
', '', " <>{''}", @@ -1280,6 +1413,16 @@ test('create virtual file w/ mdxJsxFlowElement w/ children', () => { '
', '}', '', + '/**', + ' * Render the MDX contents.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'export default function MDXContent(props) {', + ' return <_createMdxContent {...props} />', + '}', + '', '// @ts-ignore', '/** @typedef {0 extends 1 & Props ? {} : Props} MDXContentProps */', '' @@ -1347,7 +1490,7 @@ test('create virtual file w/ mdxJsxFlowElement w/o children', () => { mappings: [ { sourceOffsets: [0], - generatedOffsets: [275], + generatedOffsets: [271], lengths: [7], data: { completion: true, @@ -1360,6 +1503,17 @@ test('create virtual file w/ mdxJsxFlowElement w/o children', () => { } ], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>
', + '}', '', '/**', ' * Render the MDX contents.', @@ -1368,7 +1522,7 @@ test('create virtual file w/ mdxJsxFlowElement w/o children', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>
', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1441,7 +1595,7 @@ test('create virtual file w/ mdxJsxTextElement', () => { mappings: [ { sourceOffsets: [2], - generatedOffsets: [281], + generatedOffsets: [277], lengths: [7], data: { completion: true, @@ -1454,6 +1608,17 @@ test('create virtual file w/ mdxJsxTextElement', () => { } ], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + " return <><>{''}
", + '}', '', '/**', ' * Render the MDX contents.', @@ -1462,7 +1627,7 @@ test('create virtual file w/ mdxJsxTextElement', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - " return <><>{''}
", + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1531,7 +1696,7 @@ test('create virtual file w/ mdxTextExpression', () => { }, mappings: [ { - generatedOffsets: [281], + generatedOffsets: [277], sourceOffsets: [4], lengths: [9], data: { @@ -1545,6 +1710,17 @@ test('create virtual file w/ mdxTextExpression', () => { } ], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + " return <><>{''}{Math.PI}{''}", + '}', '', '/**', ' * Render the MDX contents.', @@ -1553,7 +1729,7 @@ test('create virtual file w/ mdxTextExpression', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - " return <><>{''}{Math.PI}{''}", + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1585,6 +1761,111 @@ test('create virtual file w/ mdxTextExpression', () => { ]) }) +test('create virtual file w/ async mdxTextExpression', () => { + const plugin = createMdxLanguagePlugin() + + const snapshot = snapshotFromLines( + '3 < {await Promise.resolve(Math.PI)} < 4', + '' + ) + + const file = plugin.createVirtualFile('/test.mdx', 'mdx', snapshot) + + assert.ok(file instanceof VirtualMdxFile) + assert.equal(file.fileName, '/test.mdx') + assert.equal(file.languageId, 'mdx') + assert.ifError(file.error) + assert.equal(file.snapshot, snapshot) + assert.deepEqual(file.mappings, [ + { + sourceOffsets: [0], + generatedOffsets: [0], + lengths: [snapshot.getLength()], + data: { + completion: true, + format: true, + navigation: true, + semantic: true, + structure: true, + verification: true + } + } + ]) + assert.deepEqual(file.embeddedFiles, [ + { + embeddedFiles: [], + fileName: '/test.mdx.jsx', + languageId: 'javascriptreact', + typescript: { + scriptKind: typescript.ScriptKind.JSX + }, + mappings: [ + { + generatedOffsets: [283], + sourceOffsets: [4], + lengths: [32], + data: { + completion: true, + format: false, + navigation: true, + semantic: true, + structure: true, + verification: true + } + } + ], + snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'async function _createMdxContent(props) {', + " return <><>{''}{await Promise.resolve(Math.PI)}{''}", + '}', + '', + '/**', + ' * Render the MDX contents.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'export default function MDXContent(props) {', + ' return <_createMdxContent {...props} />', + '}', + '', + '// @ts-ignore', + '/** @typedef {0 extends 1 & Props ? {} : Props} MDXContentProps */', + '' + ) + }, + { + embeddedFiles: [], + fileName: '/test.mdx.md', + languageId: 'markdown', + mappings: [ + { + sourceOffsets: [0, 36], + generatedOffsets: [0, 11], + lengths: [4, 5], + data: { + completion: true, + format: false, + navigation: true, + semantic: true, + structure: true, + verification: true + } + } + ], + snapshot: snapshotFromLines('3 < < 4', '') + } + ]) +}) + test('create virtual file w/ dedented markdown content', () => { const plugin = createMdxLanguagePlugin() @@ -1628,6 +1909,17 @@ test('create virtual file w/ dedented markdown content', () => { }, mappings: [], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + " return <><>{''}", + '}', '', '/**', ' * Render the MDX contents.', @@ -1636,7 +1928,7 @@ test('create virtual file w/ dedented markdown content', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - " return <><>{''}", + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1708,6 +2000,17 @@ test('create virtual file w/ syntax error', () => { languageId: 'javascriptreact', mappings: [], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', '', '/**', ' * Render the MDX contents.', @@ -1716,7 +2019,7 @@ test('create virtual file w/ syntax error', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1771,6 +2074,17 @@ test('create virtual file w/ yaml frontmatter', () => { languageId: 'javascriptreact', mappings: [], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + ' return <>', + '}', '', '/**', ' * Render the MDX contents.', @@ -1779,7 +2093,7 @@ test('create virtual file w/ yaml frontmatter', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - ' return <>', + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore', @@ -1875,6 +2189,17 @@ test('update virtual file', () => { languageId: 'javascriptreact', mappings: [], snapshot: snapshotFromLines( + '', + '/**', + ' * @deprecated', + ' * Do not use.', + ' *', + ' * @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props', + ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', + ' */', + 'function _createMdxContent(props) {', + " return <><>{''}", + '}', '', '/**', ' * Render the MDX contents.', @@ -1883,7 +2208,7 @@ test('update virtual file', () => { ' * The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.', ' */', 'export default function MDXContent(props) {', - " return <><>{''}", + ' return <_createMdxContent {...props} />', '}', '', '// @ts-ignore',