UNPKG

ts-bakery

Version:

Baked dependency injection for Typescript.

508 lines 25.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const typescript = require("typescript"); const TsClassDefinition_1 = require("../Types/TsClassDefinition"); const TsClassDefinitionType_1 = require("../Types/TsClassDefinitionType"); const TsEnumDefinition_1 = require("../Types/TsEnumDefinition"); const TsFile_1 = require("../Types/TsFile"); const TsFunctionCall_1 = require("../Types/TsFunctionCall"); const TsFunctionDefinition_1 = require("../Types/TsFunctionDefinition"); const TsImportDefinition_1 = require("../Types/TsImportDefinition"); const TsImportType_1 = require("../Types/TsImportType"); const TsNodeSequence_1 = require("../Types/TsNodeSequence"); const TsParameterDefinition_1 = require("../Types/TsParameterDefinition"); const TsPropertyDefinition_1 = require("../Types/TsPropertyDefinition"); const TsTypeAlias_1 = require("../Types/TsTypeAlias"); const TsTypeReference_1 = require("../Types/TsTypeReference"); const TsNodeConverter_1 = require("./TsNodeConverter"); class TsBakeryConverter { constructor() { this.nodeConverter = new TsNodeConverter_1.default(); } convertPath(path) { const sourceFile = this.nodeConverter.convertToSourceFile(path); const file = this.convertSourceFile(sourceFile); file.path = path; return file; } convertSourceFile(sourceFile) { const convertedFile = new TsFile_1.default(sourceFile); for (const statement of sourceFile.statements) { switch (statement.kind) { case typescript.SyntaxKind.ImportDeclaration: const importDeclaration = this.nodeConverter.convertToImportDeclaration(statement); const importDefinition = this.convertImportDeclaration(importDeclaration); importDefinition.parent = convertedFile; convertedFile.imports.push(importDefinition); break; case typescript.SyntaxKind.EnumDeclaration: const enumDeclaration = this.nodeConverter.convertToEnumDeclaration(statement); const enumDefinition = this.convertEnumDeclaration(enumDeclaration); enumDefinition.parent = convertedFile; convertedFile.enums.push(enumDefinition); break; case typescript.SyntaxKind.InterfaceDeclaration: const interfaceDeclaration = this.nodeConverter.convertToInterfaceDeclaration(statement); const interfaceDefinition = this.convertInterfaceDeclaration(interfaceDeclaration); interfaceDefinition.parent = convertedFile; convertedFile.interfaces.push(interfaceDefinition); break; case typescript.SyntaxKind.ClassDeclaration: const classDeclaration = this.nodeConverter.convertToClassDeclaration(statement); const classDefinition = this.convertClassDeclaration(classDeclaration); classDefinition.parent = convertedFile; convertedFile.classes.push(classDefinition); break; case typescript.SyntaxKind.FunctionDeclaration: const functionDeclaration = this.nodeConverter.convertToFunctionDeclaration(statement); const functionDefintion = this.convertFunctionDeclaration(functionDeclaration); functionDefintion.parent = convertedFile; convertedFile.functions.push(functionDefintion); break; case typescript.SyntaxKind.ExportAssignment: const exportAssignment = this.nodeConverter.convertToExportAssignment(statement); convertedFile.export = this.convertExportAssignment(exportAssignment); break; case typescript.SyntaxKind.TypeAliasDeclaration: //TODO: Implement break; case typescript.SyntaxKind.ImportEqualsDeclaration: //TODO: Implement break; case typescript.SyntaxKind.FirstStatement: case typescript.SyntaxKind.ExpressionStatement: case typescript.SyntaxKind.SemicolonToken: case typescript.SyntaxKind.IfStatement: //ignore break; default: console.error('Unknown content node.'); this.logNode(statement); break; } } return convertedFile; } convertImportDeclaration(importDeclaration) { const tsImportDefinition = new TsImportDefinition_1.default(importDeclaration); const importClause = importDeclaration.importClause; if (importClause.namedBindings != null) { const namedBindings = importClause.namedBindings; if (namedBindings.kind == typescript.SyntaxKind.NamespaceImport) { tsImportDefinition.importType = TsImportType_1.default.Namespace; const nameSpaceImport = this.nodeConverter.convertToNamespaceImport(namedBindings); const name = this.convertIdentifier(nameSpaceImport.name); tsImportDefinition.names.push(name); } else if (namedBindings.kind == typescript.SyntaxKind.NamedImports) { tsImportDefinition.importType = TsImportType_1.default.Named; const namedImport = this.nodeConverter.convertToNamedImports(namedBindings); for (const element of namedImport.elements) { const importSpecifier = this.nodeConverter.convertToImportSpecifier(element); const elementName = this.convertIdentifier(importSpecifier.name); tsImportDefinition.names.push(elementName); } } else { console.warn('Unknown import type.'); } } else if (importClause.name != null) { const name = this.convertIdentifier(importClause.name); tsImportDefinition.importType = TsImportType_1.default.Identifier; tsImportDefinition.names.push(name); } const moduleSpecifier = this.nodeConverter.convertToStringLiteral(importDeclaration.moduleSpecifier); tsImportDefinition.modulePath = moduleSpecifier.text; return tsImportDefinition; } convertEnumDeclaration(enumDeclaration) { const tsEnumDefinition = new TsEnumDefinition_1.default(enumDeclaration); tsEnumDefinition.name = this.convertIdentifier(enumDeclaration.name); for (const member of enumDeclaration.members) { switch (member.kind) { case typescript.SyntaxKind.EnumMember: const memberName = this.convertIdentifier(member.name); tsEnumDefinition.members.push(memberName); break; default: console.error('Unknown enum member.'); this.logNode(member); } } return tsEnumDefinition; } convertInterfaceDeclaration(interfaceDeclaration) { const tsInterfaceDefinition = new TsClassDefinition_1.default(interfaceDeclaration); tsInterfaceDefinition.definitionType = TsClassDefinitionType_1.default.Interface; tsInterfaceDefinition.name = this.convertIdentifier(interfaceDeclaration.name); this.convertClassModifiers(interfaceDeclaration.modifiers, tsInterfaceDefinition); for (const member of interfaceDeclaration.members) { switch (member.kind) { case typescript.SyntaxKind.PropertySignature: const propertySignature = this.nodeConverter.convertToPropertySignature(member); const property = this.convertPropertySignature(propertySignature); property.parent = tsInterfaceDefinition; tsInterfaceDefinition.properties.push(property); break; case typescript.SyntaxKind.MethodSignature: const methodSignature = this.nodeConverter.convertToMethodSignature(member); const method = this.convertMethodSignature(methodSignature); method.parent = tsInterfaceDefinition; tsInterfaceDefinition.methods.push(method); break; case typescript.SyntaxKind.GetAccessor: const getAccessor = this.nodeConverter.convertToGetAccessorDeclaration(member); const getter = this.convertAccessorDeclaration(getAccessor); tsInterfaceDefinition.getters.push(getter); break; case typescript.SyntaxKind.SetAccessor: const setAccessor = this.nodeConverter.convertToSetAccessorDeclaration(member); const setter = this.convertAccessorDeclaration(setAccessor); tsInterfaceDefinition.setters.push(setter); break; default: console.warn('Unknown interface member.'); this.logNode(member); } } return tsInterfaceDefinition; } convertPropertySignature(propertySignature) { const property = new TsPropertyDefinition_1.default(propertySignature); property.name = this.convertIdentifier(propertySignature.name); property.type = this.convertTypeNode(propertySignature.type); return property; } convertMethodSignature(methodSignature) { const method = new TsFunctionDefinition_1.default(methodSignature); method.name = this.convertIdentifier(methodSignature.name); method.type = this.convertTypeNode(methodSignature.type); return method; } convertAccessorDeclaration(accessor) { const tsFunctionDefinition = new TsFunctionDefinition_1.default(accessor); tsFunctionDefinition.name = this.convertIdentifier(accessor.name); tsFunctionDefinition.type = this.convertTypeNode(accessor.type); return tsFunctionDefinition; } convertParameterDeclaration(parameter) { const paramDefinition = new TsParameterDefinition_1.default(parameter); paramDefinition.name = this.convertIdentifier(parameter.name); paramDefinition.type = this.convertTypeNode(parameter.type); return paramDefinition; } convertTypeNode(node) { if (node == null) { return null; } switch (node.kind) { case typescript.SyntaxKind.StringKeyword: const stringType = new TsTypeReference_1.TsSimpleTypeReference(); stringType.name = 'string'; return stringType; case typescript.SyntaxKind.VoidKeyword: const voidType = new TsTypeReference_1.TsSimpleTypeReference(); voidType.name = 'void'; return voidType; case typescript.SyntaxKind.BooleanKeyword: const booleanType = new TsTypeReference_1.TsSimpleTypeReference(); booleanType.name = 'boolean'; return booleanType; case typescript.SyntaxKind.NumberKeyword: const numberType = new TsTypeReference_1.TsSimpleTypeReference(); numberType.name = 'number'; return numberType; case typescript.SyntaxKind.AnyKeyword: const anyType = new TsTypeReference_1.TsSimpleTypeReference(); anyType.name = 'any'; return anyType; case typescript.SyntaxKind.UnknownKeyword: const unknownType = new TsTypeReference_1.TsSimpleTypeReference(); unknownType.name = 'unknown'; return unknownType; case typescript.SyntaxKind.ArrayType: const a = node; const arrayType = new TsTypeReference_1.TsArrayTypeReference(); arrayType.type = this.convertTypeNode(a.elementType); return arrayType; case typescript.SyntaxKind.TypeReference: const typeReferenceNode = node; return this.convertTypeReferenceNode(typeReferenceNode); case typescript.SyntaxKind.FunctionType: const ftType = node; return this.convertFunctionTypeNode(ftType); case typescript.SyntaxKind.ConstructorType: const cType = node; return this.convertConstructorTypeNode(cType); case typescript.SyntaxKind.TypeOperator: const topType = node; const topReference = new TsTypeReference_1.TsTypeOperatorTypeReference(); topReference.type = this.convertTypeNode(topType.type); return topReference; } return null; } convertNodeToTypeReference(node) { if (typescript.isIdentifier(node)) { const classTypeReference = new TsTypeReference_1.TsClassTypeReference(); classTypeReference.name = this.convertIdentifier(node); return classTypeReference; } if (typescript.isPropertyAccessExpression(node)) { const pae = node; const qualifiedTypeReference = new TsTypeReference_1.TsQualifiedTypeReference(); if (!typescript.isIdentifier(pae.expression)) { return null; } qualifiedTypeReference.left = this.convertIdentifier(pae.expression); qualifiedTypeReference.right = this.convertIdentifier(pae.name); return qualifiedTypeReference; } if (typescript.isTypeNode(node)) { return this.convertTypeNode(node); } return null; } convertFunctionTypeNode(node) { const typeReference = new TsTypeReference_1.TsFunctionTypeReference(); typeReference.type = this.convertTypeNode(node.type); for (const parameterDeclaration of node.parameters) { const parameterDefinition = this.convertParameterDeclaration(parameterDeclaration); typeReference.parameters.push(parameterDefinition); } return typeReference; } convertConstructorTypeNode(node) { const typeReference = new TsTypeReference_1.TsConstructorTypeReference(); typeReference.type = this.convertTypeNode(node.type); for (const parameter of node.parameters) { const parameterDeclaration = this.convertParameterDeclaration(parameter); typeReference.parameters.push(parameterDeclaration); } return typeReference; } convertTypeReferenceNode(node) { if (node.typeName.kind == typescript.SyntaxKind.Identifier) { const typeReference = new TsTypeReference_1.TsClassTypeReference(); typeReference.name = this.convertIdentifier(node.typeName); return typeReference; } else if (node.typeName.kind == typescript.SyntaxKind.QualifiedName) { const typeReference = new TsTypeReference_1.TsQualifiedTypeReference(); typeReference.left = this.convertIdentifier(node.typeName.left); typeReference.right = this.convertIdentifier(node.typeName.right); return typeReference; } console.error('Unknown type.'); return null; } convertClassDeclaration(classDeclaration) { const tsClassDefinition = new TsClassDefinition_1.default(classDeclaration); tsClassDefinition.name = this.convertIdentifier(classDeclaration.name); if (typescript.canHaveDecorators(classDeclaration)) { const decorators = typescript.getDecorators(classDeclaration); if (decorators != null) { for (const decorator of decorators) { const tsFunctionCall = this.convertDecorator(decorator); tsClassDefinition.decorators.push(tsFunctionCall); } } } if (typescript.canHaveModifiers(classDeclaration)) { const modifiers = typescript.getModifiers(classDeclaration); this.convertClassModifiers(modifiers, tsClassDefinition); } if (classDeclaration.members != null) { for (const member of classDeclaration.members) { switch (member.kind) { case typescript.SyntaxKind.Constructor: const constructorDeclaration = this.nodeConverter.convertToConstructorDeclaration(member); const constructorDefinition = this.convertConstructorDeclaration(constructorDeclaration); tsClassDefinition.classConstructor = constructorDefinition; constructorDefinition.parent = tsClassDefinition; break; case typescript.SyntaxKind.PropertyDeclaration: const propertyDeclaration = this.nodeConverter.convertToPropertyDeclaration(member); const propertyDefinition = this.convertPropertyDeclaration(propertyDeclaration); tsClassDefinition.properties.push(propertyDefinition); propertyDefinition.parent = tsClassDefinition; break; case typescript.SyntaxKind.MethodDeclaration: const methodDeclaration = this.nodeConverter.convertToMethodDeclaration(member); const methodDefinition = this.convertMethodDeclaration(methodDeclaration); tsClassDefinition.methods.push(methodDefinition); methodDefinition.parent = tsClassDefinition; break; case typescript.SyntaxKind.GetAccessor: const getAccessor = this.nodeConverter.convertToGetAccessorDeclaration(member); const getter = this.convertAccessorDeclaration(getAccessor); tsClassDefinition.getters.push(getter); getter.parent = tsClassDefinition; break; case typescript.SyntaxKind.SetAccessor: const setAccessor = this.nodeConverter.convertToSetAccessorDeclaration(member); const setter = this.convertAccessorDeclaration(setAccessor); tsClassDefinition.setters.push(setter); setter.parent = tsClassDefinition; break; case typescript.SyntaxKind.SemicolonClassElement: // Ignore break; default: console.warn('Unknown class member.'); this.logNode(member); break; } } } if (classDeclaration.heritageClauses != null) { for (const clause of classDeclaration.heritageClauses) { const heritageClause = this.nodeConverter.convertToHeritageClause(clause); const heritageTypes = this.convertHeritageClause(heritageClause); tsClassDefinition.heritageClauses.push(...heritageTypes); } } return tsClassDefinition; } convertClassModifiers(modifiers, tsClassDefinition) { if (modifiers == null) { return; } for (const modifier of modifiers) { switch (modifier.kind) { case typescript.SyntaxKind.DefaultKeyword: tsClassDefinition.isDefault = true; break; case typescript.SyntaxKind.ExportKeyword: tsClassDefinition.isExported = true; break; case typescript.SyntaxKind.AbstractKeyword: tsClassDefinition.isAbstract = true; break; default: console.warn('Unknown modifier'); this.logNode(modifier); } } } convertDecorator(decorator) { const tsFunctionCall = new TsFunctionCall_1.default(decorator); switch (decorator.expression.kind) { case typescript.SyntaxKind.CallExpression: const expression = this.nodeConverter.convertToCallExpression(decorator.expression); tsFunctionCall.name = this.convertIdentifier(expression.expression); for (const arg of expression.arguments) { const argString = this.nodeConverter.convertToStringLiteral(arg); tsFunctionCall.arguments.push(argString.text); } break; case typescript.SyntaxKind.Identifier: tsFunctionCall.name = this.convertIdentifier(decorator.expression); break; default: throw new Error('Unable to convert decorator'); } return tsFunctionCall; } convertPropertyDeclaration(propertyDeclaration) { const propertyDefinition = new TsPropertyDefinition_1.default(propertyDeclaration); propertyDefinition.name = this.convertIdentifier(propertyDeclaration.name); propertyDefinition.type = this.convertTypeNode(propertyDeclaration.type); return propertyDefinition; } convertConstructorDeclaration(constructorDeclaration) { return this.convertFunctionLikeDeclaration(constructorDeclaration); } convertFunctionDeclaration(functionDeclaration) { return this.convertFunctionLikeDeclaration(functionDeclaration); } convertMethodDeclaration(methodDeclaration) { return this.convertFunctionLikeDeclaration(methodDeclaration); } convertHeritageClause(heritageClause) { const names = []; for (const heritageType of heritageClause.types) { const heritageName = this.convertIdentifier(heritageType.expression); names.push(heritageName); } return names; } convertExpression(expression) { const sequence = new TsNodeSequence_1.default(); this.buildExpressionSequence(expression, sequence); return sequence; } buildExpressionSequence(expression, sequence) { switch (expression.kind) { case typescript.SyntaxKind.CallExpression: const callExpression = expression; sequence.addFirst(callExpression); this.buildExpressionSequence(callExpression.expression, sequence); break; case typescript.SyntaxKind.PropertyAccessExpression: const propertyAccessExpression = expression; sequence.addFirst(propertyAccessExpression); this.buildExpressionSequence(propertyAccessExpression.expression, sequence); break; case typescript.SyntaxKind.BinaryExpression: case typescript.SyntaxKind.Identifier: case typescript.SyntaxKind.VariableStatement: case typescript.SyntaxKind.ThisKeyword: case typescript.SyntaxKind.StringLiteral: sequence.addFirst(expression); break; default: console.warn('Unable to convert ExpressionSequence with kind ' + typescript.SyntaxKind[expression.kind]); break; } } convertExportAssignment(exportAssignment) { return this.convertIdentifier(exportAssignment.expression); } convertTypeAliasDeclaration(typeAlias) { const tsAlias = new TsTypeAlias_1.default(); tsAlias.name = this.convertIdentifier(typeAlias.name); tsAlias.type = this.convertTypeNode(typeAlias.type); return tsAlias; } convertIdentifier(node) { if (node == null) { return null; } if (node.kind == typescript.SyntaxKind.ComputedPropertyName) { const computedPropertyName = this.nodeConverter.convertToComputedPropertyName(node); return this.convertIdentifier(computedPropertyName.expression); } return this.nodeConverter.convertToIdentifier(node).escapedText; } convertFunctionLikeDeclaration(functionLikeDeclaration) { const tsFunctionDefinition = new TsFunctionDefinition_1.default(functionLikeDeclaration); tsFunctionDefinition.name = this.convertIdentifier(functionLikeDeclaration.name); tsFunctionDefinition.type = this.convertTypeNode(functionLikeDeclaration.type); for (let p of functionLikeDeclaration.parameters) { const param = this.convertParameterDeclaration(p); tsFunctionDefinition.addParameter(param); } if (!typescript.canHaveDecorators(functionLikeDeclaration)) { return tsFunctionDefinition; } const decorators = typescript.getDecorators(functionLikeDeclaration); if (decorators == null) { return tsFunctionDefinition; } for (const d of decorators) { const decorator = this.convertDecorator(d); tsFunctionDefinition.decorators.push(decorator); } return tsFunctionDefinition; } logNode(node) { console.log('/--- NODE BEGIN ---/'); console.log(typescript.SyntaxKind[node.kind]); console.log(node); console.log('/--- NODE END ---/'); } } exports.default = TsBakeryConverter; //# sourceMappingURL=TsBakeryConverter.js.map