Skip to content

Commit 0df684b

Browse files
authoredMar 29, 2022
Fix to add _missingMdxReference in some more cases
Related-to GH-1986. Closes GH-1988. Reviewed-by: Titus Wormer <tituswormer@gmail.com>
1 parent 427bcad commit 0df684b

File tree

2 files changed

+103
-67
lines changed

2 files changed

+103
-67
lines changed
 

Diff for: ‎packages/mdx/lib/plugin/recma-jsx-rewrite.js

+69-67
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,8 @@ export function recmaJsxRewrite(options = {}) {
243243
}
244244
}
245245

246-
/** @type {string} */
247-
let key
248-
249-
// Add partials (so for `x.y.z` it’d generate `x` and `x.y` too).
250-
for (key in scope.references) {
251-
if (own.call(scope.references, key)) {
252-
const parts = key.split('.')
253-
let index = 0
254-
while (++index < parts.length) {
255-
const partial = parts.slice(0, index).join('.')
256-
if (!own.call(scope.references, partial)) {
257-
scope.references[partial] = {
258-
node: scope.references[key].node,
259-
component: false
260-
}
261-
}
262-
}
263-
}
264-
}
246+
/** @type {Array<Statement>} */
247+
const statements = []
265248

266249
if (defaults.length > 0 || actual.length > 0) {
267250
if (providerImportSource) {
@@ -356,60 +339,79 @@ export function recmaJsxRewrite(options = {}) {
356339
})
357340
}
358341

359-
// Arrow functions with an implied return:
360-
if (fn.body.type !== 'BlockStatement') {
361-
fn.body = {
362-
type: 'BlockStatement',
363-
body: [{type: 'ReturnStatement', argument: fn.body}]
342+
statements.push({
343+
type: 'VariableDeclaration',
344+
kind: 'const',
345+
declarations
346+
})
347+
}
348+
349+
/** @type {string} */
350+
let key
351+
352+
// Add partials (so for `x.y.z` it’d generate `x` and `x.y` too).
353+
for (key in scope.references) {
354+
if (own.call(scope.references, key)) {
355+
const parts = key.split('.')
356+
let index = 0
357+
while (++index < parts.length) {
358+
const partial = parts.slice(0, index).join('.')
359+
if (!own.call(scope.references, partial)) {
360+
scope.references[partial] = {
361+
node: scope.references[key].node,
362+
component: false
363+
}
364+
}
364365
}
365366
}
367+
}
366368

367-
/** @type {Array<Statement>} */
368-
const statements = [
369-
{
370-
type: 'VariableDeclaration',
371-
kind: 'const',
372-
declarations
373-
}
369+
const references = Object.keys(scope.references).sort()
370+
let index = -1
371+
while (++index < references.length) {
372+
const id = references[index]
373+
const info = scope.references[id]
374+
const place = stringifyPosition(positionFromEstree(info.node))
375+
/** @type {Array<Expression>} */
376+
const parameters = [
377+
{type: 'Literal', value: id},
378+
{type: 'Literal', value: info.component}
374379
]
375380

376-
const references = Object.keys(scope.references).sort()
377-
let index = -1
378-
while (++index < references.length) {
379-
const id = references[index]
380-
const info = scope.references[id]
381-
const place = stringifyPosition(positionFromEstree(info.node))
382-
/** @type {Array<Expression>} */
383-
const parameters = [
384-
{type: 'Literal', value: id},
385-
{type: 'Literal', value: info.component}
386-
]
387-
388-
createErrorHelper = true
389-
390-
if (development && place !== '1:1-1:1') {
391-
parameters.push({type: 'Literal', value: place})
392-
}
381+
createErrorHelper = true
393382

394-
statements.push({
395-
type: 'IfStatement',
396-
test: {
397-
type: 'UnaryExpression',
398-
operator: '!',
399-
prefix: true,
400-
argument: toIdOrMemberExpression(id.split('.'))
401-
},
402-
consequent: {
403-
type: 'ExpressionStatement',
404-
expression: {
405-
type: 'CallExpression',
406-
callee: {type: 'Identifier', name: '_missingMdxReference'},
407-
arguments: parameters,
408-
optional: false
409-
}
410-
},
411-
alternate: null
412-
})
383+
if (development && place !== '1:1-1:1') {
384+
parameters.push({type: 'Literal', value: place})
385+
}
386+
387+
statements.push({
388+
type: 'IfStatement',
389+
test: {
390+
type: 'UnaryExpression',
391+
operator: '!',
392+
prefix: true,
393+
argument: toIdOrMemberExpression(id.split('.'))
394+
},
395+
consequent: {
396+
type: 'ExpressionStatement',
397+
expression: {
398+
type: 'CallExpression',
399+
callee: {type: 'Identifier', name: '_missingMdxReference'},
400+
arguments: parameters,
401+
optional: false
402+
}
403+
},
404+
alternate: null
405+
})
406+
}
407+
408+
if (statements.length > 0) {
409+
// Arrow functions with an implied return:
410+
if (fn.body.type !== 'BlockStatement') {
411+
fn.body = {
412+
type: 'BlockStatement',
413+
body: [{type: 'ReturnStatement', argument: fn.body}]
414+
}
413415
}
414416

415417
fn.body.body.unshift(...statements)

Diff for: ‎packages/mdx/test/compile.js

+34
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,40 @@ test('compile', async () => {
504504
)
505505
}
506506

507+
// TODO: this is incorrect behavior, will be fixed in GH-1986
508+
try {
509+
renderToStaticMarkup(
510+
React.createElement(
511+
await run(compileSync('export const a = {}\n\n<a.b />'))
512+
)
513+
)
514+
assert.unreachable()
515+
} catch (/** @type {unknown} */ error) {
516+
const exception = /** @type {Error} */ (error)
517+
assert.match(
518+
exception.message,
519+
/Expected component `a.b` to be defined/,
520+
'should throw if a used member is not defined locally'
521+
)
522+
}
523+
524+
// TODO: this is incorrect behavior, will be fixed in GH-1986
525+
try {
526+
renderToStaticMarkup(
527+
React.createElement(
528+
await run(compileSync('<a render={(x) => <x.y />} />'))
529+
)
530+
)
531+
assert.unreachable()
532+
} catch (/** @type {unknown} */ error) {
533+
const exception = /** @type {Error} */ (error)
534+
assert.match(
535+
exception.message,
536+
/x is not defined/,
537+
'should throw if a used member is not defined locally (JSX in a function)'
538+
)
539+
}
540+
507541
try {
508542
renderToStaticMarkup(
509543
React.createElement(await run(compileSync('<X />', {development: true})))

1 commit comments

Comments
 (1)

vercel[bot] commented on Mar 29, 2022

@vercel[bot]

Successfully deployed to the following URLs:

Please sign in to comment.