Skip to content

Commit 98e192f

Browse files
committed
Move transformFunctionBody back into es2015
1 parent dff9849 commit 98e192f

9 files changed

+1404
-1474
lines changed

src/compiler/factory.ts

Lines changed: 11 additions & 550 deletions
Large diffs are not rendered by default.

src/compiler/transformers/es2015.ts

Lines changed: 511 additions & 7 deletions
Large diffs are not rendered by default.

src/compiler/transformers/es2016.ts

Lines changed: 52 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,84 +17,75 @@ namespace ts {
1717
}
1818

1919
function visitor(node: Node): VisitResult<Node> {
20-
if (node.transformFlags & TransformFlags.ES2016) {
21-
return visitorWorker(node);
22-
}
23-
else if (node.transformFlags & TransformFlags.ContainsES2016) {
24-
return visitEachChild(node, visitor, context);
25-
}
26-
else {
20+
if ((node.transformFlags & TransformFlags.ContainsES2016) === 0) {
2721
return node;
2822
}
29-
}
30-
31-
function visitorWorker(node: Node): VisitResult<Node> {
3223
switch (node.kind) {
3324
case SyntaxKind.BinaryExpression:
3425
return visitBinaryExpression(<BinaryExpression>node);
3526
default:
36-
Debug.failBadSyntaxKind(node);
3727
return visitEachChild(node, visitor, context);
3828
}
3929
}
4030

4131
function visitBinaryExpression(node: BinaryExpression): Expression {
42-
// We are here because ES2016 adds support for the exponentiation operator.
32+
switch (node.operatorToken.kind) {
33+
case SyntaxKind.AsteriskAsteriskEqualsToken:
34+
return visitExponentiationAssignmentExpression(node);
35+
case SyntaxKind.AsteriskAsteriskToken:
36+
return visitExponentiationExpression(node);
37+
default:
38+
return visitEachChild(node, visitor, context);
39+
}
40+
}
41+
42+
function visitExponentiationAssignmentExpression(node: BinaryExpression) {
43+
let target: Expression;
44+
let value: Expression;
4345
const left = visitNode(node.left, visitor, isExpression);
4446
const right = visitNode(node.right, visitor, isExpression);
45-
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
46-
let target: Expression;
47-
let value: Expression;
48-
if (isElementAccessExpression(left)) {
49-
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
50-
const expressionTemp = createTempVariable(hoistVariableDeclaration);
51-
52-
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
53-
54-
target = createElementAccess(
55-
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
56-
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
57-
/*location*/ left
58-
);
59-
60-
value = createElementAccess(
61-
expressionTemp,
62-
argumentExpressionTemp,
63-
/*location*/ left
64-
);
65-
}
66-
else if (isPropertyAccessExpression(left)) {
67-
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
68-
const expressionTemp = createTempVariable(hoistVariableDeclaration);
69-
70-
target = createPropertyAccess(
71-
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
72-
left.name,
73-
/*location*/ left
74-
);
75-
76-
value = createPropertyAccess(
77-
expressionTemp,
78-
left.name,
79-
/*location*/ left
80-
);
81-
}
82-
else {
83-
// Transforms `a **= b` into `a = Math.pow(a, b)`
84-
target = left;
85-
value = left;
86-
}
87-
88-
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
47+
if (isElementAccessExpression(left)) {
48+
// Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
49+
const expressionTemp = createTempVariable(hoistVariableDeclaration);
50+
const argumentExpressionTemp = createTempVariable(hoistVariableDeclaration);
51+
target = createElementAccess(
52+
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
53+
createAssignment(argumentExpressionTemp, left.argumentExpression, /*location*/ left.argumentExpression),
54+
/*location*/ left
55+
);
56+
value = createElementAccess(
57+
expressionTemp,
58+
argumentExpressionTemp,
59+
/*location*/ left
60+
);
8961
}
90-
else if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskToken) {
91-
// Transforms `a ** b` into `Math.pow(a, b)`
92-
return createMathPow(left, right, /*location*/ node);
62+
else if (isPropertyAccessExpression(left)) {
63+
// Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
64+
const expressionTemp = createTempVariable(hoistVariableDeclaration);
65+
target = createPropertyAccess(
66+
createAssignment(expressionTemp, left.expression, /*location*/ left.expression),
67+
left.name,
68+
/*location*/ left
69+
);
70+
value = createPropertyAccess(
71+
expressionTemp,
72+
left.name,
73+
/*location*/ left
74+
);
9375
}
9476
else {
95-
Debug.failBadSyntaxKind(node);
96-
return visitEachChild(node, visitor, context);
77+
// Transforms `a **= b` into `a = Math.pow(a, b)`
78+
target = left;
79+
value = left;
9780
}
81+
return createAssignment(target, createMathPow(value, right, /*location*/ node), /*location*/ node);
82+
}
83+
84+
function visitExponentiationExpression(node: BinaryExpression) {
85+
// Transforms `a ** b` into `Math.pow(a, b)`
86+
const left = visitNode(node.left, visitor, isExpression);
87+
const right = visitNode(node.right, visitor, isExpression);
88+
return createMathPow(left, right, /*location*/ node);
9889
}
9990
}
10091
}

