Skip to content

Commit

Permalink
Correctly transpile computed xor spread properties
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianheine committed Oct 13, 2018
1 parent 7e7e9e7 commit 7ddf225
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 42 deletions.
52 changes: 24 additions & 28 deletions src/program/types/ObjectExpression.js
Expand Up @@ -6,7 +6,6 @@ export default class ObjectExpression extends Node {
super.transpile(code, transforms);

let firstPropertyStart = this.start + 1;
let regularPropertyCount = 0;
let spreadPropertyCount = 0;
let computedPropertyCount = 0;
let firstSpreadProperty = null;
Expand All @@ -17,47 +16,44 @@ export default class ObjectExpression extends Node {
if (prop.type === 'SpreadElement') {
spreadPropertyCount += 1;
if (firstSpreadProperty === null) firstSpreadProperty = i;
} else if (prop.computed) {
} else if (prop.computed && transforms.computedProperty) {
computedPropertyCount += 1;
if (firstComputedProperty === null) firstComputedProperty = i;
} else if (prop.type === 'Property') {
regularPropertyCount += 1;
}
}

if (spreadPropertyCount && transforms.objectRestSpread) {
if (spreadPropertyCount && !transforms.objectRestSpread && !(computedPropertyCount && transforms.computedProperty)) {
spreadPropertyCount = 0;
firstSpreadProperty = null;
} else if (spreadPropertyCount) {
if (!this.program.options.objectAssign) {
throw new CompileError(
"Object spread operator requires specified objectAssign option with 'Object.assign' or polyfill helper.",
this
);
}
// enclose run of non-spread properties in curlies
let i = this.properties.length;
if (regularPropertyCount && !computedPropertyCount) {
while (i--) {
const prop = this.properties[i];

if (prop.type === 'Property' && !prop.computed) {
const lastProp = this.properties[i - 1];
const nextProp = this.properties[i + 1];

if (
!lastProp ||
lastProp.type !== 'Property' ||
lastProp.computed
) {
code.prependRight(prop.start, '{');
}
while (i--) {
const prop = this.properties[i];

if (
!nextProp ||
nextProp.type !== 'Property' ||
nextProp.computed
) {
code.appendLeft(prop.end, '}');
}
// enclose run of non-spread properties in curlies
if (prop.type === 'Property' && !computedPropertyCount) {
const lastProp = this.properties[i - 1];
const nextProp = this.properties[i + 1];

if (!lastProp || lastProp.type !== 'Property') {
code.prependRight(prop.start, '{');
}

if (!nextProp || nextProp.type !== 'Property') {
code.appendLeft(prop.end, '}');
}
}

// Remove ellipsis on spread property
if (prop.type === 'SpreadElement') {
code.remove(prop.start, prop.argument.start);
code.remove(prop.argument.end, prop.end);
}
}

Expand Down
12 changes: 0 additions & 12 deletions src/program/types/SpreadElement.js

This file was deleted.

2 changes: 0 additions & 2 deletions src/program/types/index.js
Expand Up @@ -36,7 +36,6 @@ import NewExpression from './NewExpression.js';
import ObjectExpression from './ObjectExpression.js';
import Property from './Property.js';
import ReturnStatement from './ReturnStatement.js';
import SpreadElement from './SpreadElement.js';
import Super from './Super.js';
import TaggedTemplateExpression from './TaggedTemplateExpression.js';
import TemplateElement from './TemplateElement.js';
Expand Down Expand Up @@ -85,7 +84,6 @@ export default {
ObjectExpression,
Property,
ReturnStatement,
SpreadElement,
Super,
TaggedTemplateExpression,
TemplateElement,
Expand Down
28 changes: 28 additions & 0 deletions test/samples/object-rest-spread.js
Expand Up @@ -126,6 +126,34 @@ module.exports = [
var a12 = { ...b, [c]:3, d:4 };
`
},
{
description: 'supports transpiling spread properties if computed properties shouldn\'t be transpiled',
options: {
objectAssign: 'Object.assign',
transforms: { computedProperty: false, conciseMethodProperty: false }
},
input: `
var a0 = { [ x ] : true , ... y };
`,
output: `
var a0 = Object.assign({}, {[ x ] : true} , y);
`,
},
{
description: 'supports transpiling computed properties if spread properties shouldn\'t be transpiled',
options: {
objectAssign: 'Object.assign',
transforms: { objectRestSpread: false, conciseMethodProperty: false }
},
input: `
var a0 = { [ x ] : true , ... y };
`,
output: `
var obj;
var a0 = Object.assign(( obj = {}, obj[ x ] = true, obj ), y);
`,
},
{
description:
'transpiles inline objects with spread with computed property (#144)',
Expand Down

0 comments on commit 7ddf225

Please sign in to comment.