Skip to content

Commit ba4f52c

Browse files
committed
Merge remote-tracking branch 'origin/object-rest-emit-for-method-and-accessor-parameters' into streamlineDestructuring
2 parents 8733973 + 498d978 commit ba4f52c

File tree

12 files changed

+332
-193
lines changed

12 files changed

+332
-193
lines changed

src/compiler/binder.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2781,6 +2781,11 @@ namespace ts {
27812781
transformFlags |= TransformFlags.AssertTypeScript;
27822782
}
27832783

2784+
// function declarations with object rest destructuring are ES Next syntax
2785+
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
2786+
transformFlags |= TransformFlags.AssertESNext;
2787+
}
2788+
27842789
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
27852790
return transformFlags & ~TransformFlags.ConstructorExcludes;
27862791
}
@@ -2799,6 +2804,11 @@ namespace ts {
27992804
transformFlags |= TransformFlags.AssertTypeScript;
28002805
}
28012806

2807+
// function declarations with object rest destructuring are ES Next syntax
2808+
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
2809+
transformFlags |= TransformFlags.AssertESNext;
2810+
}
2811+
28022812
// An async method declaration is ES2017 syntax.
28032813
if (hasModifier(node, ModifierFlags.Async)) {
28042814
transformFlags |= TransformFlags.AssertES2017;
@@ -2825,6 +2835,11 @@ namespace ts {
28252835
transformFlags |= TransformFlags.AssertTypeScript;
28262836
}
28272837

2838+
// function declarations with object rest destructuring are ES Next syntax
2839+
if (subtreeFlags & TransformFlags.ContainsObjectRest) {
2840+
transformFlags |= TransformFlags.AssertESNext;
2841+
}
2842+
28282843
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
28292844
return transformFlags & ~TransformFlags.MethodOrAccessorExcludes;
28302845
}

src/compiler/factory.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -646,13 +646,25 @@ namespace ts {
646646
return node;
647647
}
648648

649-
export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange) {
650-
const node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, location);
649+
export function createConditional(condition: Expression, whenTrue: Expression, whenFalse: Expression, location?: TextRange): ConditionalExpression;
650+
export function createConditional(condition: Expression, questionToken: QuestionToken, whenTrue: Expression, colonToken: ColonToken, whenFalse: Expression, location?: TextRange): ConditionalExpression;
651+
export function createConditional(condition: Expression, questionTokenOrWhenTrue: QuestionToken | Expression, whenTrueOrWhenFalse: Expression, colonTokenOrLocation?: ColonToken | TextRange, whenFalse?: Expression, location?: TextRange) {
652+
const node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, whenFalse ? location : colonTokenOrLocation);
651653
node.condition = parenthesizeForConditionalHead(condition);
652-
node.questionToken = questionToken;
653-
node.whenTrue = whenTrue;
654-
node.colonToken = colonToken;
655-
node.whenFalse = whenFalse;
654+
if (whenFalse) {
655+
// second overload
656+
node.questionToken = <QuestionToken>questionTokenOrWhenTrue;
657+
node.whenTrue = whenTrueOrWhenFalse;
658+
node.colonToken = <ColonToken>colonTokenOrLocation;
659+
node.whenFalse = whenFalse;
660+
}
661+
else {
662+
// first overload
663+
node.questionToken = createToken(SyntaxKind.QuestionToken);
664+
node.whenTrue = <Expression>questionTokenOrWhenTrue;
665+
node.colonToken = createToken(SyntaxKind.ColonToken);
666+
node.whenFalse = whenTrueOrWhenFalse;
667+
}
656668
return node;
657669
}
658670

@@ -1570,6 +1582,14 @@ namespace ts {
15701582
return createVoid(createLiteral(0));
15711583
}
15721584

