Skip to content

Commit 8babde0

Browse files
committed
WIP Clean up destructuring
1 parent d537b79 commit 8babde0

File tree

7 files changed

+814
-33
lines changed

7 files changed

+814
-33
lines changed

src/compiler/core.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,13 @@ namespace ts {
811811
}
812812
}
813813

814+
export function appendProperty<T>(map: Map<T>, key: string | number, value: T): Map<T> {
815+
if (key === undefined || value === undefined) return map;
816+
if (map === undefined) map = createMap<T>();
817+
map[key] = value;
818+
return map;
819+
}
820+
814821
export function assign<T1 extends MapLike<{}>, T2, T3>(t: T1, arg1: T2, arg2: T3): T1 & T2 & T3;
815822
export function assign<T1 extends MapLike<{}>, T2>(t: T1, arg1: T2): T1 & T2;
816823
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]): any;

src/compiler/factory.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,9 @@ namespace ts {
238238
return node;
239239
}
240240

241-
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
242-
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) {
243-
return updateNode(createParameter(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
241+
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: BindingName, type: TypeNode, initializer: Expression) {
242+
if (node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.type !== type || node.initializer !== initializer) {
243+
return updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
244244
}
245245

246246
return node;
@@ -378,9 +378,9 @@ namespace ts {
378378
return node;
379379
}
380380

381-
export function updateBindingElement(node: BindingElement, propertyName: PropertyName, name: BindingName, initializer: Expression) {
382-
if (node.propertyName !== propertyName || node.name !== name || node.initializer !== initializer) {
383-
return updateNode(createBindingElement(propertyName, node.dotDotDotToken, name, initializer, node), node);
381+
export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken, propertyName: PropertyName, name: BindingName, initializer: Expression) {
382+
if (node.propertyName !== propertyName || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.initializer !== initializer) {
383+
return updateNode(createBindingElement(propertyName, dotDotDotToken, name, initializer, node), node);
384384
}
385385
return node;
386386
}
@@ -1635,7 +1635,7 @@ namespace ts {
16351635
// flag and setting a parent node.
16361636
const react = createIdentifier(reactNamespace || "React");
16371637
react.flags &= ~NodeFlags.Synthesized;
1638-
// Set the parent that is in parse tree
1638+
// Set the parent that is in parse tree
16391639
// this makes sure that parent chain is intact for checker to traverse complete scope tree
16401640
react.parent = getParseTreeNode(parent);
16411641
return react;

src/compiler/transformers/destructuring.ts

Lines changed: 745 additions & 13 deletions
Large diffs are not rendered by default.

src/compiler/transformers/esnext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ namespace ts {
105105
* @param node A BinaryExpression node.
106106
*/
107107
function visitBinaryExpression(node: BinaryExpression): Expression {
108-
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.AssertESNext) {
108+
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsESNext) {
109109
return flattenDestructuringAssignment(context, node, /*needsDestructuringValue*/ true, hoistVariableDeclaration, visitor, /*transformRest*/ true);
110110
}
111111

src/compiler/types.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,16 +1175,18 @@ namespace ts {
11751175
right: Expression;
11761176
}
11771177

1178-
export interface AssignmentExpression extends BinaryExpression {
1178+
export type AssignmentOperatorToken = Token<AssignmentOperator>;
1179+
1180+
export interface AssignmentExpression<TOperator extends AssignmentOperatorToken> extends BinaryExpression {
11791181
left: LeftHandSideExpression;
1180-
operatorToken: Token<SyntaxKind.EqualsToken>;
1182+
operatorToken: TOperator;
11811183
}
11821184

1183-
export interface ObjectDestructuringAssignment extends AssignmentExpression {
1185+
export interface ObjectDestructuringAssignment extends AssignmentExpression<EqualsToken> {
11841186
left: ObjectLiteralExpression;
11851187
}
11861188

1187-
export interface ArrayDestructuringAssignment extends AssignmentExpression {
1189+
export interface ArrayDestructuringAssignment extends AssignmentExpression<EqualsToken> {
11881190
left: ArrayLiteralExpression;
11891191
}
11901192

src/compiler/utilities.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,19 +3125,21 @@ namespace ts {
31253125
}
31263126
}
31273127

3128-
export function isAssignmentExpression(node: Node): node is AssignmentExpression {
3128+
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
3129+
export function isAssignmentExpression(node: Node, excludeCompoundAssignment?: false): node is AssignmentExpression<AssignmentOperatorToken>;
3130+
export function isAssignmentExpression(node: Node, excludeCompoundAssignment?: boolean): node is AssignmentExpression<AssignmentOperatorToken> {
31293131
return isBinaryExpression(node)
3130-
&& isAssignmentOperator(node.operatorToken.kind)
3132+
&& (excludeCompoundAssignment
3133+
? node.operatorToken.kind === SyntaxKind.EqualsToken
3134+
: isAssignmentOperator(node.operatorToken.kind))
31313135
&& isLeftHandSideExpression(node.left);
31323136
}
31333137

31343138
export function isDestructuringAssignment(node: Node): node is DestructuringAssignment {
3135-
if (isBinaryExpression(node)) {
3136-
if (node.operatorToken.kind === SyntaxKind.EqualsToken) {
3137-
const kind = node.left.kind;
3138-
return kind === SyntaxKind.ObjectLiteralExpression
3139-
|| kind === SyntaxKind.ArrayLiteralExpression;
3140-
}
3139+
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
3140+
const kind = node.left.kind;
3141+
return kind === SyntaxKind.ObjectLiteralExpression
3142+
|| kind === SyntaxKind.ArrayLiteralExpression;
31413143
}
31423144

31433145
return false;
@@ -3918,6 +3920,14 @@ namespace ts {
39183920

39193921
// Binding patterns
39203922

3923+
export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern {
3924+
return node.kind === SyntaxKind.ArrayBindingPattern;
3925+
}
3926+
3927+
export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern {
3928+
return node.kind === SyntaxKind.ObjectBindingPattern;
3929+
}
3930+
39213931
export function isBindingPattern(node: Node): node is BindingPattern {
39223932
if (node) {
39233933
const kind = node.kind;

src/compiler/visitor.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ namespace ts {
701701
return updateParameter(<ParameterDeclaration>node,
702702
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
703703
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
704+
(<ParameterDeclaration>node).dotDotDotToken,
704705
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
705706
visitNode((<ParameterDeclaration>node).type, visitor, isTypeNode, /*optional*/ true),
706707
visitNode((<ParameterDeclaration>node).initializer, visitor, isExpression, /*optional*/ true));
@@ -767,6 +768,7 @@ namespace ts {
767768

768769
case SyntaxKind.BindingElement:
769770
return updateBindingElement(<BindingElement>node,
771+
(<BindingElement>node).dotDotDotToken,
770772
visitNode((<BindingElement>node).propertyName, visitor, isPropertyName, /*optional*/ true),
771773
visitNode((<BindingElement>node).name, visitor, isBindingName),
772774
visitNode((<BindingElement>node).initializer, visitor, isExpression, /*optional*/ true));
@@ -1287,13 +1289,41 @@ namespace ts {
12871289
? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`)
12881290
: noop;
12891291

1292+
export const assertEachNode = shouldAssert(AssertionLevel.Normal)
1293+
? (nodes: Node[], test: (node: Node) => boolean, message?: string) => assert(
1294+
test === undefined || every(nodes, test),
1295+
message || "Unexpected node.",
1296+
() => `Node array did not pass test '${getFunctionName(test)}'.`)
1297+
: noop;
1298+
12901299
export const assertNode = shouldAssert(AssertionLevel.Normal)
12911300
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
12921301
test === undefined || test(node),
12931302
message || "Unexpected node.",
12941303
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
12951304
: noop;
12961305

1306+
export const assertOptionalNode = shouldAssert(AssertionLevel.Normal)
1307+
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
1308+
test === undefined || node === undefined || test(node),
1309+
message || "Unexpected node.",
1310+
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
1311+
: noop;
1312+
1313+
export const assertOptionalToken = shouldAssert(AssertionLevel.Normal)
1314+
? (node: Node, kind: SyntaxKind, message?: string) => assert(
1315+
kind === undefined || node === undefined || node.kind === kind,
1316+
message || "Unexpected node.",
1317+
() => `Node ${formatSyntaxKind(node.kind)} was not a '${formatSyntaxKind(kind)}' token.`)
1318+
: noop;
1319+
1320+
export const assertMissingNode = shouldAssert(AssertionLevel.Normal)
1321+
? (node: Node, message?: string) => assert(
1322+
node === undefined,
1323+
message || "Unexpected node.",
1324+
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`)
1325+
: noop;
1326+
12971327
function getFunctionName(func: Function) {
12981328
if (typeof func !== "function") {
12991329
return "";

0 commit comments

Comments
 (0)