Skip to content

Commit f4a07a0

Browse files
committed
return-multiple-node - Add docs for returning multiple nodes and adding sibling
1 parent a9101ed commit f4a07a0

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

translations/en/transformer-handbook.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,11 +1086,61 @@ if (ts.isFunctionDeclaration(node)) {
10861086
10871087
#### Replacing a node with multiple nodes
10881088

1089-
> **TODO** - Is this possible?
1089+
Interestingly, a visitor function can also return a array of nodes instead of just one node.
1090+
That means, even though it gets one node as input, it can return multiple nodes which replaces that input node.
1091+
1092+
```ts
1093+
export type Visitor = (node: Node) => VisitResult<Node>;
1094+
export type VisitResult<T extends Node> = T | T[] | undefined;
1095+
```
1096+
1097+
Let's just replace every expression statement with two copies of the same statement (duplicating it) -
1098+
1099+
```ts
1100+
const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
1101+
return sourceFile => {
1102+
const visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
1103+
// If it is a expression statement,
1104+
if (ts.isExpressionStatement(node)) {
1105+
// Clone it
1106+
const newNode = ts.getMutableClone(node);
1107+
// And return it twice.
1108+
// Effectively duplicating the statement
1109+
return [node, newNode];
1110+
}
1111+
1112+
return ts.visitEachChild(node, visitor, context);
1113+
};
1114+
1115+
return ts.visitNode(sourceFile, visitor);
1116+
};
1117+
};
1118+
```
1119+
So,
1120+
1121+
```ts
1122+
let a = 1;
1123+
a = 2;
1124+
```
1125+
1126+
becomes
1127+
1128+
```js
1129+
let a = 1;
1130+
a = 2;
1131+
a = 2;
1132+
```
1133+
1134+
The declaration statement (first line) is ignored as it's not a `ExpressionStatement`.
1135+
1136+
*Note* - Make sure that what you are trying to do actually makes sense in the AST. For ex., returning two expressions instead of one is often just invalid.
1137+
1138+
Say there is a assignment expression (BinaryExpression with with EqualToken operator), `a = b = 2`. Now returning two nodes instead of `b = 2` expression is invalid (because right hand side can not be multiple nodes). So, TS will throw an error - `Debug Failure. False expression: Too many nodes written to output.`
1139+
10901140

10911141
#### Inserting a sibling node
10921142

1093-
> **TODO** - Is this possible?
1143+
This is effectively same as the [previous section](#replacing-a-node-with-multiple-nodes). Just return a array of nodes including itself and other sibling nodes.
10941144

10951145
#### Removing a node
10961146

0 commit comments

Comments
 (0)