ui5plugin-parser
Version:
523 lines (522 loc) • 21.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StandardUIClass = void 0;
const ParserPool_1 = require("../../../parser/pool/ParserPool");
const MainLooper_1 = require("../jsparser/MainLooper");
const AbstractBaseClass_1 = require("./AbstractBaseClass");
const aXmlnsData = [
{
tag: "xmlns",
value: "sap.m"
},
{
tag: "xmlns:f",
value: "sap.f"
},
{
tag: "xmlns:c",
value: "sap.ui.core"
},
{
tag: "xmlns:l",
value: "sap.ui.layout"
},
{
tag: "xmlns:tnt",
value: "sap.tnt"
},
{
tag: "xmlns:table",
value: "sap.ui.table"
},
{
tag: "xmlns:unified",
value: "sap.ui.unified"
},
{
tag: "xmlns:viz",
value: "sap.viz"
},
{
tag: "xmlns:chart",
value: "sap.chart"
},
{
tag: "xmlns:gantt",
value: "sap.gantt"
},
{
tag: "xmlns:ovp",
value: "sap.ovp"
},
{
tag: "xmlns:mc",
value: "sap.suite.ui.microchart"
},
{
tag: "xmlns:commons",
value: "sap.ui.commons"
},
{
tag: "xmlns:comp",
value: "sap.ui.comp"
},
{
tag: "xmlns:uxap",
value: "sap.uxap"
}
];
const aFioriElementsControllers = [
"sap.suite.ui.generic.template.ObjectPage.view.Details",
"sap.suite.ui.generic.template.ListReport.view.ListReport"
];
class StandardUIClass extends AbstractBaseClass_1.AbstractBaseClass {
constructor(className, parser) {
super(className, parser);
this.methods = [];
if (aFioriElementsControllers.includes(className)) {
this.classExists = true;
this._addFieldsAndMethodsForFioriElements(className);
}
else {
this.classExists = !!this._findSAPNode(this.className) || className.endsWith(".library");
if (this.classExists) {
this._fillParentClassName();
this._fillMethods();
this._fillProperties();
this._fillFields();
this._fillEvents();
this._fillAggregations();
this._fullAssociations();
this._fillConstructor();
this._fillInterfaces();
this._fillDeprecated();
this._fillDescription();
this._enrichWithXmlnsProperties();
}
else if (className === "sap.ui.core.FragmentDefinition") {
this._enrichWithXmlnsProperties();
}
}
}
_fillDescription() {
const node = this.parser.nodeDAO.findNode(this.className);
const nodeDescription = node?.getMetadata()?.getRawMetadata()?.description ?? "";
this.description = StandardUIClass.adjustLinks(this.parser, nodeDescription);
}
_fillDeprecated() {
const SAPNode = this._findSAPNode(this.className);
this.deprecated = SAPNode?.getIsDeprecated() || false;
}
_addFieldsAndMethodsForFioriElements(className) {
const proxyFioriElementsClass = {
"sap.suite.ui.generic.template.ObjectPage.view.Details": {
methods: "sap.suite.ui.generic.template.ObjectPage.controllerFrameworkExtensions",
fields: "sap.suite.ui.generic.template.ObjectPage.extensionAPI.ExtensionAPI"
},
"sap.suite.ui.generic.template.ListReport.view.ListReport": {
methods: "sap.suite.ui.generic.template.ListReport.controllerFrameworkExtensions",
fields: "sap.suite.ui.generic.template.ListReport.extensionAPI.ExtensionAPI"
}
};
const neededClassForMethods = proxyFioriElementsClass[className]?.methods;
const neededClassForFields = proxyFioriElementsClass[className]?.fields;
if (neededClassForMethods) {
const SAPNode = this._findSAPNode(neededClassForMethods);
if (SAPNode) {
const methods = SAPNode.getMetadata()?.getRawMetadata()?.methods;
this.methods =
methods?.map((method) => {
const standardMethod = {
name: method.name.replace(`${neededClassForMethods}.`, ""),
visibility: method.visibility || "public",
description: method.description
? StandardUIClass.adjustLinks(this.parser, method.description)
: StandardUIClass.adjustLinks(this.parser, method.code),
params: method.parameters?.map((param) => {
const parameter = {
isOptional: param.optional || false,
name: param.name,
description: StandardUIClass.adjustLinks(this.parser, param.description),
type: param.types?.map((type) => type.value).join("|") || "any"
};
return parameter;
}) || [],
returnType: method.returnValue?.types?.map((type) => type.value).join("|") ||
method.returnValue?.type ||
"void",
isFromParent: false,
owner: this.className,
abstract: false,
static: false,
deprecated: method.deprecated || method.bIsDeprecated
};
return standardMethod;
}) || [];
}
}
if (neededClassForFields) {
const SAPNode = this._findSAPNode(neededClassForMethods);
if (SAPNode) {
this.fields = [
{
name: "extensionAPI",
description: SAPNode.getMetadata()?.getRawMetadata()?.description
? StandardUIClass.adjustLinks(this.parser, SAPNode.getMetadata().getRawMetadata().description
// eslint-disable-next-line no-mixed-spaces-and-tabs
)
: "Extension API",
type: neededClassForFields,
visibility: "public",
owner: this.className,
abstract: false,
static: false,
deprecated: false
}
];
}
}
}
_enrichWithXmlnsProperties() {
if (this.className === "sap.ui.core.mvc.View" || this.className === "sap.ui.core.FragmentDefinition") {
aXmlnsData.forEach(xmlnsData => {
this.properties.push({
name: xmlnsData.tag,
description: xmlnsData.value,
type: "string",
visibility: "public",
typeValues: [
{
text: xmlnsData.value,
description: xmlnsData.value
}
]
});
});
}
}
_fillMethods() {
this.methods = this._getStandardClassMethods(this.className, true);
}
_getStandardClassMethods(className, isParent) {
let classMethods = [];
const SAPNode = this._findSAPNode(className);
classMethods =
SAPNode?.getMethods().map((method) => {
let methodName = method.name.replace(`${this.className}.`, "");
if (methodName.indexOf(SAPNode.getMetadata()?.getRawMetadata()?.name) > -1) {
methodName = methodName.replace(SAPNode.getMetadata().getRawMetadata().name + ".", "");
}
const classMethod = {
name: methodName,
description: `${StandardUIClass.adjustLinks(this.parser, method.description)}`,
params: method.parameters
? method.parameters
.filter((parameter) => !parameter.depth)
.map((parameter) => {
return {
name: parameter.name + (parameter.optional ? "?" : ""),
description: StandardUIClass.adjustLinks(this.parser, parameter.description),
type: parameter.types
? parameter.types.map((type) => type.value).join("|")
: "any",
isOptional: parameter.optional || false
};
})
: [],
returnType: method.returnValue ? method.returnValue.type : "void",
isFromParent: !isParent,
api: this.parser.urlBuilder.getMarkupUrlForMethodApi(SAPNode, method.name),
visibility: method.visibility,
owner: this.className,
abstract: false,
static: false,
deprecated: method.deprecated || method.bIsDeprecated
};
this._removeFirstArgumentIfItIsEvent(classMethod);
this._addParametersForDataMethod(classMethod);
return classMethod;
}) || [];
return classMethods;
}
_removeFirstArgumentIfItIsEvent(method) {
if (method.name.startsWith("attach")) {
if (method.params?.length > 0) {
const param = method.params.find(param => param.name === "oData?");
if (param) {
method.params.splice(method.params.indexOf(param), 1);
}
}
}
}
_addParametersForDataMethod(method) {
if (method.name === "data" && method.params.length === 0) {
method.params.push({
type: "string",
name: "sCustomDataKey?",
description: "Unique custom data key",
isOptional: true
});
method.params.push({
type: "any",
name: "vData?",
description: "data for Custom Data",
isOptional: true
});
method.params.push({
type: "boolean",
name: "bWriteToDom?",
description: "Custom data key",
isOptional: true
});
}
}
_findSAPNode(className) {
return this.parser.nodeDAO.findNode(className);
}
static adjustLinks(parser, text = "") {
const matches = text.match(/<a target="_self"( .*?)? href=".*?"/g);
matches?.forEach(match => {
const hrefIndex = match.indexOf('href="') + 'href="'.length;
const urlBase = parser.urlBuilder.getUrlBase();
const newHref = `${urlBase}/#/` + match.substring(hrefIndex, match.length);
const replaceTo = match.substring(0, hrefIndex) + newHref;
text = text.replace(match, replaceTo);
});
return text;
}
static removeTags(text = "") {
let textWithoutTags = "";
let i = 0;
let tagOpened = 0;
let tagClosed = 0;
while (i < text.length) {
if (text[i] === "<") {
tagOpened++;
}
else if (text[i] === ">") {
textWithoutTags += " ";
tagClosed++;
}
else if (tagOpened === tagClosed) {
textWithoutTags += text[i];
}
i++;
}
textWithoutTags = textWithoutTags.trim();
return textWithoutTags;
}
_fillParentClassName() {
const SAPNode = this._findSAPNode(this.className);
if (SAPNode) {
const metadata = SAPNode.getMetadata()?.getRawMetadata();
if (metadata) {
this.parentClassNameDotNotation = metadata.extends;
this.abstract = !!metadata.abstract;
}
}
}
_fillFields() {
const SAPNode = this._findSAPNode(this.className);
this.fields =
SAPNode?.getFields().reduce((accumulator, { name, type, description, visibility, deprecated }) => {
const additionalDescription = this._generateAdditionalDescriptionFrom(type);
accumulator.push({
name: name,
type: type,
description: `${additionalDescription}\n${StandardUIClass.adjustLinks(this.parser, description)}`.trim(),
visibility: visibility,
owner: this.className,
abstract: false,
static: false,
deprecated: deprecated
});
return accumulator;
}, []) || [];
}
_fillProperties() {
this.properties = this._getStandardClassProperties(this.className);
}
_getStandardClassProperties(className) {
let classProperties = [];
const SAPNode = this._findSAPNode(className);
classProperties =
SAPNode?.getProperties().reduce((accumulator, { defaultValue, name, type, description, visibility }) => {
const additionalDescription = this._generateAdditionalDescriptionFrom(type);
accumulator.push({
name,
defaultValue: defaultValue.toString(),
type,
typeValues: this.generateTypeValues(type),
description: `${additionalDescription}\n${StandardUIClass.adjustLinks(this.parser, description)}`.trim(),
visibility
});
return accumulator;
}, []) || [];
const specialSettings = SAPNode?.getSpecialSettings().map(({ name, type, description, visibility }) => {
const additionalDescription = this._generateAdditionalDescriptionFrom(type);
return {
name,
defaultValue: "",
type,
typeValues: this.generateTypeValues(type),
description: `${additionalDescription}\n${StandardUIClass.adjustLinks(this.parser, description)}`.trim(),
visibility
};
}) || [];
classProperties.push(...specialSettings);
return classProperties;
}
_generateAdditionalDescriptionFrom(className) {
let additionalDescription = "";
const isThisClassFromAProject = !!ParserPool_1.default.getManifestForClass(className);
if (!isThisClassFromAProject) {
const SAPNode = this._findSAPNode(className);
additionalDescription =
SAPNode?.getProperties().reduce((accumulator, property) => {
accumulator += `${property.name}\n`;
return accumulator;
}, "") || "";
}
return additionalDescription;
}
generateTypeValues(type) {
let typeValues = super.generateTypeValues(type);
const isThisClassFromAProject = !!ParserPool_1.default.getManifestForClass(type);
if (typeValues.length === 0 && !isThisClassFromAProject) {
const typeNode = this._findSAPNode(type);
const metadata = typeNode?.getMetadata();
typeValues =
metadata?.rawMetadata?.properties?.map((property) => {
return {
text: `${property.name}`.replace(`${type}.`, ""),
description: StandardUIClass.adjustLinks(this.parser, property.description)
};
}) || [];
}
return typeValues;
}
_fillEvents() {
this.events = this._getStandardClassEvents(this.className);
}
_getStandardClassEvents(className) {
let classEvents = [];
const SAPNode = this._findSAPNode(className);
classEvents =
SAPNode?.getEvents().reduce((accumulator, event) => {
accumulator.push({
name: event.name,
description: StandardUIClass.adjustLinks(this.parser, event.description),
visibility: event.visibility,
params: event?.parameters
?.filter((parameter) => parameter.depth === 2)
.map((parameter) => {
return {
name: parameter.name,
type: parameter.type
};
})
});
return accumulator;
}, []) || [];
return classEvents;
}
_fillAggregations() {
this.aggregations = this._getStandardClassAggregations(this.className);
}
_getStandardClassAggregations(className) {
let classAggregations = [];
const SAPNode = this._findSAPNode(className);
classAggregations =
SAPNode?.getAggregations().reduce((accumulator, aggregation) => {
accumulator.push({
name: aggregation.name,
type: aggregation.type,
multiple: aggregation.cardinality === "0..n",
singularName: aggregation.singularName,
description: StandardUIClass.adjustLinks(this.parser, aggregation.description),
visibility: aggregation.visibility,
default: SAPNode.getMetadata()?.getUI5Metadata()?.defaultAggregation === aggregation.name
});
return accumulator;
}, []) || [];
return classAggregations;
}
_fullAssociations() {
this.associations = this._getStandardClassAssociations(this.className);
}
_getStandardClassAssociations(className) {
let classAssociation = [];
const SAPNode = this._findSAPNode(className);
classAssociation =
SAPNode?.getAssociations().reduce((accumulator, association) => {
accumulator.push({
name: association.name,
type: association.type,
description: StandardUIClass.adjustLinks(this.parser, association.description),
multiple: association.multiple || association.cardinality === "0..n",
singularName: association.singularName,
visibility: association.visibility
});
return accumulator;
}, []) || [];
return classAssociation;
}
_fillConstructor() {
const SAPNode = this._findSAPNode(this.className);
const metadata = SAPNode?.getMetadata();
if (metadata?.rawMetadata?.constructor?.codeExample) {
const constructor = metadata.rawMetadata.constructor;
let parameters = [];
if (!constructor.parameters) {
const codeExample = StandardUIClass.adjustLinks(this.parser, constructor.codeExample);
let parameterText = MainLooper_1.MainLooper.getEndOfChar("(", ")", codeExample);
parameterText = parameterText.substring(1, parameterText.length - 1); //remove ()
parameters = parameterText
? parameterText.split(", ").map(param => {
return {
name: param,
description: "",
type: "any",
isOptional: param.endsWith("?")
};
// eslint-disable-next-line no-mixed-spaces-and-tabs
})
: [];
}
else {
parameters = constructor.parameters
.filter((param) => param.depth === 0)
.map((param) => {
return {
name: param.name + (param.optional ? "?" : ""),
description: StandardUIClass.adjustLinks(param.description),
type: param.types.map((type) => type.name).join("|"),
isOptional: param.optional
};
});
}
this.methods.push({
name: "constructor",
description: StandardUIClass.adjustLinks(this.parser, constructor.description ?? constructor.codeExample),
params: parameters,
returnType: this.className,
isFromParent: false,
api: this.parser.urlBuilder.getUrlForClassApi(this),
visibility: "public",
owner: this.className,
abstract: false,
static: false,
deprecated: false
});
}
}
_fillInterfaces() {
const SAPNode = this._findSAPNode(this.className);
const metadata = SAPNode?.getMetadata();
if (metadata?.getRawMetadata()?.implements) {
this.interfaces = metadata?.getRawMetadata()?.implements;
}
}
}
exports.StandardUIClass = StandardUIClass;