Skip to content

Commit f4ddf4b

Browse files
Merge pull request #7971 from Microsoft/objectAssignPoly-1.8
Port new '__assign' helper to TypeScript 1.8
2 parents 9ef7553 + 662dc64 commit f4ddf4b

File tree

9 files changed

+93
-16
lines changed

9 files changed

+93
-16
lines changed

src/compiler/binder.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ namespace ts {
122122
let hasAsyncFunctions: boolean;
123123
let hasDecorators: boolean;
124124
let hasParameterDecorators: boolean;
125+
let hasJsxSpreadAttribute: boolean;
125126

126127
// If this file is an external module, then it is automatically in strict-mode according to
127128
// ES6. If it is not an external module, then we'll determine if it is in strict mode or
@@ -161,6 +162,7 @@ namespace ts {
161162
hasAsyncFunctions = false;
162163
hasDecorators = false;
163164
hasParameterDecorators = false;
165+
hasJsxSpreadAttribute = false;
164166
}
165167

166168
return bindSourceFile;
@@ -498,6 +500,9 @@ namespace ts {
498500
if (hasAsyncFunctions) {
499501
flags |= NodeFlags.HasAsyncFunctions;
500502
}
503+
if (hasJsxSpreadAttribute) {
504+
flags |= NodeFlags.HasJsxSpreadAttribute;
505+
}
501506
}
502507

503508
node.flags = flags;
@@ -1289,6 +1294,10 @@ namespace ts {
12891294
case SyntaxKind.EnumMember:
12901295
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
12911296

1297+
case SyntaxKind.JsxSpreadAttribute:
1298+
hasJsxSpreadAttribute = true;
1299+
return;
1300+
12921301
case SyntaxKind.CallSignature:
12931302
case SyntaxKind.ConstructSignature:
12941303
case SyntaxKind.IndexSignature:

src/compiler/emitter.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,16 @@ var __extends = (this && this.__extends) || function (d, b) {
345345
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
346346
};`;
347347

348+
const assignHelper = `
349+
var __assign = (this && this.__assign) || Object.assign || function(t) {
350+
for (var s, i = 1, n = arguments.length; i < n; i++) {
351+
s = arguments[i];
352+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
353+
t[p] = s[p];
354+
}
355+
return t;
356+
};`;
357+
348358
// emit output for the __decorate helper function
349359
const decorateHelper = `
350360
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
@@ -540,6 +550,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
540550
let convertedLoopState: ConvertedLoopState;
541551

542552
let extendsEmitted: boolean;
553+
let assignEmitted: boolean;
543554
let decorateEmitted: boolean;
544555
let paramEmitted: boolean;
545556
let awaiterEmitted: boolean;
@@ -623,6 +634,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
623634
decorateEmitted = false;
624635
paramEmitted = false;
625636
awaiterEmitted = false;
637+
assignEmitted = false;
626638
tempFlags = 0;
627639
tempVariables = undefined;
628640
tempParameters = undefined;
@@ -1259,11 +1271,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12591271
}
12601272
else {
12611273
// Either emit one big object literal (no spread attribs), or
1262-
// a call to React.__spread
1274+
// a call to the __assign helper
12631275
const attrs = openingNode.attributes;
12641276
if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) {
1265-
emitExpressionIdentifier(syntheticReactRef);
1266-
write(".__spread(");
1277+
write("__assign(");
12671278

12681279
let haveOpenedObjectLiteral = false;
12691280
for (let i = 0; i < attrs.length; i++) {
@@ -7610,11 +7621,16 @@ const _super = (function (geti, seti) {
76107621
if (!compilerOptions.noEmitHelpers) {
76117622
// Only Emit __extends function when target ES5.
76127623
// For target ES6 and above, we can emit classDeclaration as is.
7613-
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
7624+
if (languageVersion < ScriptTarget.ES6 && !extendsEmitted && node.flags & NodeFlags.HasClassExtends) {
76147625
writeLines(extendsHelper);
76157626
extendsEmitted = true;
76167627
}
76177628

7629+
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttribute)) {
7630+
writeLines(assignHelper);
7631+
assignEmitted = true;
7632+
}
7633+
76187634
if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) {
76197635
writeLines(decorateHelper);
76207636
if (compilerOptions.emitDecoratorMetadata) {

src/compiler/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ namespace ts {
369369
FirstNode = QualifiedName,
370370
}
371371

372-
export const enum NodeFlags {
372+
export const enum NodeFlags {
373373
None = 0,
374374
Export = 1 << 1, // Declarations
375375
Ambient = 1 << 2, // Declarations
@@ -397,6 +397,10 @@ namespace ts {
397397
HasParamDecorators = 1 << 24, // If the file has parameter decorators (initialized by binding)
398398
HasAsyncFunctions = 1 << 25, // If the file has async functions (initialized by binding)
399399

400+
// This was picked out from the 'master' branch.
401+
// To keep the flags consistent, we're skipping a few ahead.
402+
HasJsxSpreadAttribute = 1 << 30,
403+
400404
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
401405
AccessibilityModifier = Public | Private | Protected,
402406
BlockScoped = Let | Const,

tests/baselines/reference/reactNamespaceJSXEmit.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@ declare var x: any;
1313

1414

1515
//// [reactNamespaceJSXEmit.js]
16+
var __assign = (this && this.__assign) || Object.assign || function(t) {
17+
for (var s, i = 1, n = arguments.length; i < n; i++) {
18+
s = arguments[i];
19+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
20+
t[p] = s[p];
21+
}
22+
return t;
23+
};
1624
myReactLib.createElement("foo", {data: true});
1725
myReactLib.createElement(Bar, {x: x});
1826
myReactLib.createElement("x-component", null);
19-
myReactLib.createElement(Bar, myReactLib.__spread({}, x));
20-
myReactLib.createElement(Bar, myReactLib.__spread({}, x, {y: 2}));
27+
myReactLib.createElement(Bar, __assign({}, x));
28+
myReactLib.createElement(Bar, __assign({}, x, {y: 2}));

tests/baselines/reference/tsxExternalModuleEmit2.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@ declare var Foo, React;
1919

2020
//// [app.js]
2121
"use strict";
22+
var __assign = (this && this.__assign) || Object.assign || function(t) {
23+
for (var s, i = 1, n = arguments.length; i < n; i++) {
24+
s = arguments[i];
25+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
26+
t[p] = s[p];
27+
}
28+
return t;
29+
};
2230
var mod_1 = require('mod');
2331
// Should see mod_1['default'] in emit here
2432
React.createElement(Foo, {handler: mod_1["default"]});
2533
// Should see mod_1['default'] in emit here
26-
React.createElement(Foo, React.__spread({}, mod_1["default"]));
34+
React.createElement(Foo, __assign({}, mod_1["default"]));

tests/baselines/reference/tsxReactEmit2.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@ var spreads5 = <div x={p2} {...p1} y={p3}>{p2}</div>;
1616

1717

1818
//// [file.js]
19+
var __assign = (this && this.__assign) || Object.assign || function(t) {
20+
for (var s, i = 1, n = arguments.length; i < n; i++) {
21+
s = arguments[i];
22+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
23+
t[p] = s[p];
24+
}
25+
return t;
26+
};
1927
var p1, p2, p3;
20-
var spreads1 = React.createElement("div", React.__spread({}, p1), p2);
21-
var spreads2 = React.createElement("div", React.__spread({}, p1), p2);
22-
var spreads3 = React.createElement("div", React.__spread({x: p3}, p1), p2);
23-
var spreads4 = React.createElement("div", React.__spread({}, p1, {x: p3}), p2);
24-
var spreads5 = React.createElement("div", React.__spread({x: p2}, p1, {y: p3}), p2);
28+
var spreads1 = React.createElement("div", __assign({}, p1), p2);
29+
var spreads2 = React.createElement("div", __assign({}, p1), p2);
30+
var spreads3 = React.createElement("div", __assign({x: p3}, p1), p2);
31+
var spreads4 = React.createElement("div", __assign({}, p1, {x: p3}), p2);
32+
var spreads5 = React.createElement("div", __assign({x: p2}, p1, {y: p3}), p2);

tests/baselines/reference/tsxReactEmit4.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ var openClosed1 = <div>
1818
var spread1 = <div {...p} x={0} />;
1919

2020
//// [file.js]
21+
var __assign = (this && this.__assign) || Object.assign || function(t) {
22+
for (var s, i = 1, n = arguments.length; i < n; i++) {
23+
s = arguments[i];
24+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
25+
t[p] = s[p];
26+
}
27+
return t;
28+
};
2129
var p;
2230
var openClosed1 = React.createElement("div", null, blah);
2331
// Should emit React.__spread({}, p, {x: 0})
24-
var spread1 = React.createElement("div", React.__spread({}, p, {x: 0}));
32+
var spread1 = React.createElement("div", __assign({}, p, {x: 0}));

tests/baselines/reference/tsxReactEmit5.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@ var spread1 = <div x='' {...foo} y='' />;
2323
//// [file.js]
2424
//// [react-consumer.js]
2525
"use strict";
26+
var __assign = (this && this.__assign) || Object.assign || function(t) {
27+
for (var s, i = 1, n = arguments.length; i < n; i++) {
28+
s = arguments[i];
29+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
30+
t[p] = s[p];
31+
}
32+
return t;
33+
};
2634
var test_1 = require("./test");
2735
// Should emit test_1.React.createElement
2836
// and React.__spread
2937
var foo;
30-
var spread1 = test_1.React.createElement("div", test_1.React.__spread({x: ''}, foo, {y: ''}));
38+
var spread1 = test_1.React.createElement("div", __assign({x: ''}, foo, {y: ''}));

tests/baselines/reference/tsxReactEmit6.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ namespace M {
2828

2929
//// [file.js]
3030
//// [react-consumer.js]
31+
var __assign = (this && this.__assign) || Object.assign || function(t) {
32+
for (var s, i = 1, n = arguments.length; i < n; i++) {
33+
s = arguments[i];
34+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
35+
t[p] = s[p];
36+
}
37+
return t;
38+
};
3139
var M;
3240
(function (M) {
3341
})(M || (M = {}));
@@ -36,7 +44,7 @@ var M;
3644
// Should emit M.React.createElement
3745
// and M.React.__spread
3846
var foo;
39-
var spread1 = M.React.createElement("div", M.React.__spread({x: ''}, foo, {y: ''}));
47+
var spread1 = M.React.createElement("div", __assign({x: ''}, foo, {y: ''}));
4048
// Quotes
4149
var x = M.React.createElement("div", null, "This \"quote\" thing");
4250
})(M || (M = {}));

0 commit comments

Comments
 (0)