UNPKG

ts-budgie

Version:

Converts TypeScript code to Budgie.

124 lines 6.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tsutils = require("tsutils"); var ts = require("typescript"); var flags_1 = require("../flags"); var types_1 = require("../types"); var arrayLiteralExpressionAliaser_1 = require("./arrayLiteralExpressionAliaser"); var elementAccessExpressionAliaser_1 = require("./elementAccessExpressionAliaser"); var newExpressionAliaser_1 = require("./newExpressionAliaser"); var numericAliaser_1 = require("./numericAliaser"); var propertyOrVariableDeclarationAliaser_1 = require("./propertyOrVariableDeclarationAliaser"); var typeLiteralAliaser_1 = require("./typeLiteralAliaser"); var typeNameAliaser_1 = require("./typeNameAliaser"); var createChildGetter = function (index) { if (index === void 0) { index = 0; } return function (node) { return node.getChildren()[index]; }; }; var recursiveFriendlyValueDeclarationTypes = new Set([ ts.SyntaxKind.Parameter, ts.SyntaxKind.PropertyDeclaration, ts.SyntaxKind.VariableDeclaration, ]); var RootAliaser = /** @class */ (function () { function RootAliaser(sourceFile, typeChecker) { var _this = this; this.getFriendlyTypeName = function (node) { var knownTypeNameConverter = _this.typesWithKnownTypeNames.get(node.kind); if (knownTypeNameConverter !== undefined) { var typeNameConverted = knownTypeNameConverter.getFriendlyTypeName(node); if (typeNameConverted !== undefined) { return typeNameConverted; } } var passThroughType = _this.passThroughTypes.get(node.kind); if (passThroughType !== undefined) { return _this.getFriendlyTypeName(passThroughType(node)); } // We use the real type checker last because our checks can know the difference // between seemingly identical types, such as "float" or "int" within "number" var typeAtLocation = _this.typeChecker.getTypeAtLocation(node); var resolvedFlagType = _this.flagResolver.resolve(typeAtLocation.flags); if (resolvedFlagType !== undefined) { return resolvedFlagType; } // TypeScript won't give up expression nodes' types, but if they have a type symbol // we can use it to find their value declaration var symbol = _this.typeChecker.getSymbolAtLocation(node); if (symbol !== undefined && symbol.valueDeclaration !== undefined) { var valueDeclaration = symbol.valueDeclaration; if (recursiveFriendlyValueDeclarationTypes.has(valueDeclaration.kind)) { return _this.getFriendlyTypeName(valueDeclaration); } } // By now, this is probably a node with a non-primitive type, such as a class instance. if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) { if (node.type !== undefined) { return _this.getFriendlyTypeName(node.type); } } if (ts.isTypeNode(node)) { return types_1.parseRawTypeToBudgie(node.getText()); } // This seems to sometimes succeed when directly calling getSymbolAtLocation doesn't var typeSymbol = typeAtLocation.symbol; if (typeSymbol !== undefined && typeSymbol.name !== "unknown") { return typeSymbol.name; } return undefined; }; this.flagResolver = new flags_1.TypeFlagsResolver(); this.sourceFile = sourceFile; this.typeChecker = typeChecker; this.passThroughTypes = new Map([ [ts.SyntaxKind.ExpressionStatement, createChildGetter()], [ts.SyntaxKind.ParenthesizedExpression, createChildGetter()], [ts.SyntaxKind.ParenthesizedType, createChildGetter()], [ts.SyntaxKind.SyntaxList, createChildGetter()], ]); this.typesWithKnownTypeNames = new Map([ [ts.SyntaxKind.ArrayLiteralExpression, new arrayLiteralExpressionAliaser_1.ArrayLiteralExpressionAliaser(typeChecker, this.getFriendlyTypeName)], [ts.SyntaxKind.BooleanKeyword, new typeNameAliaser_1.TypeNameAliaser("boolean")], [ts.SyntaxKind.ElementAccessExpression, new elementAccessExpressionAliaser_1.ElementAccessExpressionAliaser(typeChecker, this.getFriendlyTypeName)], [ts.SyntaxKind.FalseKeyword, new typeNameAliaser_1.TypeNameAliaser("boolean")], [ts.SyntaxKind.NewExpression, new newExpressionAliaser_1.NewExpressionAliaser(this.sourceFile)], [ts.SyntaxKind.NumericLiteral, new numericAliaser_1.NumericAliaser(this.sourceFile)], [ts.SyntaxKind.TrueKeyword, new typeNameAliaser_1.TypeNameAliaser("boolean")], [ts.SyntaxKind.TypeLiteral, new typeLiteralAliaser_1.TypeLiteralAliaser(typeChecker, this.getFriendlyTypeName)], [ts.SyntaxKind.StringKeyword, new typeNameAliaser_1.TypeNameAliaser("string")], [ts.SyntaxKind.StringLiteral, new typeNameAliaser_1.TypeNameAliaser("string")], [ts.SyntaxKind.VariableDeclaration, new propertyOrVariableDeclarationAliaser_1.PropertyOrVariableDeclarationAliaser(typeChecker, this.getFriendlyTypeName)], ]); } RootAliaser.prototype.getFriendlyPrivacyName = function (node) { if (tsutils.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword)) { return "private"; } if (tsutils.hasModifier(node.modifiers, ts.SyntaxKind.ProtectedKeyword)) { return "protected"; } return "public"; }; RootAliaser.prototype.getFriendlyReturnTypeName = function (node) { // If the node explicitly mentions a return type, use that if (node.type !== undefined) { return this.getFriendlyTypeName(node.type); } // The rest of this logic attempts to use the type checker to get a computed type symbol var typeAtLocation = this.typeChecker.getTypeAtLocation(node); var signaturesOfType = this.typeChecker.getSignaturesOfType(typeAtLocation, ts.SignatureKind.Call); if (signaturesOfType.length !== 1) { return undefined; } var signatureOfType = signaturesOfType[0]; var signatureReturnType = signatureOfType.getReturnType(); var symbol = signatureReturnType.getSymbol(); if (symbol !== undefined) { return symbol.getName(); } return signatureReturnType.intrinsicName; }; return RootAliaser; }()); exports.RootAliaser = RootAliaser; //# sourceMappingURL=rootAliaser.js.map