1/* @internal */ 2namespace ts { 3 export function createNodeConverters(factory: NodeFactory): NodeConverters { 4 return { 5 convertToFunctionBlock, 6 convertToFunctionExpression, 7 convertToArrayAssignmentElement, 8 convertToObjectAssignmentElement, 9 convertToAssignmentPattern, 10 convertToObjectAssignmentPattern, 11 convertToArrayAssignmentPattern, 12 convertToAssignmentElementTarget, 13 }; 14 15 function convertToFunctionBlock(node: ConciseBody, multiLine?: boolean): Block { 16 if (isBlock(node)) return node; 17 const returnStatement = factory.createReturnStatement(node); 18 setTextRange(returnStatement, node); 19 const body = factory.createBlock([returnStatement], multiLine); 20 setTextRange(body, node); 21 return body; 22 } 23 24 function convertToFunctionExpression(node: FunctionDeclaration) { 25 if (!node.body) return Debug.fail(`Cannot convert a FunctionDeclaration without a body`); 26 const updated = factory.createFunctionExpression( 27 node.modifiers, 28 node.asteriskToken, 29 node.name, 30 node.typeParameters, 31 node.parameters, 32 node.type, 33 node.body 34 ); 35 setOriginalNode(updated, node); 36 setTextRange(updated, node); 37 if (getStartsOnNewLine(node)) { 38 setStartsOnNewLine(updated, /*newLine*/ true); 39 } 40 return updated; 41 } 42 43 function convertToArrayAssignmentElement(element: ArrayBindingOrAssignmentElement) { 44 if (isBindingElement(element)) { 45 if (element.dotDotDotToken) { 46 Debug.assertNode(element.name, isIdentifier); 47 return setOriginalNode(setTextRange(factory.createSpreadElement(element.name), element), element); 48 } 49 const expression = convertToAssignmentElementTarget(element.name); 50 return element.initializer 51 ? setOriginalNode( 52 setTextRange( 53 factory.createAssignment(expression, element.initializer), 54 element 55 ), 56 element 57 ) 58 : expression; 59 } 60 return cast(element, isExpression); 61 } 62 63 function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) { 64 if (isBindingElement(element)) { 65 if (element.dotDotDotToken) { 66 Debug.assertNode(element.name, isIdentifier); 67 return setOriginalNode(setTextRange(factory.createSpreadAssignment(element.name), element), element); 68 } 69 if (element.propertyName) { 70 const expression = convertToAssignmentElementTarget(element.name); 71 return setOriginalNode(setTextRange(factory.createPropertyAssignment(element.propertyName, element.initializer ? factory.createAssignment(expression, element.initializer) : expression), element), element); 72 } 73 Debug.assertNode(element.name, isIdentifier); 74 return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); 75 } 76 77 return cast(element, isObjectLiteralElementLike); 78 } 79 80 function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { 81 switch (node.kind) { 82 case SyntaxKind.ArrayBindingPattern: 83 case SyntaxKind.ArrayLiteralExpression: 84 return convertToArrayAssignmentPattern(node); 85 86 case SyntaxKind.ObjectBindingPattern: 87 case SyntaxKind.ObjectLiteralExpression: 88 return convertToObjectAssignmentPattern(node); 89 } 90 } 91 92 function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) { 93 if (isObjectBindingPattern(node)) { 94 return setOriginalNode( 95 setTextRange( 96 factory.createObjectLiteralExpression(map(node.elements, convertToObjectAssignmentElement)), 97 node 98 ), 99 node 100 ); 101 } 102 return cast(node, isObjectLiteralExpression); 103 } 104 105 function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) { 106 if (isArrayBindingPattern(node)) { 107 return setOriginalNode( 108 setTextRange( 109 factory.createArrayLiteralExpression(map(node.elements, convertToArrayAssignmentElement)), 110 node 111 ), 112 node 113 ); 114 } 115 return cast(node, isArrayLiteralExpression); 116 } 117 118 function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression { 119 if (isBindingPattern(node)) { 120 return convertToAssignmentPattern(node); 121 } 122 123 return cast(node, isExpression); 124 } 125 } 126 127 export const nullNodeConverters: NodeConverters = { 128 convertToFunctionBlock: notImplemented, 129 convertToFunctionExpression: notImplemented, 130 convertToArrayAssignmentElement: notImplemented, 131 convertToObjectAssignmentElement: notImplemented, 132 convertToAssignmentPattern: notImplemented, 133 convertToObjectAssignmentPattern: notImplemented, 134 convertToArrayAssignmentPattern: notImplemented, 135 convertToAssignmentElementTarget: notImplemented, 136 }; 137}