Merge pull request #7952 from Microsoft/objectAssignPoly
Use an emit helper (or Object.assign) for JsxSpreadAttributes
This commit is contained in:
commit
a7bf6902ff
9 changed files with 89 additions and 15 deletions
|
@ -122,6 +122,7 @@ namespace ts {
|
|||
let hasAsyncFunctions: boolean;
|
||||
let hasDecorators: boolean;
|
||||
let hasParameterDecorators: boolean;
|
||||
let hasJsxSpreadAttribute: boolean;
|
||||
|
||||
// If this file is an external module, then it is automatically in strict-mode according to
|
||||
// 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 {
|
|||
hasAsyncFunctions = false;
|
||||
hasDecorators = false;
|
||||
hasParameterDecorators = false;
|
||||
hasJsxSpreadAttribute = false;
|
||||
}
|
||||
|
||||
return bindSourceFile;
|
||||
|
@ -498,6 +500,9 @@ namespace ts {
|
|||
if (hasAsyncFunctions) {
|
||||
flags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
if (hasJsxSpreadAttribute) {
|
||||
flags |= NodeFlags.HasJsxSpreadAttribute;
|
||||
}
|
||||
}
|
||||
|
||||
node.flags = flags;
|
||||
|
@ -1298,6 +1303,10 @@ namespace ts {
|
|||
case SyntaxKind.EnumMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
hasJsxSpreadAttribute = true;
|
||||
return;
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
|
|
|
@ -345,6 +345,16 @@ var __extends = (this && this.__extends) || function (d, b) {
|
|||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};`;
|
||||
|
||||
const assignHelper = `
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};`;
|
||||
|
||||
// emit output for the __decorate helper function
|
||||
const decorateHelper = `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
|
@ -542,6 +552,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
let convertedLoopState: ConvertedLoopState;
|
||||
|
||||
let extendsEmitted: boolean;
|
||||
let assignEmitted: boolean;
|
||||
let decorateEmitted: boolean;
|
||||
let paramEmitted: boolean;
|
||||
let awaiterEmitted: boolean;
|
||||
|
@ -625,6 +636,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
decorateEmitted = false;
|
||||
paramEmitted = false;
|
||||
awaiterEmitted = false;
|
||||
assignEmitted = false;
|
||||
tempFlags = 0;
|
||||
tempVariables = undefined;
|
||||
tempParameters = undefined;
|
||||
|
@ -1261,11 +1273,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||
}
|
||||
else {
|
||||
// Either emit one big object literal (no spread attribs), or
|
||||
// a call to React.__spread
|
||||
// a call to the __assign helper
|
||||
const attrs = openingNode.attributes;
|
||||
if (forEach(attrs, attr => attr.kind === SyntaxKind.JsxSpreadAttribute)) {
|
||||
emitExpressionIdentifier(syntheticReactRef);
|
||||
write(".__spread(");
|
||||
write("__assign(");
|
||||
|
||||
let haveOpenedObjectLiteral = false;
|
||||
for (let i = 0; i < attrs.length; i++) {
|
||||
|
@ -7704,11 +7715,16 @@ const _super = (function (geti, seti) {
|
|||
if (!compilerOptions.noEmitHelpers) {
|
||||
// Only Emit __extends function when target ES5.
|
||||
// For target ES6 and above, we can emit classDeclaration as is.
|
||||
if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) {
|
||||
if (languageVersion < ScriptTarget.ES6 && !extendsEmitted && node.flags & NodeFlags.HasClassExtends) {
|
||||
writeLines(extendsHelper);
|
||||
extendsEmitted = true;
|
||||
}
|
||||
|
||||
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttribute)) {
|
||||
writeLines(assignHelper);
|
||||
assignEmitted = true;
|
||||
}
|
||||
|
||||
if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) {
|
||||
writeLines(decorateHelper);
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
|
|
|
@ -405,6 +405,7 @@ namespace ts {
|
|||
JavaScriptFile = 1 << 27, // If node was parsed in a JavaScript
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 28, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 29, // If we've computed data from children and cached it in this node
|
||||
HasJsxSpreadAttribute = 1 << 30,
|
||||
|
||||
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
|
||||
AccessibilityModifier = Public | Private | Protected,
|
||||
|
|
|
@ -13,8 +13,16 @@ declare var x: any;
|
|||
|
||||
|
||||
//// [reactNamespaceJSXEmit.js]
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
myReactLib.createElement("foo", {data: true});
|
||||
myReactLib.createElement(Bar, {x: x});
|
||||
myReactLib.createElement("x-component", null);
|
||||
myReactLib.createElement(Bar, myReactLib.__spread({}, x));
|
||||
myReactLib.createElement(Bar, myReactLib.__spread({}, x, {y: 2}));
|
||||
myReactLib.createElement(Bar, __assign({}, x));
|
||||
myReactLib.createElement(Bar, __assign({}, x, {y: 2}));
|
||||
|
|
|
@ -19,8 +19,16 @@ declare var Foo, React;
|
|||
|
||||
//// [app.js]
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var mod_1 = require('mod');
|
||||
// Should see mod_1['default'] in emit here
|
||||
React.createElement(Foo, {handler: mod_1["default"]});
|
||||
// Should see mod_1['default'] in emit here
|
||||
React.createElement(Foo, React.__spread({}, mod_1["default"]));
|
||||
React.createElement(Foo, __assign({}, mod_1["default"]));
|
||||
|
|
|
@ -16,9 +16,17 @@ var spreads5 = <div x={p2} {...p1} y={p3}>{p2}</div>;
|
|||
|
||||
|
||||
//// [file.js]
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var p1, p2, p3;
|
||||
var spreads1 = React.createElement("div", React.__spread({}, p1), p2);
|
||||
var spreads2 = React.createElement("div", React.__spread({}, p1), p2);
|
||||
var spreads3 = React.createElement("div", React.__spread({x: p3}, p1), p2);
|
||||
var spreads4 = React.createElement("div", React.__spread({}, p1, {x: p3}), p2);
|
||||
var spreads5 = React.createElement("div", React.__spread({x: p2}, p1, {y: p3}), p2);
|
||||
var spreads1 = React.createElement("div", __assign({}, p1), p2);
|
||||
var spreads2 = React.createElement("div", __assign({}, p1), p2);
|
||||
var spreads3 = React.createElement("div", __assign({x: p3}, p1), p2);
|
||||
var spreads4 = React.createElement("div", __assign({}, p1, {x: p3}), p2);
|
||||
var spreads5 = React.createElement("div", __assign({x: p2}, p1, {y: p3}), p2);
|
||||
|
|
|
@ -18,7 +18,15 @@ var openClosed1 = <div>
|
|||
var spread1 = <div {...p} x={0} />;
|
||||
|
||||
//// [file.js]
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var p;
|
||||
var openClosed1 = React.createElement("div", null, blah);
|
||||
// Should emit React.__spread({}, p, {x: 0})
|
||||
var spread1 = React.createElement("div", React.__spread({}, p, {x: 0}));
|
||||
var spread1 = React.createElement("div", __assign({}, p, {x: 0}));
|
||||
|
|
|
@ -23,8 +23,16 @@ var spread1 = <div x='' {...foo} y='' />;
|
|||
//// [file.js]
|
||||
//// [react-consumer.js]
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var test_1 = require("./test");
|
||||
// Should emit test_1.React.createElement
|
||||
// and React.__spread
|
||||
var foo;
|
||||
var spread1 = test_1.React.createElement("div", test_1.React.__spread({x: ''}, foo, {y: ''}));
|
||||
var spread1 = test_1.React.createElement("div", __assign({x: ''}, foo, {y: ''}));
|
||||
|
|
|
@ -28,6 +28,14 @@ namespace M {
|
|||
|
||||
//// [file.js]
|
||||
//// [react-consumer.js]
|
||||
var __assign = (this && this.__assign) || Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var M;
|
||||
(function (M) {
|
||||
})(M || (M = {}));
|
||||
|
@ -36,7 +44,7 @@ var M;
|
|||
// Should emit M.React.createElement
|
||||
// and M.React.__spread
|
||||
var foo;
|
||||
var spread1 = M.React.createElement("div", M.React.__spread({x: ''}, foo, {y: ''}));
|
||||
var spread1 = M.React.createElement("div", __assign({x: ''}, foo, {y: ''}));
|
||||
// Quotes
|
||||
var x = M.React.createElement("div", null, "This \"quote\" thing");
|
||||
})(M || (M = {}));
|
||||
|
|
Loading…
Reference in a new issue