• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}