Skip to content

Commit b4a5bd1

Browse files
committed
Fix support for computed member expressions
1 parent d3b5d90 commit b4a5bd1

File tree

2 files changed

+96
-14
lines changed

2 files changed

+96
-14
lines changed

index.js

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -318,21 +318,32 @@ function toProperty(node) {
318318
}
319319

320320
function toIdentifier(node) {
321-
return create(
322-
node,
323-
node.type === 'JSXMemberExpression'
324-
? {
325-
type: 'MemberExpression',
326-
object: toIdentifier(node.object),
327-
property: toIdentifier(node.property)
328-
}
329-
: node.type === 'JSXNamespacedName'
330-
? {type: 'Literal', value: node.namespace.name + ':' + node.name.name}
331-
: // Must be `JSXIdentifier`.
332-
isIdentifierName(node.name)
321+
var replace
322+
323+
if (node.type === 'JSXMemberExpression') {
324+
replace = {
325+
type: 'MemberExpression',
326+
object: toIdentifier(node.object),
327+
// `property` is always a `JSXIdentifier`, but it could be something that
328+
// isn’t an ES identifier name.
329+
property: toIdentifier(node.property)
330+
}
331+
332+
if (replace.property.type === 'Literal') replace.computed = true
333+
} else if (node.type === 'JSXNamespacedName') {
334+
replace = {
335+
type: 'Literal',
336+
value: node.namespace.name + ':' + node.name.name
337+
}
338+
}
339+
// Must be `JSXIdentifier`.
340+
else {
341+
replace = isIdentifierName(node.name)
333342
? {type: 'Identifier', name: node.name}
334343
: {type: 'Literal', value: node.name}
335-
)
344+
}
345+
346+
return create(node, replace)
336347
}
337348

338349
function toMemberExpression(id) {
@@ -342,10 +353,15 @@ function toMemberExpression(id) {
342353
var prop
343354

344355
while (++index < identifiers.length) {
345-
prop = {type: 'Identifier', name: identifiers[index]}
356+
prop = isIdentifierName(identifiers[index])
357+
? {type: 'Identifier', name: identifiers[index]}
358+
: {type: 'Literal', value: identifiers[index]}
346359
result = index
347360
? {type: 'MemberExpression', object: result, property: prop}
348361
: prop
362+
if (index && prop.type === 'Literal') {
363+
result.computed = true
364+
}
349365
}
350366

351367
return result

test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ test('estree-util-build-jsx', function (t) {
6161
'should support `pragma`, `pragmaFrag`'
6262
)
6363

64+
t.deepEqual(
65+
build(parse('<x />'), {pragma: 'a.b-c'}).body[0].expression,
66+
{
67+
type: 'CallExpression',
68+
callee: {
69+
type: 'MemberExpression',
70+
object: {type: 'Identifier', name: 'a'},
71+
property: {type: 'Literal', value: 'b-c'},
72+
computed: true
73+
},
74+
arguments: [{type: 'Literal', value: 'x'}]
75+
},
76+
'should support `pragma` w/ non-identifiers (1)'
77+
)
78+
79+
t.equal(
80+
astring.generate(build(parse('<x />'), {pragma: 'a.b-c'})),
81+
'a["b-c"]("x");\n',
82+
'should support `pragma` w/ non-identifiers (2)'
83+
)
84+
6485
t.deepEqual(
6586
build(parse('/* @jsx a @jsxFrag b */\n<><x /></>')).body[0].expression,
6687
{
@@ -181,6 +202,51 @@ test('estree-util-build-jsx', function (t) {
181202
'should support dots in a tag name for member expressions'
182203
)
183204

205+
t.deepEqual(
206+
build(parse('<a.b-c />'), {pragma: 'h'}).body[0].expression,
207+
{
208+
type: 'CallExpression',
209+
callee: {type: 'Identifier', name: 'h'},
210+
arguments: [
211+
{
212+
type: 'MemberExpression',
213+
object: {type: 'Identifier', name: 'a'},
214+
property: {type: 'Literal', value: 'b-c'},
215+
computed: true
216+
}
217+
]
218+
},
219+
'should support dots *and* dashes in tag names (1)'
220+
)
221+
222+
t.equal(
223+
astring.generate(build(parse('<a.b-c />'), {pragma: 'h'})),
224+
'h(a["b-c"]);\n',
225+
'should support dots *and* dashes in tag names (2)'
226+
)
227+
228+
t.deepEqual(
229+
build(parse('<a-b.c />'), {pragma: 'h'}).body[0].expression,
230+
{
231+
type: 'CallExpression',
232+
callee: {type: 'Identifier', name: 'h'},
233+
arguments: [
234+
{
235+
type: 'MemberExpression',
236+
object: {type: 'Literal', value: 'a-b'},
237+
property: {type: 'Identifier', name: 'c'}
238+
}
239+
]
240+
},
241+
'should support dots *and* dashes in tag names (3)'
242+
)
243+
244+
t.equal(
245+
astring.generate(build(parse('<a-b.c />'), {pragma: 'h'})),
246+
'h(("a-b").c);\n',
247+
'should support dots *and* dashes in tag names (4)'
248+
)
249+
184250
t.deepEqual(
185251
build(parse('<a.b.c.d />'), {pragma: 'h'}).body[0].expression,
186252
{

0 commit comments

Comments
 (0)