ui5plugin-parser
Version:
212 lines (211 loc) • 9.43 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CustomTSObject = void 0;
const path = require("path");
const ts_morph_1 = require("ts-morph");
const ParserPool_1 = require("../../../../parser/pool/ParserPool");
const AbstractCustomClass_1 = require("../AbstractCustomClass");
class CustomTSObject extends AbstractCustomClass_1.AbstractCustomClass {
_fillIsAbstract() {
throw new Error("Method not implemented.");
}
_getUIDefine() {
throw new Error("Method not implemented.");
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
_fillParentClassName() { }
constructor(objectLiteralExpression, parser, typeChecker) {
const sourceFile = objectLiteralExpression.getSourceFile();
const className = parser.fileReader.getClassNameFromPath(sourceFile.compilerNode.fileName);
super(className ?? "", parser);
this.parentClassNameDotNotation = "";
this.methods = [];
this.fields = [];
this.UIDefine = [];
this.typeChecker = typeChecker;
this.classText = sourceFile.getFullText();
this._sourceFile = sourceFile;
this.fsPath = path.resolve(sourceFile.compilerNode.fileName);
this.node = objectLiteralExpression;
this._fillUI5Metadata(undefined, false);
}
loadTypes() {
this._fillUI5Metadata(undefined, true);
}
_fillUIDefine() {
const importStatements = this._sourceFile.getImportDeclarations();
this.UIDefine = importStatements.map(importStatement => {
const modulePath = importStatement.getModuleSpecifier().getLiteralText();
return {
path: modulePath,
className: modulePath.split("/").pop() ?? "",
classNameDotNotation: this._generateClassNameDotNotationFor(modulePath),
start: importStatement.getStart(),
end: importStatement.getEnd(),
acornNode: importStatement
};
});
}
_generateClassNameDotNotationFor(moduleNameSlash) {
let className = moduleNameSlash.replace(/\//g, ".");
if (moduleNameSlash?.startsWith(".")) {
const manifest = ParserPool_1.default.getManifestForClass(this.className);
if (manifest && this.fsPath) {
const normalizedManifestPath = path.normalize(manifest.fsPath);
const importClassPath = path.resolve(path.dirname(this.fsPath), moduleNameSlash);
const relativeToManifest = path.relative(normalizedManifestPath, importClassPath);
const pathRelativeToManifestDotNotation = relativeToManifest.split(path.sep).join(".");
className = `${manifest.componentName}.${pathRelativeToManifestDotNotation}`;
}
}
if (className.endsWith(".controller")) {
className = className.substring(0, className.length - ".controller".length);
}
return className;
}
_fillFields(metadata, fillTypes = false) {
const properties = this.node.getProperties();
const propertyAssignments = properties
.filter(field => field.isKind(ts_morph_1.ts.SyntaxKind.PropertyAssignment))
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map(field => field.asKind(ts_morph_1.ts.SyntaxKind.PropertyAssignment));
const fields = propertyAssignments.filter(field => !field.getInitializer()?.isKind(ts_morph_1.ts.SyntaxKind.FunctionExpression) &&
!field.getInitializer()?.isKind(ts_morph_1.ts.SyntaxKind.ArrowFunction));
const UIFields = fields.map(field => {
const positionStart = this._sourceFile.getLineAndColumnAtPos(field.getNameNode().getStart());
const positionEnd = this._sourceFile.getLineAndColumnAtPos(field.getNameNode().getEnd());
let type = fillTypes ? field.getType().getText() : "any";
type = this._modifyType(type);
return {
ui5ignored: false,
owner: this.className,
static: true,
abstract: false,
type: type,
visibility: "public",
name: field.getName(),
deprecated: false,
description: "",
isEventHandler: false,
node: field,
mentionedInTheXMLDocument: false,
loc: {
start: {
line: positionStart.line,
column: positionStart.column - 1
},
end: {
line: positionEnd.line,
column: positionEnd.column - 1
}
}
};
});
return UIFields;
}
_fillMethods(metadata, fillTypes = false) {
const properties = this.node.getProperties();
const propertyAssignments = properties
.filter(field => field.isKind(ts_morph_1.ts.SyntaxKind.PropertyAssignment))
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map(field => field.asKind(ts_morph_1.ts.SyntaxKind.PropertyAssignment));
const functions = propertyAssignments.filter(field => field.getInitializer()?.isKind(ts_morph_1.ts.SyntaxKind.FunctionExpression) ||
field.getInitializer()?.isKind(ts_morph_1.ts.SyntaxKind.ArrowFunction));
const methods = properties
.filter(field => field.isKind(ts_morph_1.ts.SyntaxKind.MethodDeclaration))
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map(field => field.asKind(ts_morph_1.ts.SyntaxKind.MethodDeclaration));
const UIMethods = [...methods, ...functions].map(method => {
const positionStart = this._sourceFile.getLineAndColumnAtPos(method.getNameNode().getStart());
const positionEnd = this._sourceFile.getLineAndColumnAtPos(method.getNameNode().getEnd());
let returnType = "void";
let parameters = [];
if (method.isKind(ts_morph_1.ts.SyntaxKind.MethodDeclaration)) {
returnType = fillTypes ? method.getReturnType().getText() : "void";
parameters = method.getParameters();
}
else if (method.isKind(ts_morph_1.ts.SyntaxKind.PropertyAssignment)) {
const myFunction = method.getInitializer()?.asKind(ts_morph_1.ts.SyntaxKind.FunctionExpression) ??
method.getInitializer()?.asKind(ts_morph_1.ts.SyntaxKind.ArrowFunction);
parameters = myFunction?.getParameters() ?? [];
returnType = fillTypes ? myFunction?.getReturnType().getText() ?? "void" : "void";
}
returnType = this._modifyType(returnType);
return {
ui5ignored: false,
owner: this.className,
static: true,
abstract: false,
returnType: returnType,
visibility: "public",
params: parameters.map(param => {
return {
name: param.getName(),
type: fillTypes ? this._modifyType(param.getType().getText()) ?? "any" : "any",
description: "",
isOptional: false
};
}),
name: method.getName(),
position: method.getStart(),
deprecated: false,
description: "",
isEventHandler: false,
node: method,
loc: {
start: {
line: positionStart.line,
column: positionStart.column - 1
},
end: {
line: positionEnd.line,
column: positionEnd.column - 1
}
},
mentionedInTheXMLDocument: false
};
});
return UIMethods;
}
_modifyType(returnType) {
if (/import\(".*?"\).default/.test(returnType)) {
const path = /(?<=import\(").*?(?="\).default)/.exec(returnType)?.[0];
const UI5Type = path?.startsWith("sap/")
? path.replace(/\//g, ".")
: path
? this.parser.fileReader.getClassNameFromPath(path)
: undefined;
if (UI5Type) {
returnType = UI5Type;
}
}
if (/import\(".*?"\)\.[a-zA-Z|$]*/.test(returnType)) {
const className = /(?<=import\(".*?"\)\.)[a-zA-Z|$]*/.exec(returnType)?.[0];
if (className) {
returnType = className;
}
}
return returnType;
}
_fillUI5Metadata(classInfo, fillTypes = false) {
this._fillUIDefine();
this.methods = this._fillMethods(undefined, fillTypes);
this.fields = this._fillFields(undefined, fillTypes);
}
_fillInterfaces() {
return [];
}
_fillAggregations() {
return [];
}
_fillEvents() {
return [];
}
_fillProperties() {
return [];
}
_fillAssociations() {
return [];
}
}
exports.CustomTSObject = CustomTSObject;