Skip to content

Commit a391d70

Browse files
Stop using rewrites for object literal downlevel emit.
1 parent 34bd298 commit a391d70

File tree

50 files changed

+624
-326
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+624
-326
lines changed

src/compiler/emitter.ts

Lines changed: 192 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2555,6 +2555,195 @@ module ts {
25552555
}
25562556
}
25572557

2558+
function emitObjectLiteralBody(node: ObjectLiteralExpression, numElements: number): void {
2559+
if (numElements === 0) {
2560+
write("{}");
2561+
return;
2562+
}
2563+
2564+
write("{");
2565+
2566+
if (numElements > 0) {
2567+
var properties = node.properties;
2568+
2569+
2570+
// If we are not doing a downlevel transformation for object literals,
2571+
// then try to preserve the original shape of the object literal.
2572+
// Otherwise just try to preserve the formatting.
2573+
if (numElements === properties.length) {
2574+
emitLinePreservingList(node, properties, /* allowTrailingComma */ languageVersion >= ScriptTarget.ES5, /* spacesBetweenBraces */ true);
2575+
}
2576+
else {
2577+
var multiLine = (node.flags & NodeFlags.MultiLine) !== 0;
2578+
if (!multiLine) {
2579+
write(" ");
2580+
}
2581+
else {
2582+
increaseIndent();
2583+
}
2584+
2585+
emitList(properties, 0, numElements, /*multiLine*/ multiLine, /*trailingComma*/ false);
2586+
2587+
if (!multiLine) {
2588+
write(" ");
2589+
}
2590+
else {
2591+
decreaseIndent();
2592+
}
2593+
}
2594+
}
2595+
2596+
write("}");
2597+
}
2598+
2599+
function emitDownlevelObjectLiteralWithComputedProperties(node: ObjectLiteralExpression, firstComputedPropertyIndex: number) {
2600+
var multiLine = (node.flags & NodeFlags.MultiLine) !== 0;
2601+
var properties = node.properties;
2602+
2603+
write("(");
2604+
2605+
if (multiLine) {
2606+
increaseIndent();
2607+
}
2608+
2609+
// For computed properties, we need to create a unique handle to the object
2610+
// literal so we can modify it without risking internal assignments tainting the object.
2611+
var tempVar = createAndRecordTempVariable(node);
2612+
2613+
// Write out the first non-computed properties
2614+
// (or all properties if none of them are computed),
2615+
// then emit the rest through indexing on the temp variable.
2616+
emit(tempVar)
2617+
write(" = ");
2618+
emitObjectLiteralBody(node, firstComputedPropertyIndex);
2619+
2620+
2621+
for (var i = firstComputedPropertyIndex, n = properties.length; i < n; i++) {
2622+
writeComma();
2623+
2624+
var property = properties[i];
2625+
2626+
emitStart(property)
2627+
if (property.kind === SyntaxKind.GetAccessor || property.kind === SyntaxKind.SetAccessor) {
2628+
// TODO (drosen): Reconcile with 'emitMemberFunctions'.
2629+
var accessors = getAllAccessorDeclarations(node.properties, <AccessorDeclaration>property);
2630+
if (property !== accessors.firstAccessor) {
2631+
continue;
2632+
}
2633+
write("Object.defineProperty(");
2634+
emit(tempVar);
2635+
write(", ");
2636+
emitStart(node.name);
2637+
emitExpressionForPropertyName(property.name);
2638+
emitEnd(property.name);
2639+
write(", {");
2640+
increaseIndent();
2641+
if (accessors.getAccessor) {
2642+
writeLine()
2643+
emitLeadingComments(accessors.getAccessor);
2644+
write("get: ");
2645+
emitStart(accessors.getAccessor);
2646+
write("function ");
2647+
emitSignatureAndBody(accessors.getAccessor);
2648+
emitEnd(accessors.getAccessor);
2649+
emitTrailingComments(accessors.getAccessor);
2650+
write(",");
2651+
}
2652+
if (accessors.setAccessor) {
2653+
writeLine();
2654+
emitLeadingComments(accessors.setAccessor);
2655+
write("set: ");
2656+
emitStart(accessors.setAccessor);
2657+
write("function ");
2658+
emitSignatureAndBody(accessors.setAccessor);
2659+
emitEnd(accessors.setAccessor);
2660+
emitTrailingComments(accessors.setAccessor);
2661+
write(",");
2662+
}
2663+
writeLine();
2664+
write("enumerable: true,");
2665+
writeLine();
2666+
write("configurable: true");
2667+
decreaseIndent();
2668+
writeLine();
2669+
write("})");
2670+
emitEnd(property);
2671+
}
2672+
else {
2673+
emitLeadingComments(property);
2674+
emitStart(property.name);
2675+
emit(tempVar);
2676+
emitMemberAccessForPropertyName(property.name);
2677+
emitEnd(property.name);
2678+
2679+
write(" = ");
2680+
2681+
if (property.kind === SyntaxKind.PropertyAssignment) {
2682+
emit((<PropertyAssignment>property).initializer);
2683+
}
2684+
else if (property.kind === SyntaxKind.ShorthandPropertyAssignment) {
2685+
emitExpressionIdentifier((<ShorthandPropertyAssignment>property).name);
2686+
}
2687+
else if (property.kind === SyntaxKind.MethodDeclaration) {
2688+
emitFunctionDeclaration(<MethodDeclaration>property);
2689+
}
2690+
else {
2691+
Debug.fail("ObjectLiteralElement type not accounted for: " + property.kind);
2692+
}
2693+
}
2694+
2695+
emitEnd(property);
2696+
}
2697+
2698+
writeComma();
2699+
emit(tempVar);
2700+
2701+
if (multiLine) {
2702+
decreaseIndent();
2703+
writeLine();
2704+
}
2705+
2706+
write(")");
2707+
2708+
function writeComma() {
2709+
if (multiLine) {
2710+
write(",");
2711+
writeLine();
2712+
}
2713+
else {
2714+
write(", ");
2715+
}
2716+
}
2717+
}
2718+
2719+
function emitObjectLiteral(node: ObjectLiteralExpression): void {
2720+
var properties = node.properties;
2721+
2722+
if (languageVersion < ScriptTarget.ES6) {
2723+
var numProperties = properties.length;
2724+
2725+
// Find the first computed property.
2726+
// Everything until that point can be emitted as part of the initial object literal.
2727+
var numInitialNonComputedProperties = numProperties;
2728+
for (var i = 0, n = properties.length; i < n; i++) {
2729+
if (properties[i].name.kind === SyntaxKind.ComputedPropertyName) {
2730+
numInitialNonComputedProperties = i;
2731+
break;
2732+
}
2733+
}
2734+
2735+
var hasComputedProperty = numInitialNonComputedProperties !== properties.length;
2736+
if (hasComputedProperty) {
2737+
emitDownlevelObjectLiteralWithComputedProperties(node, numInitialNonComputedProperties);
2738+
return;
2739+
}
2740+
}
2741+
2742+
// Ordinary case: either the object has no computed properties
2743+
// or we're compiling with an ES6+ target.
2744+
emitObjectLiteralBody(node, properties.length);
2745+
}
2746+
25582747
function createSynthesizedNode(kind: SyntaxKind): Node {
25592748
var node = createNode(kind);
25602749
node.pos = -1;
@@ -2563,7 +2752,7 @@ module ts {
25632752
return node;
25642753
}
25652754

2566-
function emitDownlevelObjectLiteralWithComputedProperties(node: ObjectLiteralExpression, firstComputedPropertyIndex: number): void {
2755+
function emitDownlevelObjectLiteralWithComputedPropertiesThroughRewrite(node: ObjectLiteralExpression, firstComputedPropertyIndex: number): void {
25672756
var parenthesizedObjectLiteral = createDownlevelObjectLiteralWithComputedProperties(node, firstComputedPropertyIndex);
25682757
return emit(parenthesizedObjectLiteral);
25692758
}
@@ -2763,7 +2952,7 @@ module ts {
27632952
return result;
27642953
}
27652954

2766-
function emitObjectLiteral(node: ObjectLiteralExpression): void {
2955+
function emitObjectLiteralThroughRewrite(node: ObjectLiteralExpression): void {
27672956
var properties = node.properties;
27682957

27692958
if (languageVersion < ScriptTarget.ES6) {
@@ -2781,7 +2970,7 @@ module ts {
27812970

27822971
var hasComputedProperty = numInitialNonComputedProperties !== properties.length;
27832972
if (hasComputedProperty) {
2784-
emitDownlevelObjectLiteralWithComputedProperties(node, numInitialNonComputedProperties);
2973+
emitDownlevelObjectLiteralWithComputedPropertiesThroughRewrite(node, numInitialNonComputedProperties);
27852974
return;
27862975
}
27872976
}

tests/baselines/reference/ES5SymbolProperty1.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ obj[Symbol.foo];
1212

1313
//// [ES5SymbolProperty1.js]
1414
var Symbol;
15-
var obj = (_a = {}, _a[Symbol.foo] =
16-
0,
17-
_a);
15+
var obj = (_a = {},
16+
_a[Symbol.foo] = 0,
17+
_a
18+
);
1819
obj[Symbol.foo];
1920
var _a;

tests/baselines/reference/FunctionDeclaration8_es6.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,5 @@
22
var v = { [yield]: foo }
33

44
//// [FunctionDeclaration8_es6.js]
5-
var v = (_a = {}, _a[yield] =
6-
foo,
7-
_a);
5+
var v = (_a = {}, _a[yield] = foo, _a);
86
var _a;

tests/baselines/reference/FunctionDeclaration9_es6.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ function * foo() {
55

66
//// [FunctionDeclaration9_es6.js]
77
function foo() {
8-
var v = (_a = {}, _a[] =
9-
foo,
10-
_a);
8+
var v = (_a = {}, _a[] = foo, _a);
119
var _a;
1210
}

tests/baselines/reference/FunctionPropertyAssignments5_es6.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@
22
var v = { *[foo()]() { } }
33

44
//// [FunctionPropertyAssignments5_es6.js]
5-
var v = (_a = {}, _a[foo()] = function () { },
6-
_a);
5+
var v = (_a = {}, _a[foo()] = function () { }, _a);
76
var _a;

tests/baselines/reference/computedPropertyNames10_ES5.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ var v = {
2020
var s;
2121
var n;
2222
var a;
23-
var v = (_a = {}, _a[s] = function () { }, _a[n] = function () { }, _a[s + s] = function () { }, _a[s + n] = function () { }, _a[+s] = function () { }, _a[""] = function () { }, _a[0] = function () { }, _a[a] = function () { }, _a[true] = function () { }, _a["hello bye"] = function () { }, _a["hello " + a + " bye"] = function () { },
24-
_a);
23+
var v = (_a = {},
24+
_a[s] = function () { },
25+
_a[n] = function () { },
26+
_a[s + s] = function () { },
27+
_a[s + n] = function () { },
28+
_a[+s] = function () { },
29+
_a[""] = function () { },
30+
_a[0] = function () { },
31+
_a[a] = function () { },
32+
_a[true] = function () { },
33+
_a["hello bye"] = function () { },
34+
_a["hello " + a + " bye"] = function () { },
35+
_a
36+
);
2537
var _a;

tests/baselines/reference/computedPropertyNames11_ES5.js

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,62 @@ var v = {
2020
var s;
2121
var n;
2222
var a;
23-
var v = (_a = {}, _a[s] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a[n] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }), _a[s + s] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a[s + n] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }), _a[+s] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a[""] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }), _a[0] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a[a] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }), _a[true] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a["hello bye"] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }), _a["hello " + a + " bye"] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }),
24-
_a);
23+
var v = (_a = {},
24+
Object.defineProperty(_a, s, {
25+
get: function () { return 0; },
26+
enumerable: true,
27+
configurable: true
28+
}),
29+
Object.defineProperty(_a, n, {
30+
set: function (v) { },
31+
enumerable: true,
32+
configurable: true
33+
}),
34+
Object.defineProperty(_a, s + s, {
35+
get: function () { return 0; },
36+
enumerable: true,
37+
configurable: true
38+
}),
39+
Object.defineProperty(_a, s + n, {
40+
set: function (v) { },
41+
enumerable: true,
42+
configurable: true
43+
}),
44+
Object.defineProperty(_a, +s, {
45+
get: function () { return 0; },
46+
enumerable: true,
47+
configurable: true
48+
}),
49+
Object.defineProperty(_a, "", {
50+
set: function (v) { },
51+
enumerable: true,
52+
configurable: true
53+
}),
54+
Object.defineProperty(_a, 0, {
55+
get: function () { return 0; },
56+
enumerable: true,
57+
configurable: true
58+
}),
59+
Object.defineProperty(_a, a, {
60+
set: function (v) { },
61+
enumerable: true,
62+
configurable: true
63+
}),
64+
Object.defineProperty(_a, true, {
65+
get: function () { return 0; },
66+
enumerable: true,
67+
configurable: true
68+
}),
69+
Object.defineProperty(_a, "hello bye", {
70+
set: function (v) { },
71+
enumerable: true,
72+
configurable: true
73+
}),
74+
Object.defineProperty(_a, "hello " + a + " bye", {
75+
get: function () { return 0; },
76+
enumerable: true,
77+
configurable: true
78+
}),
79+
_a
80+
);
2581
var _a;

