@zspk/ts-esm-generator
Version:
Генератор определений типов TypeScript для пользовательских элементов управления UI5, реализованных в TypeScript.
88 lines • 4.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.addSourceExports = void 0;
const log = require("loglevel");
const path = require("path");
const ts = require("typescript");
/**
* This function aims to find the UI5-style global name for all exports of the given source file
* and to add an entry for each such export to allExports.
* The entry maps the UI5-style global name to a module path and an optional export name. The resulting map
* is used later to find out which module needs to be loaded (and optionally: which named export) for a given global name.
*
* @param sourceFile
* @param basePath
* @param typeChecker
* @param allPathMappings
* @param allExports
* @returns
*/
function addSourceExports(sourceFile, basePath, typeChecker, allPathMappings, allExports) {
const fileName = sourceFile.fileName;
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
if (!moduleSymbol) {
// not a module -> ignore
return;
}
// find out the module path of the current file; this is done by comparing the physical file name to
// the list of the program's path mappings (logical path to physical path). If a physical path matches,
// we know the locical path that can be used to address the module.
// Also, deduce a UI5-style global name for the module.
// Caution: this is full of heuristics and guesses.
const filePath = path.normalize(fileName); // e.g. 'c:\SAPDevelop\git\ui5-typescript-control-library\src-ts\com\myorg\myUI5Library\Example.ts
let globalName, moduleFileName;
for (let i = 0; i < allPathMappings.length; i++) {
const fullTargetPath = path.join(basePath, allPathMappings[i].target);
if (filePath.indexOf(fullTargetPath) === 0) {
const restPath = filePath.replace(fullTargetPath, "");
moduleFileName = path.join(allPathMappings[i].sourcePattern, restPath).replace(/\\/g, "/").replace(/\.ts$/, "");
globalName = moduleFileName.replace(/\//g, ".");
}
}
if (!globalName) {
// log.warn("No module name could be found for file " + filePath + "\nIs this a problem?");
}
else if (globalName.endsWith(".library")) {
// heuristics: library.ts files usually use the parent path as library name
globalName = globalName.slice(0, -".library".length);
}
let defaultExportName = path.basename(filePath, path.extname(filePath));
// controller
if (defaultExportName.indexOf(".controller") !== -1) {
defaultExportName = defaultExportName.slice(0, defaultExportName.indexOf(".controller"));
}
log.info(defaultExportName);
// ask tsc for all exports of the file
const exports = typeChecker.getExportsOfModule(moduleSymbol);
// for each export, add an entry with the assumed global name to the allExports array
exports.forEach((exp) => {
const exportName = exp.getName();
const globalExportName = globalName + (exportName === "default" ? "" : "." + exportName);
if (exp.declarations && exp.declarations.length) {
for (const declaration of exp.declarations) {
const commentsAndTags = ts.getJSDocTags(declaration);
if (!commentsAndTags)
continue;
for (let i = 0; i < commentsAndTags.length; i++) {
const tag = commentsAndTags[i];
if (tag.tagName.escapedText === "namespace") {
moduleFileName = tag.comment.toString().split(".").join("/") + "/" + defaultExportName;
break;
}
}
}
}
// TODO: once annotation is supported, ignore duplicate named export when annotated
allExports[globalExportName] = {
moduleName: moduleFileName,
exportName: exportName === "default" ? undefined : exportName
};
allExports[defaultExportName] = {
moduleName: moduleFileName,
exportName: exportName === "default" ? undefined : exportName
};
log.info("\t=>", "ModuleName: " + moduleFileName, "| ImportName: " + globalExportName);
});
}
exports.addSourceExports = addSourceExports;
//# sourceMappingURL=addSourceExports.js.map