mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Declaration emit spread types and downlevel spread
This commit is contained in:
parent
a3ffe6f874
commit
7004652a0a
@ -1121,6 +1121,14 @@ namespace ts {
|
||||
writeLine();
|
||||
}
|
||||
|
||||
|
||||
function emitSpreadTypeElement(type: SpreadTypeElement) {
|
||||
write("...");
|
||||
emitType(type.type);
|
||||
write(";");
|
||||
writeLine();
|
||||
}
|
||||
|
||||
function emitVariableDeclaration(node: VariableDeclaration) {
|
||||
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
|
||||
// so there is no check needed to see if declaration is visible
|
||||
@ -1702,6 +1710,8 @@ namespace ts {
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return emitPropertyDeclaration(<PropertyDeclaration>node);
|
||||
case SyntaxKind.SpreadTypeElement:
|
||||
return emitSpreadTypeElement(node as SpreadTypeElement);
|
||||
case SyntaxKind.EnumMember:
|
||||
return emitEnumMemberDeclaration(<EnumMember>node);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
|
||||
@ -2195,7 +2195,7 @@ const _super = (function (geti, seti) {
|
||||
helpersEmitted = true;
|
||||
}
|
||||
|
||||
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttributes)) {
|
||||
if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasSpreadAttribute)) {
|
||||
writeLines(assignHelper);
|
||||
assignEmitted = true;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/experimental.ts" />
|
||||
/// <reference path="transformers/es7.ts" />
|
||||
/// <reference path="transformers/es6.ts" />
|
||||
/// <reference path="transformers/generators.ts" />
|
||||
@ -176,6 +177,7 @@ namespace ts {
|
||||
transformers.push(transformJsx);
|
||||
}
|
||||
|
||||
transformers.push(transformExperimental);
|
||||
transformers.push(transformES7);
|
||||
|
||||
if (languageVersion < ScriptTarget.ES6) {
|
||||
@ -629,4 +631,4 @@ namespace ts {
|
||||
return t => t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,6 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(<BinaryExpression>node);
|
||||
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
@ -94,4 +93,4 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
80
src/compiler/transformers/experimental.ts
Normal file
80
src/compiler/transformers/experimental.ts
Normal file
@ -0,0 +1,80 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function transformExperimental(context: TransformationContext) {
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if (node.transformFlags & TransformFlags.Experimental) {
|
||||
return visitorWorker(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsExperimental) {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
default:
|
||||
Debug.failBadSyntaxKind(node);
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
if (e.kind === SyntaxKind.SpreadElement) {
|
||||
if (chunkObject) {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
chunkObject = undefined;
|
||||
}
|
||||
const target = (e as SpreadElement).target;
|
||||
objects.push(visitNode(target, visitor, isExpression));
|
||||
}
|
||||
else {
|
||||
if (!chunkObject) {
|
||||
chunkObject = [];
|
||||
}
|
||||
if (e.kind === SyntaxKind.PropertyAssignment) {
|
||||
const p = e as PropertyAssignment;
|
||||
chunkObject.push(createPropertyAssignment(p.name, visitNode(p.initializer, visitor, isExpression)));
|
||||
}
|
||||
else {
|
||||
chunkObject.push(e as ShorthandPropertyAssignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunkObject) {
|
||||
objects.push(createObjectLiteral(chunkObject));
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
|
||||
// spread elements emit like so:
|
||||
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
|
||||
// { a, ...o, b } => __assign({a}, o, {b});
|
||||
// If the first element is a spread element, then the first argument to __assign is {}:
|
||||
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
|
||||
const objects = chunkObjectLiteralElements(node.properties);
|
||||
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
objects.unshift(createObjectLiteral());
|
||||
}
|
||||
return createCall(createIdentifier("__assign"), undefined, objects);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user