@rightcapital/phpdoc-parser
Version:
TypeScript version of PHPDoc parser with support for intersection types and generics
116 lines (115 loc) • 6.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PhpDocTypeNodeToTypescriptTypeNodeTranspiler = void 0;
const typescript_1 = require("typescript");
const array_shape_node_1 = require("../ast/type/array-shape-node");
const array_type_node_1 = require("../ast/type/array-type-node");
const object_shape_node_1 = require("../ast/type/object-shape-node");
const union_type_node_1 = require("../ast/type/union-type-node");
class PhpDocTypeNodeToTypescriptTypeNodeTranspiler {
constructor(nameNodePathResolver) {
this.nameNodePathResolver = nameNodePathResolver;
}
transpile(sourceTypeNode) {
if (sourceTypeNode instanceof union_type_node_1.UnionTypeNode) {
return typescript_1.factory.createUnionTypeNode(sourceTypeNode.types.map(this.transpile.bind(this)));
}
if (sourceTypeNode instanceof array_type_node_1.ArrayTypeNode) {
return typescript_1.factory.createArrayTypeNode(this.transpile(sourceTypeNode.type));
}
if (sourceTypeNode instanceof array_shape_node_1.ArrayShapeNode) {
return typescript_1.factory.createTypeLiteralNode(sourceTypeNode.items.map((item) => {
return typescript_1.factory.createPropertySignature(undefined, item.keyName.toString(), item.optional
? typescript_1.factory.createToken(typescript_1.SyntaxKind.QuestionToken)
: undefined, this.transpile(item.valueType));
}));
}
if (sourceTypeNode instanceof object_shape_node_1.ObjectShapeNode) {
return typescript_1.factory.createTypeLiteralNode(sourceTypeNode.items.map((item) => {
return typescript_1.factory.createPropertySignature(undefined, item.keyName.toString(), item.optional
? typescript_1.factory.createToken(typescript_1.SyntaxKind.QuestionToken)
: undefined, this.transpile(item.valueType));
}));
}
if (sourceTypeNode.isGenericTypeNode()) {
if ([
'array',
'non-empty-array',
'list',
'non-empty-list',
'\\Illuminate\\Support\\Collection',
'\\Illuminate\\Database\\Eloquent\\Collection',
].includes(sourceTypeNode.type.name)) {
if (sourceTypeNode.genericTypes.length === 1) {
return typescript_1.factory.createArrayTypeNode(this.transpile(sourceTypeNode.genericTypes[0]));
}
if (sourceTypeNode.genericTypes.length === 2) {
if (sourceTypeNode.genericTypes[0].isIdentifierTypeNode() &&
['int', 'integer', 'float', 'double'].includes(sourceTypeNode.genericTypes[0].name)) {
return typescript_1.factory.createArrayTypeNode(this.transpile(sourceTypeNode.genericTypes[1]));
}
return typescript_1.factory.createTypeReferenceNode(typescript_1.factory.createIdentifier('Record'), [
this.transpile(sourceTypeNode.genericTypes[0]),
this.transpile(sourceTypeNode.genericTypes[1]),
]);
}
}
throw Error('Not yet supported Generic type so far');
}
if (sourceTypeNode.isIdentifierTypeNode()) {
if (['bool', 'boolean', 'true', 'false'].includes(sourceTypeNode.name)) {
return typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.BooleanKeyword);
}
if (['int', 'integer', 'float', 'double'].includes(sourceTypeNode.name)) {
return typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.NumberKeyword);
}
if (sourceTypeNode.name === 'string') {
return typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.StringKeyword);
}
if (sourceTypeNode.name === 'array-key') {
return typescript_1.factory.createUnionTypeNode([
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.StringKeyword),
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.NumberKeyword),
]);
}
if (sourceTypeNode.name === 'scalar') {
return typescript_1.factory.createUnionTypeNode([
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.StringKeyword),
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.NumberKeyword),
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.BooleanKeyword),
]);
}
if (sourceTypeNode.name === 'mixed') {
typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.AnyKeyword);
}
if (sourceTypeNode.name === 'void') {
return typescript_1.factory.createToken(typescript_1.SyntaxKind.VoidKeyword);
}
if (['\\Illuminate\\Http\\Resources\\MissingValue', 'null'].includes(sourceTypeNode.name)) {
return typescript_1.factory.createLiteralTypeNode(typescript_1.factory.createNull());
}
if (/^[A-Z\\]/.test(sourceTypeNode.name)) {
const nameNodeParts = sourceTypeNode.name.split('\\');
const { path, isTypeOnly, importName, typeIdentifiers } = this.nameNodePathResolver(nameNodeParts);
if (importName !== 'string' && path !== '') {
this.importDeclarations.push(typescript_1.factory.createImportDeclaration(undefined, typescript_1.factory.createImportClause(isTypeOnly, undefined, typescript_1.factory.createNamedImports([
typescript_1.factory.createImportSpecifier(false, undefined, typescript_1.factory.createIdentifier(importName)),
])), typescript_1.factory.createStringLiteral(path), undefined));
}
let typeNameNode = typescript_1.factory.createIdentifier(typeIdentifiers[0]);
for (let i = 1; i < typeIdentifiers.length; i += 1) {
typeNameNode = typescript_1.factory.createQualifiedName(typeNameNode, typescript_1.factory.createIdentifier(typeIdentifiers[i]));
}
return typescript_1.factory.createTypeReferenceNode(typeNameNode, undefined);
}
}
return typescript_1.factory.createKeywordTypeNode(typescript_1.SyntaxKind.AnyKeyword);
}
beforeTranspile() {
this.importDeclarations = [];
}
getImportDeclarations() {
return this.importDeclarations;
}
}
exports.PhpDocTypeNodeToTypescriptTypeNodeTranspiler = PhpDocTypeNodeToTypescriptTypeNodeTranspiler;