mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add __spreadArrays helper (#31166)
This commit is contained in:
@@ -19080,8 +19080,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type {
|
||||
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.SpreadIncludes);
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? ExternalEmitHelpers.SpreadIncludes : ExternalEmitHelpers.SpreadArrays);
|
||||
}
|
||||
|
||||
const arrayOrIterableType = checkExpression(node.expression, checkMode);
|
||||
@@ -31104,6 +31104,7 @@ namespace ts {
|
||||
case ExternalEmitHelpers.Values: return "__values";
|
||||
case ExternalEmitHelpers.Read: return "__read";
|
||||
case ExternalEmitHelpers.Spread: return "__spread";
|
||||
case ExternalEmitHelpers.SpreadArrays: return "__spreadArrays";
|
||||
case ExternalEmitHelpers.Await: return "__await";
|
||||
case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator";
|
||||
case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator";
|
||||
|
||||
@@ -2657,6 +2657,7 @@ namespace ts {
|
||||
valuesHelper,
|
||||
readHelper,
|
||||
spreadHelper,
|
||||
spreadArraysHelper,
|
||||
restHelper,
|
||||
decorateHelper,
|
||||
metadataHelper,
|
||||
@@ -3693,6 +3694,31 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export const spreadArraysHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:spreadArrays",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};`
|
||||
};
|
||||
|
||||
export function createSpreadArraysHelper(context: TransformationContext, argumentList: ReadonlyArray<Expression>, location?: TextRange) {
|
||||
context.requestEmitHelper(spreadArraysHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__spreadArrays"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentList
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
||||
export function createForOfBindingStatement(node: ForInitializer, boundValue: Expression): Statement {
|
||||
|
||||
@@ -3819,8 +3819,11 @@ namespace ts {
|
||||
// [source]
|
||||
// [a, ...b, c]
|
||||
//
|
||||
// [output (downlevelIteration)]
|
||||
// __spread([a], b, [c])
|
||||
//
|
||||
// [output]
|
||||
// [a].concat(b, [c])
|
||||
// __spreadArrays([a], b, [c])
|
||||
|
||||
// Map spans of spread expressions into their expressions and spans of other
|
||||
// expressions into an array literal.
|
||||
@@ -3834,10 +3837,7 @@ namespace ts {
|
||||
if (compilerOptions.downlevelIteration) {
|
||||
if (segments.length === 1) {
|
||||
const firstSegment = segments[0];
|
||||
if (isCallExpression(firstSegment)
|
||||
&& isIdentifier(firstSegment.expression)
|
||||
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
|
||||
&& firstSegment.expression.escapedText === "___spread") {
|
||||
if (isCallToHelper(firstSegment, "___spread" as __String)) {
|
||||
return segments[0];
|
||||
}
|
||||
}
|
||||
@@ -3846,17 +3846,33 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadElement(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
const firstSegment = segments[0];
|
||||
if (!needsUniqueCopy
|
||||
|| isPackedArrayLiteral(firstSegment)
|
||||
|| isCallToHelper(firstSegment, "___spreadArrays" as __String)) {
|
||||
return segments[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift()!, segments);
|
||||
return createSpreadArraysHelper(context, segments);
|
||||
}
|
||||
}
|
||||
|
||||
function isPackedElement(node: Expression) {
|
||||
return !isOmittedExpression(node);
|
||||
}
|
||||
|
||||
function isPackedArrayLiteral(node: Expression) {
|
||||
return isArrayLiteralExpression(node) && every(node.elements, isPackedElement);
|
||||
}
|
||||
|
||||
function isCallToHelper(firstSegment: Expression, helperName: __String) {
|
||||
return isCallExpression(firstSegment)
|
||||
&& isIdentifier(firstSegment.expression)
|
||||
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
|
||||
&& firstSegment.expression.escapedText === helperName;
|
||||
}
|
||||
|
||||
function partitionSpread(node: Expression) {
|
||||
return isSpreadElement(node)
|
||||
? visitSpanOfSpreads
|
||||
|
||||
@@ -5339,12 +5339,13 @@ namespace ts {
|
||||
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
|
||||
Read = 1 << 9, // __read (used by ES2015 iterator destructuring transformation)
|
||||
Spread = 1 << 10, // __spread (used by ES2015 array spread and argument list spread transformations)
|
||||
Await = 1 << 11, // __await (used by ES2017 async generator transformation)
|
||||
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation)
|
||||
MakeTemplateObject = 1 << 16, // __makeTemplateObject (used for constructing template string array objects)
|
||||
SpreadArrays = 1 << 11, // __spreadArrays (used by ES2015 array spread and argument list spread transformations)
|
||||
Await = 1 << 12, // __await (used by ES2017 async generator transformation)
|
||||
AsyncGenerator = 1 << 13, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 14, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 15, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
ExportStar = 1 << 16, // __exportStar (used by CommonJS/AMD/UMD module transformation)
|
||||
MakeTemplateObject = 1 << 17, // __makeTemplateObject (used for constructing template string array objects)
|
||||
FirstEmitHelper = Extends,
|
||||
LastEmitHelper = MakeTemplateObject,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user