Skip to content

Commit 32eece8

Browse files
committed
Simplify visitObjectLiteralExpression
I ran into it and the comment at the top tripped me, then I proceeded to simplify the code. Patched a bit more of the function to make sure that the indentation doesn't change, and added tests.
1 parent 185e7ad commit 32eece8

6 files changed

+615
-44
lines changed

src/compiler/transformers/es2015.ts

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,62 +2566,54 @@ namespace ts {
25662566
* @param node An ObjectLiteralExpression node.
25672567
*/
25682568
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
2569-
// We are here because a ComputedPropertyName was used somewhere in the expression.
25702569
const properties = node.properties;
2571-
const numProperties = properties.length;
25722570

25732571
// Find the first computed property.
25742572
// Everything until that point can be emitted as part of the initial object literal.
2575-
let numInitialProperties = numProperties;
2576-
let numInitialPropertiesWithoutYield = numProperties;
2577-
for (let i = 0; i < numProperties; i++) {
2573+
let numInitialProperties = -1, hasComputed = false;
2574+
for (let i = 0; i < properties.length; i++) {
25782575
const property = properties[i];
2579-
if ((property.transformFlags & TransformFlags.ContainsYield && hierarchyFacts & HierarchyFacts.AsyncFunctionBody)
2580-
&& i < numInitialPropertiesWithoutYield) {
2581-
numInitialPropertiesWithoutYield = i;
2582-
}
2583-
if (Debug.checkDefined(property.name).kind === SyntaxKind.ComputedPropertyName) {
2576+
if ((property.transformFlags & TransformFlags.ContainsYield &&
2577+
hierarchyFacts & HierarchyFacts.AsyncFunctionBody)
2578+
|| (hasComputed = Debug.checkDefined(property.name).kind === SyntaxKind.ComputedPropertyName)) {
25842579
numInitialProperties = i;
25852580
break;
25862581
}
25872582
}
25882583

2589-
if (numInitialProperties !== numProperties) {
2590-
if (numInitialPropertiesWithoutYield < numInitialProperties) {
2591-
numInitialProperties = numInitialPropertiesWithoutYield;
2592-
}
2584+
if (numInitialProperties < 0) {
2585+
return visitEachChild(node, visitor, context);
2586+
}
25932587

2594-
// For computed properties, we need to create a unique handle to the object
2595-
// literal so we can modify it without risking internal assignments tainting the object.
2596-
const temp = createTempVariable(hoistVariableDeclaration);
2588+
// For computed properties, we need to create a unique handle to the object
2589+
// literal so we can modify it without risking internal assignments tainting the object.
2590+
const temp = createTempVariable(hoistVariableDeclaration);
25972591

2598-
// Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
2599-
const expressions: Expression[] = [];
2600-
const assignment = createAssignment(
2601-
temp,
2602-
setEmitFlags(
2603-
createObjectLiteral(
2604-
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
2605-
node.multiLine
2606-
),
2607-
EmitFlags.Indented
2608-
)
2609-
);
2592+
// Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
2593+
const expressions: Expression[] = [];
2594+
const assignment = createAssignment(
2595+
temp,
2596+
setEmitFlags(
2597+
createObjectLiteral(
2598+
visitNodes(properties, visitor, isObjectLiteralElementLike, 0, numInitialProperties),
2599+
node.multiLine
2600+
),
2601+
hasComputed ? EmitFlags.Indented : 0
2602+
)
2603+
);
26102604

2611-
if (node.multiLine) {
2612-
startOnNewLine(assignment);
2613-
}
2605+
if (node.multiLine) {
2606+
startOnNewLine(assignment);
2607+
}
26142608

2615-
expressions.push(assignment);
2609+
expressions.push(assignment);
26162610

2617-
addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
2611+
addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
26182612

2619-
// We need to clone the temporary identifier so that we can write it on a
2620-
// new line
2621-
expressions.push(node.multiLine ? startOnNewLine(getMutableClone(temp)) : temp);
2622-
return inlineExpressions(expressions);
2623-
}
2624-
return visitEachChild(node, visitor, context);
2613+
// We need to clone the temporary identifier so that we can write it on a
2614+
// new line
2615+
expressions.push(node.multiLine ? startOnNewLine(getMutableClone(temp)) : temp);
2616+
return inlineExpressions(expressions);
26252617
}
26262618

26272619
interface ForStatementWithConvertibleInitializer extends ForStatement {

tests/baselines/reference/es5-asyncFunctionObjectLiterals.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ function objectLiteral5() {
146146
switch (_b.label) {
147147
case 0:
148148
_a = {
149-
a: y
150-
};
149+
a: y
150+
};
151151
return [4 /*yield*/, b];
152152
case 1:
153153
x = (_a[_b.sent()] = z,
@@ -165,8 +165,8 @@ function objectLiteral6() {
165165
switch (_c.label) {
166166
case 0:
167167
_b = {
168-
a: y
169-
};
168+
a: y
169+
};
170170
_a = b;
171171
return [4 /*yield*/, z];
172172
case 1:
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//// [es5-yieldFunctionObjectLiterals.ts]
2+
// mainly to verify indentation of emitted code
3+
4+
function g() { return "g"; }
5+
6+
function* objectLiteral1() {
7+
const x = {
8+
a: 1,
9+
b: yield 2,
10+
c: 3,
11+
}
12+
}
13+
14+
function* objectLiteral2() {
15+
const x = {
16+
a: 1,
17+
[g()]: yield 2,
18+
c: 3,
19+
}
20+
}
21+
22+
function* objectLiteral3() {
23+
const x = {
24+
a: 1,
25+
b: yield 2,
26+
[g()]: 3,
27+
c: 4,
28+
}
29+
}
30+
31+
function* objectLiteral4() {
32+
const x = {
33+
a: 1,
34+
[g()]: 2,
35+
b: yield 3,
36+
c: 4,
37+
}
38+
}
39+
40+
function* objectLiteral5() {
41+
const x = {
42+
a: 1,
43+
[g()]: yield 2,
44+
c: 4,
45+
}
46+
}
47+
48+
function* objectLiteral6() {
49+
const x = {
50+
a: 1,
51+
[yield]: 2,
52+
c: 4,
53+
}
54+
}
55+
56+
function* objectLiteral7() {
57+
const x = {
58+
a: 1,
59+
[yield]: yield 2,
60+
c: 4,
61+
}
62+
}
63+
64+
65+
//// [es5-yieldFunctionObjectLiterals.js]
66+
// mainly to verify indentation of emitted code
67+
function g() { return "g"; }
68+
function objectLiteral1() {
69+
var x, _a;
70+
return __generator(this, function (_b) {
71+
switch (_b.label) {
72+
case 0:
73+
_a = {
74+
a: 1
75+
};
76+
return [4 /*yield*/, 2];
77+
case 1:
78+
x = (_a.b = _b.sent(),
79+
_a.c = 3,
80+
_a);
81+
return [2 /*return*/];
82+
}
83+
});
84+
}
85+
function objectLiteral2() {
86+
var x, _a;
87+
var _b;
88+
return __generator(this, function (_c) {
89+
switch (_c.label) {
90+
case 0:
91+
_b = {
92+
a: 1
93+
};
94+
_a = g();
95+
return [4 /*yield*/, 2];
96+
case 1:
97+
x = (_b[_a] = _c.sent(),
98+
_b.c = 3,
99+
_b);
100+
return [2 /*return*/];
101+
}
102+
});
103+
}
104+
function objectLiteral3() {
105+
var x, _a;
106+
var _b;
107+
return __generator(this, function (_c) {
108+
switch (_c.label) {
109+
case 0:
110+
_a = {
111+
a: 1
112+
};
113+
return [4 /*yield*/, 2];
114+
case 1:
115+
x = (_b = (_a.b = _c.sent(),
116+
_a),
117+
_b[g()] = 3,
118+
_b.c = 4,
119+
_b);
120+
return [2 /*return*/];
121+
}
122+
});
123+
}
124+
function objectLiteral4() {
125+
var x;
126+
var _a;
127+
return __generator(this, function (_b) {
128+
switch (_b.label) {
129+
case 0:
130+
_a = {
131+
a: 1
132+
},
133+
_a[g()] = 2;
134+
return [4 /*yield*/, 3];
135+
case 1:
136+
x = (_a.b = _b.sent(),
137+
_a.c = 4,
138+
_a);
139+
return [2 /*return*/];
140+
}
141+
});
142+
}
143+
function objectLiteral5() {
144+
var x, _a;
145+
var _b;
146+
return __generator(this, function (_c) {
147+
switch (_c.label) {
148+
case 0:
149+
_b = {
150+
a: 1
151+
};
152+
_a = g();
153+
return [4 /*yield*/, 2];
154+
case 1:
155+
x = (_b[_a] = _c.sent(),
156+
_b.c = 4,
157+
_b);
158+
return [2 /*return*/];
159+
}
160+
});
161+
}
162+
function objectLiteral6() {
163+
var x;
164+
var _a;
165+
return __generator(this, function (_b) {
166+
switch (_b.label) {
167+
case 0:
168+
_a = {
169+
a: 1
170+
};
171+
return [4 /*yield*/];
172+
case 1:
173+
x = (_a[_b.sent()] = 2,
174+
_a.c = 4,
175+
_a);
176+
return [2 /*return*/];
177+
}
178+
});
179+
}
180+
function objectLiteral7() {
181+
var x, _a;
182+
var _b;
183+
return __generator(this, function (_c) {
184+
switch (_c.label) {
185+
case 0:
186+
_b = {
187+
a: 1
188+
};
189+
return [4 /*yield*/];
190+
case 1:
191+
_a = _c.sent();
192+
return [4 /*yield*/, 2];
193+
case 2:
194+
x = (_b[_a] = _c.sent(),
195+
_b.c = 4,
196+
_b);
197+
return [2 /*return*/];
198+
}
199+
});
200+
}

0 commit comments

Comments
 (0)