UNPKG

ts-budgie

Version:

Converts TypeScript code to Budgie.

71 lines (52 loc) 2.97 kB
import { CaseStyle, CommandNames, KeywordNames } from "budgie"; import * as path from "path"; import * as ts from "typescript"; import { BudgieLine } from "../../output/budgieLine"; import { Transformation } from "../../output/transformation"; import { createUnsupportedBudgieLine } from "../../output/unsupported"; import { NodeVisitor } from "../visitor"; const noBaseDirectoryComplaint = "Import directory goes out of bounds of the base directory."; const noImportClauseComplaint = "Import declarations must import items."; const noNamespaceImportsComplaint = "Namespace imports are not supported."; const noPackageImportsComplaint = "Package imports are not yet supported."; export class ImportDeclarationVisitor extends NodeVisitor { public visit(node: ts.ImportDeclaration) { return [Transformation.fromNode(node, this.sourceFile, [this.getTransformationContents(node)])]; } private getTransformationContents(node: ts.ImportDeclaration) { if (node.importClause === undefined || node.importClause.namedBindings === undefined) { return createUnsupportedBudgieLine(noImportClauseComplaint); } if (node.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport) { return createUnsupportedBudgieLine(noNamespaceImportsComplaint); } const packagePath = this.parsePackagePath(node); if (packagePath instanceof BudgieLine) { return packagePath; } const importedItems = node.importClause.namedBindings.elements.map((element) => element.name.text); return new BudgieLine(CommandNames.ImportLocal, ...packagePath, KeywordNames.Use, ...importedItems); } private parsePackagePath(node: ts.ImportDeclaration): string[] | BudgieLine { const packagePathRaw = node.moduleSpecifier.getText(this.sourceFile); if (packagePathRaw[1] !== ".") { return createUnsupportedBudgieLine(noPackageImportsComplaint); } const sourceDir = path.dirname(this.sourceFile.fileName); const packagePath = packagePathRaw.replace(/"|'|`/g, ""); const pathResolved = path.posix.join(sourceDir, packagePath); if (pathResolved.indexOf(this.context.options.baseDirectory) === -1) { return createUnsupportedBudgieLine(noBaseDirectoryComplaint); } const pathWithNamespace = path.posix.join( this.context.options.outputNamespace, pathResolved.substring(this.context.options.baseDirectory.length), ); const pathWithNamespaceAndFileSplit = pathWithNamespace .split(/\//g) .filter((pathComponent) => pathComponent !== "") .map((pathComponent) => this.casing.convertToCase(CaseStyle.PascalCase, [pathComponent])); pathWithNamespaceAndFileSplit.pop(); return pathWithNamespaceAndFileSplit; } }