tests/baselines/reference/computedPropertyNames18_ES5.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ function foo() {
77

88
//// [computedPropertyNames18_ES5.js]
99
function foo() {
10-
var obj = (_a = {}, _a[this.bar] =
11-
0,
12-
_a);
10+
var obj = (_a = {},
11+
_a[this.bar] = 0,
12+
_a
13+
);
1314
var _a;
1415
}

tests/baselines/reference/computedPropertyNames19_ES5.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ module M {
88
//// [computedPropertyNames19_ES5.js]
99
var M;
1010
(function (M) {
11-
var obj = (_a = {}, _a[this.bar] =
12-
0,
13-
_a);
11+
var obj = (_a = {},
12+
_a[this.bar] = 0,
13+
_a
14+
);
1415
var _a;
1516
})(M || (M = {}));

tests/baselines/reference/computedPropertyNames1_ES5.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ var v = {
55
}
66

77
//// [computedPropertyNames1_ES5.js]
8-
var v = (_a = {}, _a[0 + 1] = Object.defineProperty({ get: function () { return 0; }, enumerable: true, configurable: true }), _a[0 + 1] = Object.defineProperty({ set: function (v) { }, enumerable: true, configurable: true }),
9-
_a);
8+
var v = (_a = {},
9+
Object.defineProperty(_a, 0 + 1, {
10+
get: function () { return 0; },
11+
enumerable: true,
12+
configurable: true
13+
}),
14+
Object.defineProperty(_a, 0 + 1, {
15+
set: function (v) { } //No error
16+
,
17+
enumerable: true,
18+
configurable: true
19+
}),
20+
_a
21+
);
1022
var _a;

0 commit comments

Comments
 (0)