diff --git a/example/src/routeInfo.tsx b/example/src/routeInfo.tsx
index 2b27679..127a7e8 100644
--- a/example/src/routeInfo.tsx
+++ b/example/src/routeInfo.tsx
@@ -7,10 +7,22 @@ export default () => (
+ ,
+
+
+ ,
+
+
,
+ {/*
+ ,
+ */}
- Swap expression
+ log-identifiers
+ return-multiple-node
+ swap-expression
+ {/* rename-symbol */}
diff --git a/example/src/transforms/index.ts b/example/src/transforms/index.ts
index 8004532..9e382f0 100644
--- a/example/src/transforms/index.ts
+++ b/example/src/transforms/index.ts
@@ -1,8 +1,18 @@
+import LogIdentifiers from "./log-identifiers";
+import ReturnMultipleNode from "./return-multiple-node";
import SwapExpression from "./swap-expression";
+// import RenameSymbol from "./rename-symbol";
import { TransformModuleExport } from "src/types";
-export type ModuleNames = "swap-expression";
+export type ModuleNames =
+ | "swap-expression"
+ | "return-multiple-node"
+ | "log-identifiers";
+ // | "rename-symbol"
export const moduleMap: { [key in ModuleNames]: TransformModuleExport } = {
- "swap-expression": SwapExpression
+ "swap-expression": SwapExpression,
+ "return-multiple-node": ReturnMultipleNode,
+ "log-identifiers": LogIdentifiers,
+ // "rename-symbol": RenameSymbol
};
diff --git a/example/src/transforms/log-identifiers.ts b/example/src/transforms/log-identifiers.ts
new file mode 100644
index 0000000..2ac77f3
--- /dev/null
+++ b/example/src/transforms/log-identifiers.ts
@@ -0,0 +1,32 @@
+import * as ts from "typescript";
+import { TransformModuleExport } from "../types";
+
+const sourceCodeString = `\
+let foo = 1, bar = 2;
+foo = bar;
+{
+ bar++;
+ "bar"
+ function() {console.log(bar)}
+}
+`;
+
+const transformer: ts.TransformerFactory = context => {
+ return sourceFile => {
+ const visitor = (node: ts.Node): ts.Node => {
+ if (ts.isIdentifier(node)) {
+ console.log(node.text);
+ }
+ return ts.visitEachChild(node, visitor, context);
+ };
+
+ return ts.visitNode(sourceFile, visitor);
+ };
+};
+
+const toExport: TransformModuleExport = {
+ sourceCodeString,
+ transformer,
+};
+
+export default toExport;
diff --git a/example/src/transforms/rename-symbol.ts b/example/src/transforms/rename-symbol.ts
new file mode 100644
index 0000000..ba071c9
--- /dev/null
+++ b/example/src/transforms/rename-symbol.ts
@@ -0,0 +1,96 @@
+import * as ts from "typescript";
+import { TransformModuleExport } from "../types";
+
+const sourceCodeString = `\
+let foo = 1;
+foo = 2;
+{
+ const foo = "abcd";
+}
+foo = 3;
+`;
+
+// Renames all references to the first identifier with the text "foo"
+const identifierText = "foo";
+const identifierMatchIndex = 1;
+const newIdentifierText = "bar";
+
+const transformerProgram = (program: ts.Program) => {
+ const typeChecker = program.getTypeChecker();
+
+ const transformerFactory: ts.TransformerFactory = context => {
+ return sourceFile => {
+ // 1. Find the symbol, if any
+ let identifierCurrentIndex = -1;
+ const findSymbolVisitor = (node: ts.Node): ts.Symbol | undefined => {
+ if (ts.isIdentifier(node)) {
+ const relatedSymbol = typeChecker.getSymbolAtLocation(node);
+
+ if (relatedSymbol === undefined) {
+ return;
+ }
+ console.log(relatedSymbol.escapedName);
+ if (relatedSymbol.escapedName === identifierText) {
+ identifierCurrentIndex += 1;
+ if (identifierCurrentIndex === identifierMatchIndex) {
+ console.log("found");
+ return relatedSymbol;
+ }
+ }
+ }
+
+ return ts.forEachChild(node, findSymbolVisitor);
+ };
+
+ // 2. Mark the identifiers, if any
+ const foundIdentifiers = new Array();
+ const findIdentifiersVisitor = (node: ts.Node): true | undefined => {
+ if (ts.isIdentifier(node)) {
+ const relatedSymbol = typeChecker.getSymbolAtLocation(node);
+
+ if (relatedSymbol === foundSymbol) {
+ foundIdentifiers.push(node);
+ // Stop finding
+ return true;
+ }
+ }
+
+ ts.forEachChild(node, findIdentifiersVisitor);
+ return undefined;
+ };
+
+ // 3. Modify the identifiers
+ const modifyIdentifiersVisitor = (node: ts.Node): ts.Node => {
+ if (ts.isIdentifier(node) && foundIdentifiers.includes(node)) {
+ return ts.updateIdentifier(ts.createIdentifier(newIdentifierText));
+ }
+
+ return ts.visitEachChild(node, modifyIdentifiersVisitor, context);
+ };
+
+ // Execute step 1
+ const foundSymbol = ts.forEachChild(sourceFile, findSymbolVisitor);
+
+ // Execute step 2, if step 1 passed
+ if (foundSymbol) {
+ ts.forEachChild(sourceFile, findIdentifiersVisitor);
+ }
+
+ // Execute step 3, if step 2 passed
+ if (foundIdentifiers.length > 0) {
+ return ts.visitNode(sourceFile, modifyIdentifiersVisitor);
+ }
+
+ return sourceFile;
+ };
+ };
+
+ return transformerFactory;
+};
+
+const toExport: TransformModuleExport = {
+ sourceCodeString,
+ transformer: transformerProgram
+};
+
+export default toExport;
diff --git a/example/src/transforms/return-multiple-node.ts b/example/src/transforms/return-multiple-node.ts
new file mode 100644
index 0000000..f618552
--- /dev/null
+++ b/example/src/transforms/return-multiple-node.ts
@@ -0,0 +1,32 @@
+import * as ts from "typescript";
+import { TransformModuleExport } from "../types";
+
+const sourceCodeString = `\
+let a = 1;
+a = 2;
+a++;
+`;
+
+const transformer: ts.TransformerFactory = context => {
+ return sourceFile => {
+ const visitor = (node: ts.Node): ts.VisitResult => {
+ // If it is a expression statement,
+ if (ts.isExpressionStatement(node)) {
+ // Return it twice.
+ // Effectively duplicating the statement
+ return [node, node];
+ }
+
+ return ts.visitEachChild(node, visitor, context);
+ };
+
+ return ts.visitNode(sourceFile, visitor);
+ };
+};
+
+const toExport: TransformModuleExport = {
+ sourceCodeString,
+ transformer,
+};
+
+export default toExport;
diff --git a/example/src/transforms/swap-expression.ts b/example/src/transforms/swap-expression.ts
index d00a2e3..e6163da 100644
--- a/example/src/transforms/swap-expression.ts
+++ b/example/src/transforms/swap-expression.ts
@@ -1,7 +1,7 @@
import * as ts from "typescript";
import { TransformModuleExport } from "../types";
-const sourceCodeString = `x = y; a = b + c`;
+const sourceCodeString = `x = y; a = b + c;`;
const transformer: ts.TransformerFactory = context => {
return sourceFile => {