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