@@ -152,7 +152,7 @@ namespace ts {
152
152
/**
153
153
* Creates a shallow, memberwise clone of a node for mutation.
154
154
*/
155
- export function getMutableNode < T extends Node > ( node : T ) : T {
155
+ export function getMutableClone < T extends Node > ( node : T ) : T {
156
156
return cloneNode ( node , /*location*/ node , node . flags , /*parent*/ undefined , /*original*/ node ) ;
157
157
}
158
158
@@ -320,15 +320,21 @@ namespace ts {
320
320
321
321
// Expression
322
322
323
- export function createArrayLiteral ( elements ?: Expression [ ] ) {
324
- const node = < ArrayLiteralExpression > createNode ( SyntaxKind . ArrayLiteralExpression ) ;
323
+ export function createArrayLiteral ( elements ?: Expression [ ] , location ?: TextRange , multiLine ?: boolean ) {
324
+ const node = < ArrayLiteralExpression > createNode ( SyntaxKind . ArrayLiteralExpression , location ) ;
325
325
node . elements = parenthesizeListElements ( createNodeArray ( elements ) ) ;
326
+ if ( multiLine ) {
327
+ node . multiLine = multiLine ;
328
+ }
326
329
return node ;
327
330
}
328
331
329
- export function createObjectLiteral ( properties ?: ObjectLiteralElement [ ] , location ?: TextRange ) {
332
+ export function createObjectLiteral ( properties ?: ObjectLiteralElement [ ] , location ?: TextRange , multiLine ?: boolean ) {
330
333
const node = < ObjectLiteralExpression > createNode ( SyntaxKind . ObjectLiteralExpression , location ) ;
331
334
node . properties = createNodeArray ( properties ) ;
335
+ if ( multiLine ) {
336
+ node . multiLine = multiLine ;
337
+ }
332
338
return node ;
333
339
}
334
340
@@ -356,7 +362,7 @@ namespace ts {
356
362
357
363
export function createNew ( expression : Expression , argumentsArray : Expression [ ] , location ?: TextRange ) {
358
364
const node = < NewExpression > createNode ( SyntaxKind . NewExpression , location ) ;
359
- node . expression = parenthesizeForAccess ( expression ) ;
365
+ node . expression = parenthesizeForNew ( expression ) ;
360
366
node . arguments = argumentsArray
361
367
? parenthesizeListElements ( createNodeArray ( argumentsArray ) )
362
368
: undefined ;
@@ -369,7 +375,7 @@ namespace ts {
369
375
return node ;
370
376
}
371
377
372
- export function createFunctionExpression ( asteriskToken : Node , name : string | Identifier , parameters : ParameterDeclaration [ ] , body : Block , location ?: TextRange ) {
378
+ export function createFunctionExpression ( asteriskToken : Node , name : string | Identifier , parameters : ParameterDeclaration [ ] , body : Block , location ?: TextRange , original ?: Node ) {
373
379
const node = < FunctionExpression > createNode ( SyntaxKind . FunctionExpression , location ) ;
374
380
node . modifiers = undefined ;
375
381
node . asteriskToken = asteriskToken ;
@@ -378,6 +384,10 @@ namespace ts {
378
384
node . parameters = createNodeArray ( parameters ) ;
379
385
node . type = undefined ;
380
386
node . body = body ;
387
+ if ( original ) {
388
+ node . original = original ;
389
+ }
390
+
381
391
return node ;
382
392
}
383
393
@@ -468,9 +478,12 @@ namespace ts {
468
478
469
479
// Element
470
480
471
- export function createBlock ( statements : Statement [ ] , location ?: TextRange ) : Block {
481
+ export function createBlock ( statements : Statement [ ] , location ?: TextRange , multiLine ?: boolean ) : Block {
472
482
const block = < Block > createNode ( SyntaxKind . Block , location ) ;
473
483
block . statements = createNodeArray ( statements ) ;
484
+ if ( multiLine ) {
485
+ block . multiLine = true ;
486
+ }
474
487
return block ;
475
488
}
476
489
@@ -573,7 +586,7 @@ namespace ts {
573
586
return node ;
574
587
}
575
588
576
- export function createFunctionDeclaration ( modifiers : Modifier [ ] , asteriskToken : Node , name : string | Identifier , parameters : ParameterDeclaration [ ] , body : Block , location ?: TextRange ) {
589
+ export function createFunctionDeclaration ( modifiers : Modifier [ ] , asteriskToken : Node , name : string | Identifier , parameters : ParameterDeclaration [ ] , body : Block , location ?: TextRange , original ?: Node ) {
577
590
const node = < FunctionDeclaration > createNode ( SyntaxKind . FunctionDeclaration , location ) ;
578
591
node . decorators = undefined ;
579
592
setModifiers ( node , modifiers ) ;
@@ -583,6 +596,9 @@ namespace ts {
583
596
node . parameters = createNodeArray ( parameters ) ;
584
597
node . type = undefined ;
585
598
node . body = body ;
599
+ if ( original ) {
600
+ node . original = original ;
601
+ }
586
602
return node ;
587
603
}
588
604
@@ -1068,6 +1084,68 @@ namespace ts {
1068
1084
) ;
1069
1085
}
1070
1086
1087
+ export interface CallBinding {
1088
+ target : LeftHandSideExpression ;
1089
+ thisArg : Expression ;
1090
+ }
1091
+
1092
+ export function createCallBinding ( expression : Expression , languageVersion ?: ScriptTarget ) : CallBinding {
1093
+ const callee = skipParentheses ( expression ) ;
1094
+ let thisArg : Expression ;
1095
+ let target : LeftHandSideExpression ;
1096
+ if ( isSuperProperty ( callee ) ) {
1097
+ thisArg = createThis ( /*location*/ callee . expression ) ;
1098
+ target = callee ;
1099
+ }
1100
+ else if ( isSuperCall ( callee ) ) {
1101
+ thisArg = createThis ( /*location*/ callee ) ;
1102
+ target = languageVersion < ScriptTarget . ES6 ? createIdentifier ( "_super" , /*location*/ callee ) : callee ;
1103
+ }
1104
+ else {
1105
+ switch ( callee . kind ) {
1106
+ case SyntaxKind . PropertyAccessExpression : {
1107
+ // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
1108
+ thisArg = createTempVariable ( ) ;
1109
+ target = createPropertyAccess (
1110
+ createAssignment (
1111
+ thisArg ,
1112
+ ( < PropertyAccessExpression > callee ) . expression ,
1113
+ /*location*/ ( < PropertyAccessExpression > callee ) . expression
1114
+ ) ,
1115
+ ( < PropertyAccessExpression > callee ) . name ,
1116
+ /*location*/ callee
1117
+ ) ;
1118
+ break ;
1119
+ }
1120
+
1121
+ case SyntaxKind . ElementAccessExpression : {
1122
+ // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
1123
+ thisArg = createTempVariable ( ) ;
1124
+ target = createElementAccess (
1125
+ createAssignment (
1126
+ thisArg ,
1127
+ ( < ElementAccessExpression > callee ) . expression ,
1128
+ /*location*/ ( < ElementAccessExpression > callee ) . expression
1129
+ ) ,
1130
+ ( < ElementAccessExpression > callee ) . argumentExpression ,
1131
+ /*location*/ callee
1132
+ ) ;
1133
+
1134
+ break ;
1135
+ }
1136
+
1137
+ default : {
1138
+ // for `a()` target is `a` and thisArg is `void 0`
1139
+ thisArg = createVoidZero ( ) ;
1140
+ target = parenthesizeForAccess ( expression ) ;
1141
+ break ;
1142
+ }
1143
+ }
1144
+ }
1145
+
1146
+ return { target, thisArg } ;
1147
+ }
1148
+
1071
1149
export function inlineExpressions ( expressions : Expression [ ] ) {
1072
1150
return reduceLeft ( expressions , createComma ) ;
1073
1151
}
@@ -1206,6 +1284,23 @@ namespace ts {
1206
1284
|| binaryOperator === SyntaxKind . CaretToken ;
1207
1285
}
1208
1286
1287
+ /**
1288
+ * Wraps an expression in parentheses if it is needed in order to use the expression
1289
+ * as the expression of a NewExpression node.
1290
+ *
1291
+ * @param expression The Expression node.
1292
+ */
1293
+ export function parenthesizeForNew ( expression : Expression ) : LeftHandSideExpression {
1294
+ const lhs = parenthesizeForAccess ( expression ) ;
1295
+ switch ( lhs . kind ) {
1296
+ case SyntaxKind . CallExpression :
1297
+ case SyntaxKind . NewExpression :
1298
+ return createParen ( lhs ) ;
1299
+ }
1300
+
1301
+ return lhs ;
1302
+ }
1303
+
1209
1304
/**
1210
1305
* Wraps an expression in parentheses if it is needed in order to use the expression for
1211
1306
* property or element access.
0 commit comments