ts-budgie
Version:
Converts TypeScript code to Budgie.
120 lines (103 loc) • 4.09 kB
text/typescript
import { CaseStyleConverterBag, NameSplitter } from "budgie";
import * as tsutils from "tsutils";
import * as ts from "typescript";
import { BudgieLine } from "../output/budgieLine";
import { Transformation } from "../output/transformation";
import { RootAliaser } from "../parsing/aliasers/rootAliaser";
import { TransformationsPrinter } from "../printing/transformationsPrinter";
import { VisitorContext } from "./context";
import { VisitorCreatorsBag } from "./visitorCreatorsBag";
import { INodeVisitorCreator, VisitorsBag } from "./visitorsBag";
export interface INodeVisitRouterDependencies {
aliaser: RootAliaser;
casing: CaseStyleConverterBag;
printer: TransformationsPrinter;
nameSplitter: NameSplitter;
sourceFile: ts.SourceFile;
typeChecker: ts.TypeChecker;
variableUsage: Map<ts.Identifier, tsutils.VariableInfo>;
visitorContext: VisitorContext;
visitorCreatorsBag: VisitorCreatorsBag;
}
/**
* Routes visitors for node types.
*/
export class NodeVisitRouter {
/**
* Dependencies used for initialization.
*/
private readonly dependencies: INodeVisitRouterDependencies;
/**
* Lazily creates visitors for node types.
*/
private readonly visitorsBag: VisitorsBag;
/**
* Initializes a new instance of the NodeVisitRouter.
*
* @param dependencies Dependencies to be used for initialization.
*/
public constructor(dependencies: INodeVisitRouterDependencies) {
this.dependencies = dependencies;
this.visitorsBag = new VisitorsBag({
aliaser: dependencies.aliaser,
casing: dependencies.casing,
nameSplitter: dependencies.nameSplitter,
router: this,
sourceFile: dependencies.sourceFile,
typeChecker: dependencies.typeChecker,
variableUsage: dependencies.variableUsage,
visitorContext: dependencies.visitorContext,
});
}
/**
* Retrieves the output transformations for a node.
*
* @param node Node to retrieve transformations for.
* @returns Output transformations for the node.
*/
public recurseIntoNode(node: ts.Node): Transformation[] {
const creator = this.dependencies.visitorCreatorsBag.getCreator(node.kind) as INodeVisitorCreator | undefined;
if (creator === undefined) {
return this.recurseIntoNodes(node.getChildren());
}
return this.visitorsBag.createVisitor(creator).visit(node);
}
/**
* Retrieves the Budgie output for a set of nodes.
*
* @param node Node to transform.
* @param parent Common parent of the nodes.
* @returns Transformed Budgie output for the nodes.
*/
public recurseIntoNodes(nodes: ReadonlyArray<ts.Node>): Transformation[] {
const transformations: Transformation[] = [];
for (const node of nodes) {
transformations.push(...this.recurseIntoNode(node));
}
return transformations;
}
/**
* Retrieves the Budgie output for an inline value.
*
* @param node Node to transform.
* @returns Transformed Budgie output for the inline value.
*/
public recurseIntoValue(node: ts.Node): string | BudgieLine {
const subTransformations = this.recurseIntoNode(node);
const { sourceFile } = this.dependencies;
return this.dependencies.printer.printTransformations(sourceFile.getText(sourceFile), subTransformations)[0];
}
/**
* Retrieves the Budgie output for a set of inline values.
*
* @param nodes Nodes to transform.
* @returns Transformed Budgie output for the inline values.
*/
public recurseIntoValues(nodes: ts.NodeArray<ts.Node>): (string | BudgieLine)[] {
const values: (string | BudgieLine)[] = [];
for (const node of nodes) {
values.push(this.recurseIntoValue(node));
}
return values;
}
}