diff --git a/src/utils/__tests__/getPropertyName-test.js b/src/utils/__tests__/getPropertyName-test.js index 39c42fa465e..0404addb8f0 100644 --- a/src/utils/__tests__/getPropertyName-test.js +++ b/src/utils/__tests__/getPropertyName-test.js @@ -8,13 +8,18 @@ * */ +import { parse, expression } from '../../../tests/utils'; + describe('getPropertyName', () => { let getPropertyName; - let expression; + + function parsePath(src) { + const root = parse(src.trim()); + return root.get('body', root.node.body.length - 1, 'expression'); + } beforeEach(() => { getPropertyName = require('../getPropertyName').default; - ({ expression } = require('../../../tests/utils')); }); it('returns the name for a normal property', () => { @@ -42,14 +47,14 @@ describe('getPropertyName', () => { const def = expression('{ ["foo"]: 21 }'); const param = def.get('properties', 0); - expect(getPropertyName(param)).toBe('@computed#foo'); + expect(getPropertyName(param)).toBe('foo'); }); it('creates name for computed properties from int', () => { const def = expression('{ [31]: 21 }'); const param = def.get('properties', 0); - expect(getPropertyName(param)).toBe('@computed#31'); + expect(getPropertyName(param)).toBe('31'); }); it('returns null for computed properties from regex', () => { @@ -65,4 +70,26 @@ describe('getPropertyName', () => { expect(getPropertyName(param)).toBe(null); }); + + it('resolves simple variables', () => { + const def = parsePath(` + const foo = "name"; + + ({ [foo]: 21 }); + `); + const param = def.get('properties', 0); + + expect(getPropertyName(param)).toBe('name'); + }); + + it('resolves simple member expressions', () => { + const def = parsePath(` + const a = { foo: "name" }; + + ({ [a.foo]: 21 }); + `); + const param = def.get('properties', 0); + + expect(getPropertyName(param)).toBe('name'); + }); }); diff --git a/src/utils/getPropertyName.js b/src/utils/getPropertyName.js index a5d625dd282..cc46bf756b2 100644 --- a/src/utils/getPropertyName.js +++ b/src/utils/getPropertyName.js @@ -12,6 +12,7 @@ import recast from 'recast'; import getNameOrValue from './getNameOrValue'; +import resolveToValue from './resolveToValue'; const { types: { namedTypes: types }, @@ -28,17 +29,30 @@ export default function getPropertyName(propertyPath: NodePath): ?string { if (types.ObjectTypeSpreadProperty.check(propertyPath.node)) { return getNameOrValue(propertyPath.get('argument').get('id'), false); } else if (propertyPath.node.computed) { - if (types.Identifier.check(propertyPath.node.key)) { - return `${COMPUTED_PREFIX}${getNameOrValue( - propertyPath.get('key'), - false, - )}`; - } else if ( - types.Literal.check(propertyPath.node.key) && - (typeof propertyPath.node.key.value === 'string' || - typeof propertyPath.node.key.value === 'number') + const key = propertyPath.get('key'); + + // Try to resolve variables and member expressions + if (types.Identifier.check(key.node) || types.MemberExpression.check(key.node)) { + const value = resolveToValue(key).node; + + if ( + types.Literal.check(value) && + (typeof value.value === 'string' || typeof value.value === 'number') + ) { + return `${value.value}`; + } + } + + // generate name for identifier + if (types.Identifier.check(key.node)) { + return `${COMPUTED_PREFIX}${key.node.name}`; + } + + if ( + types.Literal.check(key.node) && + (typeof key.node.value === 'string' || typeof key.node.value === 'number') ) { - return `${COMPUTED_PREFIX}${propertyPath.node.key.value}`; + return `${key.node.value}`; } return null;