@ui5/linter
Version:
A static code analysis tool for UI5
53 lines • 2.26 kB
JavaScript
import ts from "typescript";
export default class SourceFileMetadataCollector {
metadata;
constructor() {
this.metadata = {
controllerInfo: {
classNodeByPath: new Map(),
nameToPath: new Map(),
},
};
}
visitNode(node, sourceFile) {
if (ts.isClassLike(node)) {
this.addControllerClass(node, sourceFile.fileName);
}
ts.forEachChild(node, (child) => {
this.visitNode(child, sourceFile);
});
}
addControllerClass(node, filePath) {
const localNameMatch = /([^/]+)\.controller\.(js|ts)$/.exec(filePath);
const localName = localNameMatch ? localNameMatch[1] : undefined;
if (!localName) {
// Not a controller file, ignore
return;
}
const jsDocs = ts.getJSDocTags(node);
const controllerNameJSDocNode = jsDocs.find((tag) => tag.tagName.text === "namespace");
const controllerNamespace = controllerNameJSDocNode && typeof controllerNameJSDocNode.comment === "string" ?
controllerNameJSDocNode.comment.trim() :
undefined;
const fullyQuantifiedName = [controllerNamespace, localName].filter(Boolean).join(".");
// Stashing the node here is safe until we use the same ts.Program instance
// We must ensure that the node will be released within the same program lifecycle,
// otherwise we may encounter memory leaks or stale references
this.metadata.controllerInfo.classNodeByPath.set(filePath, node);
if (!this.metadata.controllerInfo.nameToPath.has(fullyQuantifiedName)) {
this.metadata.controllerInfo.nameToPath.set(fullyQuantifiedName, new Set());
}
this.metadata.controllerInfo.nameToPath.get(fullyQuantifiedName).add(filePath);
}
collectControllerInfo(sourceFile) {
// Limit collection to only controllers
if (!sourceFile.fileName.endsWith(".controller.js") && !sourceFile.fileName.endsWith(".controller.ts")) {
return;
}
this.visitNode(sourceFile, sourceFile);
}
getMetadata() {
return this.metadata;
}
}
//# sourceMappingURL=SourceFileMetadataCollector.js.map