UNPKG

@ui5/linter

Version:

A static code analysis tool for UI5

121 lines 5.79 kB
import { resolveUniqueName } from "../../ui5Types/utils/utils.js"; import Writer from "./Writer.js"; import path from "node:path/posix"; // TODO: Generate type information to make View#byId() access typed? export default class AbstractGenerator { _imports = new Set(); _variableNames = new Set(); _body; _idToModule = new Map(); _controllerByIdInfo; constructor(filePath, controllerByIdInfo) { const fileName = path.basename(filePath, ".xml"); this._body = new Writer(fileName + ".js", fileName + ".xml"); this._controllerByIdInfo = controllerByIdInfo; } // eslint-disable-next-line @typescript-eslint/no-unused-vars writeRootControl(controlDeclaration) { throw new Error("Not implemented"); } writeControl(controlDeclaration, rootControl = false) { const importVariableName = this._getUniqueVariableName(controlDeclaration.name); const moduleName = controlDeclaration.namespace.replaceAll(".", "/") + `/${controlDeclaration.name}`; // Add import this._imports.add({ moduleName, variableName: importVariableName, start: controlDeclaration.start, end: controlDeclaration.end, }); // Generate variable name controlDeclaration.variableName = this._getUniqueVariableName(`o${controlDeclaration.name}`); // Create the control this._writeControlFactoryCall(moduleName, importVariableName, controlDeclaration, rootControl); // Write properties controlDeclaration.properties.forEach((attribute) => { // Add mapping of id to module name so that specific byId lookup for controllers can be generated. // This information can only be added to the ControllerByIdInfo once the controllerName is known, // which happens last as outer nodes are visited last. if (attribute.name === "id") { this._idToModule.set(attribute.value, moduleName); } // TODO: Determine attribute type based on metadata and parse/write value accordingly this._body.write(` `); this._body.writeln(`${attribute.name}: ${JSON.stringify(attribute.value)},`, attribute.start, attribute.end); }); // Write aggregations controlDeclaration.aggregations.forEach((aggregationDeclaration, aggregationName) => { this._body.write(` `); this._body.write(aggregationName, aggregationDeclaration.start, aggregationDeclaration.end); this._body.writeln(`: [`); aggregationDeclaration.controls.forEach((control) => { if (!control.variableName) { throw new Error(`Control ${control.name} required in aggregation ` + `${aggregationName} of control ${controlDeclaration.name} has no yet been declared`); } this._body.writeln(` ${control.variableName},`); }); this._body.writeln(` ],`); }); this._body.writeln("});\n"); } writeRequire(requireExpression) { requireExpression.declarations.forEach((declaration) => { if (!declaration.moduleName) { // Module name might be missing, e.g. when a variable is declared via template:alias return; } if (!declaration.variableName) { // Side effect require? declaration.variableName = "_"; } const variableName = this._getUniqueVariableName(declaration.variableName); declaration.variableName = variableName; this._imports.add({ moduleName: declaration.moduleName, variableName: variableName, start: requireExpression.start, end: requireExpression.end, }); }); } getModuleContent() { // Sort by import variable name const imports = Array.from(this._imports).sort((a, b) => { return b.variableName.localeCompare(a.variableName); }); imports.forEach((importStatment) => { this._body.prependln(`import ${importStatment.variableName} from "${importStatment.moduleName}";`, importStatment.start, importStatment.end); }); return { source: this._body.getString(), map: JSON.stringify(this._body.getSourceMap()), }; } _getUniqueVariableName(variableName) { let resolvedName = variableName; if (this._variableNames.has(variableName)) { resolvedName = resolveUniqueName(variableName, this._variableNames); } this._variableNames.add(resolvedName); return resolvedName; } _writeControlFactoryCall(moduleName, importVariableName, controlDeclaration, rootControl) { this._body.write(`const ${controlDeclaration.variableName} = `); if (!rootControl) { // Special case: Use View.create for nested views if (moduleName === "sap/ui/core/mvc/View") { this._body.writeln(`await ${importVariableName}.create({`, controlDeclaration.start, controlDeclaration.end); return; } // Special case: Use Fragment.load for nested fragments if (moduleName === "sap/ui/core/Fragment") { this._body.writeln(`await ${importVariableName}.load({`, controlDeclaration.start, controlDeclaration.end); return; } } // Default case: Use new for controls this._body.writeln(`new ${importVariableName}({`, controlDeclaration.start, controlDeclaration.end); } } //# sourceMappingURL=AbstractGenerator.js.map