/** * @typedef {import('estree-jsx').Identifier} Identifier * @typedef {import('estree-jsx').JSXIdentifier} JSXIdentifier * @typedef {import('estree-jsx').JSXMemberExpression} JSXMemberExpression * @typedef {import('estree-jsx').Literal} Literal * @typedef {import('estree-jsx').MemberExpression} MemberExpression */ import {ok as assert} from 'devlop' import {name as isIdentifierName} from 'estree-util-is-identifier-name' /** * @param {ReadonlyArray} ids * Identifiers (example: `['list', 0]). * @returns {Identifier | MemberExpression} * Identifier or member expression. */ export function toIdOrMemberExpression(ids) { let index = -1 /** @type {Identifier | Literal | MemberExpression | undefined} */ let object while (++index < ids.length) { const name = ids[index] /** @type {Identifier | Literal} */ const id = typeof name === 'string' && isIdentifierName(name) ? {type: 'Identifier', name} : {type: 'Literal', value: name} object = object ? { type: 'MemberExpression', object, property: id, computed: id.type === 'Literal', optional: false } : id } assert(object, 'expected non-empty `ids` to be passed') assert(object.type !== 'Literal', 'expected identifier as left-most value') return object } /** * @param {ReadonlyArray} ids * Identifiers (example: `['list', 0]). * @returns {JSXIdentifier | JSXMemberExpression} * Identifier or member expression. */ export function toJsxIdOrMemberExpression(ids) { let index = -1 /** @type {JSXIdentifier | JSXMemberExpression | undefined} */ let object while (++index < ids.length) { const name = ids[index] assert( typeof name === 'string' && isIdentifierName(name, {jsx: true}), 'expected valid jsx identifier, not `' + name + '`' ) /** @type {JSXIdentifier} */ const id = {type: 'JSXIdentifier', name} object = object ? {type: 'JSXMemberExpression', object, property: id} : id } assert(object, 'expected non-empty `ids` to be passed') return object }