mirror of
https://github.com/bendtherules/ts-transformer-visualizer.git
synced 2026-08-18 22:01:45 +00:00
example - Add other examples and routes
This commit is contained in:
@@ -7,10 +7,22 @@ export default () => (
|
|||||||
<Router>
|
<Router>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/1">
|
<Route path="/1">
|
||||||
|
<App moduleName="log-identifiers" />,
|
||||||
|
</Route>
|
||||||
|
<Route path="/2">
|
||||||
|
<App moduleName="return-multiple-node" />,
|
||||||
|
</Route>
|
||||||
|
<Route path="/3">
|
||||||
<App moduleName="swap-expression" />,
|
<App moduleName="swap-expression" />,
|
||||||
</Route>
|
</Route>
|
||||||
|
{/* <Route path="/4">
|
||||||
|
<App moduleName="rename-symbol" />,
|
||||||
|
</Route> */}
|
||||||
<Route>
|
<Route>
|
||||||
<Link to="/1">Swap expression</Link>
|
<Link to="/1">log-identifiers</Link>
|
||||||
|
<Link to="/2">return-multiple-node</Link>
|
||||||
|
<Link to="/3">swap-expression</Link>
|
||||||
|
{/* <Link to="/4">rename-symbol</Link> */}
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</Router>
|
</Router>
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
|
import LogIdentifiers from "./log-identifiers";
|
||||||
|
import ReturnMultipleNode from "./return-multiple-node";
|
||||||
import SwapExpression from "./swap-expression";
|
import SwapExpression from "./swap-expression";
|
||||||
|
// import RenameSymbol from "./rename-symbol";
|
||||||
import { TransformModuleExport } from "src/types";
|
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 } = {
|
export const moduleMap: { [key in ModuleNames]: TransformModuleExport } = {
|
||||||
"swap-expression": SwapExpression
|
"swap-expression": SwapExpression,
|
||||||
|
"return-multiple-node": ReturnMultipleNode,
|
||||||
|
"log-identifiers": LogIdentifiers,
|
||||||
|
// "rename-symbol": RenameSymbol
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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<ts.SourceFile> = 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;
|
||||||
@@ -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<ts.SourceFile> = 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<ts.Identifier>();
|
||||||
|
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;
|
||||||
@@ -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<ts.SourceFile> = context => {
|
||||||
|
return sourceFile => {
|
||||||
|
const visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
|
||||||
|
// 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;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as ts from "typescript";
|
import * as ts from "typescript";
|
||||||
import { TransformModuleExport } from "../types";
|
import { TransformModuleExport } from "../types";
|
||||||
|
|
||||||
const sourceCodeString = `x = y; a = b + c`;
|
const sourceCodeString = `x = y; a = b + c;`;
|
||||||
|
|
||||||
const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
|
const transformer: ts.TransformerFactory<ts.SourceFile> = context => {
|
||||||
return sourceFile => {
|
return sourceFile => {
|
||||||
|
|||||||
Reference in New Issue
Block a user