src/compiler/transformers/esnext.ts

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,38 @@ namespace ts {
77
const {
88
endLexicalEnvironment
99
} = context;
10-
let currentSourceFile: SourceFile;
1110
return transformSourceFile;
1211

1312
function transformSourceFile(node: SourceFile) {
14-
currentSourceFile = node;
1513
return visitEachChild(node, visitor, context);
1614
}
1715

1816
function visitor(node: Node): VisitResult<Node> {
19-
if (node.transformFlags & TransformFlags.ESNext) {
20-
return visitorWorker(node);
21-
}
22-
else if (node.transformFlags & TransformFlags.ContainsESNext) {
23-
return visitNodeContainingESNext(node);
24-
}
25-
else {
17+
return visitorWorker(node, /*noDestructuringValue*/ false);
18+
}
19+
20+
function visitorNoDestructuringValue(node: Node): VisitResult<Node> {
21+
return visitorWorker(node, /*noDestructuringValue*/ true);
22+
}
23+
24+
function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult<Node> {
25+
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
2626
return node;
2727
}
28-
}
2928

30-
function visitorWorker(node: Node): VisitResult<Node> {
3129
switch (node.kind) {
3230
case SyntaxKind.ObjectLiteralExpression:
3331
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
3432
case SyntaxKind.BinaryExpression:
35-
return visitBinaryExpression(node as BinaryExpression, /*needsDestructuringValue*/ true);
33+
return visitBinaryExpression(node as BinaryExpression, noDestructuringValue);
3634
case SyntaxKind.VariableDeclaration:
3735
return visitVariableDeclaration(node as VariableDeclaration);
3836
case SyntaxKind.ForOfStatement:
3937
return visitForOfStatement(node as ForOfStatement);
40-
case SyntaxKind.ObjectBindingPattern:
41-
case SyntaxKind.ArrayBindingPattern:
42-
return node;
38+
case SyntaxKind.ForStatement:
39+
return visitForStatement(node as ForStatement);
40+
case SyntaxKind.VoidExpression:
41+
return visitVoidExpression(node as VoidExpression);
4342
case SyntaxKind.Constructor:
4443
return visitConstructorDeclaration(node as ConstructorDeclaration);
4544
case SyntaxKind.MethodDeclaration:
@@ -56,20 +55,13 @@ namespace ts {
5655
return visitArrowFunction(node as ArrowFunction);
5756
case SyntaxKind.Parameter:
5857
return visitParameter(node as ParameterDeclaration);
59-
default:
60-
Debug.failBadSyntaxKind(node);
61-
return visitEachChild(node, visitor, context);
62-
}
63-
}
64-
65-
function visitNodeContainingESNext(node: Node) {
66-
switch (node.kind) {
6758
case SyntaxKind.ExpressionStatement:
6859
return visitExpressionStatement(node as ExpressionStatement);
6960
case SyntaxKind.ParenthesizedExpression:
70-
return visitParenthesizedExpression(node as ParenthesizedExpression, /*needsDestructuringValue*/ true);
61+
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
62+
default:
63+
return visitEachChild(node, visitor, context);
7164
}
72-
return visitEachChild(node, visitor, context);
7365
}
7466

7567
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
@@ -105,56 +97,52 @@ namespace ts {
10597
}
10698

10799
function visitObjectLiteralExpression(node: ObjectLiteralExpression): Expression {
108-
// spread elements emit like so:
109-
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
110-
// { a, ...o, b } => __assign({a}, o, {b});
111-
// If the first element is a spread element, then the first argument to __assign is {}:
112-
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
113-
const objects = chunkObjectLiteralElements(node.properties);
114-
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
115-
objects.unshift(createObjectLiteral());
100+
if (node.transformFlags & TransformFlags.ContainsObjectSpread) {
101+
// spread elements emit like so:
102+
// non-spread elements are chunked together into object literals, and then all are passed to __assign:
103+
// { a, ...o, b } => __assign({a}, o, {b});
104+
// If the first element is a spread element, then the first argument to __assign is {}:
105+
// { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2)
106+
const objects = chunkObjectLiteralElements(node.properties);
107+
if (objects.length && objects[0].kind !== SyntaxKind.ObjectLiteralExpression) {
108+
objects.unshift(createObjectLiteral());
109+
}
110+
return createCall(createIdentifier("__assign"), undefined, objects);
116111
}
117-
return createCall(createIdentifier("__assign"), undefined, objects);
112+
return visitEachChild(node, visitor, context);
118113
}
119114

120115
function visitExpressionStatement(node: ExpressionStatement): ExpressionStatement {
121-
switch (node.expression.kind) {
122-
case SyntaxKind.ParenthesizedExpression:
123-
return updateStatement(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
124-
case SyntaxKind.BinaryExpression:
125-
return updateStatement(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
126-
}
127-
return visitEachChild(node, visitor, context);
116+
return visitEachChild(node, visitorNoDestructuringValue, context);
128117
}
129118

130-
function visitParenthesizedExpression(node: ParenthesizedExpression, needsDestructuringValue: boolean): ParenthesizedExpression {
131-
if (!needsDestructuringValue) {
132-
switch (node.expression.kind) {
133-
case SyntaxKind.ParenthesizedExpression:
134-
return updateParen(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
135-
case SyntaxKind.BinaryExpression:
136-
return updateParen(node, visitBinaryExpression(<BinaryExpression>node.expression, /*needsDestructuringValue*/ false));
137-
}
138-
}
139-
return visitEachChild(node, visitor, context);
119+
function visitParenthesizedExpression(node: ParenthesizedExpression, noDestructuringValue: boolean): ParenthesizedExpression {
120+
return visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
140121
}
141122

142123
/**
143124
* Visits a BinaryExpression that contains a destructuring assignment.
144125
*
145126
* @param node A BinaryExpression node.
146127
*/
147-
function visitBinaryExpression(node: BinaryExpression, needsDestructuringValue: boolean): Expression {
128+
function visitBinaryExpression(node: BinaryExpression, noDestructuringValue: boolean): Expression {
148129
if (isDestructuringAssignment(node) && node.left.transformFlags & TransformFlags.ContainsObjectRest) {
149130
return flattenDestructuringAssignment(
150131
context,
151132
node,
152-
needsDestructuringValue,
133+
!noDestructuringValue,
153134
FlattenLevel.ObjectRest,
154135
/*createAssignmentCallback*/ undefined,
155136
visitor
156137
);
157138
}
139+
else if (node.operatorToken.kind === SyntaxKind.CommaToken) {
140+
return updateBinary(
141+
node,
142+
visitNode(node.left, visitorNoDestructuringValue, isExpression),
143+
visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, isExpression)
144+
);
145+
}
158146
return visitEachChild(node, visitor, context);
159147
}
160148

@@ -178,6 +166,20 @@ namespace ts {
178166
return visitEachChild(node, visitor, context);
179167
}
180168

169+
function visitForStatement(node: ForStatement): VisitResult<Statement> {
170+
return updateFor(
171+
node,
172+
visitNode(node.initializer, visitorNoDestructuringValue, isForInitializer),
173+
visitNode(node.condition, visitor, isExpression),
174+
visitNode(node.incrementor, visitor, isExpression),
175+
visitNode(node.statement, visitor, isStatement)
176+
);
177+
}
178+
179+
function visitVoidExpression(node: VoidExpression) {
180+
return visitEachChild(node, visitorNoDestructuringValue, context);
181+
}
182+
181183
/**
182184
* Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
183185
*

0 commit comments

Comments
 (0)