@@ -152,7 +152,7 @@ namespace ts {
152152 /**
153153 * Creates a shallow, memberwise clone of a node for mutation.
154154 */
155- export function getMutableNode < T extends Node > ( node : T ) : T {
155+ export function getMutableClone < T extends Node > ( node : T ) : T {
156156 return cloneNode ( node , /*location*/ node , node . flags , /*parent*/ undefined , /*original*/ node ) ;
157157 }
158158
@@ -320,15 +320,21 @@ namespace ts {
320320
321321 // Expression
322322
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 ) ;
325325 node . elements = parenthesizeListElements ( createNodeArray ( elements ) ) ;
326+ if ( multiLine ) {
327+ node . multiLine = multiLine ;
328+ }
326329 return node ;
327330 }
328331
329- export function createObjectLiteral ( properties ?: ObjectLiteralElement [ ] , location ?: TextRange ) {
332+ export function createObjectLiteral ( properties ?: ObjectLiteralElement [ ] , location ?: TextRange , multiLine ?: boolean ) {
330333 const node = < ObjectLiteralExpression > createNode ( SyntaxKind . ObjectLiteralExpression , location ) ;
331334 node . properties = createNodeArray ( properties ) ;
335+ if ( multiLine ) {
336+ node . multiLine = multiLine ;
337+ }
332338 return node ;
333339 }
334340
@@ -356,7 +362,7 @@ namespace ts {
356362
357363 export function createNew ( expression : Expression , argumentsArray : Expression [ ] , location ?: TextRange ) {
358364 const node = < NewExpression > createNode ( SyntaxKind . NewExpression , location ) ;
359- node . expression = parenthesizeForAccess ( expression ) ;
365+ node . expression = parenthesizeForNew ( expression ) ;
360366 node . arguments = argumentsArray
361367 ? parenthesizeListElements ( createNodeArray ( argumentsArray ) )
362368 : undefined ;
@@ -369,7 +375,7 @@ namespace ts {
369375 return node ;
370376 }
371377
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 ) {
373379 const node = < FunctionExpression > createNode ( SyntaxKind . FunctionExpression , location ) ;
374380 node . modifiers = undefined ;
375381 node . asteriskToken = asteriskToken ;
@@ -378,6 +384,10 @@ namespace ts {
378384 node . parameters = createNodeArray ( parameters ) ;
379385 node . type = undefined ;
380386 node . body = body ;
387+ if ( original ) {
388+ node . original = original ;
389+ }
390+
381391 return node ;
382392 }
383393
@@ -468,9 +478,12 @@ namespace ts {
468478
469479 // Element
470480
471- export function createBlock ( statements : Statement [ ] , location ?: TextRange ) : Block {
481+ export function createBlock ( statements : Statement [ ] , location ?: TextRange , multiLine ?: boolean ) : Block {
472482 const block = < Block > createNode ( SyntaxKind . Block , location ) ;
473483 block . statements = createNodeArray ( statements ) ;
484+ if ( multiLine ) {
485+ block . multiLine = true ;
486+ }
474487 return block ;
475488 }
476489
@@ -573,7 +586,7 @@ namespace ts {
573586 return node ;
574587 }
575588
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 ) {
577590 const node = < FunctionDeclaration > createNode ( SyntaxKind . FunctionDeclaration , location ) ;
578591 node . decorators = undefined ;
579592 setModifiers ( node , modifiers ) ;
@@ -583,6 +596,9 @@ namespace ts {
583596 node . parameters = createNodeArray ( parameters ) ;
584597 node . type = undefined ;
585598 node . body = body ;
599+ if ( original ) {
600+ node . original = original ;
601+ }
586602 return node ;
587603 }
588604
@@ -1068,6 +1084,68 @@ namespace ts {
10681084 ) ;
10691085 }
10701086
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+
10711149 export function inlineExpressions ( expressions : Expression [ ] ) {
10721150 return reduceLeft ( expressions , createComma ) ;
10731151 }
@@ -1206,6 +1284,23 @@ namespace ts {
12061284 || binaryOperator === SyntaxKind . CaretToken ;
12071285 }
12081286
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+
12091304 /**
12101305 * Wraps an expression in parentheses if it is needed in order to use the expression for
12111306 * property or element access.
0 commit comments