1585+
export type TypeOfTag = "undefined" | "number" | "boolean" | "string" | "symbol" | "object" | "function";
1586+
1587+
export function createTypeCheck(value: Expression, tag: TypeOfTag) {
1588+
return tag === "undefined"
1589+
? createStrictEquality(value, createVoidZero())
1590+
: createStrictEquality(createTypeOf(value), createLiteral(tag));
1591+
}
1592+
15731593
export function createMemberAccessForPropertyName(target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression {
15741594
if (isComputedPropertyName(memberName)) {
15751595
return createElementAccess(target, memberName.expression, location);

src/compiler/transformers/destructuring.ts

Lines changed: 143 additions & 106 deletions
Large diffs are not rendered by default.

src/compiler/transformers/es2015.ts

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,13 +1159,11 @@ namespace ts {
11591159
/*modifiers*/ undefined,
11601160
createVariableDeclarationList(
11611161
flattenDestructuringBinding(
1162-
context,
11631162
parameter,
1164-
temp,
1165-
/*skipInitializer*/ false,
1166-
/*recordTempVariablesInLine*/ true,
1163+
visitor,
1164+
context,
11671165
FlattenLevel.All,
1168-
visitor
1166+
temp
11691167
)
11701168
)
11711169
),
@@ -1199,10 +1197,7 @@ namespace ts {
11991197
function addDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void {
12001198
initializer = visitNode(initializer, visitor, isExpression);
12011199
const statement = createIf(
1202-
createStrictEquality(
1203-
getSynthesizedClone(name),
1204-
createVoidZero()
1205-
),
1200+
createTypeCheck(getSynthesizedClone(name), "undefined"),
12061201
setEmitFlags(
12071202
createBlock([
12081203
createStatement(
@@ -1713,12 +1708,11 @@ namespace ts {
17131708
// If we are here it is because this is a destructuring assignment.
17141709
Debug.assert(isDestructuringAssignment(node));
17151710
return flattenDestructuringAssignment(
1716-
context,
17171711
<DestructuringAssignment>node,
1718-
needsDestructuringValue,
1712+
visitor,
1713+
context,
17191714
FlattenLevel.All,
1720-
/*createAssignmentCallback*/ undefined,
1721-
visitor);
1715+
needsDestructuringValue);
17221716
}
17231717

17241718
function visitVariableStatement(node: VariableStatement): Statement {
@@ -1731,12 +1725,10 @@ namespace ts {
17311725
let assignment: Expression;
17321726
if (isBindingPattern(decl.name)) {
17331727
assignment = flattenDestructuringAssignment(
1734-
context,
17351728
decl,
1736-
/*needsValue*/ false,
1737-
FlattenLevel.All,
1738-
/*createAssignmentCallback*/ undefined,
1739-
visitor
1729+
visitor,
1730+
context,
1731+
FlattenLevel.All
17401732
);
17411733
}
17421734
else {
@@ -1888,16 +1880,15 @@ namespace ts {
18881880
function visitVariableDeclaration(node: VariableDeclaration): VisitResult<VariableDeclaration> {
18891881
// If we are here it is because the name contains a binding pattern.
18901882
if (isBindingPattern(node.name)) {
1891-
const recordTempVariablesInLine = !enclosingVariableStatement
1892-
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
1883+
const doNotRecordTempVariablesInLine = enclosingVariableStatement
1884+
&& hasModifier(enclosingVariableStatement, ModifierFlags.Export);
18931885
return flattenDestructuringBinding(
1894-
context,
18951886
node,
1896-
/*value*/ undefined,
1897-
/*skipInitializer*/ false,
1898-
recordTempVariablesInLine,
1887+
visitor,
1888+
context,
18991889
FlattenLevel.All,
1900-
visitor
1890+
/*value*/ undefined,
1891+
doNotRecordTempVariablesInLine
19011892
);
19021893
}
19031894

@@ -2001,13 +1992,11 @@ namespace ts {
20011992
// This works whether the declaration is a var, let, or const.
20021993
// It will use rhsIterationValue _a[_i] as the initializer.
20031994
const declarations = flattenDestructuringBinding(
2004-
context,
20051995
firstOriginalDeclaration,
2006-
elementAccess,
2007-
/*skipInitializer*/ false,
2008-
/*recordTempVariablesInLine*/ true,
1996+
visitor,
1997+
context,
20091998
FlattenLevel.All,
2010-
visitor
1999+
elementAccess
20112000
);
20122001

20132002
const declarationList = createVariableDeclarationList(declarations, /*location*/ initializer);
@@ -2056,12 +2045,10 @@ namespace ts {
20562045
statements.push(
20572046
createStatement(
20582047
flattenDestructuringAssignment(
2059-
context,
20602048
assignment,
2061-
/*needsValue*/ false,
2062-
FlattenLevel.All,
2063-
/*createAssignmentCallback*/ undefined,
2064-
visitor
2049+
visitor,
2050+
context,
2051+
FlattenLevel.All
20652052
)
20662053
)
20672054
);
@@ -2697,7 +2684,13 @@ namespace ts {
26972684
const temp = createTempVariable(undefined);
26982685
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
26992686

2700-
const vars = flattenDestructuringBinding(context, node.variableDeclaration, temp, /*skipInitializer*/ false, /*recordTempVariablesInLine*/ true, FlattenLevel.All, visitor);
2687+
const vars = flattenDestructuringBinding(
2688+
node.variableDeclaration,
2689+
visitor,
2690+
context,
2691+
FlattenLevel.All,
2692+
temp
2693+
);
27012694
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
27022695
const destructure = createVariableStatement(undefined, list);
27032696

src/compiler/transformers/esnext.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,11 @@ namespace ts {
128128
function visitBinaryExpression(node: BinaryExpression, noDestructuringValue: boolean): Expression {
129129
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRest) {
130130
return flattenDestructuringAssignment(
131-
context,
132131
node,
133-
!noDestructuringValue,
132+
visitor,
133+
context,
134134
FlattenLevel.ObjectRest,
135-
/*createAssignmentCallback*/ undefined,
136-
visitor
135+
!noDestructuringValue
137136
);
138137
}
139138
else if (node.operatorToken.kind === SyntaxKind.CommaToken) {
@@ -155,13 +154,11 @@ namespace ts {
155154
// If we are here it is because the name contains a binding pattern with a rest somewhere in it.
156155
if (isBindingPattern(node.name) && node.name.transformFlags & TransformFlags.ContainsObjectRest) {
157156
return flattenDestructuringBinding(
158-
context,
159157
node,
160-
/*boundValue*/ undefined,
161-
/*skipInitializer*/ false,
162-
/*recordTempVariablesInLine*/ true,
163-
FlattenLevel.ObjectRest,
164-
visitor);
158+
visitor,
159+
context,
160+
FlattenLevel.ObjectRest
161+
);
165162
}
166163
return visitEachChild(node, visitor, context);
167164
}
@@ -194,13 +191,13 @@ namespace ts {
194191
temp = createTempVariable(/*recordTempVariable*/ undefined);
195192
const firstDeclaration = firstOrUndefined(initializer.declarations);
196193
const declarations = flattenDestructuringBinding(
197-
context,
198194
firstDeclaration,
195+
visitor,
196+
context,
197+
FlattenLevel.ObjectRest,
199198
temp,
199+
/*doNotRecordTempVariablesInLine*/ false,
200200
/*skipInitializer*/ true,
201-
/*recordTempVariablesInLine*/ true,
202-
FlattenLevel.ObjectRest,
203-
visitor
204201
);
205202
if (some(declarations)) {
206203
const statement = createVariableStatement(
@@ -214,12 +211,10 @@ namespace ts {
214211
else if (isAssignmentPattern(initializer)) {
215212
temp = createTempVariable(/*recordTempVariable*/ undefined);
216213
const expression = flattenDestructuringAssignment(
217-
context,
218214
aggregateTransformFlags(createAssignment(initializer, temp, /*location*/ node.initializer)),
219-
/*needsValue*/ false,
220-
FlattenLevel.ObjectRest,
221-
/*createAssignmentCallback*/ undefined,
222-
visitor
215+
visitor,
216+
context,
217+
FlattenLevel.ObjectRest
223218
);
224219
leadingStatements = append(leadingStatements, createStatement(expression, /*location*/ node.initializer));
225220
}
@@ -352,7 +347,15 @@ namespace ts {
352347
for (const parameter of node.parameters) {
353348
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
354349
const temp = getGeneratedNameForNode(parameter);
355-
const declarations = flattenDestructuringBinding(context, parameter, temp, /*skipInitializer*/ true, /*recordTempVariablesInLine*/ true, FlattenLevel.ObjectRest, visitor);
350+
const declarations = flattenDestructuringBinding(
351+
parameter,
352+
visitor,
353+
context,
354+
FlattenLevel.ObjectRest,
355+
temp,
356+
/*doNotRecordTempVariablesInLine*/ false,
357+
/*skipInitializer*/ true,
358+
);
356359
if (some(declarations)) {
357360
const statement = createVariableStatement(
358361
/*modifiers*/ undefined,

src/compiler/transformers/module/module.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -757,12 +757,12 @@ namespace ts {
757757
function transformInitializedVariable(node: VariableDeclaration): Expression {
758758
if (isBindingPattern(node.name)) {
759759
return flattenDestructuringAssignment(
760-
context,
761760
node,
762-
/*needsValue*/ false,
761+
/*visitor*/ undefined,
762+
context,
763763
FlattenLevel.All,
764-
createExportExpression,
765-
/*visitor*/ undefined
764+
/*needsValue*/ false,
765+
createExportExpression
766766
);
767767
}
768768
else {

src/compiler/transformers/module/system.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,14 @@ namespace ts {
808808
function transformInitializedVariable(node: VariableDeclaration, isExportedDeclaration: boolean): Expression {
809809
const createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
810810
return isBindingPattern(node.name)
811-
? flattenDestructuringAssignment(context, node, /*needsValue*/ false, FlattenLevel.All, createAssignment, destructuringVisitor)
811+
? flattenDestructuringAssignment(
812+
node,
813+
destructuringVisitor,
814+
context,
815+
FlattenLevel.All,
816+
/*needsValue*/ false,
817+
createAssignment
818+
)
812819
: createAssignment(node.name, visitNode(node.initializer, destructuringVisitor, isExpression));
813820
}
814821

@@ -1460,12 +1467,12 @@ namespace ts {
14601467
function visitDestructuringAssignment(node: DestructuringAssignment): VisitResult<Expression> {
14611468
if (hasExportedReferenceInDestructuringTarget(node.left)) {
14621469
return flattenDestructuringAssignment(
1463-
context,
14641470
node,
1465-
/*needsValue*/ true,
1471+
destructuringVisitor,
1472+
context,
14661473
FlattenLevel.All,
1467-
/*createAssignmentCallback*/ undefined,
1468-
destructuringVisitor);
1474+
/*needsValue*/ true
1475+
);
14691476
}
14701477

14711478
return visitEachChild(node, destructuringVisitor, context);

src/compiler/transformers/ts.ts

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,12 +1819,7 @@ namespace ts {
18191819
const temp = createTempVariable(hoistVariableDeclaration);
18201820
return createLogicalOr(
18211821
createLogicalAnd(
1822-
createStrictEquality(
1823-
createTypeOf(
1824-
createAssignment(temp, serialized)
1825-
),
1826-
createLiteral("function")
1827-
),
1822+
createTypeCheck(createAssignment(temp, serialized), "function"),
18281823
temp
18291824
),
18301825
createIdentifier("Object")
@@ -1933,13 +1928,8 @@ namespace ts {
19331928
*/
19341929
function getGlobalSymbolNameWithFallback(): Expression {
19351930
return createConditional(
1936-
createStrictEquality(
1937-
createTypeOf(createIdentifier("Symbol")),
1938-
createLiteral("function")
1939-
),
1940-
createToken(SyntaxKind.QuestionToken),
1931+
createTypeCheck(createIdentifier("Symbol"), "function"),
19411932
createIdentifier("Symbol"),
1942-
createToken(SyntaxKind.ColonToken),
19431933
createIdentifier("Object")
19441934
);
19451935
}
@@ -2356,12 +2346,12 @@ namespace ts {
23562346
const name = node.name;
23572347
if (isBindingPattern(name)) {
23582348
return flattenDestructuringAssignment(
2359-
context,
23602349
node,
2361-
/*needsValue*/ false,
2350+
visitor,
2351+
context,
23622352
FlattenLevel.All,
2363-
createNamespaceExportExpression,
2364-
visitor
2353+
/*needsValue*/ false,
2354+
createNamespaceExportExpression
23652355
);
23662356
}
23672357
else {

0 commit comments

Comments
 (0)