Skip to content

Commit 31d9730

Browse files
committed
Pass around scope instead of array of defined variables
This small refactor is a preparation for upcoming changes. The `_components` object in the virtual code is no longer sorted.
1 parent 442d20c commit 31d9730

3 files changed

Lines changed: 23 additions & 15 deletions

File tree

packages/language-service/lib/jsx-utils.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* @import {Scope} from 'estree-util-scope'
3+
*/
4+
15
/**
26
* Check if a name belongs to a JSX component that can be injected.
37
*
@@ -6,7 +10,7 @@
610
*
711
* @param {string | null} name
812
* The name of the component to check.
9-
* @param {string[]} scope
13+
* @param {Scope} scope
1014
* The variable names available in the scope.
1115
* @returns {boolean}
1216
* Whether or not the given name is that of an injectable JSX component.
@@ -21,5 +25,5 @@ export function isInjectableComponent(name, scope) {
2125
return false
2226
}
2327

24-
return !scope.includes(name)
28+
return !scope.defined.includes(name)
2529
}

packages/language-service/lib/virtual-code.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @import {CodeMapping, VirtualCode} from '@volar/language-service'
33
* @import {ExportDefaultDeclaration, JSXClosingElement, JSXOpeningElement, Program} from 'estree-jsx'
4+
* @import {Scope} from 'estree-util-scope'
45
* @import {Nodes, Root} from 'mdast'
56
* @import {MdxjsEsm} from 'mdast-util-mdxjs-esm'
67
* @import {IScriptSnapshot} from 'typescript'
@@ -50,9 +51,9 @@ const layoutJsDoc = (propsName) => `
5051
/**
5152
* @param {boolean} isAsync
5253
* Whether or not the `_createMdxContent` should be async
53-
* @param {string[]} variables
54+
* @param {Scope} [scope]
5455
*/
55-
const componentStart = (isAsync, variables) => `
56+
const componentStart = (isAsync, scope) => `
5657
/**
5758
* @internal
5859
* **Do not use.** This function is generated by MDX for internal use.
@@ -70,7 +71,11 @@ ${isAsync ? 'async ' : ''}function _createMdxContent(props) {
7071
.../** @type {0 extends 1 & MDXProvidedComponents ? {} : MDXProvidedComponents} */ ({}),
7172
...props.components,
7273
/** The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component. */
73-
props${Array.from(variables, (name) => ',\n /** {@link ' + name + '} */\n ' + name).join('')}
74+
props${
75+
scope?.defined
76+
.map((name) => ',\n /** {@link ' + name + '} */\n ' + name)
77+
.join('') ?? ''
78+
}
7479
}
7580
_components
7681
return <>`
@@ -95,8 +100,7 @@ export default function MDXContent(props) {
95100

96101
const jsxIndent = '\n '
97102

98-
const fallback =
99-
jsPrefix(false, 'react') + componentStart(false, []) + componentEnd
103+
const fallback = jsPrefix(false, 'react') + componentStart(false) + componentEnd
100104

101105
/**
102106
* Visit an mdast tree with and enter and exit callback.
@@ -395,7 +399,7 @@ function getEmbeddedCodes(mdx, ast, checkMdx, jsxImportSource) {
395399
}
396400
}
397401

398-
const variables = [...visitors.scopes[0].defined].sort()
402+
const programScope = visitors.scopes[0]
399403

400404
/**
401405
* Update the **markdown** mappings from a start and end offset of a **JavaScript** chunk.
@@ -468,7 +472,7 @@ function getEmbeddedCodes(mdx, ast, checkMdx, jsxImportSource) {
468472
return
469473
}
470474

471-
if (!isInjectableComponent(name.name, variables)) {
475+
if (!isInjectableComponent(name.name, programScope)) {
472476
return
473477
}
474478

@@ -595,7 +599,7 @@ function getEmbeddedCodes(mdx, ast, checkMdx, jsxImportSource) {
595599

596600
let lastIndex = start + 1
597601
jsx = addOffset(jsxMapping, mdx, jsx + jsxIndent, start, lastIndex)
598-
if (isInjectableComponent(node.name, variables)) {
602+
if (isInjectableComponent(node.name, programScope)) {
599603
jsx += '_components.'
600604
}
601605

@@ -670,7 +674,7 @@ function getEmbeddedCodes(mdx, ast, checkMdx, jsxImportSource) {
670674
const end = getNodeEndOffset(node)
671675

672676
updateMarkdownFromOffsets(start, end)
673-
if (isInjectableComponent(node.name, variables)) {
677+
if (isInjectableComponent(node.name, programScope)) {
674678
const closingStart = start + 2
675679
jsx = addOffset(
676680
jsxMapping,
@@ -712,7 +716,7 @@ function getEmbeddedCodes(mdx, ast, checkMdx, jsxImportSource) {
712716
)
713717

714718
updateMarkdownFromOffsets(mdx.length, mdx.length)
715-
esm += componentStart(hasAwait, variables)
719+
esm += componentStart(hasAwait, programScope)
716720

717721
for (let i = 0; i < jsxMapping.generatedOffsets.length; i++) {
718722
jsxMapping.generatedOffsets[i] += esm.length

packages/language-service/test/language-plugin.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,10 +1463,10 @@ test('create virtual code w/ MDX layout in case of a default export preceded by
14631463
' ...props.components,',
14641464
' /** The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component. */',
14651465
' props,',
1466-
' /** {@link MDXLayout} */',
1467-
' MDXLayout,',
14681466
' /** {@link named} */',
1469-
' named',
1467+
' named,',
1468+
' /** {@link MDXLayout} */',
1469+
' MDXLayout',
14701470
' }',
14711471
' _components',
14721472
' return <>',

0 commit comments

Comments
 (0)