UNPKG

sardines-compile-time-tools

Version:

sardines.compile-time-tools.js is part of the sardines.io project

302 lines (301 loc) 13.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.gatherExports = exports.illegalExportTypes = exports.legalExportTypes = void 0; var ts = require("typescript"); var fs = require("fs"); var builtInTypes = ['Promise', 'Map', 'Array', 'Set', 'void', 'any', 'null', 'undefined', 'object', 'number', 'string', 'boolean']; exports.legalExportTypes = [ ts.SyntaxKind.FunctionExpression, ts.SyntaxKind.FunctionDeclaration, ts.SyntaxKind.ArrowFunction, ts.SyntaxKind.InterfaceDeclaration, ts.SyntaxKind.ObjectLiteralExpression, ts.SyntaxKind.ArrayLiteralExpression, ts.SyntaxKind.PropertyAccessExpression, ts.SyntaxKind.EnumDeclaration, ]; exports.illegalExportTypes = [ ts.SyntaxKind.ClassDeclaration, ]; function gatherExports(sourceFilePath) { var sourceFile = ts.createSourceFile(sourceFilePath, fs.readFileSync(sourceFilePath).toString(), ts.ScriptTarget.ES2015, true); var idnetifiers = new Map(); var referencedTypes = []; var importedIds = []; var proxyIds = []; var storeSyntax = function (syntax) { if (syntax.name) { if (idnetifiers.has(syntax.name)) { throw "duplicated identifier: " + syntax.name; } else if (syntax.isExport && exports.illegalExportTypes.indexOf(syntax.type) >= 0) { throw "illegal export type: " + ts.SyntaxKind[syntax.type] + " for syntax [" + syntax.name + "]"; } else { idnetifiers.set(syntax.name, syntax); } } }; var storeReferencedTypes = function (types) { for (var _i = 0, types_1 = types; _i < types_1.length; _i++) { var t = types_1[_i]; if (referencedTypes.indexOf(t) < 0) referencedTypes.push(t); } }; var storeImportedOrExportedIds = function (ids, source, isImport) { if (isImport === void 0) { isImport = true; } if (!source) return; for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) { var item_1 = ids_1[_i]; var line = item_1 + "|" + source; if (isImport && importedIds.indexOf(line) < 0) importedIds.push(line); else if (!isImport && proxyIds.indexOf(line) < 0) proxyIds.push(line); } }; var checkSyntaxType = function (node, type) { if (type === void 0) { type = ts.SyntaxKind.ExportKeyword; } if (node.kind === type) return true; var result = false; if (node.getChildCount() > 0) { for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) { var child = _a[_i]; if (checkSyntaxType(child, type)) { result = true; break; } } } return result; }; var printNode = function (node, prefix) { if (prefix === void 0) { prefix = ''; } console.log(prefix, ts.SyntaxKind[node.kind], node.getText()); for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) { var item_2 = _a[_i]; printNode(item_2, prefix + ' '); } }; var getTypeRefInParam = function (param) { var result = []; for (var _i = 0, _a = param.getChildren(); _i < _a.length; _i++) { var item_3 = _a[_i]; var digIn = true; if (item_3.kind === ts.SyntaxKind.TypeReference) { var text = item_3.getText(); if (text.indexOf('<') < 0 && builtInTypes.indexOf(text) < 0 && text.indexOf('|') < 0) { result.push(text); digIn = false; } } if (digIn) { var subResult = getTypeRefInParam(item_3); for (var _b = 0, subResult_1 = subResult; _b < subResult_1.length; _b++) { var t = subResult_1[_b]; if (result.indexOf(t) < 0) { result.push(t); } } } } return result; }; var getParamSyntax = function (node) { var paramSyntax = null, pre = null, preBeforePre = null; for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) { var item_4 = _a[_i]; if (item_4.kind === ts.SyntaxKind.CloseParenToken) { if (pre && pre.kind !== ts.SyntaxKind.OpenParenToken && preBeforePre && preBeforePre.kind === ts.SyntaxKind.OpenParenToken) { paramSyntax = pre; } break; } preBeforePre = pre; pre = item_4; } var params = []; if (paramSyntax) { for (var _b = 0, _c = paramSyntax.getChildren(); _b < _c.length; _b++) { var item_5 = _c[_b]; if (item_5.kind === ts.SyntaxKind.Parameter) { var paramName = null; for (var _d = 0, _e = item_5.getChildren(); _d < _e.length; _d++) { var subItem = _e[_d]; if (subItem.kind === ts.SyntaxKind.Identifier) { paramName = subItem.getText(); } } if (paramName) { var paramObj = { name: paramName, type: item_5.kind, typeStr: ts.SyntaxKind[item_5.kind], isExport: false, isAsync: false, text: item_5.getText() }; params.push(paramObj); } } } return params; } return null; }; var getReturnType = function (node) { var preBeforePre = null, pre = null, returnType = null; for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) { var child = _a[_i]; if (pre && preBeforePre && preBeforePre.kind === ts.SyntaxKind.ColonToken) if (child.kind === ts.SyntaxKind.EqualsGreaterThanToken || child.kind === ts.SyntaxKind.Block) { returnType = pre.getText(); } preBeforePre = pre; pre = child; } return returnType; }; var parseParamsIntoSyntax = function (node, syntax) { syntax.param = getParamSyntax(node); if (syntax.param) { syntax.typeRef = getTypeRefInParam(node); if (syntax.typeRef.length > 0) storeReferencedTypes(syntax.typeRef); } syntax.isAsync = checkSyntaxType(node, ts.SyntaxKind.AsyncKeyword); var returnType = getReturnType(node); if (!returnType) returnType = 'any'; else if (syntax.isAsync && returnType.indexOf('Promise<') === 0) { returnType = returnType.substr(8); returnType = returnType.substr(0, returnType.length - 1); } syntax.returnType = returnType; return syntax; }; var getNamedImportsOrExports = function (node) { var importedOrExportedIds = []; var source = null, isSource = false; for (var _i = 0, _a = node.getChildren(); _i < _a.length; _i++) { var item_6 = _a[_i]; if (item_6.kind === ts.SyntaxKind.ImportSpecifier || item_6.kind === ts.SyntaxKind.ExportSpecifier) { var children = item_6.getChildren(); if (children.length === 1) { importedOrExportedIds.push(children[0].getText()); } else if (children.length === 3 && children[1].kind === ts.SyntaxKind.AsKeyword) { importedOrExportedIds.push(children[0].getText() + ':' + children[2].getText()); } } else if (item_6.kind === ts.SyntaxKind.FromKeyword) { isSource = true; } else if (item_6.kind === ts.SyntaxKind.StringLiteral && isSource) { source = item_6.getText(); } else { var _b = getNamedImportsOrExports(item_6), subIds = _b[0], subSource = _b[1]; for (var _c = 0, subIds_1 = subIds; _c < subIds_1.length; _c++) { var subId = subIds_1[_c]; if (importedOrExportedIds.indexOf(subId) < 0) importedOrExportedIds.push(subId); } if (subSource) { if (!source) source = subSource; } } } return [importedOrExportedIds, source]; }; var analyzeNode = function (node) { if (node.kind === ts.SyntaxKind.SourceFile) { ts.forEachChild(node, analyzeNode); return; } var name = '', isAsync = false, isExport = checkSyntaxType(node), text = node.getText().replace(/export +/g, ''), syntax = { name: name, isAsync: isAsync, isExport: isExport, type: node.kind, typeStr: ts.SyntaxKind[node.kind], text: text }; switch (node.kind) { case ts.SyntaxKind.VariableStatement: for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var item_7 = _a[_i]; analyzeNode(item_7); } break; case ts.SyntaxKind.ExportDeclaration: case ts.SyntaxKind.ImportDeclaration: var _b = getNamedImportsOrExports(node), importedIds_1 = _b[0], source = _b[1]; storeImportedOrExportedIds(importedIds_1, source, node.kind === ts.SyntaxKind.ImportDeclaration); break; case ts.SyntaxKind.ExportAssignment: throw 'export default is not supported'; case ts.SyntaxKind.InterfaceDeclaration: syntax.name = node.name.text; break; case ts.SyntaxKind.EnumDeclaration: syntax.name = node.name.text; break; case ts.SyntaxKind.ClassDeclaration: syntax.name = node.name.text; break; case ts.SyntaxKind.ArrowFunction: syntax.name = node.name; syntax.isExport = checkSyntaxType(node, ts.SyntaxKind.ExportKeyword); parseParamsIntoSyntax(node, syntax); break; case ts.SyntaxKind.FunctionDeclaration: case ts.SyntaxKind.FunctionExpression: syntax.name = node.name.text; syntax.isExport = checkSyntaxType(node, ts.SyntaxKind.ExportKeyword); parseParamsIntoSyntax(node, syntax); break; case ts.SyntaxKind.VariableDeclaration: isExport = checkSyntaxType(node.parent.parent); name = node.name.getText(); var isValueSyntax = false; for (var _c = 0, _d = node.getChildren(); _c < _d.length; _c++) { var item_8 = _d[_c]; if (isValueSyntax) { var sourceId = item_8.getText(); if (item_8.kind === ts.SyntaxKind.Identifier && idnetifiers.has(sourceId)) { var tmpSyntax = Object.assign({}, idnetifiers.get(sourceId)); tmpSyntax.name = name; tmpSyntax.isExport = isExport; storeSyntax(tmpSyntax); } else if (item_8.kind !== ts.SyntaxKind.Identifier) { var itemSyntax = { name: name, isAsync: false, isExport: isExport, type: item_8.kind, typeStr: ts.SyntaxKind[item_8.kind], text: sourceId }; if (item_8.kind === ts.SyntaxKind.FunctionExpression || item_8.kind === ts.SyntaxKind.ArrowFunction) { parseParamsIntoSyntax(item_8, itemSyntax); } storeSyntax(itemSyntax); } isValueSyntax = false; } else if (item_8.kind === ts.SyntaxKind.FirstAssignment) { isValueSyntax = true; } } break; default: break; } storeSyntax(syntax); }; analyzeNode(sourceFile); var iterator = idnetifiers.keys(); var item = iterator.next(); while (!item.done) { var idenObj = (idnetifiers.get(item.value)); if (!idenObj.isExport || exports.legalExportTypes.indexOf(idenObj.type) < 0) { idnetifiers.delete(item.value); } item = iterator.next(); } return [idnetifiers, referencedTypes, importedIds, proxyIds]; } exports.gatherExports = gatherExports;